Skip to content

Commit 5866c05

Browse files
authored
Feat/visual watchdog (#673)
* feat(Watchdog): Add visual indication for watchdog reset (it also blocks the system) * chore: Add changeset
1 parent 81ea04d commit 5866c05

4 files changed

Lines changed: 77 additions & 6 deletions

File tree

.changesets/visual-watchdog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
release: minor
2+
summary: Makes the watchdog reset check block the system and have a visual indication similar to hardfault

Inc/HALAL/HardFault/HardfaultTrace.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ extern "C" {
1111
#endif
1212
extern uint8_t _metadata[];
1313
extern uint8_t _hf_log[];
14+
extern GPIO_TypeDef* ports_hard_fault[];
15+
extern uint16_t pins_hard_fault[];
16+
extern uint8_t hard_fault_leds_count;
1417
#ifdef __cplusplus
1518
}
1619
#endif

Inc/HALAL/Services/Watchdog/Watchdog.hpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,7 @@ class Watchdog {
4141
}
4242

4343
static void refresh() { HAL_IWDG_Refresh(&watchdog_handle); }
44-
static void check_reset_flag() {
45-
if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDG1RST)) {
46-
reset_by_iwdg = true;
47-
}
48-
__HAL_RCC_CLEAR_RESET_FLAGS();
49-
}
44+
static void check_reset_flag();
5045
template <typename TimeUnit> Watchdog(chrono::duration<int64_t, TimeUnit> period) {
5146
watchdog_time = std::chrono::duration_cast<std::chrono::microseconds>(period);
5247
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,77 @@
11
#include "HALAL/Services/Watchdog/Watchdog.hpp"
2+
#include "HALAL/HardFault/HardfaultTrace.h"
23

34
IWDG_HandleTypeDef watchdog_handle;
45
std::chrono::microseconds Watchdog::watchdog_time =
56
std::chrono::microseconds(1000000); // 1 second by default
67
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

Comments
 (0)