diff --git a/Core/Src/app_gui.c b/Core/Src/app_gui.c index 21404eb..34dbb2e 100644 --- a/Core/Src/app_gui.c +++ b/Core/Src/app_gui.c @@ -12,6 +12,7 @@ #include "queue.h" #include "ufb/framebuffer.h" #include "ufb/fb_text.h" +#include "ufb/fb_7seg.h" #define MAX_TEMP 400 @@ -23,12 +24,18 @@ typedef void (*screen_t)(GuiEvent event); static struct State { float oven_temp; - float soc_temp; + //float soc_temp; + + // manual mode controls int set_temp; int set_temp_wheel; bool heater_enabled; + bool pushed; + bool paint_needed; + uint32_t last_tick_event; uint32_t push_tick; + uint32_t last_read_temp_tick; // true if the button is still held since init (i.e. the push action should not work as "enter") bool initial_pushed; @@ -42,6 +49,10 @@ static uint32_t push_time() { return s_app.pushed ? (xTaskGetTickCount() - s_app.push_tick) : 0; } +static void request_paint() { + s_app.paint_needed = true; +} + static void screen_home(GuiEvent event); static void screen_manual(GuiEvent event); @@ -50,7 +61,7 @@ static void screen_manual_menu(GuiEvent event); static void draw_common_overlay(); -static void input_sound_effect(GuiEvent event); +static void input_sound_effect(); static void switch_screen(screen_t pScreen, bool init); @@ -77,37 +88,59 @@ void app_task_gui(void *argument) ulTaskNotifyTake(pdTRUE, portMAX_DELAY); PUTS("GUI task starts\r\n"); + s_app.last_tick_event = xTaskGetTickCount(); + switch_screen(screen_home, true); while (1) { - s_app.oven_temp = app_temp_read_oven(); - s_app.soc_temp = app_temp_read_soc(); + s_app.paint_needed = false; uint32_t message = GUI_EVENT_NONE; - osMessageQueueGet(guiEventQueHandle, &message, NULL, pdMS_TO_TICKS(50)); + int32_t ticks_remain = (int32_t) pdMS_TO_TICKS(10) - (int32_t)(xTaskGetTickCount() - s_app.last_tick_event); + if (ticks_remain < 0) { + ticks_remain = 0; + } + osMessageQueueGet(guiEventQueHandle, &message, NULL, ticks_remain); + + uint32_t tickNow = xTaskGetTickCount(); + + // 10ms tick event + if (tickNow - s_app.last_tick_event > pdMS_TO_TICKS(10)) { + s_app.screen(GUI_EVENT_TICK); + s_app.last_tick_event = tickNow; + } + + if (tickNow - s_app.last_read_temp_tick > pdMS_TO_TICKS(250)) { + s_app.oven_temp = app_temp_read_oven(); + //s_app.soc_temp = app_temp_read_soc(); + request_paint(); + s_app.last_read_temp_tick = tickNow; + } switch (message) { case GUI_EVENT_KNOB_PRESS: s_app.pushed = true; - s_app.push_tick = xTaskGetTickCount(); + s_app.push_tick = tickNow; break; case GUI_EVENT_KNOB_RELEASE: s_app.pushed = false; - break; - default: + if (s_app.initial_pushed) { + s_app.initial_pushed = false; + message = GUI_EVENT_NONE; + } break; } - if (s_app.initial_pushed && message == GUI_EVENT_KNOB_RELEASE) { - s_app.initial_pushed = false; - } else { - fb_clear(); - draw_common_overlay(); - + if (message != GUI_EVENT_NONE) { s_app.screen(message); + } + if (s_app.paint_needed) { + fb_clear(); + draw_common_overlay(); + s_app.screen(GUI_EVENT_PAINT); fb_blit(); } } @@ -118,6 +151,7 @@ void app_task_gui(void *argument) static void switch_screen(screen_t pScreen, bool init) { s_app.initial_pushed = s_app.pushed; s_app.screen = pScreen; + request_paint(); if (init) { pScreen(GUI_EVENT_SCREEN_INIT); @@ -129,25 +163,16 @@ static void draw_common_overlay() { SPRINTF(tmp, "%3.1f°C →%3d°C", s_app.oven_temp, s_app.set_temp); fb_text(3, 3, tmp, FONT_3X5, 1); -// -// SPRINTF(tmp, "Tsoc=%.1f°C", s_app.soc_temp); -// fb_text(3, 19, tmp, FONT_5X7, 1); if (s_app.heater_enabled) { - fb_frame(0, 0, FBW, FBH, 2, 1); + fb_frame(0, 0, FBW, 11, 2, 1); } } /** Play input sound effect if this is an input event */ -static void input_sound_effect(GuiEvent event) +static void input_sound_effect() { - switch (event) { - case GUI_EVENT_KNOB_PLUS: - case GUI_EVENT_KNOB_MINUS: - case GUI_EVENT_KNOB_RELEASE: - app_buzzer_beep(); - break; - } + app_buzzer_beep(); } // ------------- home screen ---------------- @@ -183,7 +208,6 @@ static void screen_home(GuiEvent event) static void screen_manual(GuiEvent event) { if (event == GUI_EVENT_SCREEN_INIT) { - s_app.set_temp_wheel = 0; return; } @@ -193,26 +217,33 @@ static void screen_manual(GuiEvent event) return; } - input_sound_effect(event); - switch (event) { case GUI_EVENT_KNOB_RELEASE: - if (s_app.initial_pushed) { - s_app.initial_pushed = false; - break; - } + input_sound_effect(); s_app.heater_enabled ^= 1; app_heater_enable(s_app.heater_enabled); + request_paint(); break; case GUI_EVENT_KNOB_PLUS: + input_sound_effect(); s_app.set_temp_wheel++; calc_set_temp(); + request_paint(); break; case GUI_EVENT_KNOB_MINUS: + input_sound_effect(); s_app.set_temp_wheel--; calc_set_temp(); + request_paint(); + break; + + case GUI_EVENT_PAINT: + fb_7seg_number(4, 40, 12, 20, 2, 2, + 1, + s_app.set_temp, 3, 0 + ); break; } } @@ -233,7 +264,8 @@ static void manual_menu_cb(int opt) { break; case 1: - // Close menu + s_app.heater_enabled = false; + app_heater_enable(false); switch_screen(screen_home, true); break; } @@ -265,32 +297,37 @@ void screen_menu(GuiEvent event, const char **options, menu_callback_t cb) { return; } - input_sound_effect(event); - - for (int i = 0; i < s_app.menu_len; i++) { - fbcolor_t color = s_app.menu_pos != i; - fbpos_t y = 27 + i * 10; - fb_rect(0, y, 64, 10, !color); - fb_text(1, y + 1, options[i], FONT_5X7, color); - // ensure the text doesnt escape the screen - fb_vline(63, y, 10, !color); - } - switch (event) { // the button is held! release is what activates the button case GUI_EVENT_KNOB_RELEASE: + input_sound_effect(); cb(s_app.menu_pos); break; case GUI_EVENT_KNOB_PLUS: if (s_app.menu_pos < s_app.menu_len - 1) { s_app.menu_pos++; + input_sound_effect(); + request_paint(); } break; case GUI_EVENT_KNOB_MINUS: if (s_app.menu_pos > 0) { s_app.menu_pos--; + input_sound_effect(); + request_paint(); + } + break; + + case GUI_EVENT_PAINT: + for (int i = 0; i < s_app.menu_len; i++) { + fbcolor_t color = s_app.menu_pos != i; + fbpos_t y = 27 + i * 10; + fb_rect(0, y, 64, 10, !color); + fb_text(1, y + 1, options[i], FONT_5X7, color); + // ensure the text doesnt escape the screen + fb_vline(63, y, 10, !color); } break; } diff --git a/Core/Src/app_gui.h b/Core/Src/app_gui.h index ca07142..768cdc5 100644 --- a/Core/Src/app_gui.h +++ b/Core/Src/app_gui.h @@ -16,8 +16,13 @@ void app_task_gui(void *argument); typedef enum GuiEvent { /// No event, zero; This is a default value. GUI_EVENT_NONE = 0, + /// Cause redraw + GUI_EVENT_PAINT = 0, /// Used as the argument when initing a screen GUI_EVENT_SCREEN_INIT = 1, + /// Time tick, used to carry timing to the screen functions. + /// This tick has 10ms interval + GUI_EVENT_TICK = 2, /// Knob rotate CW GUI_EVENT_KNOB_PLUS, /// Knob rotate CCW