From 55e8a50b710ca91f9dcd5e707d4c327e93f2c04e Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Fri, 30 May 2025 12:22:55 +0200 Subject: [PATCH] feat(gx12): add safety timer for port expander (#6325) --- radio/src/boards/generic_stm32/rgb_leds.cpp | 3 +- radio/src/boards/generic_stm32/rgb_leds.h | 1 - radio/src/edgetx.cpp | 4 -- radio/src/os/timer.h | 1 + radio/src/os/timer_pthread.cpp | 8 ++-- .../common/arm/stm32/timers_driver.cpp | 4 +- radio/src/targets/taranis/gx12/bsp_io.cpp | 43 +++++++++++++++---- radio/src/tasks.cpp | 2 +- 8 files changed, 43 insertions(+), 23 deletions(-) diff --git a/radio/src/boards/generic_stm32/rgb_leds.cpp b/radio/src/boards/generic_stm32/rgb_leds.cpp index d928d6231..69c1547c3 100644 --- a/radio/src/boards/generic_stm32/rgb_leds.cpp +++ b/radio/src/boards/generic_stm32/rgb_leds.cpp @@ -78,7 +78,7 @@ static void _refresh_cb(timer_handle_t* timer) ws2812_update(&_led_timer); } -void rgbLedStart() +static void rgbLedStart() { if (!timer_is_created(&_refresh_timer)) { timer_create(&_refresh_timer, _refresh_cb, "rgbled", @@ -111,6 +111,7 @@ void rgbLedInit() { ws2812_init(&_led_timer, _led_colors, LED_STRIP_LENGTH, WS2812_GRB); rgbLedClearAll(); + rgbLedStart(); } // Make sure the timer channel is supported diff --git a/radio/src/boards/generic_stm32/rgb_leds.h b/radio/src/boards/generic_stm32/rgb_leds.h index 96da0df7d..f085c1d81 100644 --- a/radio/src/boards/generic_stm32/rgb_leds.h +++ b/radio/src/boards/generic_stm32/rgb_leds.h @@ -24,7 +24,6 @@ #include void rgbLedInit(); -void rgbLedStart(); void rgbLedStop(); void rgbSetLedColor(uint8_t led, uint8_t r, uint8_t g, uint8_t b); diff --git a/radio/src/edgetx.cpp b/radio/src/edgetx.cpp index c29e9f215..e345e2931 100644 --- a/radio/src/edgetx.cpp +++ b/radio/src/edgetx.cpp @@ -1559,10 +1559,6 @@ void edgeTxInit() resetBacklightTimeout(); -#if defined(LED_STRIP_GPIO) && !defined(SIMU) - rgbLedStart(); -#endif - pulsesStart(); WDG_ENABLE(WDG_DURATION); } diff --git a/radio/src/os/timer.h b/radio/src/os/timer.h index ba56385cb..0544e0ab1 100644 --- a/radio/src/os/timer.h +++ b/radio/src/os/timer.h @@ -43,3 +43,4 @@ int timer_start(timer_handle_t* h); int timer_stop(timer_handle_t* h); int timer_set_period(timer_handle_t* h, unsigned period); +static inline int timer_reset(timer_handle_t* h) { return timer_start(h); } diff --git a/radio/src/os/timer_pthread.cpp b/radio/src/os/timer_pthread.cpp index 0c62b5e9b..12418fcce 100644 --- a/radio/src/os/timer_pthread.cpp +++ b/radio/src/os/timer_pthread.cpp @@ -133,6 +133,7 @@ void timer_queue::main_loop() { void timer_queue::process_cmds() { + int added = 0; while (!_cmds.empty()) { timer_req_t req = _cmds.back(); _cmds.pop_back(); @@ -150,6 +151,7 @@ void timer_queue::process_cmds() t->active = true; if (pos == _timers.end()) { _timers.emplace_back(t); + added++; } break; @@ -164,6 +166,7 @@ void timer_queue::process_cmds() } } } + if (added) sort_timers(); } void timer_queue::trigger_timers() { @@ -182,10 +185,7 @@ void timer_queue::trigger_timers() { break; } } - - if (triggered) { - sort_timers(); - } + if (triggered) sort_timers(); } void timer_queue::async_calls() { diff --git a/radio/src/targets/common/arm/stm32/timers_driver.cpp b/radio/src/targets/common/arm/stm32/timers_driver.cpp index 9cca5d0f6..5dd68790f 100644 --- a/radio/src/targets/common/arm/stm32/timers_driver.cpp +++ b/radio/src/targets/common/arm/stm32/timers_driver.cpp @@ -26,8 +26,6 @@ #include "hal.h" #include "hal/watchdog_driver.h" -#include "FreeRTOSConfig.h" - static volatile uint32_t _ms_ticks; static void _init_1ms_timer() @@ -45,7 +43,7 @@ static void _init_1ms_timer() MS_TIMER->DIER = TIM_DIER_UIE; NVIC_EnableIRQ(MS_TIMER_IRQn); - NVIC_SetPriority(MS_TIMER_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); + NVIC_SetPriority(MS_TIMER_IRQn, 4); } void timersInit() diff --git a/radio/src/targets/taranis/gx12/bsp_io.cpp b/radio/src/targets/taranis/gx12/bsp_io.cpp index 4695e57de..41936c6e6 100644 --- a/radio/src/targets/taranis/gx12/bsp_io.cpp +++ b/radio/src/targets/taranis/gx12/bsp_io.cpp @@ -22,13 +22,12 @@ #include "bsp_io.h" #include "hal/switch_driver.h" #include "drivers/pca95xx.h" -#include "os/async.h" #include "stm32_i2c_driver.h" #include "timers_driver.h" #include "stm32_ws2812.h" -#include -#include +#include "os/async.h" +#include "os/timer.h" #include "myeeprom.h" @@ -39,9 +38,11 @@ struct bsp_io_expander { }; static volatile bool _poll_switches_in_queue = false; + static bsp_io_expander _io_switches; static bsp_io_expander _io_fs_switches; +static timer_handle_t _poll_timer = TIMER_INITIALIZER; static void _init_io_expander(bsp_io_expander* io, uint32_t mask) { @@ -58,18 +59,40 @@ static uint32_t _read_io_expander(bsp_io_expander* io) return io->state; } -static void _poll_switches(void *param1, uint32_t param2) +typedef enum { + TRIGGERED_BY_TIMER = 0, + TRIGGERED_BY_IRQ, +} trigger_source_t; + +static void _poll_switches(void *param1, uint32_t trigger_source) { (void)param1; - (void)param2; - _poll_switches_in_queue = false; - _read_io_expander(&_io_switches); - _read_io_expander(&_io_fs_switches); + + if (trigger_source == TRIGGERED_BY_IRQ) { + _poll_switches_in_queue = false; + timer_reset(&_poll_timer); + } + + bsp_io_read_switches(); + bsp_io_read_fs_switches(); } static void _io_int_handler() { - async_call_isr(_poll_switches, &_poll_switches_in_queue, nullptr, 0); + async_call_isr(_poll_switches, &_poll_switches_in_queue, nullptr, + TRIGGERED_BY_IRQ); +} + +static void _poll_cb(timer_handle_t* timer) +{ + (void)timer; + _poll_switches(nullptr, TRIGGERED_BY_TIMER); +} + +static void start_poll_timer() +{ + timer_create(&_poll_timer, _poll_cb, "portex", 100, true); + timer_start(&_poll_timer); } int bsp_io_init() @@ -102,6 +125,8 @@ int bsp_io_init() bsp_io_read_switches(); bsp_io_read_fs_switches(); + start_poll_timer(); + return 0; } diff --git a/radio/src/tasks.cpp b/radio/src/tasks.cpp index 34d175524..e21a1dd6a 100644 --- a/radio/src/tasks.cpp +++ b/radio/src/tasks.cpp @@ -127,7 +127,7 @@ static void _timer_10ms_cb(timer_handle_t* h) per10ms(); } -void timer10msStart() +static void timer10msStart() { if (!timer_is_created(&_timer10ms)) { timer_create(&_timer10ms, _timer_10ms_cb, "10ms", 10, true);