Skip to content

Commit 92f2f4c

Browse files
committed
Improve critical border flashing and LVGL buffer usage
Switch critical border visibility logic from hidden flag to border opacity for smoother flashing and more reliable redraws. Increase LVGL buffer size to full screen to reduce partial update issues. Adjust UI task refresh rate from 25 Hz to 20 Hz for better performance.
1 parent 8efb518 commit 92f2f4c

File tree

4 files changed

+20
-18
lines changed

4 files changed

+20
-18
lines changed

inc/sp140/lvgl/lvgl_core.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
#define SCREEN_HEIGHT 128
1414

1515
// LVGL buffer size - optimize for our display
16-
// Use 1/4 of the screen size to balance memory usage and performance
17-
#define LVGL_BUFFER_SIZE (SCREEN_WIDTH * (SCREEN_HEIGHT / 4))
16+
// Use half screen size for single flush to balance performance and memory usage
17+
#define LVGL_BUFFER_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT / 2)
1818

1919
// LVGL refresh time in ms - match the config file setting
2020
#define LVGL_REFRESH_TIME 40

src/sp140/lvgl/lvgl_main_screen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@ void setupMainScreen(bool darkMode) {
624624
lv_obj_set_style_border_color(critical_border, LVGL_RED, LV_PART_MAIN);
625625
lv_obj_set_style_bg_opa(critical_border, LV_OPA_0, LV_PART_MAIN); // Transparent background
626626
lv_obj_set_style_radius(critical_border, 0, LV_PART_MAIN); // Sharp corners
627-
lv_obj_add_flag(critical_border, LV_OBJ_FLAG_HIDDEN); // Initially hidden
627+
lv_obj_set_style_border_opa(critical_border, LV_OPA_0, LV_PART_MAIN); // Initially invisible border
628628
// Move border to front so it's visible over all other elements
629629
lv_obj_move_foreground(critical_border);
630630
}

src/sp140/lvgl/lvgl_updates.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -179,23 +179,23 @@ void startArmFailIconFlash() {
179179
static void critical_border_flash_timer_cb(lv_timer_t* timer) {
180180
// This callback runs within the LVGL task handler, so no mutex needed here.
181181
if (critical_border != NULL) {
182-
// Toggle visibility: 300ms on, 700ms off
183-
bool is_on = !lv_obj_has_flag(critical_border, LV_OBJ_FLAG_HIDDEN);
184-
if (is_on) {
185-
lv_obj_add_flag(critical_border, LV_OBJ_FLAG_HIDDEN);
186-
// Invalidate the border area to ensure clean redraw
187-
lv_obj_invalidate(critical_border);
182+
// Toggle opacity: 300ms on (opaque), 700ms off (transparent)
183+
uint8_t current_opa = lv_obj_get_style_border_opa(critical_border, LV_PART_MAIN);
184+
if (current_opa == LV_OPA_100) {
185+
lv_obj_set_style_border_opa(critical_border, LV_OPA_0, LV_PART_MAIN);
188186
lv_timer_set_period(timer, 700); // Off duration
187+
// Invalidate entire screen when hiding to ensure clean removal of border pixels
188+
lv_obj_invalidate(lv_scr_act());
189189
} else {
190-
lv_obj_clear_flag(critical_border, LV_OBJ_FLAG_HIDDEN);
191-
// Invalidate the border area to ensure clean redraw
192-
lv_obj_invalidate(critical_border);
190+
lv_obj_set_style_border_opa(critical_border, LV_OPA_100, LV_PART_MAIN);
193191
lv_timer_set_period(timer, 300); // On duration
194192

195193
// Trigger vibration pulse in sync with border "on"
196194
if (ENABLE_VIBE) {
197195
pulseVibration(300, 200); // 300ms pulse, intensity 200
198196
}
197+
// Invalidate the border area when showing
198+
lv_obj_invalidate(critical_border);
199199
}
200200
// Force immediate refresh to minimize tearing
201201
lv_refr_now(lv_disp_get_default());
@@ -206,7 +206,7 @@ void startCriticalBorderFlash() {
206206
if (xSemaphoreTake(lvglMutex, pdMS_TO_TICKS(50)) == pdTRUE) {
207207
if (critical_border != NULL && !isFlashingCriticalBorder) {
208208
isFlashingCriticalBorder = true;
209-
lv_obj_clear_flag(critical_border, LV_OBJ_FLAG_HIDDEN); // Start visible
209+
lv_obj_set_style_border_opa(critical_border, LV_OPA_100, LV_PART_MAIN); // Start visible
210210
critical_border_flash_timer = lv_timer_create(critical_border_flash_timer_cb, 300, NULL);
211211
}
212212
xSemaphoreGive(lvglMutex);
@@ -220,7 +220,9 @@ void stopCriticalBorderFlash() {
220220
critical_border_flash_timer = NULL;
221221
}
222222
if (critical_border != NULL) {
223-
lv_obj_add_flag(critical_border, LV_OBJ_FLAG_HIDDEN);
223+
lv_obj_set_style_border_opa(critical_border, LV_OPA_0, LV_PART_MAIN);
224+
// Invalidate entire screen to ensure clean removal
225+
lv_obj_invalidate(lv_scr_act());
224226
}
225227
isFlashingCriticalBorder = false;
226228
xSemaphoreGive(lvglMutex);
@@ -235,7 +237,7 @@ bool isCriticalBorderFlashing() {
235237
void startCriticalBorderFlashDirect() {
236238
if (critical_border != NULL && !isFlashingCriticalBorder) {
237239
isFlashingCriticalBorder = true;
238-
lv_obj_clear_flag(critical_border, LV_OBJ_FLAG_HIDDEN); // Start visible
240+
lv_obj_set_style_border_opa(critical_border, LV_OPA_100, LV_PART_MAIN); // Start visible
239241
lv_obj_invalidate(critical_border); // Ensure clean initial draw
240242
critical_border_flash_timer = lv_timer_create(critical_border_flash_timer_cb, 300, NULL);
241243
// Force immediate refresh for clean start
@@ -249,8 +251,8 @@ void stopCriticalBorderFlashDirect() {
249251
critical_border_flash_timer = NULL;
250252
}
251253
if (critical_border != NULL) {
252-
lv_obj_add_flag(critical_border, LV_OBJ_FLAG_HIDDEN);
253-
lv_obj_invalidate(critical_border); // Ensure clean removal
254+
lv_obj_set_style_border_opa(critical_border, LV_OPA_0, LV_PART_MAIN);
255+
lv_obj_invalidate(lv_scr_act()); // Ensure clean removal of border
254256
// Force immediate refresh for clean stop
255257
lv_refr_now(lv_disp_get_default());
256258
}

src/sp140/sp140.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ void monitoringTask(void *pvParameters) {
497497
// UI task: fixed 25 Hz refresh and snapshot publish
498498
void uiTask(void *pvParameters) {
499499
TickType_t lastWake = xTaskGetTickCount();
500-
const TickType_t uiTicks = pdMS_TO_TICKS(40); // 25 Hz
500+
const TickType_t uiTicks = pdMS_TO_TICKS(50); // 20 Hz
501501
for (;;) {
502502
refreshDisplay();
503503
pushTelemetrySnapshot();

0 commit comments

Comments
 (0)