From e61bf4f4ff002ac202e52d71c0150809a8a11ad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=27=C3=A9lectron=20rare?= <108685187+electron-rare@users.noreply.github.com> Date: Thu, 6 Aug 2026 04:05:46 +0200 Subject: [PATCH] fix(box3): keep link alive during SD ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No STATE frame flows while the looper is inside its blocking SD code, so liveness relies on progress events alone — and mounting the card before the first one can outlast the 500 ms timeout, flashing the disconnected banner mid-save. The timeout widens to 8 s between sending an SD command and its terminal event, then returns to 500 ms. Also reset the progress bar when starting an operation. --- box3_display/main/link_task.c | 11 ++++++++++- box3_display/main/link_task.h | 6 ++++++ box3_display/main/ui.c | 6 ++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/box3_display/main/link_task.c b/box3_display/main/link_task.c index b6c5121..0ab0bd6 100644 --- a/box3_display/main/link_task.c +++ b/box3_display/main/link_task.c @@ -35,6 +35,12 @@ static SemaphoreHandle_t tx_mutex; * (a 64-bit value would be read in two words) */ static volatile uint32_t last_frame_ms = 0; static volatile bool ever_received = false; +static volatile bool sd_pending = false; + +void link_set_sd_pending(bool pending) +{ + sd_pending = pending; +} bool link_connected(void) { @@ -44,8 +50,11 @@ bool link_connected(void) * instead of a false "connected" during the first 500 ms */ return false; } + /* mounting the card and writing a chunk can both outlast the normal + * timeout, and no STATE frame flows during an SD operation */ + uint32_t timeout = sd_pending ? LINK_SD_TIMEOUT_MS : LINK_TIMEOUT_MS; uint32_t now_ms = (uint32_t)(esp_timer_get_time() / 1000); - return (uint32_t)(now_ms - last_frame_ms) < LINK_TIMEOUT_MS; + return (uint32_t)(now_ms - last_frame_ms) < timeout; } void link_send_cmd(uint8_t op, uint8_t arg0, uint16_t arg1) diff --git a/box3_display/main/link_task.h b/box3_display/main/link_task.h index 0872a37..0ca7569 100644 --- a/box3_display/main/link_task.h +++ b/box3_display/main/link_task.h @@ -30,8 +30,14 @@ extern QueueHandle_t link_state_queue; /* queue of link_evt_t */ extern QueueHandle_t link_evt_queue; +/* while an SD operation is in flight the looper sends no STATE frames + * (its core 0 task is inside the blocking SD code) and the gaps between + * progress events can exceed the normal liveness timeout */ +#define LINK_SD_TIMEOUT_MS 8000 + void link_task_start(void); void link_send_cmd(uint8_t op, uint8_t arg0, uint16_t arg1); bool link_connected(void); +void link_set_sd_pending(bool pending); #endif /* LINK_TASK_H_ */ diff --git a/box3_display/main/ui.c b/box3_display/main/ui.c index b648495..618cf9d 100644 --- a/box3_display/main/ui.c +++ b/box3_display/main/ui.c @@ -122,6 +122,8 @@ static void sd_save_event_cb(lv_event_t *e) { (void)e; lv_label_set_text(sd_status_label, "Sauvegarde..."); + lv_bar_set_value(sd_progress, 0, LV_ANIM_OFF); + link_set_sd_pending(true); link_send_cmd(LINK_CMD_SD_SAVE, (uint8_t)lv_dropdown_get_selected(sd_dropdown), 0); } @@ -130,6 +132,8 @@ static void sd_load_event_cb(lv_event_t *e) { (void)e; lv_label_set_text(sd_status_label, "Chargement..."); + lv_bar_set_value(sd_progress, 0, LV_ANIM_OFF); + link_set_sd_pending(true); link_send_cmd(LINK_CMD_SD_LOAD, (uint8_t)lv_dropdown_get_selected(sd_dropdown), 0); } @@ -493,11 +497,13 @@ void ui_apply_evt(const link_evt_t *e) lv_bar_set_value(sd_progress, e->arg, LV_ANIM_OFF); break; case LINK_EVT_SD_DONE: + link_set_sd_pending(false); lv_bar_set_value(sd_progress, 100, LV_ANIM_OFF); lv_label_set_text_fmt(sd_status_label, "Session %u OK", (unsigned)e->arg); break; case LINK_EVT_SD_ERROR: + link_set_sd_pending(false); lv_label_set_text_fmt(sd_status_label, "Erreur SD (code %u)", (unsigned)e->arg); break;