|
1 | 1 | #include "../../../inc/sp140/lvgl/lvgl_updates.h" |
2 | 2 | #include "../../../inc/sp140/esp32s3-config.h" |
3 | 3 | #include "../../../inc/sp140/globals.h" |
| 4 | +#include "../../../inc/sp140/vibration_pwm.h" |
| 5 | +#include "../../../inc/sp140/shared-config.h" |
4 | 6 |
|
5 | 7 | // Flash timer globals - definitions |
6 | 8 | lv_timer_t* cruise_flash_timer = NULL; |
@@ -175,79 +177,47 @@ void startArmFailIconFlash() { |
175 | 177 |
|
176 | 178 | // --- Critical Alert Border Flashing Implementation --- |
177 | 179 | static void critical_border_flash_timer_cb(lv_timer_t* timer) { |
178 | | - // This callback runs within the LVGL task handler, which is already protected by lvglMutex |
| 180 | + // This callback runs within the LVGL task handler, so no mutex needed here. |
| 181 | + 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 | + lv_timer_set_period(timer, 700); // Off duration |
| 187 | + } else { |
| 188 | + lv_obj_clear_flag(critical_border, LV_OBJ_FLAG_HIDDEN); |
| 189 | + lv_timer_set_period(timer, 300); // On duration |
179 | 190 |
|
180 | | - if (critical_border == NULL) { |
181 | | - // Safety check |
182 | | - if (critical_border_flash_timer != NULL) { |
183 | | - lv_timer_del(critical_border_flash_timer); |
184 | | - critical_border_flash_timer = NULL; |
| 191 | + // Trigger vibration pulse in sync with border "on" |
| 192 | + if (ENABLE_VIBE) { |
| 193 | + pulseVibration(300, 200); // 300ms pulse, intensity 200 |
| 194 | + } |
185 | 195 | } |
186 | | - isFlashingCriticalBorder = false; |
187 | | - return; |
188 | | - } |
189 | | - |
190 | | - // Toggle visibility |
191 | | - if (lv_obj_has_flag(critical_border, LV_OBJ_FLAG_HIDDEN)) { |
192 | | - lv_obj_clear_flag(critical_border, LV_OBJ_FLAG_HIDDEN); |
193 | | - } else { |
194 | | - lv_obj_add_flag(critical_border, LV_OBJ_FLAG_HIDDEN); |
195 | 196 | } |
196 | 197 | } |
197 | 198 |
|
198 | 199 | void startCriticalBorderFlash() { |
199 | | - // This function can be called from other tasks, so protect with mutex |
200 | | - if (xSemaphoreTake(lvglMutex, pdMS_TO_TICKS(50)) == pdTRUE) { // Use a timeout |
201 | | - if (critical_border == NULL) { |
202 | | - xSemaphoreGive(lvglMutex); |
203 | | - return; // Can't flash if border doesn't exist |
| 200 | + if (xSemaphoreTake(lvglMutex, pdMS_TO_TICKS(50)) == pdTRUE) { |
| 201 | + if (critical_border != NULL && !isFlashingCriticalBorder) { |
| 202 | + isFlashingCriticalBorder = true; |
| 203 | + lv_obj_clear_flag(critical_border, LV_OBJ_FLAG_HIDDEN); // Start visible |
| 204 | + critical_border_flash_timer = lv_timer_create(critical_border_flash_timer_cb, 300, NULL); |
204 | 205 | } |
205 | | - |
206 | | - // If a flash timer is already running, delete it first |
207 | | - if (critical_border_flash_timer != NULL) { |
208 | | - lv_timer_del(critical_border_flash_timer); |
209 | | - critical_border_flash_timer = NULL; |
210 | | - } |
211 | | - |
212 | | - // Reset state and start flashing |
213 | | - isFlashingCriticalBorder = true; |
214 | | - |
215 | | - // Start with the border visible |
216 | | - lv_obj_clear_flag(critical_border, LV_OBJ_FLAG_HIDDEN); |
217 | | - |
218 | | - // Create the timer (500ms interval for on/off cycle - matches vibration rate) |
219 | | - critical_border_flash_timer = lv_timer_create(critical_border_flash_timer_cb, 500, NULL); |
220 | | - if (critical_border_flash_timer == NULL) { |
221 | | - // Failed to create timer, reset state |
222 | | - isFlashingCriticalBorder = false; |
223 | | - lv_obj_add_flag(critical_border, LV_OBJ_FLAG_HIDDEN); // Hide it again |
224 | | - USBSerial.println("Error: Failed to create critical border flash timer!"); |
225 | | - } |
226 | | - |
227 | 206 | xSemaphoreGive(lvglMutex); |
228 | | - } else { |
229 | | - USBSerial.println("Warning: Failed to acquire LVGL mutex for startCriticalBorderFlash"); |
230 | 207 | } |
231 | 208 | } |
232 | 209 |
|
233 | 210 | void stopCriticalBorderFlash() { |
234 | | - // This function can be called from other tasks, so protect with mutex |
235 | | - if (xSemaphoreTake(lvglMutex, pdMS_TO_TICKS(50)) == pdTRUE) { // Use a timeout |
| 211 | + if (xSemaphoreTake(lvglMutex, pdMS_TO_TICKS(50)) == pdTRUE) { |
236 | 212 | if (critical_border_flash_timer != NULL) { |
237 | 213 | lv_timer_del(critical_border_flash_timer); |
238 | 214 | critical_border_flash_timer = NULL; |
239 | 215 | } |
240 | | - |
241 | | - isFlashingCriticalBorder = false; |
242 | | - |
243 | | - // Hide the border |
244 | 216 | if (critical_border != NULL) { |
245 | 217 | lv_obj_add_flag(critical_border, LV_OBJ_FLAG_HIDDEN); |
246 | 218 | } |
247 | | - |
| 219 | + isFlashingCriticalBorder = false; |
248 | 220 | xSemaphoreGive(lvglMutex); |
249 | | - } else { |
250 | | - USBSerial.println("Warning: Failed to acquire LVGL mutex for stopCriticalBorderFlash"); |
251 | 221 | } |
252 | 222 | } |
253 | 223 |
|
|
0 commit comments