summaryrefslogtreecommitdiff
path: root/ports
diff options
context:
space:
mode:
authorSean Cross <sean@xobs.io>2020-05-22 17:29:54 +0800
committerSean Cross <sean@xobs.io>2020-05-27 11:28:49 +0800
commit589cb1af6de04a01e1cfda1082fea4f6fbc4440c (patch)
treed14864d46b13e925e3aa06a9ca74b1428665359b /ports
parente738f5eaa13c0e30dc082c511d9659c5f35e7f7e (diff)
nrf: watchdog: use nrfx_wdt driver
Instead of directly poking registers, use `nrfx_wdt`. Signed-off-by: Sean Cross <sean@xobs.io>
Diffstat (limited to 'ports')
-rwxr-xr-xports/nrf/Makefile1
-rw-r--r--ports/nrf/common-hal/watchdog/WatchDogTimer.c69
-rw-r--r--ports/nrf/nrfx_config.h7
-rw-r--r--ports/nrf/nrfx_glue.h8
4 files changed, 48 insertions, 37 deletions
diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile
index 8a7b1104b..e5931af5e 100755
--- a/ports/nrf/Makefile
+++ b/ports/nrf/Makefile
@@ -136,6 +136,7 @@ SRC_NRFX = $(addprefix nrfx/,\
drivers/src/nrfx_gpiote.c \
drivers/src/nrfx_rtc.c \
drivers/src/nrfx_nvmc.c \
+ drivers/src/nrfx_wdt.c \
)
ifdef EXTERNAL_FLASH_DEVICES
diff --git a/ports/nrf/common-hal/watchdog/WatchDogTimer.c b/ports/nrf/common-hal/watchdog/WatchDogTimer.c
index 28a96138f..358fab798 100644
--- a/ports/nrf/common-hal/watchdog/WatchDogTimer.c
+++ b/ports/nrf/common-hal/watchdog/WatchDogTimer.c
@@ -37,42 +37,17 @@
#include "shared-bindings/watchdog/__init__.h"
#include "shared-bindings/watchdog/WatchDogTimer.h"
+#include "supervisor/port.h"
+
+#include "nrf/timers.h"
#include "nrf_wdt.h"
+#include "nrfx_wdt.h"
#include "nrfx_timer.h"
-#include "nrf/timers.h"
STATIC uint8_t timer_refcount = 0;
-#define WATCHDOG_RELOAD_COUNT 2
STATIC nrfx_timer_t *timer = NULL;
-
-STATIC void watchdogtimer_hardware_init(mp_float_t duration, bool pause_during_sleep) {
- unsigned int channel;
- nrf_wdt_behaviour_t behaviour = NRF_WDT_BEHAVIOUR_RUN_SLEEP_HALT;
- if (pause_during_sleep) {
- behaviour = NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT;
- }
-
- nrf_wdt_behaviour_set(NRF_WDT, behaviour);
-
- uint64_t ticks = duration * 32768ULL;
- if (ticks > UINT32_MAX) {
- mp_raise_ValueError(translate("timeout duration exceeded the maximum supported value"));
- }
- nrf_wdt_reload_value_set(NRF_WDT, (uint32_t) ticks);
-
- for (channel = 0; channel < WATCHDOG_RELOAD_COUNT; channel++) {
- nrf_wdt_reload_request_enable(NRF_WDT, channel);
- }
-
- nrf_wdt_task_trigger(NRF_WDT, NRF_WDT_TASK_START);
-}
-
-STATIC void watchdogtimer_hardware_feed(void) {
- unsigned int channel;
- for (channel = 0; channel < WATCHDOG_RELOAD_COUNT; channel++) {
- nrf_wdt_reload_request_set(NRF_WDT, (nrf_wdt_rr_register_t)(NRF_WDT_RR0 + channel));
- }
-}
+STATIC nrfx_wdt_t wdt = NRFX_WDT_INSTANCE(0);
+STATIC nrfx_wdt_channel_id wdt_channel_id;
NORETURN void mp_raise_WatchDogTimeout(void) {
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
#endif
}
+// This function is called if the timer expires. The system will reboot in 1/16384 of a second.
+// Issue a reboot ourselves so we can do any cleanup necessary.
+STATIC void watchdogtimer_watchdog_event_handler(void) {
+ reset_cpu();
+}
+
void watchdog_watchdogtimer_reset(void) {
if (timer != NULL) {
nrf_peripherals_free_timer(timer);
@@ -112,7 +93,7 @@ STATIC mp_obj_t watchdog_watchdogtimer_feed(mp_obj_t self_in) {
watchdog_watchdogtimer_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (self->mode == WATCHDOGMODE_RESET) {
- watchdogtimer_hardware_feed();
+ nrfx_wdt_feed(&wdt);
} else if (self->mode == WATCHDOGMODE_RAISE) {
nrfx_timer_clear(timer);
} 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
timer = NULL;
}
}
- watchdogtimer_hardware_init(self->timeout, self->sleep);
+
+ uint64_t ticks = self->timeout * 1000.0f;
+ if (ticks > UINT32_MAX) {
+ mp_raise_ValueError(translate("timeout duration exceeded the maximum supported value"));
+ }
+
+ nrfx_wdt_config_t config = {
+ .reload_value = ticks, // in units of ms
+ .behaviour = NRF_WDT_BEHAVIOUR_RUN_SLEEP,
+ NRFX_WDT_IRQ_CONFIG
+ };
+
+ nrfx_err_t err_code;
+ err_code = nrfx_wdt_init(&wdt, &config, watchdogtimer_watchdog_event_handler);
+ if (err_code != NRFX_SUCCESS) {
+ mp_raise_OSError(1);
+ }
+ err_code = nrfx_wdt_channel_alloc(&wdt, &wdt_channel_id);
+ if (err_code != NRFX_SUCCESS) {
+ mp_raise_OSError(1);
+ }
+ nrfx_wdt_enable(&wdt);
+ nrfx_wdt_feed(&wdt);
self->mode = WATCHDOGMODE_RESET;
}
diff --git a/ports/nrf/nrfx_config.h b/ports/nrf/nrfx_config.h
index 7a7f2e6d6..2dcdba14c 100644
--- a/ports/nrf/nrfx_config.h
+++ b/ports/nrf/nrfx_config.h
@@ -122,4 +122,11 @@
// NVM controller
#define NRFX_NVMC_ENABLED 1
+// Watchdog timer
+#define NRFX_WDT_ENABLED 1
+#define NRFX_WDT0_ENABLED 1
+// This IRQ indicates the system will reboot shortly, so give
+// it a high priority.
+#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY 1
+
#endif // NRFX_CONFIG_H__
diff --git a/ports/nrf/nrfx_glue.h b/ports/nrf/nrfx_glue.h
index 345de3870..9f91b72a1 100644
--- a/ports/nrf/nrfx_glue.h
+++ b/ports/nrf/nrfx_glue.h
@@ -180,17 +180,17 @@ static inline bool _NRFX_IRQ_IS_PENDING(IRQn_Type irq_number)
return (NVIC_GetPendingIRQ(irq_number) == 1);
}
-//#include <nordic_common.h>
-//#include <app_util_platform.h>
+void common_hal_mcu_disable_interrupts(void);
+void common_hal_mcu_enable_interrupts(void);
/**
* @brief Macro for entering into a critical section.
*/
-#define NRFX_CRITICAL_SECTION_ENTER() CRITICAL_REGION_ENTER()
+#define NRFX_CRITICAL_SECTION_ENTER() common_hal_mcu_disable_interrupts()
/**
* @brief Macro for exiting from a critical section.
*/
-#define NRFX_CRITICAL_SECTION_EXIT() CRITICAL_REGION_EXIT()
+#define NRFX_CRITICAL_SECTION_EXIT() common_hal_mcu_enable_interrupts()
//------------------------------------------------------------------------------