diff options
| author | Sean Cross <sean@xobs.io> | 2020-05-22 17:29:54 +0800 |
|---|---|---|
| committer | Sean Cross <sean@xobs.io> | 2020-05-27 11:28:49 +0800 |
| commit | 589cb1af6de04a01e1cfda1082fea4f6fbc4440c (patch) | |
| tree | d14864d46b13e925e3aa06a9ca74b1428665359b /ports | |
| parent | e738f5eaa13c0e30dc082c511d9659c5f35e7f7e (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-x | ports/nrf/Makefile | 1 | ||||
| -rw-r--r-- | ports/nrf/common-hal/watchdog/WatchDogTimer.c | 69 | ||||
| -rw-r--r-- | ports/nrf/nrfx_config.h | 7 | ||||
| -rw-r--r-- | ports/nrf/nrfx_glue.h | 8 |
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() //------------------------------------------------------------------------------ |
