37
37
#include "shared-bindings/watchdog/__init__.h"
38
38
#include "shared-bindings/watchdog/WatchDogTimer.h"
39
39
40
+ #include "supervisor/port.h"
41
+
42
+ #include "nrf/timers.h"
40
43
#include "nrf_wdt.h"
44
+ #include "nrfx_wdt.h"
41
45
#include "nrfx_timer.h"
42
- #include "nrf/timers.h"
43
46
44
47
STATIC uint8_t timer_refcount = 0 ;
45
- #define WATCHDOG_RELOAD_COUNT 2
46
48
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 ;
76
51
77
52
NORETURN void mp_raise_WatchDogTimeout (void ) {
78
53
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
95
70
#endif
96
71
}
97
72
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
+
98
79
void watchdog_watchdogtimer_reset (void ) {
99
80
if (timer != NULL ) {
100
81
nrf_peripherals_free_timer (timer );
@@ -112,7 +93,7 @@ STATIC mp_obj_t watchdog_watchdogtimer_feed(mp_obj_t self_in) {
112
93
watchdog_watchdogtimer_obj_t * self = MP_OBJ_TO_PTR (self_in );
113
94
114
95
if (self -> mode == WATCHDOGMODE_RESET ) {
115
- watchdogtimer_hardware_feed ( );
96
+ nrfx_wdt_feed ( & wdt );
116
97
} else if (self -> mode == WATCHDOGMODE_RAISE ) {
117
98
nrfx_timer_clear (timer );
118
99
} 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
276
257
timer = NULL ;
277
258
}
278
259
}
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 );
280
283
self -> mode = WATCHDOGMODE_RESET ;
281
284
}
282
285
0 commit comments