diff --git a/src/app_config.h b/src/app_config.h index 4e72695..8767bd9 100644 --- a/src/app_config.h +++ b/src/app_config.h @@ -10,6 +10,7 @@ #define CIRCUIT_COUNT 4 #define SCHEDULE_COUNT 4 +#define MENU_AUTOEXIT_TIME_S 120 struct __attribute__((packed)) ScheduleTime { bool enable; diff --git a/src/screens/app_gui.c b/src/screens/app_gui.c index 56662b7..7310e1b 100644 --- a/src/screens/app_gui.c +++ b/src/screens/app_gui.c @@ -5,8 +5,9 @@ #include #include #include "app_gui.h" -#include "../lcd/lcdbuf.h" +#include "lcd/lcdbuf.h" #include "lcd.h" +#include "app_config.h" struct State s_app = {}; @@ -26,18 +27,38 @@ char sbuf[100]; void gui_init() { switch_screen(screen_home, true); - s_app.last_tick_time = timestamp(); + rtc_get_time(&s_app.rtc_time); LcdBuffer_Init(&lcd, CGROM_A00, CGRAM_CZ); } void gui_loop_iter(GuiEvent message) { - uint32_t tickNow = timestamp(); + uint32_t tickNow = timestamp_ms(); + + // screen auto-close + if (s_app.screen != screen_home && s_app.screen != screen_cyklus) { + if ((tickNow - s_app.screen_open_time) >= (MENU_AUTOEXIT_TIME_S * 1000)) { + switch_screen(screen_home, true); + } + } + + // Read RTC every second + if (tickNow - s_app.last_1s_time >= 1000) { + s_app.screen(GUI_EVENT_SCREEN_TICK_1S); + rtc_get_time(&s_app.rtc_time); // now is a good time to update timestamp - we could just increment it though + s_app.last_1s_time = tickNow; + } + + // 100ms tick event + if (tickNow - s_app.last_100ms_time >= 100) { + s_app.screen(GUI_EVENT_SCREEN_TICK_100MS); + s_app.last_100ms_time = tickNow; + } // 10ms tick event - if (tickNow - s_app.last_tick_time > 10) { + if (tickNow - s_app.last_10ms_time >= 10) { s_app.screen(GUI_EVENT_SCREEN_TICK_10MS); - s_app.last_tick_time = tickNow; + s_app.last_10ms_time = tickNow; } if (message != GUI_EVENT_NONE) { @@ -68,12 +89,18 @@ void switch_screen(screen_t pScreen, bool init) { return; } + s_app.screen_open_time = timestamp_ms(); s_app.screen = pScreen; LcdBuffer_Clear(&lcd); LcdBuffer_SetCursor(&lcd, 0, 0, CURSOR_NONE); // always start with a hidden cursor. If the page wants a visible cursor, it should do that in PAINT request_paint(); + // Reset the timers, so the screen has nicely aligned events + s_app.last_10ms_time = s_app.last_100ms_time = s_app.last_1s_time = timestamp_ms(); + // also read time so we have the latest greatest + rtc_get_time(&s_app.rtc_time); + if (init) { pScreen(GUI_EVENT_SCREEN_INIT); } diff --git a/src/screens/app_gui.h b/src/screens/app_gui.h index d7916c5..4e77128 100644 --- a/src/screens/app_gui.h +++ b/src/screens/app_gui.h @@ -10,6 +10,7 @@ #include #include "gui_event.h" #include "lcd/lcdbuf.h" +#include "ds_rtc.h" // 🌢🅰🅱🅲🅳❶❷❸❹⊛¤▌↑↓✔ @@ -25,7 +26,7 @@ extern struct LcdBuffer lcd; typedef void (*screen_t)(GuiEvent event); -static inline uint32_t timestamp() { +static inline uint32_t timestamp_ms() { return to_ms_since_boot(get_absolute_time()); } @@ -64,13 +65,19 @@ void screen_program_edit(GuiEvent event); // XXX other prototypes struct State { + struct rtc_time rtc_time; + /// Repaint was requested from the screen code bool paint_needed; /// Pointer to the currently active screen func screen_t screen; - uint32_t last_tick_time; + uint32_t last_10ms_time; + uint32_t last_100ms_time; + uint32_t last_1s_time; + + uint32_t screen_open_time; }; extern struct State s_app; diff --git a/src/screens/gui_event.h b/src/screens/gui_event.h index 57485c2..0e0a5fc 100644 --- a/src/screens/gui_event.h +++ b/src/screens/gui_event.h @@ -10,12 +10,14 @@ typedef enum GuiEvent { /// No event, zero; This is a default value. GUI_EVENT_NONE = 0, /// Cause redraw - GUI_EVENT_PAINT = 0, + GUI_EVENT_PAINT, /// Used as the argument when initing a screen - GUI_EVENT_SCREEN_INIT = 1, + GUI_EVENT_SCREEN_INIT, /// Time tick, used to carry timing to the screen functions. /// This tick has 10ms interval - GUI_EVENT_SCREEN_TICK_10MS = 2, + GUI_EVENT_SCREEN_TICK_10MS, + GUI_EVENT_SCREEN_TICK_100MS, + GUI_EVENT_SCREEN_TICK_1S, /// Keypad GUI_EVENT_KEY_0 = '0', GUI_EVENT_KEY_1, diff --git a/src/screens/screen_cyklus.c b/src/screens/screen_cyklus.c index c83b431..41dbf9d 100644 --- a/src/screens/screen_cyklus.c +++ b/src/screens/screen_cyklus.c @@ -10,15 +10,11 @@ #include "gui_event.h" #include "app_io.h" #include "app_config.h" -#include "ds_rtc.h" static int phase = 0; static uint32_t phase_seconds = 0; static uint32_t phase_seconds_max = 0; -static uint8_t last_secs = 0; -static struct rtc_time time; - static void end_cycle() { open_valve(0); } @@ -36,25 +32,22 @@ void screen_cyklus(GuiEvent event) phase_seconds = 0; start_branch(); break; - case GUI_EVENT_SCREEN_TICK_10MS: - last_secs = time.second; - rtc_get_time(&time); - if (time.second != last_secs) { - phase_seconds += 1; - if (phase_seconds >= phase_seconds_max) { - phase += 1; - if (phase >= CIRCUIT_COUNT) { - end_cycle(); - switch_screen(screen_home, true); - return; - } + case GUI_EVENT_SCREEN_TICK_1S: + phase_seconds += 1; - start_branch(); - phase_seconds = 0; + if (phase_seconds >= phase_seconds_max) { + phase += 1; + if (phase >= CIRCUIT_COUNT) { + end_cycle(); + switch_screen(screen_home, true); + return; } - request_paint(); + + start_branch(); + phase_seconds = 0; } + request_paint(); break; case GUI_EVENT_PAINT: diff --git a/src/screens/screen_home.c b/src/screens/screen_home.c index 4bf17b3..c698931 100644 --- a/src/screens/screen_home.c +++ b/src/screens/screen_home.c @@ -9,37 +9,28 @@ #include #include "app_gui.h" #include "gui_event.h" -#include "ds_rtc.h" #include "app_io.h" #include "app_config.h" -static uint32_t last_time = 0; -static struct rtc_time rtc_time = {}; static uint16_t moisture_pt = 0; -static uint8_t showbuf_wp = 0; - void screen_home(GuiEvent event) { - uint32_t now = timestamp(); - uint32_t elapsed = now - last_time; - switch (event) { case GUI_EVENT_SCREEN_INIT: // pass - case GUI_EVENT_SCREEN_TICK_10MS: - if (elapsed >= 100) { - last_time = now; - rtc_get_time(&rtc_time); - moisture_pt = moisture_convert(moisture_read()); - request_paint(); - } + case GUI_EVENT_SCREEN_TICK_100MS: + moisture_pt = moisture_convert(moisture_read()); + request_paint(); break; - case GUI_EVENT_PAINT:; - // TODO + case GUI_EVENT_PAINT: + sprintf(sbuf, " %2d:%02d:%02d %3d%% 🌢 ", + s_app.rtc_time.hour, + s_app.rtc_time.minute, + s_app.rtc_time.second, + moisture_pt); - sprintf(sbuf, " %2d:%02d:%02d %3d%% 🌢 ", rtc_time.hour, rtc_time.minute, rtc_time.second, moisture_pt); LcdBuffer_Write(&lcd, 0, 0, sbuf); LcdBuffer_Write(&lcd, 1, 0, "Plán. závlaha 7:15"); diff --git a/src/screens/screen_set_time.c b/src/screens/screen_set_time.c index 8148b1f..455f0f8 100644 --- a/src/screens/screen_set_time.c +++ b/src/screens/screen_set_time.c @@ -12,9 +12,8 @@ void screen_set_time(GuiEvent event) { switch (event) { case GUI_EVENT_SCREEN_INIT: - rtc_get_time(&time); // so it's shown in the preview -// time.hour = 0; -// time.minute = 0; + time.hour = s_app.rtc_time.hour; + time.minute = s_app.rtc_time.minute; time.second = 0; cursor = 0; break;