Skip to content

Commit 589cb1a

Browse files
committed
nrf: watchdog: use nrfx_wdt driver
Instead of directly poking registers, use `nrfx_wdt`. Signed-off-by: Sean Cross <[email protected]>
1 parent e738f5e commit 589cb1a

File tree

4 files changed

+48
-37
lines changed

4 files changed

+48
-37
lines changed

ports/nrf/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ SRC_NRFX = $(addprefix nrfx/,\
136136
drivers/src/nrfx_gpiote.c \
137137
drivers/src/nrfx_rtc.c \
138138
drivers/src/nrfx_nvmc.c \
139+
drivers/src/nrfx_wdt.c \
139140
)
140141

141142
ifdef EXTERNAL_FLASH_DEVICES

ports/nrf/common-hal/watchdog/WatchDogTimer.c

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -37,42 +37,17 @@
3737
#include "shared-bindings/watchdog/__init__.h"
3838
#include "shared-bindings/watchdog/WatchDogTimer.h"
3939

40+
#include "supervisor/port.h"
41+
42+
#include "nrf/timers.h"
4043
#include "nrf_wdt.h"
44+
#include "nrfx_wdt.h"
4145
#include "nrfx_timer.h"
42-
#include "nrf/timers.h"
4346

4447
STATIC uint8_t timer_refcount = 0;
45-
#define WATCHDOG_RELOAD_COUNT 2
4648
STATIC nrfx_timer_t *timer = NULL;
47-
48-
STATIC void watchdogtimer_hardware_init(mp_float_t duration, bool pause_during_sleep) {
49-
unsigned int channel;
50-
nrf_wdt_behaviour_t behaviour = NRF_WDT_BEHAVIOUR_RUN_SLEEP_HALT;
51-
if (pause_during_sleep) {
52-
behaviour = NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT;
53-
}
54-
55-
nrf_wdt_behaviour_set(NRF_WDT, behaviour);
56-
57-
uint64_t ticks = duration * 32768ULL;
58-
if (ticks > UINT32_MAX) {
59-
mp_raise_ValueError(translate("timeout duration exceeded the maximum supported value"));
60-
}
61-
nrf_wdt_reload_value_set(NRF_WDT, (uint32_t) ticks);
62-
63-
for (channel = 0; channel < WATCHDOG_RELOAD_COUNT; channel++) {
64-
nrf_wdt_reload_request_enable(NRF_WDT, channel);
65-
}
66-
67-
nrf_wdt_task_trigger(NRF_WDT, NRF_WDT_TASK_START);
68-
}
69-
70-
STATIC void watchdogtimer_hardware_feed(void) {
71-
unsigned int channel;
72-
for (channel = 0; channel < WATCHDOG_RELOAD_COUNT; channel++) {
73-
nrf_wdt_reload_request_set(NRF_WDT, (nrf_wdt_rr_register_t)(NRF_WDT_RR0 + channel));
74-
}
75-
}
49+
STATIC nrfx_wdt_t wdt = NRFX_WDT_INSTANCE(0);
50+
STATIC nrfx_wdt_channel_id wdt_channel_id;
7651

7752
NORETURN void mp_raise_WatchDogTimeout(void) {
7853
nlr_raise(MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_watchdog_exception)));
@@ -95,6 +70,12 @@ STATIC void watchdogtimer_timer_event_handler(nrf_timer_event_t event_type, void
9570
#endif
9671
}
9772

73+
// This function is called if the timer expires. The system will reboot in 1/16384 of a second.
74+
// Issue a reboot ourselves so we can do any cleanup necessary.
75+
STATIC void watchdogtimer_watchdog_event_handler(void) {
76+
reset_cpu();
77+
}
78+
9879
void watchdog_watchdogtimer_reset(void) {
9980
if (timer != NULL) {
10081
nrf_peripherals_free_timer(timer);
@@ -112,7 +93,7 @@ STATIC mp_obj_t watchdog_watchdogtimer_feed(mp_obj_t self_in) {
11293
watchdog_watchdogtimer_obj_t *self = MP_OBJ_TO_PTR(self_in);
11394

11495
if (self->mode == WATCHDOGMODE_RESET) {
115-
watchdogtimer_hardware_feed();
96+
nrfx_wdt_feed(&wdt);
11697
} else if (self->mode == WATCHDOGMODE_RAISE) {
11798
nrfx_timer_clear(timer);
11899
} else if (self->mode == WATCHDOGMODE_NONE) {
@@ -276,7 +257,29 @@ STATIC mp_obj_t watchdog_watchdogtimer_obj_set_mode(mp_obj_t self_in, mp_obj_t m
276257
timer = NULL;
277258
}
278259
}
279-
watchdogtimer_hardware_init(self->timeout, self->sleep);
260+
261+
uint64_t ticks = self->timeout * 1000.0f;
262+
if (ticks > UINT32_MAX) {
263+
mp_raise_ValueError(translate("timeout duration exceeded the maximum supported value"));
264+
}
265+
266+
nrfx_wdt_config_t config = {
267+
.reload_value = ticks, // in units of ms
268+
.behaviour = NRF_WDT_BEHAVIOUR_RUN_SLEEP,
269+
NRFX_WDT_IRQ_CONFIG
270+
};
271+
272+
nrfx_err_t err_code;
273+
err_code = nrfx_wdt_init(&wdt, &config, watchdogtimer_watchdog_event_handler);
274+
if (err_code != NRFX_SUCCESS) {
275+
mp_raise_OSError(1);
276+
}
277+
err_code = nrfx_wdt_channel_alloc(&wdt, &wdt_channel_id);
278+
if (err_code != NRFX_SUCCESS) {
279+
mp_raise_OSError(1);
280+
}
281+
nrfx_wdt_enable(&wdt);
282+
nrfx_wdt_feed(&wdt);
280283
self->mode = WATCHDOGMODE_RESET;
281284
}
282285

ports/nrf/nrfx_config.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,11 @@
122122
// NVM controller
123123
#define NRFX_NVMC_ENABLED 1
124124

125+
// Watchdog timer
126+
#define NRFX_WDT_ENABLED 1
127+
#define NRFX_WDT0_ENABLED 1
128+
// This IRQ indicates the system will reboot shortly, so give
129+
// it a high priority.
130+
#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY 1
131+
125132
#endif // NRFX_CONFIG_H__

ports/nrf/nrfx_glue.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,17 +180,17 @@ static inline bool _NRFX_IRQ_IS_PENDING(IRQn_Type irq_number)
180180
return (NVIC_GetPendingIRQ(irq_number) == 1);
181181
}
182182

183-
//#include <nordic_common.h>
184-
//#include <app_util_platform.h>
183+
void common_hal_mcu_disable_interrupts(void);
184+
void common_hal_mcu_enable_interrupts(void);
185185
/**
186186
* @brief Macro for entering into a critical section.
187187
*/
188-
#define NRFX_CRITICAL_SECTION_ENTER() CRITICAL_REGION_ENTER()
188+
#define NRFX_CRITICAL_SECTION_ENTER() common_hal_mcu_disable_interrupts()
189189

190190
/**
191191
* @brief Macro for exiting from a critical section.
192192
*/
193-
#define NRFX_CRITICAL_SECTION_EXIT() CRITICAL_REGION_EXIT()
193+
#define NRFX_CRITICAL_SECTION_EXIT() common_hal_mcu_enable_interrupts()
194194

195195
//------------------------------------------------------------------------------
196196

0 commit comments

Comments
 (0)