3434
3535#include "common-hal/watchdog/WatchDogTimer.h"
3636
37+ #include "shared-bindings/microcontroller/__init__.h"
3738#include "shared-bindings/watchdog/__init__.h"
3839#include "shared-bindings/watchdog/WatchDogTimer.h"
3940
@@ -57,7 +58,7 @@ const mp_obj_type_t mp_type_WatchDogTimeout = {
5758 .parent = & mp_type_Exception ,
5859};
5960
60- static mp_obj_exception_t mp_watchdog_timeout_exception = {
61+ mp_obj_exception_t mp_watchdog_timeout_exception = {
6162 .base .type = & mp_type_WatchDogTimeout ,
6263 .traceback_alloc = 0 ,
6364 .traceback_len = 0 ,
@@ -66,14 +67,15 @@ static mp_obj_exception_t mp_watchdog_timeout_exception = {
6667};
6768
6869STATIC void watchdogtimer_timer_event_handler (nrf_timer_event_t event_type , void * p_context ) {
69- ( void ) p_context ;
70+ watchdog_watchdogtimer_obj_t * self = MP_OBJ_TO_PTR ( p_context ) ;
7071 if (event_type != NRF_TIMER_EVENT_COMPARE0 ) {
7172 // Spurious event.
7273 return ;
7374 }
7475
7576 // If the timer hits without being cleared, pause the timer and raise an exception.
7677 nrfx_timer_pause (timer );
78+ self -> mode = WATCHDOGMODE_NONE ;
7779 mp_obj_exception_clear_traceback (MP_OBJ_FROM_PTR (& mp_watchdog_timeout_exception ));
7880 MP_STATE_VM (mp_pending_exception ) = & mp_watchdog_timeout_exception ;
7981#if MICROPY_ENABLE_SCHEDULER
@@ -89,105 +91,6 @@ STATIC void watchdogtimer_watchdog_event_handler(void) {
8991 reset_cpu ();
9092}
9193
92- void watchdog_watchdogtimer_reset (void ) {
93- if (timer != NULL ) {
94- nrf_peripherals_free_timer (timer );
95- }
96- timer = NULL ;
97- timer_refcount = 0 ;
98- }
99-
100- <<<<<<< HEAD
101- == = == ==
102- //| class WDT:
103- //| """Watchdog Timer"""
104- //|
105- //| def __init__(self, ):
106- //| """This class represents the system's Watchdog Timer. It is a
107- //| singleton and will always return the same instance.
108- //|
109- //| """
110- //| ...
111- //|
112- STATIC mp_obj_t watchdog_watchdogtimer_make_new (const mp_obj_type_t * type , size_t n_args ,
113- const mp_obj_t * pos_args ,
114- mp_map_t * kw_args ) {
115- enum { ARG_timeout , ARG_sleep , ARG_hardware };
116- static const mp_arg_t allowed_args [] = {
117- {MP_QSTR_timeout , MP_ARG_OBJ | MP_ARG_REQUIRED },
118- {MP_QSTR_sleep , MP_ARG_BOOL , {.u_bool = false}},
119- {MP_QSTR_hardware , MP_ARG_BOOL , {.u_bool = false}},
120- };
121- mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
122-
123- mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ),
124- allowed_args , args );
125- mp_float_t timeout = mp_obj_get_float (args [ARG_timeout ].u_obj );
126- bool hardware = args [ARG_hardware ].u_bool ;
127- bool sleep = args [ARG_sleep ].u_bool ;
128-
129- // If the hardware timer is already running, return that timer.
130- // If the parameters have changed, then ignore them, but print
131- // an error.
132- if (wdt_singleton && hardware ) {
133- if ((sleep != wdt_singleton -> sleep )
134- || (hardware != wdt_singleton -> hardware )
135- || fabsf (timeout - wdt_singleton -> timeout ) > 0.01f ) {
136- // Print a warning indicating things aren't quite right
137- // mp_printf(&mp_stderr_print, translate("warning: hardware timer was already running"));
138- }
139- watchdogtimer_hardware_feed ();
140- return wdt_singleton ;
141- }
142-
143- if (timeout <= 0 ) {
144- mp_raise_ValueError (translate ("watchdog timeout must be greater than 0" ));
145- }
146-
147- watchdog_watchdogtimer_obj_t * self = m_new_obj (watchdog_watchdogtimer_obj_t );
148- self -> base .type = & watchdog_watchdogtimer_type ;
149- self -> timeout = timeout ;
150- self -> sleep = sleep ;
151- self -> hardware = hardware ;
152-
153- if (hardware ) {
154- watchdogtimer_hardware_init (self -> timeout , self -> sleep );
155- wdt_singleton = self ;
156- } else {
157- uint64_t ticks = timeout * 31250ULL ;
158- if (ticks > UINT32_MAX ) {
159- mp_raise_ValueError (translate ("timeout duration exceeded the maximum supported value" ));
160- }
161-
162- if (timer_refcount == 0 ) {
163- timer = nrf_peripherals_allocate_timer_or_throw ();
164- }
165- timer_refcount ++ ;
166-
167- nrfx_timer_config_t timer_config = {
168- .frequency = NRF_TIMER_FREQ_31250Hz ,
169- .mode = NRF_TIMER_MODE_TIMER ,
170- .bit_width = NRF_TIMER_BIT_WIDTH_32 ,
171- .interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY ,
172- .p_context = self ,
173- };
174-
175- nrfx_timer_init (timer , & timer_config , & watchdogtimer_event_handler );
176-
177- // true enables interrupt.
178- nrfx_timer_clear (timer );
179- nrfx_timer_compare (timer , NRF_TIMER_CC_CHANNEL0 , ticks , true);
180- nrfx_timer_resume (timer );
181- }
182-
183- // Feed the watchdog, in case there's a timer that's already running
184- // and it's only partially finished.
185- mp_obj_t * self_obj = MP_OBJ_FROM_PTR (self );
186- watchdog_watchdogtimer_feed (self_obj );
187- return self_obj ;
188- }
189-
190- >>>>>>> parent of 561e7e619 ... add WatchDogTimeout exception
19194//| def feed(self):
19295//| """Feed the watchdog timer. This must be called regularly, otherwise
19396//| the timer will expire."""
@@ -221,6 +124,7 @@ STATIC mp_obj_t watchdog_watchdogtimer_deinit(mp_obj_t self_in) {
221124 nrf_peripherals_free_timer (timer );
222125 timer = NULL ;
223126 }
127+ self -> mode = WATCHDOGMODE_NONE ;
224128 } else if (self -> mode == WATCHDOGMODE_RESET ) {
225129 mp_raise_NotImplementedError (translate ("WatchDogTimer cannot be deinitialized once mode is set to RESET" ));
226130 }
@@ -229,6 +133,17 @@ STATIC mp_obj_t watchdog_watchdogtimer_deinit(mp_obj_t self_in) {
229133}
230134STATIC MP_DEFINE_CONST_FUN_OBJ_1 (watchdog_watchdogtimer_deinit_obj , watchdog_watchdogtimer_deinit );
231135
136+ void watchdog_reset (void ) {
137+ if (common_hal_mcu_watchdogtimer_obj .mode == WATCHDOGMODE_RAISE ) {
138+ common_hal_mcu_watchdogtimer_obj .mode = WATCHDOGMODE_NONE ;
139+ timer_refcount -- ;
140+ if (timer_refcount == 0 ) {
141+ nrf_peripherals_free_timer (timer );
142+ timer = NULL ;
143+ }
144+ }
145+ }
146+
232147//| timeout: float = ...
233148//| """The maximum number of seconds that can elapse between calls
234149//| to feed()"""
@@ -250,7 +165,7 @@ STATIC mp_obj_t watchdog_watchdogtimer_obj_set_timeout(mp_obj_t self_in, mp_obj_
250165 if (self -> mode == WATCHDOGMODE_RESET ) {
251166 // If the WatchDogTimer is already running in "RESET" mode, raise an error
252167 // since the mode cannot be changed once started.
253- mp_raise_TypeError (translate ("Cannot change the timeout once mode is WatchDogMode.RESET" ));
168+ mp_raise_TypeError (translate ("cannot change the timeout once mode is WatchDogMode.RESET" ));
254169 } else if (self -> mode == WATCHDOGMODE_RAISE ) {
255170 // If the WatchDogTimer is already running in "RAISE" mode, reset the timer
256171 // with the new value.
@@ -322,15 +237,13 @@ STATIC mp_obj_t watchdog_watchdogtimer_obj_set_mode(mp_obj_t self_in, mp_obj_t m
322237 if (self -> mode == WATCHDOGMODE_RESET ) {
323238 mp_raise_ValueError (translate ("WatchDogTimer mode cannot be changed once set to WatchDogMode.RESET" ));
324239 }
325- else if (self -> mode == WATCHDOGMODE_NONE ) {
326- uint64_t ticks = self -> timeout * 31250ULL ;
327- if (ticks > UINT32_MAX ) {
328- mp_raise_ValueError (translate ("timeout duration exceeded the maximum supported value" ));
329- }
330-
240+ else if (self -> mode == WATCHDOGMODE_NONE || self -> mode == WATCHDOGMODE_RAISE ) {
331241 if (timer_refcount == 0 ) {
332242 timer = nrf_peripherals_allocate_timer_or_throw ();
333243 }
244+ if (timer == NULL ) {
245+ mp_raise_RuntimeError (translate ("timer was null" ));
246+ }
334247 timer_refcount ++ ;
335248
336249 nrfx_timer_config_t timer_config = {
@@ -343,6 +256,11 @@ STATIC mp_obj_t watchdog_watchdogtimer_obj_set_mode(mp_obj_t self_in, mp_obj_t m
343256
344257 nrfx_timer_init (timer , & timer_config , & watchdogtimer_timer_event_handler );
345258
259+ uint64_t ticks = nrfx_timer_ms_to_ticks (timer , self -> timeout * 1000 );
260+ if (ticks > UINT32_MAX ) {
261+ mp_raise_ValueError (translate ("timeout duration exceeded the maximum supported value" ));
262+ }
263+
346264 // true enables interrupt.
347265 nrfx_timer_clear (timer );
348266 nrfx_timer_compare (timer , NRF_TIMER_CC_CHANNEL0 , ticks , true);
0 commit comments