|
1 | 1 | #include "HALAL/Services/Watchdog/Watchdog.hpp" |
| 2 | +#include "HALAL/HardFault/HardfaultTrace.h" |
2 | 3 |
|
3 | 4 | IWDG_HandleTypeDef watchdog_handle; |
4 | 5 | std::chrono::microseconds Watchdog::watchdog_time = |
5 | 6 | std::chrono::microseconds(1000000); // 1 second by default |
6 | 7 | bool reset_by_iwdg{}; |
| 8 | + |
| 9 | +#ifdef NUCLEO |
| 10 | +#define WDG_REPS 200000 |
| 11 | +#endif |
| 12 | +#ifdef BOARD |
| 13 | +#define WDG_REPS 800000 |
| 14 | +#endif |
| 15 | + |
| 16 | +__attribute__((optimize("O0"))) static void wdg_delay() { |
| 17 | + for (uint32_t i = 0; i < WDG_REPS; i++) { |
| 18 | + __NOP(); |
| 19 | + } |
| 20 | +} |
| 21 | + |
| 22 | +static void wdg_enable_gpio_clock(GPIO_TypeDef* port) { |
| 23 | + if (port == GPIOA) |
| 24 | + LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOA); |
| 25 | + else if (port == GPIOB) |
| 26 | + LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOB); |
| 27 | + else if (port == GPIOC) |
| 28 | + LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOC); |
| 29 | + else if (port == GPIOD) |
| 30 | + LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOD); |
| 31 | + else if (port == GPIOE) |
| 32 | + LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOE); |
| 33 | + else if (port == GPIOF) |
| 34 | + LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOF); |
| 35 | + else if (port == GPIOG) |
| 36 | + LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOG); |
| 37 | + else if (port == GPIOJ) |
| 38 | + LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOJ); |
| 39 | + else if (port == GPIOK) |
| 40 | + LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOK); |
| 41 | +} |
| 42 | + |
| 43 | +static void wdg_init_gpio_output(GPIO_TypeDef* port, uint16_t pin) { |
| 44 | + LL_GPIO_SetPinMode(port, pin, LL_GPIO_MODE_OUTPUT); |
| 45 | + LL_GPIO_SetPinOutputType(port, pin, LL_GPIO_OUTPUT_PUSHPULL); |
| 46 | + LL_GPIO_SetPinSpeed(port, pin, LL_GPIO_SPEED_FREQ_LOW); |
| 47 | + LL_GPIO_SetPinPull(port, pin, LL_GPIO_PULL_NO); |
| 48 | +} |
| 49 | + |
| 50 | +static void wdg_led_init() { |
| 51 | + for (int i = 0; i < hard_fault_leds_count; i++) { |
| 52 | + wdg_enable_gpio_clock(ports_hard_fault[i]); |
| 53 | + wdg_init_gpio_output(ports_hard_fault[i], pins_hard_fault[i]); |
| 54 | + } |
| 55 | +} |
| 56 | + |
| 57 | +__attribute__((optimize("O0"))) void Watchdog::check_reset_flag() { |
| 58 | + if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDG1RST)) { |
| 59 | + reset_by_iwdg = true; |
| 60 | + } |
| 61 | + __HAL_RCC_CLEAR_RESET_FLAGS(); |
| 62 | + |
| 63 | + if (reset_by_iwdg) { |
| 64 | + if (hard_fault_leds_count == 0U) { |
| 65 | + while (1) |
| 66 | + ; |
| 67 | + } |
| 68 | + wdg_led_init(); |
| 69 | + while (1) { |
| 70 | + for (int i = 0; i < hard_fault_leds_count; i++) { |
| 71 | + LL_GPIO_SetOutputPin(ports_hard_fault[i], pins_hard_fault[i]); |
| 72 | + wdg_delay(); |
| 73 | + LL_GPIO_ResetOutputPin(ports_hard_fault[i], pins_hard_fault[i]); |
| 74 | + } |
| 75 | + } |
| 76 | + } |
| 77 | +} |
0 commit comments