From 4528e102a28221459ae4956a2e32105a8c065c59 Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Wed, 29 Jun 2022 07:47:38 +0200 Subject: [PATCH] Moved the UI event queue inside the UI engine itself, UI FSM update now becomes a periodic task --- openrtx/include/core/event.h | 2 +- openrtx/include/core/ui.h | 16 +++++++++++++--- openrtx/src/core/threads.c | 25 ++++--------------------- openrtx/src/ui/ui.c | 36 +++++++++++++++++++++++++++++++----- openrtx/src/ui/ui_main.c | 8 ++++---- openrtx/src/ui/ui_menu.c | 8 ++++---- openrtx/src/ui/ui_mode.c | 8 ++++---- 7 files changed, 61 insertions(+), 42 deletions(-) diff --git a/openrtx/include/core/event.h b/openrtx/include/core/event.h index 30792cfd..8a9db398 100644 --- a/openrtx/include/core/event.h +++ b/openrtx/include/core/event.h @@ -27,7 +27,7 @@ */ enum eventType_t { - EVENT_KBD = 0, + EVENT_KBD = 0, EVENT_STATUS = 1 }; diff --git a/openrtx/include/core/ui.h b/openrtx/include/core/ui.h index f122c080..6ce691a6 100644 --- a/openrtx/include/core/ui.h +++ b/openrtx/include/core/ui.h @@ -34,6 +34,8 @@ #define FREQ_DIGITS 8 // Time & Date digits #define TIMEDATE_DIGITS 10 +// Max number of UI events +#define MAX_NUM_EVENTS 16 enum uiScreen { @@ -218,6 +220,7 @@ void ui_init(); /** * This function writes the OpenRTX splash screen image into the framebuffer. + * * @param centered: if true the logo will be printed at the center of * the screen, otherwise it will be printed at the top of the screen. */ @@ -233,17 +236,24 @@ void ui_saveState(); /** * This function advances the User Interface FSM, basing on the * current radio state and the keys pressed. - * @param last_state: A local copy of the previous radio state - * @param event: An event from other threads + * * @param sync_rtx: If true RTX needs to be synchronized */ -void ui_updateFSM(event_t event, bool *sync_rtx); +void ui_updateFSM(bool *sync_rtx); /** * This function redraws the GUI based on the last radio state. */ void ui_updateGUI(); +/** + * Push an event to the UI event queue. + * + * @param event: event to be pushed. + * @return true on success false on failure. + */ +bool ui_pushEvent(const event_t event); + /** * This function terminates the User Interface. */ diff --git a/openrtx/src/core/threads.c b/openrtx/src/core/threads.c index a1171d37..92eaadf7 100644 --- a/openrtx/src/core/threads.c +++ b/openrtx/src/core/threads.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -50,9 +49,6 @@ pthread_mutex_t rtx_mutex; /* Mutex to avoid reading keyboard during display update */ pthread_mutex_t display_mutex; -/* Queue for sending and receiving ui update requests */ -queue_t ui_queue; - /** * \internal Task function in charge of updating the UI. */ @@ -78,16 +74,10 @@ void *ui_task(void *arg) while(1) { - // Read from the keyboard queue (returns 0 if no message is present) - // Copy keyboard_t keys from received void * pointer msg - event_t event; - event.value = 0; - (void) queue_pend(&ui_queue, &event.value, true); - // Lock mutex, read and write state pthread_mutex_lock(&state_mutex); // React to keypresses and update FSM inside state - ui_updateFSM(event, &sync_rtx); + ui_updateFSM(&sync_rtx); // Update state local copy ui_saveState(); // Unlock mutex @@ -127,10 +117,7 @@ void *ui_task(void *arg) gfx_render(); pthread_mutex_unlock(&display_mutex); - // We don't need a delay because we lock on incoming events - // TODO: Enable self refresh when a continuous visualization is enabled - // Update UI at ~33 FPS - //OSTimeDlyHMSM(0u, 0u, 0u, 30u, OS_OPT_TIME_HMSM_STRICT, &os_err); + sleepFor(0u, 30u); } } @@ -158,8 +145,7 @@ void *kbd_task(void *arg) event_t event; event.type = EVENT_KBD; event.payload = msg.value; - // Send keyboard status in queue - (void) queue_post(&ui_queue, event.value); + ui_pushEvent(event); } // Read keyboard state at 40Hz @@ -187,7 +173,7 @@ void *dev_task(void *arg) event_t dev_msg; dev_msg.type = EVENT_STATUS; dev_msg.payload = 0; - (void) queue_post(&ui_queue, dev_msg.value); + ui_pushEvent(dev_msg); // Execute state update thread every 1s sleepFor(1u, 0u); @@ -256,9 +242,6 @@ void create_threads() // Create display mutex pthread_mutex_init(&display_mutex, NULL); - // Create UI event queue - queue_init(&ui_queue); - // Create rtx radio thread pthread_t rtx_thread; pthread_attr_t rtx_attr; diff --git a/openrtx/src/ui/ui.c b/openrtx/src/ui/ui.c index 1ebba15a..b316cca0 100644 --- a/openrtx/src/ui/ui.c +++ b/openrtx/src/ui/ui.c @@ -1,8 +1,8 @@ /*************************************************************************** - * Copyright (C) 2020 by Federico Amedeo Izzo IU2NUO, * - * Niccolò Izzo IU2KIN * - * Frederik Saraci IU2NRO * - * Silvano Seva IU2KWO * + * Copyright (C) 2020 - 2022 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * Silvano Seva IU2KWO * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -243,6 +243,11 @@ bool redraw_needed = true; bool standby = false; long long last_event_tick = 0; +// UI event queue +uint8_t evQueue_rdPos; +uint8_t evQueue_wrPos; +event_t evQueue[MAX_NUM_EVENTS]; + layout_t _ui_calculateLayout() { // Horizontal line height @@ -929,7 +934,7 @@ void ui_saveState() last_state = state; } -void ui_updateFSM(event_t event, bool *sync_rtx) +void ui_updateFSM(bool *sync_rtx) { // User wants to power off the radio, so shutdown. if(!platform_pwrButtonStatus()) @@ -940,6 +945,14 @@ void ui_updateFSM(event_t event, bool *sync_rtx) return; } + // Check for events + if(evQueue_wrPos == evQueue_rdPos) return; + + // Pop an event from the queue + uint8_t newTail = (evQueue_rdPos + 1) % MAX_NUM_EVENTS; + event_t event = evQueue[evQueue_rdPos]; + evQueue_rdPos = newTail; + // Check if battery has enough charge to operate. // Check is skipped if there is an ongoing transmission, since the voltage // drop caused by the RF PA power absorption causes spurious triggers of @@ -1779,6 +1792,19 @@ void ui_updateGUI() } } +bool ui_pushEvent(const event_t event) +{ + uint8_t newHead = (evQueue_wrPos + 1) % MAX_NUM_EVENTS; + + // Queue is full + if(newHead == evQueue_rdPos) return false; + + evQueue[evQueue_wrPos] = event; + evQueue_wrPos = newHead; + + return true; +} + void ui_terminate() { } diff --git a/openrtx/src/ui/ui_main.c b/openrtx/src/ui/ui_main.c index 81a0f73a..61cc4205 100644 --- a/openrtx/src/ui/ui_main.c +++ b/openrtx/src/ui/ui_main.c @@ -1,8 +1,8 @@ /*************************************************************************** - * Copyright (C) 2020 by Federico Amedeo Izzo IU2NUO, * - * Niccolò Izzo IU2KIN * - * Frederik Saraci IU2NRO * - * Silvano Seva IU2KWO * + * Copyright (C) 2020 - 2022 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * Silvano Seva IU2KWO * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * diff --git a/openrtx/src/ui/ui_menu.c b/openrtx/src/ui/ui_menu.c index a8c1dbcf..be898cb4 100644 --- a/openrtx/src/ui/ui_menu.c +++ b/openrtx/src/ui/ui_menu.c @@ -1,8 +1,8 @@ /*************************************************************************** - * Copyright (C) 2020 by Federico Amedeo Izzo IU2NUO, * - * Niccolò Izzo IU2KIN * - * Frederik Saraci IU2NRO * - * Silvano Seva IU2KWO * + * Copyright (C) 2020 - 2022 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * Silvano Seva IU2KWO * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * diff --git a/openrtx/src/ui/ui_mode.c b/openrtx/src/ui/ui_mode.c index 8c7b6619..68c6ca3b 100644 --- a/openrtx/src/ui/ui_mode.c +++ b/openrtx/src/ui/ui_mode.c @@ -1,8 +1,8 @@ /*************************************************************************** - * Copyright (C) 2021 by Federico Amedeo Izzo IU2NUO, * - * Niccolò Izzo IU2KIN * - * Frederik Saraci IU2NRO * - * Silvano Seva IU2KWO * + * Copyright (C) 2021 - 2022 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * Silvano Seva IU2KWO * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by *