From 2b6761bb1afbb8768cbfac1eaf0bc1f709484dd3 Mon Sep 17 00:00:00 2001 From: RaceMiata Date: Wed, 28 Jan 2026 09:26:54 +0000 Subject: [PATCH 1/5] Fix ELRS baclpack DVR timed start/stop logic --- src/core/elrs.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/core/elrs.c b/src/core/elrs.c index 4aab75e9..f64fab89 100644 --- a/src/core/elrs.c +++ b/src/core/elrs.c @@ -349,10 +349,23 @@ void msp_process_packet() { if (g_app_state == APP_STATE_VIDEO) { record_state = packet.payload[0] == 0 ? 1 : 2; uint32_t delay = packet.payload[1] | (uint32_t)packet.payload[2] << 8; - if (delay == 0) + if (delay == 0) { + record_time = 0; dvr_cmd(record_state); - else - record_time = time(NULL) + delay; + } + else { + switch (record_state) { + case DVR_STOP: + if (!dvr_is_recording) { + // discard "timer off" if dvr not already started + record_time = 0; + break; + } + // fall thru' if dvr started + case DVR_START: + record_time = time(NULL) + delay; + } + } } } break; case MSP_GET_VRX_MODE: From f14c3fce44eb67835a227e86b480aba10b29620c Mon Sep 17 00:00:00 2001 From: RaceMiata Date: Fri, 30 Jan 2026 22:04:12 +0000 Subject: [PATCH 2/5] New flags record_pending, g_sdcard_ready --- src/core/dvr.c | 34 ++++++++++++++++++++++------------ src/core/dvr.h | 1 + src/core/elrs.c | 2 +- src/core/thread.c | 10 ++++++++++ src/ui/page_common.c | 1 + src/ui/page_common.h | 1 + 6 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/core/dvr.c b/src/core/dvr.c index 881bea00..db1f0297 100644 --- a/src/core/dvr.c +++ b/src/core/dvr.c @@ -19,8 +19,10 @@ #include "util/system.h" bool dvr_is_recording = false; +bool record_pending = false; static time_t dvr_recording_start = 0; +static int ret_prev = 1; static pthread_mutex_t dvr_mutex; /////////////////////////////////////////////////////////////////// @@ -39,7 +41,8 @@ void dvr_update_status() { if (ret != 1) { dvr_is_recording = false; system_script(REC_STOP); - sleep(2); // wait for record process + record_pending = (ret_prev != -1); // retry only if not 2 fails in a row + sleep(2); // wait for record process } } pthread_mutex_unlock(&dvr_mutex); @@ -311,16 +314,11 @@ static void dvr_update_record_conf() { void dvr_cmd(osd_dvr_cmd_t cmd) { LOGI("dvr_cmd: sdcard=%d, recording=%d, cmd=%d", g_sdcard_enable, dvr_is_recording, cmd); - if (!g_sdcard_enable) - return; - - pthread_mutex_lock(&dvr_mutex); - bool start_rec = dvr_is_recording; switch (cmd) { case DVR_TOGGLE: - start_rec = !dvr_is_recording; + start_rec = !dvr_is_recording && !record_pending; break; case DVR_STOP: start_rec = false; @@ -330,14 +328,26 @@ void dvr_cmd(osd_dvr_cmd_t cmd) { break; } + if (!g_sdcard_enable) { + record_pending = start_rec; + return; + } + + pthread_mutex_lock(&dvr_mutex); + if (start_rec) { if (!dvr_is_recording && !sdcard_is_full()) { dvr_update_record_conf(); - dvr_is_recording = true; - usleep(100 * 1000); - system_script(REC_START); - dvr_recording_start = time(NULL); - sleep(2); // wait for record process + if (g_sdcard_ready) { + dvr_is_recording = true; + record_pending = false; + usleep(100 * 1000); + system_script(REC_START); + dvr_recording_start = time(NULL); + sleep(2); // wait for record process + } else { + record_pending = true; + } } } else { if (dvr_is_recording) { diff --git a/src/core/dvr.h b/src/core/dvr.h index 54fead28..743c1a48 100644 --- a/src/core/dvr.h +++ b/src/core/dvr.h @@ -16,6 +16,7 @@ typedef enum { } osd_dvr_cmd_t; extern bool dvr_is_recording; +extern bool record_pending; void dvr_update_status(); void dvr_select_audio_source(uint8_t audio_source); diff --git a/src/core/elrs.c b/src/core/elrs.c index f64fab89..02e2a26a 100644 --- a/src/core/elrs.c +++ b/src/core/elrs.c @@ -356,7 +356,7 @@ void msp_process_packet() { else { switch (record_state) { case DVR_STOP: - if (!dvr_is_recording) { + if (!dvr_is_recording && !record_pending) { // discard "timer off" if dvr not already started record_time = 0; break; diff --git a/src/core/thread.c b/src/core/thread.c index b5dc78ff..d9f52897 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -49,24 +49,34 @@ static void detect_sdcard(void) { // repair is not currently executing. if (ok_to_execute) { g_sdcard_enable = sdcard_mounted(); + if (!g_sdcard_enable) + g_sdcard_ready = false; // General Runtime behavior if (-1 == g_bootup_sdcard_state) { + g_sdcard_ready = true; if ((g_sdcard_enable && !sdcard_enable_last) || g_sdcard_det_req) { sdcard_update_free_size(); g_sdcard_det_req = 0; + g_sdcard_ready = false; } // Only repair sd card when inserted if (sdcard_init_scan && g_sdcard_enable) { if (sdcard_ready_cb) { sdcard_ready_cb(); + g_sdcard_ready = false; } sdcard_init_scan = false; } else if (!g_sdcard_enable && sdcard_enable_last) { + g_sdcard_ready = false; sdcard_init_scan = true; } + if (record_pending && g_sdcard_ready && !sdcard_is_full()) { + dvr_cmd(DVR_START); + } + sdcard_enable_last = g_sdcard_enable; } // SDCard detected at bootup diff --git a/src/ui/page_common.c b/src/ui/page_common.c index 002b9a4d..21c9af65 100644 --- a/src/ui/page_common.c +++ b/src/ui/page_common.c @@ -10,6 +10,7 @@ /////////////////////////////////////////////////////////////////////////////// bool g_sdcard_enable = false; +bool g_sdcard_ready = false; bool g_sdcard_det_req = false; bool g_autoscan_exit = true; bool g_scanning = false; diff --git a/src/ui/page_common.h b/src/ui/page_common.h index b3b2688c..bf0e45d8 100644 --- a/src/ui/page_common.h +++ b/src/ui/page_common.h @@ -135,6 +135,7 @@ enum { typedef uint8_t lv_menu_builder_variant_t; extern bool g_sdcard_enable; +extern bool g_sdcard_ready; extern bool g_sdcard_det_req; extern bool g_autoscan_exit; extern bool g_scanning; From dd4ac0f552e28665304d55411b5ece9ce32b993c Mon Sep 17 00:00:00 2001 From: RaceMiata Date: Fri, 30 Jan 2026 23:13:56 +0000 Subject: [PATCH 3/5] stop retry if open record file failed --- src/core/dvr.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/core/dvr.c b/src/core/dvr.c index db1f0297..607080f8 100644 --- a/src/core/dvr.c +++ b/src/core/dvr.c @@ -22,13 +22,12 @@ bool dvr_is_recording = false; bool record_pending = false; static time_t dvr_recording_start = 0; -static int ret_prev = 1; static pthread_mutex_t dvr_mutex; /////////////////////////////////////////////////////////////////// //-1=error; // 0=idle,1=recording,2=stopped,3=No SD card,4=recorf file path error, -// 5=SD card Full,6=Encoder error +// 5=SD card Full,6=Encoder error,7=Open Record File Failed void dvr_update_status() { pthread_mutex_lock(&dvr_mutex); if (dvr_is_recording) { @@ -41,8 +40,8 @@ void dvr_update_status() { if (ret != 1) { dvr_is_recording = false; system_script(REC_STOP); - record_pending = (ret_prev != -1); // retry only if not 2 fails in a row - sleep(2); // wait for record process + record_pending = (ret != 7); // don't retry if record file failed + sleep(2); // wait for record process } } pthread_mutex_unlock(&dvr_mutex); From a9ccacf4d695e26730ac66e05d65faf81aa369c3 Mon Sep 17 00:00:00 2001 From: RaceMiata Date: Fri, 30 Jan 2026 23:42:18 +0000 Subject: [PATCH 4/5] correct record_pending state on REC_STOP --- src/core/dvr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/dvr.c b/src/core/dvr.c index 607080f8..2862ede8 100644 --- a/src/core/dvr.c +++ b/src/core/dvr.c @@ -40,7 +40,7 @@ void dvr_update_status() { if (ret != 1) { dvr_is_recording = false; system_script(REC_STOP); - record_pending = (ret != 7); // don't retry if record file failed + record_pending = false; sleep(2); // wait for record process } } From 9eae0ee1d14bcbe25d196e54f9c0e51e4395b0f1 Mon Sep 17 00:00:00 2001 From: RaceMiata Date: Sat, 31 Jan 2026 00:05:18 +0000 Subject: [PATCH 5/5] sdcard icon includes !sdcard_ready state --- src/core/osd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/osd.c b/src/core/osd.c index 7107d29c..e4c65fdc 100644 --- a/src/core/osd.c +++ b/src/core/osd.c @@ -174,7 +174,7 @@ void osd_rec_show(bool bShow) { return; } - if (!g_sdcard_enable) { + if (!g_sdcard_enable || !g_sdcard_ready) { osd_resource_path(buf, "%s", is_fhd, noSdcard_bmp); lv_img_set_src(g_osd_hdzero.sd_rec[is_fhd], buf); lv_obj_clear_flag(g_osd_hdzero.sd_rec[is_fhd], LV_OBJ_FLAG_HIDDEN);