Skip to content

Commit 737db96

Browse files
committed
nrf: common-hal: finish reworking exceptions
This finishes the rework of the exception handler, which is once again stored inside the watchdog timer module. This also implements a `watchdog_reset()` that is used to disable the RAISE watchdog, if one is enabled. Signed-off-by: Sean Cross <[email protected]>
1 parent 82d64a1 commit 737db96

File tree

2 files changed

+28
-108
lines changed

2 files changed

+28
-108
lines changed

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

Lines changed: 26 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
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

6869
STATIC 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
}
230134
STATIC 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);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,6 @@ typedef struct _watchdog_watchdogtimer_obj_t {
3838
watchdog_watchdogmode_t mode;
3939
} watchdog_watchdogtimer_obj_t;
4040

41+
void watchdog_reset(void);
42+
4143
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H

0 commit comments

Comments
 (0)