diff --git a/openrtx/include/ui.h b/openrtx/include/ui.h index 33a356df..9777a3c6 100644 --- a/openrtx/include/ui.h +++ b/openrtx/include/ui.h @@ -121,6 +121,8 @@ typedef struct ui_state_t } ui_state_t; extern layout_t layout; +// Copy of the radio state +extern state_t last_state; extern settings_t settings; extern const char *menu_items[]; extern const char *settings_items[]; @@ -146,6 +148,13 @@ void ui_init(); */ void ui_drawSplashScreen(); +/** + * This function updates the local copy of the radio state + * the local copy is called last_state + * and is accessible from all the UI code as extern variable. + */ +void ui_saveState(); + /** * This function advances the User Interface FSM, basing on the * current radio state and the keys pressed. @@ -157,9 +166,8 @@ void ui_updateFSM(event_t event, bool *sync_rtx); /** * This function redraws the GUI based on the last radio state. - * @param last_state: A local copy of the previous radio state */ -void ui_updateGUI(state_t last_state); +void ui_updateGUI(); /** * This function terminates the User Interface. diff --git a/openrtx/src/threads.c b/openrtx/src/threads.c index 61c292b8..2363f3cb 100644 --- a/openrtx/src/threads.c +++ b/openrtx/src/threads.c @@ -85,7 +85,6 @@ static void ui_task(void *arg) // Get initial state local copy OSMutexPend(&state_mutex, 0u, OS_OPT_PEND_BLOCKING, 0u, &os_err); - state_t last_state = state; OSMutexPost(&state_mutex, OS_OPT_POST_NONE, &os_err); // Initial GUI draw @@ -105,7 +104,7 @@ static void ui_task(void *arg) // React to keypresses and update FSM inside state ui_updateFSM(event, &sync_rtx); // Update state local copy - last_state = state; + ui_saveState(); // Unlock mutex OSMutexPost(&state_mutex, OS_OPT_POST_NONE, &os_err); @@ -130,7 +129,7 @@ static void ui_task(void *arg) } // Redraw GUI based on last state copy - ui_updateGUI(last_state); + ui_updateGUI(); // Lock display mutex and render display OSMutexPend(&display_mutex, 0u, OS_OPT_PEND_BLOCKING, 0u, &os_err); gfx_render(); diff --git a/openrtx/src/ui/ui.c b/openrtx/src/ui/ui.c index 590fcc6b..4af10806 100644 --- a/openrtx/src/ui/ui.c +++ b/openrtx/src/ui/ui.c @@ -76,14 +76,14 @@ /* UI main screen functions, their implementation is in "ui_main.c" */ extern void _ui_drawMainBackground(); -extern void _ui_drawMainTop(state_t* last_state); -extern void _ui_drawVFOMiddle(state_t* last_state); -extern void _ui_drawMEMMiddle(state_t* last_state); +extern void _ui_drawMainTop(); +extern void _ui_drawVFOMiddle(); +extern void _ui_drawMEMMiddle(); extern void _ui_drawVFOBottom(); extern void _ui_drawMEMBottom(); -extern void _ui_drawMainVFO(state_t* last_state); -extern void _ui_drawMainVFOInput(state_t* last_state, ui_state_t* ui_state); -extern void _ui_drawMainMEM(state_t* last_state); +extern void _ui_drawMainVFO(); +extern void _ui_drawMainVFOInput(ui_state_t* ui_state); +extern void _ui_drawMainMEM(); /* UI menu functions, their implementation is in "ui_menu.c" */ extern void _ui_drawMenuList(point_t pos, const char *entries[], uint8_t num_entries, uint8_t selected); extern void _ui_drawChannelList(point_t pos, uint8_t selected); @@ -94,11 +94,11 @@ extern void _ui_drawMenuContacts(ui_state_t* ui_state); extern void _ui_drawMenuSettings(ui_state_t* ui_state); extern void _ui_drawMenuInfo(ui_state_t* ui_state); #ifdef HAS_RTC -extern void _ui_drawSettingsTimeDate(state_t* last_state); -extern void _ui_drawSettingsTimeDateSet(state_t* last_state, ui_state_t* ui_state); +extern void _ui_drawSettingsTimeDate(); +extern void _ui_drawSettingsTimeDateSet(ui_state_t* ui_state); #endif extern void _ui_drawSettingsDisplay(ui_state_t* ui_state); -extern bool _ui_drawMacroMenu(state_t* last_state); +extern bool _ui_drawMacroMenu(); const char *menu_items[7] = { @@ -159,6 +159,7 @@ const color_t color_white = {255, 255, 255, 255}; const color_t yellow_fab413 = {250, 180, 19, 255}; layout_t layout; +state_t last_state; ui_state_t ui_state; settings_t settings; bool layout_ready = false; @@ -602,6 +603,11 @@ void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx) { #endif } +void ui_saveState() +{ + last_state = state; +} + void ui_updateFSM(event_t event, bool *sync_rtx) { // Check if battery has enough charge to operate @@ -1039,7 +1045,7 @@ void ui_updateFSM(event_t event, bool *sync_rtx) } } -void ui_updateGUI(state_t last_state) +void ui_updateGUI() { if(!layout_ready) { @@ -1051,15 +1057,15 @@ void ui_updateGUI(state_t last_state) { // VFO main screen case MAIN_VFO: - _ui_drawMainVFO(&last_state); + _ui_drawMainVFO(); break; // VFO frequency input screen case MAIN_VFO_INPUT: - _ui_drawMainVFOInput(&last_state, &ui_state); + _ui_drawMainVFOInput(&ui_state); break; // MEM main screen case MAIN_MEM: - _ui_drawMainMEM(&last_state); + _ui_drawMainMEM(); break; // Top menu screen case MENU_TOP: @@ -1079,7 +1085,7 @@ void ui_updateGUI(state_t last_state) break; // Macro menu case MENU_MACRO: - _ui_drawMacroMenu(&last_state); + _ui_drawMacroMenu(); break; // Settings menu screen case MENU_SETTINGS: @@ -1092,11 +1098,11 @@ void ui_updateGUI(state_t last_state) #ifdef HAS_RTC // Time&Date settings screen case SETTINGS_TIMEDATE: - _ui_drawSettingsTimeDate(&last_state); + _ui_drawSettingsTimeDate(); break; // Time&Date settings screen, edit mode case SETTINGS_TIMEDATE_SET: - _ui_drawSettingsTimeDateSet(&last_state, &ui_state); + _ui_drawSettingsTimeDateSet(&ui_state); break; #endif case SETTINGS_DISPLAY: diff --git a/openrtx/src/ui/ui_main.c b/openrtx/src/ui/ui_main.c index 1bc3a881..5f7a84ec 100644 --- a/openrtx/src/ui/ui_main.c +++ b/openrtx/src/ui/ui_main.c @@ -31,13 +31,13 @@ void _ui_drawMainBackground() gfx_drawHLine(SCREEN_HEIGHT - layout.bottom_h - 1, layout.hline_h, color_grey); } -void _ui_drawMainTop(state_t* last_state) +void _ui_drawMainTop() { #ifdef HAS_RTC // Print clock on top bar char clock_buf[9] = ""; - snprintf(clock_buf, sizeof(clock_buf), "%02d:%02d:%02d", last_state->time.hour, - last_state->time.minute, last_state->time.second); + snprintf(clock_buf, sizeof(clock_buf), "%02d:%02d:%02d", last_state.time.hour, + last_state.time.minute, last_state.time.second); gfx_print(layout.top_left, clock_buf, layout.top_font, TEXT_ALIGN_CENTER, color_white); #endif @@ -47,11 +47,11 @@ void _ui_drawMainTop(state_t* last_state) uint16_t bat_height = layout.top_h - (layout.status_v_pad * 2); point_t bat_pos = {SCREEN_WIDTH - bat_width - layout.horizontal_pad, layout.status_v_pad}; - gfx_drawBattery(bat_pos, bat_width, bat_height, last_state->charge); + gfx_drawBattery(bat_pos, bat_width, bat_height, last_state.charge); // Print radio mode on top bar char mode[4] = ""; - switch(last_state->channel.mode) + switch(last_state.channel.mode) { case FM: strcpy(mode, "FM"); @@ -64,42 +64,42 @@ void _ui_drawMainTop(state_t* last_state) color_white); } -void _ui_drawVFOMiddle(state_t* last_state) +void _ui_drawVFOMiddle() { // Print VFO frequencies char freq_buf[20] = ""; snprintf(freq_buf, sizeof(freq_buf), " Rx:%03lu.%05lu", - (unsigned long)last_state->channel.rx_frequency/1000000, - (unsigned long)last_state->channel.rx_frequency%1000000/10); + (unsigned long)last_state.channel.rx_frequency/1000000, + (unsigned long)last_state.channel.rx_frequency%1000000/10); gfx_print(layout.line2_left, freq_buf, layout.line2_font, TEXT_ALIGN_CENTER, color_white); snprintf(freq_buf, sizeof(freq_buf), " Tx:%03lu.%05lu", - (unsigned long)last_state->channel.tx_frequency/1000000, - (unsigned long)last_state->channel.tx_frequency%1000000/10); + (unsigned long)last_state.channel.tx_frequency/1000000, + (unsigned long)last_state.channel.tx_frequency%1000000/10); gfx_print(layout.line3_left, freq_buf, layout.line3_font, TEXT_ALIGN_CENTER, color_white); } -void _ui_drawMEMMiddle(state_t* last_state) +void _ui_drawMEMMiddle() { // Print Channel name - gfx_print(layout.line1_left, last_state->channel.name, layout.line1_font, TEXT_ALIGN_CENTER, + gfx_print(layout.line1_left, last_state.channel.name, layout.line1_font, TEXT_ALIGN_CENTER, color_white); // Print Channel frequencies char freq_buf[20] = ""; snprintf(freq_buf, sizeof(freq_buf), " Rx:%03lu.%05lu", - (unsigned long)last_state->channel.rx_frequency/1000000, - (unsigned long)last_state->channel.rx_frequency%1000000/10); + (unsigned long)last_state.channel.rx_frequency/1000000, + (unsigned long)last_state.channel.rx_frequency%1000000/10); gfx_print(layout.line2_left, freq_buf, layout.line2_font, TEXT_ALIGN_CENTER, color_white); snprintf(freq_buf, sizeof(freq_buf), " Tx:%03lu.%05lu", - (unsigned long)last_state->channel.tx_frequency/1000000, - (unsigned long)last_state->channel.tx_frequency%1000000/10); + (unsigned long)last_state.channel.tx_frequency/1000000, + (unsigned long)last_state.channel.tx_frequency%1000000/10); gfx_print(layout.line3_left, freq_buf, layout.line3_font, TEXT_ALIGN_CENTER, color_white); } -void _ui_drawVFOMiddleInput(state_t* last_state, ui_state_t* ui_state) +void _ui_drawVFOMiddleInput(ui_state_t* ui_state) { // Add inserted number to string, skipping "Rx: "/"Tx: " and "." uint8_t insert_pos = ui_state->input_position + 3; @@ -127,8 +127,8 @@ void _ui_drawVFOMiddleInput(state_t* last_state, ui_state_t* ui_state) color_white); } snprintf(freq_buf, sizeof(freq_buf), " Tx:%03lu.%05lu", - (unsigned long)last_state->channel.tx_frequency/1000000, - (unsigned long)last_state->channel.tx_frequency%1000000/10); + (unsigned long)last_state.channel.tx_frequency/1000000, + (unsigned long)last_state.channel.tx_frequency%1000000/10); gfx_print(layout.line3_left, freq_buf, layout.line3_font, TEXT_ALIGN_CENTER, color_white); } @@ -159,11 +159,11 @@ void _ui_drawVFOMiddleInput(state_t* last_state, ui_state_t* ui_state) } } -void _ui_drawBottom(state_t *last_state) +void _ui_drawBottom() { // Squelch bar - float rssi = last_state->rssi; - float squelch = last_state->sqlLevel / 16.0f; + float rssi = last_state.rssi; + float squelch = last_state.sqlLevel / 16.0f; point_t smeter_pos = { 0, layout.bottom_left.y + layout.status_v_pad + layout.text_v_offset - @@ -171,29 +171,29 @@ void _ui_drawBottom(state_t *last_state) gfx_drawSmeter(smeter_pos, SCREEN_WIDTH, layout.bottom_h - 1, rssi, squelch); } -void _ui_drawMainVFO(state_t* last_state) +void _ui_drawMainVFO() { gfx_clearScreen(); _ui_drawMainBackground(); - _ui_drawMainTop(last_state); - _ui_drawVFOMiddle(last_state); - _ui_drawBottom(last_state); + _ui_drawMainTop(); + _ui_drawVFOMiddle(); + _ui_drawBottom(); } -void _ui_drawMainVFOInput(state_t* last_state, ui_state_t* ui_state) +void _ui_drawMainVFOInput(ui_state_t* ui_state) { gfx_clearScreen(); _ui_drawMainBackground(); - _ui_drawMainTop(last_state); - _ui_drawVFOMiddleInput(last_state, ui_state); - _ui_drawBottom(last_state); + _ui_drawMainTop(); + _ui_drawVFOMiddleInput(ui_state); + _ui_drawBottom(); } -void _ui_drawMainMEM(state_t* last_state) +void _ui_drawMainMEM() { gfx_clearScreen(); _ui_drawMainBackground(); - _ui_drawMainTop(last_state); - _ui_drawMEMMiddle(last_state); - _ui_drawBottom(last_state); + _ui_drawMainTop(); + _ui_drawMEMMiddle(); + _ui_drawBottom(); } diff --git a/openrtx/src/ui/ui_menu.c b/openrtx/src/ui/ui_menu.c index a37d218b..332de9a2 100644 --- a/openrtx/src/ui/ui_menu.c +++ b/openrtx/src/ui/ui_menu.c @@ -135,10 +135,14 @@ int _ui_getInfoEntryName(char *buf, uint8_t max_len, uint8_t index) int _ui_getInfoValueName(char *buf, uint8_t max_len, uint8_t index) { if(index >= info_num) return -1; - uint8_t value = 0; if(strcmp(info_items[index], "Model") == 0) - value = 0; - snprintf(buf, max_len, "%d", value); + snprintf(buf, max_len, "%s", ""); + else if(strcmp(info_items[index], "Bat. Voltage") == 0) + snprintf(buf, max_len, "%.1fV", last_state.v_bat); + else if(strcmp(info_items[index], "Bat. Charge") == 0) + snprintf(buf, max_len, "%.1f%%", last_state.charge); + else if(strcmp(info_items[index], "RSSI") == 0) + snprintf(buf, max_len, "%.1fdBm", last_state.rssi); return 0; } int _ui_getZoneName(char *buf, uint8_t max_len, uint8_t index) @@ -241,7 +245,7 @@ void _ui_drawSettingsDisplay(ui_state_t* ui_state) } #ifdef HAS_RTC -void _ui_drawSettingsTimeDate(state_t* last_state) +void _ui_drawSettingsTimeDate() { gfx_clearScreen(); // Print "Time&Date" on top bar @@ -251,16 +255,16 @@ void _ui_drawSettingsTimeDate(state_t* last_state) char date_buf[10] = ""; char time_buf[10] = ""; snprintf(date_buf, sizeof(date_buf), "%02d/%02d/%02d", - last_state->time.date, last_state->time.month, last_state->time.year); + last_state.time.date, last_state.time.month, last_state.time.year); snprintf(time_buf, sizeof(time_buf), "%02d:%02d:%02d", - last_state->time.hour, last_state->time.minute, last_state->time.second); + last_state.time.hour, last_state.time.minute, last_state.time.second); gfx_print(layout.line2_left, date_buf, layout.line2_font, TEXT_ALIGN_CENTER, color_white); gfx_print(layout.line3_left, time_buf, layout.line3_font, TEXT_ALIGN_CENTER, color_white); } -void _ui_drawSettingsTimeDateSet(state_t* last_state, ui_state_t* ui_state) +void _ui_drawSettingsTimeDateSet(ui_state_t* ui_state) { (void) last_state; @@ -301,7 +305,7 @@ void _ui_drawSettingsTimeDateSet(state_t* last_state, ui_state_t* ui_state) } #endif -bool _ui_drawMacroMenu(state_t* last_state) { +bool _ui_drawMacroMenu() { // Header gfx_print(layout.top_left, "Macro Menu", layout.top_font, TEXT_ALIGN_CENTER, color_white); @@ -310,14 +314,14 @@ bool _ui_drawMacroMenu(state_t* last_state) { yellow_fab413); char code_str[11] = { 0 }; snprintf(code_str, 11, " %6.1f", - ctcss_tone[last_state->channel.fm.txTone]/10.0f); + ctcss_tone[last_state.channel.fm.txTone]/10.0f); gfx_print(layout.line1_left, code_str, layout.top_font, TEXT_ALIGN_LEFT, color_white); gfx_print(layout.line1_left, "2 ", layout.top_font, TEXT_ALIGN_CENTER, yellow_fab413); char encdec_str[9] = { 0 }; - bool tone_tx_enable = last_state->channel.fm.txToneEn; - bool tone_rx_enable = last_state->channel.fm.rxToneEn; + bool tone_tx_enable = last_state.channel.fm.txToneEn; + bool tone_rx_enable = last_state.channel.fm.rxToneEn; if (tone_tx_enable && tone_rx_enable) snprintf(encdec_str, 9, " E+D"); else if (tone_tx_enable && !tone_rx_enable) @@ -331,14 +335,14 @@ bool _ui_drawMacroMenu(state_t* last_state) { gfx_print(layout.line1_right, "3 ", layout.top_font, TEXT_ALIGN_RIGHT, yellow_fab413); char pow_str[9] = { 0 }; - snprintf(pow_str, 9, "%.1gW", last_state->channel.power); + snprintf(pow_str, 9, "%.1gW", last_state.channel.power); gfx_print(layout.line1_right, pow_str, layout.top_font, TEXT_ALIGN_RIGHT, color_white); // Second row gfx_print(layout.line2_left, "4", layout.top_font, TEXT_ALIGN_LEFT, yellow_fab413); char bw_str[8] = { 0 }; - switch (last_state->channel.bandwidth) + switch (last_state.channel.bandwidth) { case BW_12_5: snprintf(bw_str, 8, " 12.5"); @@ -355,7 +359,7 @@ bool _ui_drawMacroMenu(state_t* last_state) { gfx_print(layout.line2_left, "5 ", layout.top_font, TEXT_ALIGN_CENTER, yellow_fab413); char mode_str[9] = ""; - switch(last_state->channel.mode) + switch(last_state.channel.mode) { case FM: snprintf(mode_str, 9," FM"); @@ -384,7 +388,7 @@ bool _ui_drawMacroMenu(state_t* last_state) { gfx_print(layout.line3_right, "Sav", layout.top_font, TEXT_ALIGN_RIGHT, color_white); // Squelch bar - uint16_t squelch_width = SCREEN_WIDTH / 16 * last_state->sqlLevel; + uint16_t squelch_width = SCREEN_WIDTH / 16 * last_state.sqlLevel; point_t squelch_pos = { layout.bottom_left.x, layout.bottom_left.y + layout.status_v_pad + layout.text_v_offset -