rework refresh display

This commit is contained in:
liquidraver
2026-07-04 14:15:31 +02:00
parent 74aa3810ee
commit 38b8ff07cf
6 changed files with 43 additions and 33 deletions
+10 -7
View File
@@ -63,7 +63,6 @@ LOG_MODULE_REGISTER(ui_pages, CONFIG_ZEPHCORE_BOARD_LOG_LEVEL);
#define UI_COLOR_TITLE 0xffde /* warm white */
#define UI_COLOR_LABEL 0x8410 /* muted gray */
#define UI_COLOR_VALUE MC_COLOR_WHITE
#define UI_COLOR_SECONDARY 0xbdf7 /* soft gray-white */
#define UI_COLOR_OK 0x07e0
#define UI_COLOR_ACTIVE UI_COLOR_OK
#define UI_COLOR_WARN 0xffa0
@@ -383,6 +382,14 @@ static bool use_compact_color_home(void)
return mc_display_has_color() && DISP_W <= 180 && DISP_H <= 100;
}
/* Short label for the current LoRa radio state, shared across pages. */
static const char *radio_state_label(void)
{
return state.lora_tx_active ? "TX" :
state.lora_in_rx ? "RX" :
state.lora_radio_ready ? "RDY" : "WAIT";
}
static uint8_t clamp_activity_delta(uint32_t delta)
{
return (delta > 15U) ? 15U : (uint8_t)delta;
@@ -491,9 +498,7 @@ static void render_messages(void)
int y = CONTENT_Y;
uint16_t ble_color = state.ble_connected ? UI_COLOR_OK : UI_COLOR_WARN;
const char *ble = state.ble_connected ? "BLE OK" : "BLE ADV";
const char *radio = state.lora_tx_active ? "TX" :
(state.lora_in_rx ? "RX" :
(state.lora_radio_ready ? "RDY" : "WAIT"));
const char *radio = radio_state_label();
uint16_t radio_color = state.lora_tx_active ? UI_COLOR_TX :
state.lora_in_rx ? UI_COLOR_RX :
state.lora_radio_ready ? UI_COLOR_OK
@@ -632,9 +637,7 @@ static void render_radio(void)
uint32_t freq_frac = (state.lora_freq_hz % 1000000 + 500) / 1000;
uint16_t bw_int = state.lora_bw_khz_x10 / 10;
uint16_t bw_frac = state.lora_bw_khz_x10 % 10;
const char *packet_state = state.lora_tx_active ? "TX" :
(state.lora_in_rx ? "RX" :
(state.lora_radio_ready ? "RDY" : "WAIT"));
const char *packet_state = radio_state_label();
const char *rx_mode = state.lora_rx_duty_cycle ? "DC" : "CONT";
uint16_t warn_color = (state.lora_apc_enabled && state.lora_apc_reduction > 0)
? UI_COLOR_WARN : UI_COLOR_OK;
+28 -1
View File
@@ -185,6 +185,7 @@ static void splash_work_handler(struct k_work *work)
}
static void schedule_render(void);
static void schedule_render_auto(void);
static void advert_defer_handler(struct k_work *work)
{
@@ -882,6 +883,10 @@ void ui_set_radio_params(uint32_t freq_hz, uint8_t sf, uint16_t bw_khz_x10,
uint8_t cr, int8_t tx_power, int16_t noise_floor)
{
struct ui_state *s = get_state();
bool changed = s->lora_freq_hz != freq_hz || s->lora_sf != sf ||
s->lora_bw_khz_x10 != bw_khz_x10 || s->lora_cr != cr ||
s->lora_tx_power != tx_power ||
s->lora_noise_floor != noise_floor;
s->lora_freq_hz = freq_hz;
s->lora_sf = sf;
@@ -889,6 +894,10 @@ void ui_set_radio_params(uint32_t freq_hz, uint8_t sf, uint16_t bw_khz_x10,
s->lora_cr = cr;
s->lora_tx_power = tx_power;
s->lora_noise_floor = noise_floor;
if (changed) {
schedule_render_auto();
}
}
void ui_set_radio_runtime(int8_t effective_tx_power, bool apc_enabled,
@@ -898,6 +907,17 @@ void ui_set_radio_runtime(int8_t effective_tx_power, bool apc_enabled,
bool radio_ready, bool in_rx, bool tx_active)
{
struct ui_state *s = get_state();
bool changed = s->lora_effective_tx_power != effective_tx_power ||
s->lora_apc_enabled != apc_enabled ||
s->lora_apc_reduction != apc_reduction ||
s->lora_apc_margin_x10 != apc_margin_x10 ||
s->lora_apc_target_margin != apc_target_margin ||
s->lora_sync_word != sync_word ||
s->lora_preamble_len != preamble_len ||
s->lora_rx_duty_cycle != rx_duty_cycle ||
s->lora_radio_ready != radio_ready ||
s->lora_in_rx != in_rx ||
s->lora_tx_active != tx_active;
s->lora_effective_tx_power = effective_tx_power;
s->lora_apc_enabled = apc_enabled;
@@ -910,6 +930,10 @@ void ui_set_radio_runtime(int8_t effective_tx_power, bool apc_enabled,
s->lora_radio_ready = radio_ready;
s->lora_in_rx = in_rx;
s->lora_tx_active = tx_active;
if (changed) {
schedule_render_auto();
}
}
void ui_set_radio_stats(uint32_t packets_rx, uint32_t packets_tx,
@@ -1080,7 +1104,10 @@ void ui_set_offgrid_mode(bool enabled)
s->offgrid_enabled = enabled;
}
void ui_refresh_display(void)
/* Schedule a redraw for an automatic (non-interactive) state update, e.g. a
* live radio value changing. Skips EPD panels, which only repaint on real
* events to avoid ~2s flashes. */
static void schedule_render_auto(void)
{
if (!ui_initialized) {
return;
@@ -266,14 +266,6 @@ extern "C" void ui_set_ble_enabled(bool enabled)
}
}
extern "C" void ui_refresh_display(void)
{
if (s_task) {
s_task->forceRefresh();
}
}
/* ===== Pull-model no-ops =====
* The joystick UI reads all hardware state on demand at render time, so these
* push-model hooks from the old button UI have no work to do. */
-2
View File
@@ -68,8 +68,6 @@ WEAK void ui_set_radio_stats(uint32_t packets_rx, uint32_t packets_tx,
ARG_UNUSED(packets_rx); ARG_UNUSED(packets_tx); ARG_UNUSED(packets_err);
}
WEAK void ui_refresh_display(void) { }
WEAK void ui_set_gps_data(bool has_fix, uint8_t sats,
int32_t lat_mdeg, int32_t lon_mdeg, int32_t alt_mm)
{
-6
View File
@@ -99,12 +99,6 @@ void ui_set_radio_runtime(int8_t effective_tx_power, bool apc_enabled,
void ui_set_radio_stats(uint32_t packets_rx, uint32_t packets_tx,
uint32_t packets_err);
/**
* Request an immediate display redraw for the current UI state.
* No-op on headless builds.
*/
void ui_refresh_display(void);
/**
* Update GPS data for display.
*/
+5 -9
View File
@@ -141,7 +141,7 @@ K_TIMER_DEFINE(housekeeping_timer, housekeeping_timer_fn, NULL);
/* Forward declarations */
#ifdef ZEPHCORE_LORA
static RepeaterMesh *repeater_mesh_ptr;
static void refresh_repeater_ui_radio_state(bool redraw);
static void refresh_repeater_ui_radio_state(void);
#endif
/* Print string to USB serial */
@@ -234,7 +234,7 @@ static void process_cli_commands(void)
while (repeater_mesh_ptr && k_msgq_get(&cli_cmd_queue, &c, K_NO_WAIT) == 0) {
cli_reply_buf[0] = '\0';
repeater_mesh_ptr->handleCommand(0, c.buf, cli_reply_buf);
refresh_repeater_ui_radio_state(true);
refresh_repeater_ui_radio_state();
if (cli_reply_buf[0] != '\0') {
cli_print("\r\n -> ");
cli_print(cli_reply_buf);
@@ -361,7 +361,7 @@ static mesh::SimpleMeshTables mesh_tables;
/* RepeaterMesh requires: board, radio, ms_clock, rng, rtc, tables */
static RepeaterMesh repeater_mesh(zephyr_board, lora_radio, ms_clock, zephyr_rng, rtc_clock, mesh_tables);
static void refresh_repeater_ui_radio_state(bool redraw)
static void refresh_repeater_ui_radio_state(void)
{
if (!repeater_mesh_ptr) {
return;
@@ -404,10 +404,6 @@ static void refresh_repeater_ui_radio_state(bool redraw)
lora_radio.getPacketsRecv(),
lora_radio.getPacketsSent(),
lora_radio.getPacketsRecvErrors());
if (redraw) {
ui_refresh_display();
}
}
#endif
@@ -478,7 +474,7 @@ static void repeater_event_loop(void)
#ifdef ZEPHCORE_LORA
/* Refresh live radio/APC state (noise floor, TX power
* reduction, RX/TX mode, packet counters). */
refresh_repeater_ui_radio_state(true);
refresh_repeater_ui_radio_state();
/* Battery is now refreshed lazily from ui_pages_render() with
* a 30 s freshness guard no periodic ADC fire here. */
@@ -637,7 +633,7 @@ int main(void)
/* Feed initial UI state from loaded prefs */
ui_set_node_name(prefs->node_name);
refresh_repeater_ui_radio_state(false);
refresh_repeater_ui_radio_state();
ui_set_battery_provider(get_battery_mv);
ui_set_battery(zephyr_board.getBattMilliVolts(), 0);
ui_set_gps_available(gps_is_available());