From 668f96e6e9dd53f97c4a033db3042d71a0f14e8f Mon Sep 17 00:00:00 2001 From: MicroDev <70126934+MicroDev1@users.noreply.github.com> Date: Wed, 15 Mar 2023 12:05:38 +0530 Subject: [PATCH 1/7] update watchdog implementation - add note about deprecation of `deinit` - refactor `WatchDogMode` implementation - make validation of watchdog mode port specific --- shared-bindings/watchdog/WatchDogMode.c | 85 ++++++------------------ shared-bindings/watchdog/WatchDogMode.h | 13 +--- shared-bindings/watchdog/WatchDogTimer.c | 32 ++++----- 3 files changed, 35 insertions(+), 95 deletions(-) diff --git a/shared-bindings/watchdog/WatchDogMode.c b/shared-bindings/watchdog/WatchDogMode.c index c707054d27..343702e4b1 100644 --- a/shared-bindings/watchdog/WatchDogMode.c +++ b/shared-bindings/watchdog/WatchDogMode.c @@ -1,9 +1,9 @@ /* - * This file is part of the Micro Python project, http://micropython.org/ + * This file is part of the MicroPython project, http://micropython.org/ * * The MIT License (MIT) * - * Copyright (c) 2020 Sean Cross for Adafruit Industries + * Copyright (c) 2023 MicroDev * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,76 +24,33 @@ * THE SOFTWARE. */ +#include "py/enum.h" + #include "shared-bindings/watchdog/WatchDogMode.h" +MAKE_ENUM_VALUE(watchdog_watchdogmode_type, watchdogmode, NONE, WATCHDOGMODE_NONE); +MAKE_ENUM_VALUE(watchdog_watchdogmode_type, watchdogmode, RAISE, WATCHDOGMODE_RAISE); +MAKE_ENUM_VALUE(watchdog_watchdogmode_type, watchdogmode, RESET, WATCHDOGMODE_RESET); + //| class WatchDogMode: -//| """run state of the watchdog timer""" +//| """Run state of the watchdog timer.""" +//| +//| NONE: WatchDogMode +//| """The `WatchDogTimer` is disabled.""" //| -//| def __init__(self) -> None: -//| """Enum-like class to define the run mode of the watchdog timer.""" //| RAISE: WatchDogMode -//| """Raise an exception when the WatchDogTimer expires. -//| -//| **Limitations:** ``RAISE`` mode is not supported on SAMD or RP2040. -//| -//| :type WatchDogMode:""" +//| """Raise an exception when the `WatchDogTimer` expires.""" //| //| RESET: WatchDogMode -//| """Reset the system if the WatchDogTimer expires. +//| """Reset the system when the `WatchDogTimer` expires.""" //| -//| :type WatchDogMode:""" -//| -const mp_obj_type_t watchdog_watchdogmode_type; - -const watchdog_watchdogmode_obj_t watchdog_watchdogmode_raise_obj = { - { &watchdog_watchdogmode_type }, +MAKE_ENUM_MAP(watchdog_watchdogmode) { + MAKE_ENUM_MAP_ENTRY(watchdogmode, NONE), + MAKE_ENUM_MAP_ENTRY(watchdogmode, RAISE), + MAKE_ENUM_MAP_ENTRY(watchdogmode, RESET), }; +STATIC MP_DEFINE_CONST_DICT(watchdog_watchdogmode_locals_dict, watchdog_watchdogmode_locals_table); -const watchdog_watchdogmode_obj_t watchdog_watchdogmode_reset_obj = { - { &watchdog_watchdogmode_type }, -}; +MAKE_PRINTER(watchdog, watchdog_watchdogmode); -watchdog_watchdogmode_t watchdog_watchdogmode_obj_to_type(mp_obj_t obj) { - if (obj == MP_ROM_PTR(&watchdog_watchdogmode_raise_obj)) { - return WATCHDOGMODE_RAISE; - } else if (obj == MP_ROM_PTR(&watchdog_watchdogmode_reset_obj)) { - return WATCHDOGMODE_RESET; - } - return WATCHDOGMODE_NONE; -} - -mp_obj_t watchdog_watchdogmode_type_to_obj(watchdog_watchdogmode_t mode) { - switch (mode) { - case WATCHDOGMODE_RAISE: - return (mp_obj_t)MP_ROM_PTR(&watchdog_watchdogmode_raise_obj); - case WATCHDOGMODE_RESET: - return (mp_obj_t)MP_ROM_PTR(&watchdog_watchdogmode_reset_obj); - case WATCHDOGMODE_NONE: - default: - return MP_ROM_NONE; - } -} - -STATIC const mp_rom_map_elem_t watchdog_watchdogmode_locals_dict_table[] = { - {MP_ROM_QSTR(MP_QSTR_RAISE), MP_ROM_PTR(&watchdog_watchdogmode_raise_obj)}, - {MP_ROM_QSTR(MP_QSTR_RESET), MP_ROM_PTR(&watchdog_watchdogmode_reset_obj)}, -}; -STATIC MP_DEFINE_CONST_DICT(watchdog_watchdogmode_locals_dict, watchdog_watchdogmode_locals_dict_table); - -STATIC void watchdog_watchdogmode_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - qstr runmode = MP_QSTR_None; - if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&watchdog_watchdogmode_raise_obj)) { - runmode = MP_QSTR_RAISE; - } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&watchdog_watchdogmode_reset_obj)) { - runmode = MP_QSTR_RESET; - } - mp_printf(print, "%q.%q.%q", MP_QSTR_watchdog, MP_QSTR_WatchDogMode, - runmode); -} - -const mp_obj_type_t watchdog_watchdogmode_type = { - { &mp_type_type }, - .name = MP_QSTR_WatchDogMode, - .print = watchdog_watchdogmode_print, - .locals_dict = (mp_obj_t)&watchdog_watchdogmode_locals_dict, -}; +MAKE_ENUM_TYPE(watchdog, WatchDogMode, watchdog_watchdogmode); diff --git a/shared-bindings/watchdog/WatchDogMode.h b/shared-bindings/watchdog/WatchDogMode.h index fb09445a9f..fd27d4d46a 100644 --- a/shared-bindings/watchdog/WatchDogMode.h +++ b/shared-bindings/watchdog/WatchDogMode.h @@ -1,5 +1,5 @@ /* - * This file is part of the Micro Python project, http://micropython.org/ + * This file is part of the MicroPython project, http://micropython.org/ * * The MIT License (MIT) * @@ -27,7 +27,7 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_WATCHDOG_WATCHDOGMODE_H #define MICROPY_INCLUDED_SHARED_BINDINGS_WATCHDOG_WATCHDOGMODE_H -#include "py/obj.h" +#include "py/enum.h" typedef enum { WATCHDOGMODE_NONE, @@ -37,13 +37,4 @@ typedef enum { extern const mp_obj_type_t watchdog_watchdogmode_type; -watchdog_watchdogmode_t watchdog_watchdogmode_obj_to_type(mp_obj_t obj); -mp_obj_t watchdog_watchdogmode_type_to_obj(watchdog_watchdogmode_t mode); - -typedef struct { - mp_obj_base_t base; -} watchdog_watchdogmode_obj_t; -extern const watchdog_watchdogmode_obj_t watchdog_watchdogmode_raise_obj; -extern const watchdog_watchdogmode_obj_t watchdog_watchdogmode_reset_obj; - #endif // MICROPY_INCLUDED_SHARED_BINDINGS_WATCHDOG_WATCHDOGMODE_H diff --git a/shared-bindings/watchdog/WatchDogTimer.c b/shared-bindings/watchdog/WatchDogTimer.c index acfd353c34..10ab334330 100644 --- a/shared-bindings/watchdog/WatchDogTimer.c +++ b/shared-bindings/watchdog/WatchDogTimer.c @@ -71,8 +71,14 @@ STATIC mp_obj_t watchdog_watchdogtimer_feed(mp_obj_t self_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(watchdog_watchdogtimer_feed_obj, watchdog_watchdogtimer_feed); //| def deinit(self) -> None: -//| """Stop the watchdog timer. This may raise an error if the watchdog -//| timer cannot be disabled on this platform.""" +//| """Stop the watchdog timer. +//| +//| :raises RuntimeError: if the watchdog timer cannot be disabled on this platform. +//| +//| .. note:: This is deprecated in ``8.1.0`` and will be removed in ``9.0.0``. +//| Set watchdog `mode` to `WatchDogMode.NONE` instead. +//| +//| """ //| ... STATIC mp_obj_t watchdog_watchdogtimer_deinit(mp_obj_t self_in) { watchdog_watchdogtimer_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -94,7 +100,7 @@ STATIC mp_obj_t watchdog_watchdogtimer_obj_set_timeout(mp_obj_t self_in, mp_obj_ watchdog_watchdogtimer_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_float_t timeout = mp_obj_get_float(timeout_obj); - mp_arg_validate_int_min((int)timeout, 0, MP_QSTR_timeout); + mp_arg_validate_int_min(timeout, 0, MP_QSTR_timeout); common_hal_watchdog_set_timeout(self, timeout); return mp_const_none; @@ -122,27 +128,13 @@ MP_PROPERTY_GETSET(watchdog_watchdogtimer_timeout_obj, //| STATIC mp_obj_t watchdog_watchdogtimer_obj_get_mode(mp_obj_t self_in) { watchdog_watchdogtimer_obj_t *self = MP_OBJ_TO_PTR(self_in); - return watchdog_watchdogmode_type_to_obj(common_hal_watchdog_get_mode(self)); + return cp_enum_find(&watchdog_watchdogmode_type, common_hal_watchdog_get_mode(self)); } MP_DEFINE_CONST_FUN_OBJ_1(watchdog_watchdogtimer_get_mode_obj, watchdog_watchdogtimer_obj_get_mode); -STATIC mp_obj_t watchdog_watchdogtimer_obj_set_mode(mp_obj_t self_in, mp_obj_t mode_obj) { +STATIC mp_obj_t watchdog_watchdogtimer_obj_set_mode(mp_obj_t self_in, mp_obj_t obj) { watchdog_watchdogtimer_obj_t *self = MP_OBJ_TO_PTR(self_in); - watchdog_watchdogmode_t current_mode = common_hal_watchdog_get_mode(self); - watchdog_watchdogmode_t new_mode = watchdog_watchdogmode_obj_to_type(mode_obj); - mp_float_t current_timeout = common_hal_watchdog_get_timeout(self); - - // When setting the mode, the timeout value must be greater than zero - if (new_mode == WATCHDOGMODE_RESET || new_mode == WATCHDOGMODE_RAISE) { - mp_arg_validate_int_min((int)current_timeout, 0, MP_QSTR_timeout); - } - - // Don't allow changing the mode once the watchdog timer has been started - if (current_mode == WATCHDOGMODE_RESET && new_mode != WATCHDOGMODE_RESET) { - mp_raise_TypeError(translate("WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET")); - } - - common_hal_watchdog_set_mode(self, new_mode); + common_hal_watchdog_set_mode(self, cp_enum_value(&watchdog_watchdogmode_type, obj, MP_QSTR_mode)); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(watchdog_watchdogtimer_set_mode_obj, watchdog_watchdogtimer_obj_set_mode); From 5e0dce286ee8c8aea71e6ac77c09b1da048d5fdb Mon Sep 17 00:00:00 2001 From: MicroDev <70126934+MicroDev1@users.noreply.github.com> Date: Wed, 15 Mar 2023 13:14:21 +0530 Subject: [PATCH 2/7] update watchdog implementation for atmel-samd --- .../common-hal/watchdog/WatchDogTimer.c | 107 +++++++++++------- .../common-hal/watchdog/WatchDogTimer.h | 2 +- ports/atmel-samd/supervisor/port.c | 11 ++ 3 files changed, 76 insertions(+), 44 deletions(-) diff --git a/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c b/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c index 65d238ce75..0c0ef85bb2 100644 --- a/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c +++ b/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c @@ -34,58 +34,69 @@ #include "component/wdt.h" +#define SYNC_CTRL_WRITE while (WDT->SYNCBUSY.reg) {} + +static void watchdog_disable(void) { + // disable watchdog + WDT->CTRLA.reg = 0; + SYNC_CTRL_WRITE +} + +static void watchdog_enable(watchdog_watchdogtimer_obj_t *self) { + // disable watchdog for config + watchdog_disable(); + + int wdt_cycles = (int)(self->timeout * 1024); + if (wdt_cycles < 8) { + wdt_cycles = 8; + } + + // ceil(log2(n)) = 32 - __builtin_clz(n - 1) when n > 1 (if int is 32 bits) + int log2_wdt_cycles = (sizeof(int) * CHAR_BIT) - __builtin_clz(wdt_cycles - 1); + int setting = log2_wdt_cycles - 3; // CYC8_Val is 0 + + OSC32KCTRL->OSCULP32K.bit.EN1K = 1; // Enable out 1K (for WDT) + + WDT->INTENCLR.reg = WDT_INTENCLR_EW; // Disable early warning interrupt + WDT->CONFIG.bit.PER = setting; // Set period for chip reset + WDT->CTRLA.bit.WEN = 0; // Disable window mode + SYNC_CTRL_WRITE + common_hal_watchdog_feed(self); // Clear watchdog interval + WDT->CTRLA.bit.ENABLE = 1; // Start watchdog now! + SYNC_CTRL_WRITE +} + void common_hal_watchdog_feed(watchdog_watchdogtimer_obj_t *self) { WDT->CLEAR.reg = WDT_CLEAR_CLEAR_KEY; } void common_hal_watchdog_deinit(watchdog_watchdogtimer_obj_t *self) { - if (self->mode == WATCHDOGMODE_RESET) { - mp_raise_RuntimeError(translate("WatchDogTimer cannot be deinitialized once mode is set to RESET")); - } else { - self->mode = WATCHDOGMODE_NONE; + if (self->mode == WATCHDOGMODE_NONE) { + return; } + watchdog_disable(); + self->mode = WATCHDOGMODE_NONE; +} + +void watchdog_reset(void) { + common_hal_watchdog_deinit(&common_hal_mcu_watchdogtimer_obj); } mp_float_t common_hal_watchdog_get_timeout(watchdog_watchdogtimer_obj_t *self) { return self->timeout; } -STATIC void setup_wdt(watchdog_watchdogtimer_obj_t *self, int setting) { - OSC32KCTRL->OSCULP32K.bit.EN1K = 1; // Enable out 1K (for WDT) - - // disable watchdog for config - WDT->CTRLA.reg = 0; - while (WDT->SYNCBUSY.reg) { // Sync CTRL write - } - - WDT->INTENCLR.reg = WDT_INTENCLR_EW; // Disable early warning interrupt - WDT->CONFIG.bit.PER = setting; // Set period for chip reset - WDT->CTRLA.bit.WEN = 0; // Disable window mode - while (WDT->SYNCBUSY.reg) { // Sync CTRL write - } - common_hal_watchdog_feed(self); // Clear watchdog interval - WDT->CTRLA.bit.ENABLE = 1; // Start watchdog now! - while (WDT->SYNCBUSY.reg) { - } -} - void common_hal_watchdog_set_timeout(watchdog_watchdogtimer_obj_t *self, mp_float_t new_timeout) { - int wdt_cycles = (int)(new_timeout * 1024); - if (wdt_cycles < 8) { - wdt_cycles = 8; + if (!(self->timeout < new_timeout || self->timeout > new_timeout)) { + return; } - if (wdt_cycles > 16384) { - mp_raise_ValueError(translate("timeout duration exceeded the maximum supported value")); - } - // ceil(log2(n)) = 32 - __builtin_clz(n - 1) when n > 1 (if int is 32 bits) - int log2_wdt_cycles = (sizeof(int) * CHAR_BIT) - __builtin_clz(wdt_cycles - 1); - int setting = log2_wdt_cycles - 3; // CYC8_Val is 0 - float timeout = (8 << setting) / 1024.f; + + mp_arg_validate_int_max(new_timeout, 16, MP_QSTR_timeout); + self->timeout = new_timeout; if (self->mode == WATCHDOGMODE_RESET) { - setup_wdt(self, setting); + watchdog_enable(self); } - self->timeout = timeout; } watchdog_watchdogmode_t common_hal_watchdog_get_mode(watchdog_watchdogtimer_obj_t *self) { @@ -93,13 +104,23 @@ watchdog_watchdogmode_t common_hal_watchdog_get_mode(watchdog_watchdogtimer_obj_ } void common_hal_watchdog_set_mode(watchdog_watchdogtimer_obj_t *self, watchdog_watchdogmode_t new_mode) { - if (self->mode != new_mode) { - if (new_mode == WATCHDOGMODE_RAISE) { - mp_raise_NotImplementedError(translate("RAISE mode is not implemented")); - } else if (new_mode == WATCHDOGMODE_NONE) { - common_hal_watchdog_deinit(self); - } - self->mode = new_mode; - common_hal_watchdog_set_timeout(self, self->timeout); + if (self->mode == new_mode) { + return; } + + switch (new_mode) { + case WATCHDOGMODE_NONE: + common_hal_watchdog_deinit(self); + break; + case WATCHDOGMODE_RAISE: + mp_raise_NotImplementedError(NULL); + break; + case WATCHDOGMODE_RESET: + watchdog_enable(self); + break; + default: + return; + } + + self->mode = new_mode; } diff --git a/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.h b/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.h index ce34f0b8ab..579e8ce65f 100644 --- a/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.h +++ b/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.h @@ -38,6 +38,6 @@ struct _watchdog_watchdogtimer_obj_t { }; // This needs to be called in order to disable the watchdog -// void watchdog_reset(void); +void watchdog_reset(void); #endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 45b999f1a1..1a961dd12e 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -388,13 +388,16 @@ void reset_port(void) { #if CIRCUITPY_BUSIO reset_sercoms(); #endif + #if CIRCUITPY_AUDIOIO audio_dma_reset(); audioout_reset(); #endif + #if CIRCUITPY_AUDIOBUSIO pdmin_reset(); #endif + #if CIRCUITPY_AUDIOBUSIO_I2SOUT i2sout_reset(); #endif @@ -406,14 +409,18 @@ void reset_port(void) { #if CIRCUITPY_TOUCHIO && CIRCUITPY_TOUCHIO_USE_NATIVE touchin_reset(); #endif + eic_reset(); + #if CIRCUITPY_PULSEIO pulsein_reset(); pulseout_reset(); #endif + #if CIRCUITPY_PWMIO pwmout_reset(); #endif + #if CIRCUITPY_PWMIO || CIRCUITPY_AUDIOIO || CIRCUITPY_FREQUENCYIO reset_timers(); #endif @@ -423,6 +430,10 @@ void reset_port(void) { analogout_reset(); #endif + #if CIRCUITPY_WATCHDOG + watchdog_reset(); + #endif + reset_gclks(); #if CIRCUITPY_PEW From 0acf2e8c9bbfe90aa5b6b84272e8d8ada93dd722 Mon Sep 17 00:00:00 2001 From: MicroDev <70126934+MicroDev1@users.noreply.github.com> Date: Wed, 15 Mar 2023 13:18:13 +0530 Subject: [PATCH 3/7] update watchdog implementation for espressif --- .../common-hal/watchdog/WatchDogTimer.c | 56 ++++++++++++++----- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/ports/espressif/common-hal/watchdog/WatchDogTimer.c b/ports/espressif/common-hal/watchdog/WatchDogTimer.c index 159c99458f..6a7c91622e 100644 --- a/ports/espressif/common-hal/watchdog/WatchDogTimer.c +++ b/ports/espressif/common-hal/watchdog/WatchDogTimer.c @@ -33,9 +33,18 @@ #include "esp_task_wdt.h" extern void esp_task_wdt_isr_user_handler(void); + void esp_task_wdt_isr_user_handler(void) { + // just delete, deiniting TWDT in isr context causes a crash + if (esp_task_wdt_delete(NULL) == ESP_OK) { + watchdog_watchdogtimer_obj_t *self = &common_hal_mcu_watchdogtimer_obj; + self->mode = WATCHDOGMODE_NONE; + } + + // schedule watchdog timeout exception mp_obj_exception_clear_traceback(MP_OBJ_FROM_PTR(&mp_watchdog_timeout_exception)); MP_STATE_THREAD(mp_pending_exception) = &mp_watchdog_timeout_exception; + #if MICROPY_ENABLE_SCHEDULER if (MP_STATE_VM(sched_state) == MP_SCHED_IDLE) { MP_STATE_VM(sched_state) = MP_SCHED_PENDING; @@ -44,12 +53,13 @@ void esp_task_wdt_isr_user_handler(void) { } void common_hal_watchdog_feed(watchdog_watchdogtimer_obj_t *self) { - if (esp_task_wdt_reset() != ESP_OK) { - mp_raise_RuntimeError(translate("watchdog not initialized")); - } + esp_task_wdt_reset(); } void common_hal_watchdog_deinit(watchdog_watchdogtimer_obj_t *self) { + if (self->mode == WATCHDOGMODE_NONE) { + return; + } if (esp_task_wdt_delete(NULL) == ESP_OK && esp_task_wdt_deinit() == ESP_OK) { self->mode = WATCHDOGMODE_NONE; } @@ -59,11 +69,11 @@ void watchdog_reset(void) { common_hal_watchdog_deinit(&common_hal_mcu_watchdogtimer_obj); } -static void wdt_config(watchdog_watchdogtimer_obj_t *self) { +static void wdt_config(uint32_t timeout, watchdog_watchdogmode_t mode) { // enable panic hanler in WATCHDOGMODE_RESET mode // initialize Task Watchdog Timer (TWDT) - if (esp_task_wdt_init((uint32_t)self->timeout, (self->mode == WATCHDOGMODE_RESET)) != ESP_OK) { - mp_raise_RuntimeError(translate("Initialization failed due to lack of memory")); + if (esp_task_wdt_init(timeout, mode == WATCHDOGMODE_RESET) != ESP_OK) { + mp_raise_msg(&mp_type_MemoryError, NULL); } esp_task_wdt_add(NULL); } @@ -73,12 +83,17 @@ mp_float_t common_hal_watchdog_get_timeout(watchdog_watchdogtimer_obj_t *self) { } void common_hal_watchdog_set_timeout(watchdog_watchdogtimer_obj_t *self, mp_float_t new_timeout) { - if ((uint64_t)new_timeout > UINT32_MAX) { - mp_raise_ValueError(translate("timeout duration exceeded the maximum supported value")); + if (!(self->timeout < new_timeout || self->timeout > new_timeout)) { + return; } - if ((uint32_t)self->timeout != (uint32_t)new_timeout) { - self->timeout = new_timeout; - wdt_config(self); + + if ((uint64_t)new_timeout > UINT32_MAX) { + mp_raise_ValueError_varg(translate("%q must be <= %d"), MP_QSTR_timeout, UINT32_MAX); + } + self->timeout = new_timeout; + + if (self->mode != WATCHDOGMODE_NONE) { + wdt_config(new_timeout, self->mode); } } @@ -87,8 +102,21 @@ watchdog_watchdogmode_t common_hal_watchdog_get_mode(watchdog_watchdogtimer_obj_ } void common_hal_watchdog_set_mode(watchdog_watchdogtimer_obj_t *self, watchdog_watchdogmode_t new_mode) { - if (self->mode != new_mode) { - self->mode = new_mode; - wdt_config(self); + if (self->mode == new_mode) { + return; } + + switch (new_mode) { + case WATCHDOGMODE_NONE: + common_hal_watchdog_deinit(self); + break; + case WATCHDOGMODE_RAISE: + case WATCHDOGMODE_RESET: + wdt_config(self->timeout, new_mode); + break; + default: + return; + } + + self->mode = new_mode; } From 8ff408161aaec99d0e3e6a9871fcb8bc86ea1213 Mon Sep 17 00:00:00 2001 From: MicroDev <70126934+MicroDev1@users.noreply.github.com> Date: Wed, 15 Mar 2023 16:38:50 +0530 Subject: [PATCH 4/7] update watchdog implementation for raspberrypi --- .../common-hal/watchdog/WatchDogTimer.c | 56 +++++++++++-------- .../common-hal/watchdog/WatchDogTimer.h | 2 +- ports/raspberrypi/supervisor/port.c | 4 ++ 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c b/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c index f23ccda777..14ae9c7f9b 100644 --- a/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c +++ b/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c @@ -32,38 +32,39 @@ #include "src/rp2_common/hardware_watchdog/include/hardware/watchdog.h" +#define WATCHDOG_ENABLE watchdog_enable(self->timeout * 1000, false) + void common_hal_watchdog_feed(watchdog_watchdogtimer_obj_t *self) { watchdog_update(); } void common_hal_watchdog_deinit(watchdog_watchdogtimer_obj_t *self) { - if (self->mode == WATCHDOGMODE_RESET) { - mp_raise_RuntimeError(translate("WatchDogTimer cannot be deinitialized once mode is set to RESET")); - } else { - self->mode = WATCHDOGMODE_NONE; + if (self->mode == WATCHDOGMODE_NONE) { + return; } + hw_clear_bits(&watchdog_hw->ctrl, WATCHDOG_CTRL_ENABLE_BITS); + self->mode = WATCHDOGMODE_NONE; } -/* void watchdog_reset(void) { - common_hal_watchdog_deinit(&common_hal_mcu_watchdogtimer_obj); + common_hal_watchdog_deinit(&common_hal_mcu_watchdogtimer_obj); } -*/ mp_float_t common_hal_watchdog_get_timeout(watchdog_watchdogtimer_obj_t *self) { return self->timeout; } void common_hal_watchdog_set_timeout(watchdog_watchdogtimer_obj_t *self, mp_float_t new_timeout) { - // max timeout is 8.388607 sec - // this is rounded down to 8.388 sec - uint64_t timeout = new_timeout * 1000; - if (timeout > 8388) { - mp_raise_ValueError(translate("timeout duration exceeded the maximum supported value")); + if (!(self->timeout < new_timeout || self->timeout > new_timeout)) { + return; } - if ((uint16_t)self->timeout != timeout) { - watchdog_enable(timeout, false); - self->timeout = new_timeout; + + // max timeout is 8.388607 sec, this is rounded down to 8 sec + mp_arg_validate_int_max(new_timeout, 8, MP_QSTR_timeout); + self->timeout = new_timeout; + + if (self->mode == WATCHDOGMODE_RESET) { + WATCHDOG_ENABLE; } } @@ -72,12 +73,23 @@ watchdog_watchdogmode_t common_hal_watchdog_get_mode(watchdog_watchdogtimer_obj_ } void common_hal_watchdog_set_mode(watchdog_watchdogtimer_obj_t *self, watchdog_watchdogmode_t new_mode) { - if (self->mode != new_mode) { - if (new_mode == WATCHDOGMODE_RAISE) { - mp_raise_NotImplementedError(translate("RAISE mode is not implemented")); - } else if (new_mode == WATCHDOGMODE_NONE) { - common_hal_watchdog_deinit(self); - } - self->mode = new_mode; + if (self->mode == new_mode) { + return; } + + switch (new_mode) { + case WATCHDOGMODE_NONE: + common_hal_watchdog_deinit(self); + break; + case WATCHDOGMODE_RAISE: + mp_raise_NotImplementedError(NULL); + break; + case WATCHDOGMODE_RESET: + WATCHDOG_ENABLE; + break; + default: + return; + } + + self->mode = new_mode; } diff --git a/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.h b/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.h index ce34f0b8ab..579e8ce65f 100644 --- a/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.h +++ b/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.h @@ -38,6 +38,6 @@ struct _watchdog_watchdogtimer_obj_t { }; // This needs to be called in order to disable the watchdog -// void watchdog_reset(void); +void watchdog_reset(void); #endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H diff --git a/ports/raspberrypi/supervisor/port.c b/ports/raspberrypi/supervisor/port.c index f3da71cbd7..f2331f8cfd 100644 --- a/ports/raspberrypi/supervisor/port.c +++ b/ports/raspberrypi/supervisor/port.c @@ -201,6 +201,10 @@ void reset_port(void) { ssl_reset(); #endif + #if CIRCUITPY_WATCHDOG + watchdog_reset(); + #endif + #if CIRCUITPY_WIFI wifi_reset(); #endif From 11cf031284d42228f6b6d4af35cf07155ac2cc4f Mon Sep 17 00:00:00 2001 From: MicroDev <70126934+MicroDev1@users.noreply.github.com> Date: Wed, 15 Mar 2023 19:03:57 +0530 Subject: [PATCH 5/7] reset watchdog conditionally --- main.c | 6 ++++++ .../common-hal/watchdog/WatchDogTimer.c | 15 ++++++++++++++- .../common-hal/watchdog/WatchDogTimer.c | 16 ++++++++++++++-- ports/nrf/common-hal/watchdog/WatchDogTimer.c | 15 +++++++++++++-- .../common-hal/watchdog/WatchDogTimer.c | 18 +++++++++++++++--- shared/runtime/pyexec.h | 4 ++++ 6 files changed, 66 insertions(+), 8 deletions(-) diff --git a/main.c b/main.c index 002c97c167..2b4545379e 100644 --- a/main.c +++ b/main.c @@ -243,6 +243,12 @@ void supervisor_execution_status(void) { } #endif +#if CIRCUITPY_WATCHDOG +pyexec_result_t *pyexec_result(void) { + return &_exec_result; +} +#endif + // Look for the first file that exists in the list of filenames, using mp_import_stat(). // Return its index. If no file found, return -1. STATIC const char *first_existing_file_in_list(const char *const *filenames, size_t n_filenames) { diff --git a/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c b/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c index 0c0ef85bb2..15683a1275 100644 --- a/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c +++ b/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c @@ -28,8 +28,12 @@ #include "py/runtime.h" +#include "shared/runtime/pyexec.h" + #include "shared-bindings/watchdog/__init__.h" #include "shared-bindings/watchdog/WatchDogTimer.h" +#include "shared-bindings/microcontroller/__init__.h" + #include "common-hal/watchdog/WatchDogTimer.h" #include "component/wdt.h" @@ -79,7 +83,16 @@ void common_hal_watchdog_deinit(watchdog_watchdogtimer_obj_t *self) { } void watchdog_reset(void) { - common_hal_watchdog_deinit(&common_hal_mcu_watchdogtimer_obj); + watchdog_watchdogtimer_obj_t *self = &common_hal_mcu_watchdogtimer_obj; + if (self->mode == WATCHDOGMODE_RESET) { + mp_obj_t exception = pyexec_result()->exception; + if (exception != MP_OBJ_NULL && + exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) && + exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { + return; + } + } + common_hal_watchdog_deinit(self); } mp_float_t common_hal_watchdog_get_timeout(watchdog_watchdogtimer_obj_t *self) { diff --git a/ports/espressif/common-hal/watchdog/WatchDogTimer.c b/ports/espressif/common-hal/watchdog/WatchDogTimer.c index 6a7c91622e..b11da03770 100644 --- a/ports/espressif/common-hal/watchdog/WatchDogTimer.c +++ b/ports/espressif/common-hal/watchdog/WatchDogTimer.c @@ -25,11 +25,14 @@ */ #include "py/runtime.h" -#include "common-hal/watchdog/WatchDogTimer.h" + +#include "shared/runtime/pyexec.h" #include "shared-bindings/watchdog/__init__.h" #include "shared-bindings/microcontroller/__init__.h" +#include "common-hal/watchdog/WatchDogTimer.h" + #include "esp_task_wdt.h" extern void esp_task_wdt_isr_user_handler(void); @@ -66,7 +69,16 @@ void common_hal_watchdog_deinit(watchdog_watchdogtimer_obj_t *self) { } void watchdog_reset(void) { - common_hal_watchdog_deinit(&common_hal_mcu_watchdogtimer_obj); + watchdog_watchdogtimer_obj_t *self = &common_hal_mcu_watchdogtimer_obj; + if (self->mode == WATCHDOGMODE_RESET) { + mp_obj_t exception = pyexec_result()->exception; + if (exception != MP_OBJ_NULL && + exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) && + exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { + return; + } + } + common_hal_watchdog_deinit(self); } static void wdt_config(uint32_t timeout, watchdog_watchdogmode_t mode) { diff --git a/ports/nrf/common-hal/watchdog/WatchDogTimer.c b/ports/nrf/common-hal/watchdog/WatchDogTimer.c index 99c360c46d..872c4642db 100644 --- a/ports/nrf/common-hal/watchdog/WatchDogTimer.c +++ b/ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -33,12 +33,14 @@ #include "py/objproperty.h" #include "py/runtime.h" -#include "common-hal/watchdog/WatchDogTimer.h" +#include "shared/runtime/pyexec.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/watchdog/__init__.h" #include "shared-bindings/watchdog/WatchDogTimer.h" +#include "common-hal/watchdog/WatchDogTimer.h" + #include "supervisor/port.h" #include "nrf/timers.h" @@ -108,7 +110,16 @@ void common_hal_watchdog_deinit(watchdog_watchdogtimer_obj_t *self) { } void watchdog_reset(void) { - common_hal_watchdog_deinit(&common_hal_mcu_watchdogtimer_obj); + watchdog_watchdogtimer_obj_t *self = &common_hal_mcu_watchdogtimer_obj; + if (self->mode == WATCHDOGMODE_RESET) { + mp_obj_t exception = pyexec_result()->exception; + if (exception != MP_OBJ_NULL && + exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) && + exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { + return; + } + } + common_hal_watchdog_deinit(self); } mp_float_t common_hal_watchdog_get_timeout(watchdog_watchdogtimer_obj_t *self) { diff --git a/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c b/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c index 14ae9c7f9b..29234b46b0 100644 --- a/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c +++ b/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c @@ -25,12 +25,15 @@ */ #include "py/runtime.h" -#include "common-hal/watchdog/WatchDogTimer.h" + +#include "shared/runtime/pyexec.h" #include "shared-bindings/watchdog/__init__.h" #include "shared-bindings/microcontroller/__init__.h" -#include "src/rp2_common/hardware_watchdog/include/hardware/watchdog.h" +#include "common-hal/watchdog/WatchDogTimer.h" + +#include "hardware/watchdog.h" #define WATCHDOG_ENABLE watchdog_enable(self->timeout * 1000, false) @@ -47,7 +50,16 @@ void common_hal_watchdog_deinit(watchdog_watchdogtimer_obj_t *self) { } void watchdog_reset(void) { - common_hal_watchdog_deinit(&common_hal_mcu_watchdogtimer_obj); + watchdog_watchdogtimer_obj_t *self = &common_hal_mcu_watchdogtimer_obj; + if (self->mode == WATCHDOGMODE_RESET) { + mp_obj_t exception = pyexec_result()->exception; + if (exception != MP_OBJ_NULL && + exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) && + exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { + return; + } + } + common_hal_watchdog_deinit(self); } mp_float_t common_hal_watchdog_get_timeout(watchdog_watchdogtimer_obj_t *self) { diff --git a/shared/runtime/pyexec.h b/shared/runtime/pyexec.h index 411426eaaa..d0c012fe46 100644 --- a/shared/runtime/pyexec.h +++ b/shared/runtime/pyexec.h @@ -67,6 +67,10 @@ extern uint8_t pyexec_repl_active; int pyexec_exit_handler(const void *source, pyexec_result_t *result); #endif +#if CIRCUITPY_WATCHDOG +pyexec_result_t *pyexec_result(void); +#endif + #if MICROPY_REPL_INFO mp_obj_t pyb_set_repl_info(mp_obj_t o_value); MP_DECLARE_CONST_FUN_OBJ_1(pyb_set_repl_info_obj); From 8964228ed5daeed5ffe184336e752779e048063b Mon Sep 17 00:00:00 2001 From: MicroDev <70126934+MicroDev1@users.noreply.github.com> Date: Thu, 16 Mar 2023 11:24:43 +0530 Subject: [PATCH 6/7] silently return when watchdog isn't active --- locale/circuitpython.pot | 49 +++++-------------- .../common-hal/watchdog/WatchDogTimer.c | 2 +- shared-bindings/watchdog/WatchDogTimer.c | 25 ++++------ 3 files changed, 23 insertions(+), 53 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 560dffe6a4..6f1d86c7ee 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -184,12 +184,12 @@ msgstr "" msgid "%q must be <= %d" msgstr "" -#: py/argcheck.c -msgid "%q must be >= %d" +#: ports/espressif/common-hal/watchdog/WatchDogTimer.c +msgid "%q must be <= %u" msgstr "" -#: ports/espressif/common-hal/analogbufio/BufferedIn.c -msgid "%q must be array of type 'H'" +#: py/argcheck.c +msgid "%q must be >= %d" msgstr "" #: shared-bindings/analogbufio/BufferedIn.c @@ -200,6 +200,10 @@ msgstr "" msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "" + #: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c #: shared-bindings/canio/CAN.c shared-bindings/digitalio/Pull.c msgid "%q must be of type %q or %q, not %q" @@ -1154,10 +1158,6 @@ msgstr "" msgid "Initial set pin state conflicts with initial out pin state" msgstr "" -#: ports/espressif/common-hal/watchdog/WatchDogTimer.c -msgid "Initialization failed due to lack of memory" -msgstr "" - #: shared-bindings/bitops/__init__.c #, c-format msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" @@ -1229,7 +1229,8 @@ msgstr "" msgid "Interrupt error." msgstr "" -#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c py/argcheck.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/displayio/EPaperDisplay.c msgid "Invalid %q" msgstr "" @@ -1523,10 +1524,6 @@ msgstr "" msgid "No in or out in program" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "No key was specified" -msgstr "" - #: shared-bindings/time/__init__.c msgid "No long integer support" msgstr "" @@ -1822,11 +1819,6 @@ msgstr "" msgid "Pull not used when direction is output." msgstr "" -#: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c -#: ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c -msgid "RAISE mode is not implemented" -msgstr "" - #: ports/raspberrypi/common-hal/countio/Counter.c msgid "RISE_AND_FALL not available on this chip" msgstr "" @@ -2350,20 +2342,10 @@ msgstr "" msgid "WARNING: Your code filename has two extensions\n" msgstr "" -#: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c -#: ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET" msgstr "" -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer is not currently running" -msgstr "" - -#: shared-bindings/watchdog/WatchDogTimer.c -msgid "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET" -msgstr "" - #: py/builtinhelp.c #, c-format msgid "" @@ -3044,8 +3026,8 @@ msgid "extra positional arguments given" msgstr "" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c -#: shared-module/gifio/GifWriter.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" msgstr "" @@ -4087,10 +4069,7 @@ msgstr "" msgid "syntax error in uctypes descriptor" msgstr "" -#: ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c -#: ports/espressif/common-hal/watchdog/WatchDogTimer.c #: ports/nrf/common-hal/watchdog/WatchDogTimer.c -#: ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c msgid "timeout duration exceeded the maximum supported value" msgstr "" @@ -4291,10 +4270,6 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: ports/espressif/common-hal/watchdog/WatchDogTimer.c -msgid "watchdog not initialized" -msgstr "" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "" diff --git a/ports/espressif/common-hal/watchdog/WatchDogTimer.c b/ports/espressif/common-hal/watchdog/WatchDogTimer.c index b11da03770..5cc778a0b9 100644 --- a/ports/espressif/common-hal/watchdog/WatchDogTimer.c +++ b/ports/espressif/common-hal/watchdog/WatchDogTimer.c @@ -100,7 +100,7 @@ void common_hal_watchdog_set_timeout(watchdog_watchdogtimer_obj_t *self, mp_floa } if ((uint64_t)new_timeout > UINT32_MAX) { - mp_raise_ValueError_varg(translate("%q must be <= %d"), MP_QSTR_timeout, UINT32_MAX); + mp_raise_ValueError_varg(translate("%q must be <= %u"), MP_QSTR_timeout, UINT32_MAX); } self->timeout = new_timeout; diff --git a/shared-bindings/watchdog/WatchDogTimer.c b/shared-bindings/watchdog/WatchDogTimer.c index 10ab334330..cc91a09ef2 100644 --- a/shared-bindings/watchdog/WatchDogTimer.c +++ b/shared-bindings/watchdog/WatchDogTimer.c @@ -50,22 +50,18 @@ //| //| def __init__(self) -> None: -//| """Not currently dynamically supported. Access the sole instance through `microcontroller.watchdog`.""" +//| """Access the sole instance through `microcontroller.watchdog`.""" //| ... //| def feed(self) -> None: //| """Feed the watchdog timer. This must be called regularly, otherwise -//| the timer will expire.""" +//| the timer will expire. Silently does nothing if the watchdog isn't active.""" //| ... STATIC mp_obj_t watchdog_watchdogtimer_feed(mp_obj_t self_in) { watchdog_watchdogtimer_obj_t *self = MP_OBJ_TO_PTR(self_in); - watchdog_watchdogmode_t current_mode = common_hal_watchdog_get_mode(self); - - if (current_mode == WATCHDOGMODE_NONE) { - mp_raise_ValueError(translate("WatchDogTimer is not currently running")); + if (common_hal_watchdog_get_mode(self) != WATCHDOGMODE_NONE) { + common_hal_watchdog_feed(self); } - - common_hal_watchdog_feed(self); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(watchdog_watchdogtimer_feed_obj, watchdog_watchdogtimer_feed); @@ -89,7 +85,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(watchdog_watchdogtimer_deinit_obj, watchdog_wat //| timeout: float //| """The maximum number of seconds that can elapse between calls -//| to feed()""" +//| to `feed()`""" STATIC mp_obj_t watchdog_watchdogtimer_obj_get_timeout(mp_obj_t self_in) { watchdog_watchdogtimer_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_float(common_hal_watchdog_get_timeout(self)); @@ -114,17 +110,16 @@ MP_PROPERTY_GETSET(watchdog_watchdogtimer_timeout_obj, //| mode: WatchDogMode //| """The current operating mode of the WatchDogTimer `watchdog.WatchDogMode`. //| -//| Setting a WatchDogMode activates the WatchDog:: +//| Setting a `WatchDogMode` activates the WatchDog:: //| -//| import microcontroller -//| import watchdog +//| from microcontroller import watchdog as w +//| from watchdog import WatchDogMode //| -//| w = microcontroller.watchdog //| w.timeout = 5 -//| w.mode = watchdog.WatchDogMode.RAISE +//| w.mode = WatchDogMode.RESET //| //| -//| Once set, the WatchDogTimer will perform the specified action if the timer expires.""" +//| Once set, the `WatchDogTimer` will perform the specified action if the timer expires.""" //| STATIC mp_obj_t watchdog_watchdogtimer_obj_get_mode(mp_obj_t self_in) { watchdog_watchdogtimer_obj_t *self = MP_OBJ_TO_PTR(self_in); From 27fd60d73962901d29e3f7fd9fd06b90cd934379 Mon Sep 17 00:00:00 2001 From: MicroDev <70126934+microdev1@users.noreply.github.com> Date: Sun, 24 Sep 2023 15:23:38 +0000 Subject: [PATCH 7/7] implement suggested changes - update the docs - split out common `watchdog_reset` - revert to using `None` instead of `WatchDogMode.NONE` --- locale/circuitpython.pot | 15 +++--- .../common-hal/watchdog/WatchDogTimer.c | 15 ------ .../common-hal/watchdog/WatchDogTimer.h | 6 +-- .../common-hal/watchdog/WatchDogTimer.c | 15 ------ .../common-hal/watchdog/WatchDogTimer.h | 6 +-- ports/nrf/common-hal/watchdog/WatchDogTimer.c | 15 ------ ports/nrf/common-hal/watchdog/WatchDogTimer.h | 7 ++- .../common-hal/watchdog/WatchDogTimer.c | 15 ------ .../common-hal/watchdog/WatchDogTimer.h | 6 +-- .../common-hal/watchdog/WatchDogTimer.c | 4 -- .../common-hal/watchdog/WatchDogTimer.h | 6 +-- ports/silabs/supervisor/port.c | 4 ++ py/circuitpy_defns.mk | 1 + shared-bindings/watchdog/WatchDogMode.c | 5 -- shared-bindings/watchdog/WatchDogTimer.c | 18 +++---- shared-bindings/watchdog/WatchDogTimer.h | 4 +- shared-module/watchdog/__init__.c | 47 +++++++++++++++++++ shared-module/watchdog/__init__.h | 32 +++++++++++++ 18 files changed, 117 insertions(+), 104 deletions(-) create mode 100644 shared-module/watchdog/__init__.c create mode 100644 shared-module/watchdog/__init__.h diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 768d353b27..f40ef66999 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -200,6 +200,10 @@ msgstr "" msgid "%q must be <= %u" msgstr "" +#: py/argcheck.c +msgid "%q must be >= %d" +msgstr "" + #: shared-bindings/analogbufio/BufferedIn.c msgid "%q must be a bytearray or array of type 'H' or 'B'" msgstr "" @@ -447,10 +451,6 @@ msgstr "" msgid "A hardware interrupt channel is already in use" msgstr "" -#: ports/espressif/common-hal/analogio/AnalogIn.c -msgid "ADC2 is being used by WiFi" -msgstr "" - #: ports/raspberrypi/common-hal/wifi/Radio.c msgid "AP could not be started" msgstr "" @@ -4185,7 +4185,8 @@ msgstr "" msgid "unexpected keyword argument" msgstr "" -#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#: shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" msgstr "" @@ -4279,10 +4280,6 @@ msgstr "" msgid "value out of range of target" msgstr "" -#: ports/espressif/common-hal/watchdog/WatchDogTimer.c -msgid "watchdog not initialized" -msgstr "" - #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "" diff --git a/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c b/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c index 15683a1275..435cfd6731 100644 --- a/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c +++ b/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.c @@ -28,8 +28,6 @@ #include "py/runtime.h" -#include "shared/runtime/pyexec.h" - #include "shared-bindings/watchdog/__init__.h" #include "shared-bindings/watchdog/WatchDogTimer.h" #include "shared-bindings/microcontroller/__init__.h" @@ -82,19 +80,6 @@ void common_hal_watchdog_deinit(watchdog_watchdogtimer_obj_t *self) { self->mode = WATCHDOGMODE_NONE; } -void watchdog_reset(void) { - watchdog_watchdogtimer_obj_t *self = &common_hal_mcu_watchdogtimer_obj; - if (self->mode == WATCHDOGMODE_RESET) { - mp_obj_t exception = pyexec_result()->exception; - if (exception != MP_OBJ_NULL && - exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) && - exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { - return; - } - } - common_hal_watchdog_deinit(self); -} - mp_float_t common_hal_watchdog_get_timeout(watchdog_watchdogtimer_obj_t *self) { return self->timeout; } diff --git a/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.h b/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.h index 579e8ce65f..ae214a95e6 100644 --- a/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.h +++ b/ports/atmel-samd/common-hal/watchdog/WatchDogTimer.h @@ -28,6 +28,9 @@ #define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H #include "py/obj.h" + +#include "shared-module/watchdog/__init__.h" + #include "shared-bindings/watchdog/WatchDogMode.h" #include "shared-bindings/watchdog/WatchDogTimer.h" @@ -37,7 +40,4 @@ struct _watchdog_watchdogtimer_obj_t { watchdog_watchdogmode_t mode; }; -// This needs to be called in order to disable the watchdog -void watchdog_reset(void); - #endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H diff --git a/ports/espressif/common-hal/watchdog/WatchDogTimer.c b/ports/espressif/common-hal/watchdog/WatchDogTimer.c index 6410f5e61a..68437958e5 100644 --- a/ports/espressif/common-hal/watchdog/WatchDogTimer.c +++ b/ports/espressif/common-hal/watchdog/WatchDogTimer.c @@ -26,8 +26,6 @@ #include "py/runtime.h" -#include "shared/runtime/pyexec.h" - #include "shared-bindings/watchdog/__init__.h" #include "shared-bindings/microcontroller/__init__.h" @@ -68,19 +66,6 @@ void common_hal_watchdog_deinit(watchdog_watchdogtimer_obj_t *self) { } } -void watchdog_reset(void) { - watchdog_watchdogtimer_obj_t *self = &common_hal_mcu_watchdogtimer_obj; - if (self->mode == WATCHDOGMODE_RESET) { - mp_obj_t exception = pyexec_result()->exception; - if (exception != MP_OBJ_NULL && - exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) && - exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { - return; - } - } - common_hal_watchdog_deinit(self); -} - static void wdt_config(uint32_t timeout, watchdog_watchdogmode_t mode) { // enable panic hanler in WATCHDOGMODE_RESET mode // initialize Task Watchdog Timer (TWDT) diff --git a/ports/espressif/common-hal/watchdog/WatchDogTimer.h b/ports/espressif/common-hal/watchdog/WatchDogTimer.h index 8d95bfa4cc..461d11f18c 100644 --- a/ports/espressif/common-hal/watchdog/WatchDogTimer.h +++ b/ports/espressif/common-hal/watchdog/WatchDogTimer.h @@ -28,6 +28,9 @@ #define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H #include "py/obj.h" + +#include "shared-module/watchdog/__init__.h" + #include "shared-bindings/watchdog/WatchDogMode.h" #include "shared-bindings/watchdog/WatchDogTimer.h" @@ -37,7 +40,4 @@ struct _watchdog_watchdogtimer_obj_t { watchdog_watchdogmode_t mode; }; -// This needs to be called in order to disable the watchdog -void watchdog_reset(void); - #endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H diff --git a/ports/nrf/common-hal/watchdog/WatchDogTimer.c b/ports/nrf/common-hal/watchdog/WatchDogTimer.c index 872c4642db..1ac0ee1076 100644 --- a/ports/nrf/common-hal/watchdog/WatchDogTimer.c +++ b/ports/nrf/common-hal/watchdog/WatchDogTimer.c @@ -33,8 +33,6 @@ #include "py/objproperty.h" #include "py/runtime.h" -#include "shared/runtime/pyexec.h" - #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/watchdog/__init__.h" #include "shared-bindings/watchdog/WatchDogTimer.h" @@ -109,19 +107,6 @@ void common_hal_watchdog_deinit(watchdog_watchdogtimer_obj_t *self) { self->mode = WATCHDOGMODE_NONE; } -void watchdog_reset(void) { - watchdog_watchdogtimer_obj_t *self = &common_hal_mcu_watchdogtimer_obj; - if (self->mode == WATCHDOGMODE_RESET) { - mp_obj_t exception = pyexec_result()->exception; - if (exception != MP_OBJ_NULL && - exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) && - exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { - return; - } - } - common_hal_watchdog_deinit(self); -} - mp_float_t common_hal_watchdog_get_timeout(watchdog_watchdogtimer_obj_t *self) { return self->timeout; } diff --git a/ports/nrf/common-hal/watchdog/WatchDogTimer.h b/ports/nrf/common-hal/watchdog/WatchDogTimer.h index 1ff654c321..e298a71ba7 100644 --- a/ports/nrf/common-hal/watchdog/WatchDogTimer.h +++ b/ports/nrf/common-hal/watchdog/WatchDogTimer.h @@ -28,6 +28,9 @@ #define MICROPY_INCLUDED_NRF_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H #include "py/obj.h" + +#include "shared-module/watchdog/__init__.h" + #include "shared-bindings/watchdog/WatchDogMode.h" #include "shared-bindings/watchdog/WatchDogTimer.h" @@ -37,8 +40,4 @@ struct _watchdog_watchdogtimer_obj_t { watchdog_watchdogmode_t mode; }; -// This needs to be called in order to disable the watchdog if it's set to -// "RAISE". If set to "RESET", then the watchdog cannot be reset. -void watchdog_reset(void); - #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H diff --git a/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c b/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c index 29234b46b0..61c71ccd62 100644 --- a/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c +++ b/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c @@ -26,8 +26,6 @@ #include "py/runtime.h" -#include "shared/runtime/pyexec.h" - #include "shared-bindings/watchdog/__init__.h" #include "shared-bindings/microcontroller/__init__.h" @@ -49,19 +47,6 @@ void common_hal_watchdog_deinit(watchdog_watchdogtimer_obj_t *self) { self->mode = WATCHDOGMODE_NONE; } -void watchdog_reset(void) { - watchdog_watchdogtimer_obj_t *self = &common_hal_mcu_watchdogtimer_obj; - if (self->mode == WATCHDOGMODE_RESET) { - mp_obj_t exception = pyexec_result()->exception; - if (exception != MP_OBJ_NULL && - exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) && - exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { - return; - } - } - common_hal_watchdog_deinit(self); -} - mp_float_t common_hal_watchdog_get_timeout(watchdog_watchdogtimer_obj_t *self) { return self->timeout; } diff --git a/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.h b/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.h index 579e8ce65f..ae214a95e6 100644 --- a/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.h +++ b/ports/raspberrypi/common-hal/watchdog/WatchDogTimer.h @@ -28,6 +28,9 @@ #define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H #include "py/obj.h" + +#include "shared-module/watchdog/__init__.h" + #include "shared-bindings/watchdog/WatchDogMode.h" #include "shared-bindings/watchdog/WatchDogTimer.h" @@ -37,7 +40,4 @@ struct _watchdog_watchdogtimer_obj_t { watchdog_watchdogmode_t mode; }; -// This needs to be called in order to disable the watchdog -void watchdog_reset(void); - #endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H diff --git a/ports/silabs/common-hal/watchdog/WatchDogTimer.c b/ports/silabs/common-hal/watchdog/WatchDogTimer.c index b6158e1cc6..d65c794833 100644 --- a/ports/silabs/common-hal/watchdog/WatchDogTimer.c +++ b/ports/silabs/common-hal/watchdog/WatchDogTimer.c @@ -41,10 +41,6 @@ void common_hal_watchdog_deinit(watchdog_watchdogtimer_obj_t *self) { WDOG_Enable(false); } -void watchdog_reset(void) { - common_hal_watchdog_deinit(&common_hal_mcu_watchdogtimer_obj); -} - mp_float_t common_hal_watchdog_get_timeout(watchdog_watchdogtimer_obj_t *self) { return self->timeout; } diff --git a/ports/silabs/common-hal/watchdog/WatchDogTimer.h b/ports/silabs/common-hal/watchdog/WatchDogTimer.h index d1538bd491..9aad655e73 100644 --- a/ports/silabs/common-hal/watchdog/WatchDogTimer.h +++ b/ports/silabs/common-hal/watchdog/WatchDogTimer.h @@ -28,6 +28,9 @@ #define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H #include "py/obj.h" + +#include "shared-module/watchdog/__init__.h" + #include "shared-bindings/watchdog/WatchDogMode.h" #include "shared-bindings/watchdog/WatchDogTimer.h" @@ -37,7 +40,4 @@ struct _watchdog_watchdogtimer_obj_t { watchdog_watchdogmode_t mode; }; -// This needs to be called in order to disable the watchdog -void watchdog_reset(void); - #endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_WATCHDOG_WATCHDOGTIMER_H diff --git a/ports/silabs/supervisor/port.c b/ports/silabs/supervisor/port.c index 8247c813a7..fba90882df 100644 --- a/ports/silabs/supervisor/port.c +++ b/ports/silabs/supervisor/port.c @@ -192,6 +192,10 @@ void reset_port(void) { #if CIRCUITPY_RTC rtc_reset(); #endif + + #if CIRCUITPY_WATCHDOG + watchdog_reset(); + #endif } void reset_to_bootloader(void) { diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index c819d46db8..3974e27df4 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -666,6 +666,7 @@ SRC_SHARED_MODULE_ALL = \ usb/core/__init__.c \ usb/core/Device.c \ ustack/__init__.c \ + watchdog/__init__.c \ zlib/__init__.c \ vectorio/Circle.c \ vectorio/Polygon.c \ diff --git a/shared-bindings/watchdog/WatchDogMode.c b/shared-bindings/watchdog/WatchDogMode.c index 343702e4b1..944ab451fa 100644 --- a/shared-bindings/watchdog/WatchDogMode.c +++ b/shared-bindings/watchdog/WatchDogMode.c @@ -28,16 +28,12 @@ #include "shared-bindings/watchdog/WatchDogMode.h" -MAKE_ENUM_VALUE(watchdog_watchdogmode_type, watchdogmode, NONE, WATCHDOGMODE_NONE); MAKE_ENUM_VALUE(watchdog_watchdogmode_type, watchdogmode, RAISE, WATCHDOGMODE_RAISE); MAKE_ENUM_VALUE(watchdog_watchdogmode_type, watchdogmode, RESET, WATCHDOGMODE_RESET); //| class WatchDogMode: //| """Run state of the watchdog timer.""" //| -//| NONE: WatchDogMode -//| """The `WatchDogTimer` is disabled.""" -//| //| RAISE: WatchDogMode //| """Raise an exception when the `WatchDogTimer` expires.""" //| @@ -45,7 +41,6 @@ MAKE_ENUM_VALUE(watchdog_watchdogmode_type, watchdogmode, RESET, WATCHDOGMODE_RE //| """Reset the system when the `WatchDogTimer` expires.""" //| MAKE_ENUM_MAP(watchdog_watchdogmode) { - MAKE_ENUM_MAP_ENTRY(watchdogmode, NONE), MAKE_ENUM_MAP_ENTRY(watchdogmode, RAISE), MAKE_ENUM_MAP_ENTRY(watchdogmode, RESET), }; diff --git a/shared-bindings/watchdog/WatchDogTimer.c b/shared-bindings/watchdog/WatchDogTimer.c index cc91a09ef2..49cfdaecb4 100644 --- a/shared-bindings/watchdog/WatchDogTimer.c +++ b/shared-bindings/watchdog/WatchDogTimer.c @@ -71,8 +71,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(watchdog_watchdogtimer_feed_obj, watchdog_watch //| //| :raises RuntimeError: if the watchdog timer cannot be disabled on this platform. //| -//| .. note:: This is deprecated in ``8.1.0`` and will be removed in ``9.0.0``. -//| Set watchdog `mode` to `WatchDogMode.NONE` instead. +//| .. note:: This is deprecated in ``9.0.0`` and will be removed in ``10.0.0``. +//| Set watchdog `mode` to `None` instead. //| //| """ //| ... @@ -107,16 +107,17 @@ MP_PROPERTY_GETSET(watchdog_watchdogtimer_timeout_obj, (mp_obj_t)&watchdog_watchdogtimer_get_timeout_obj, (mp_obj_t)&watchdog_watchdogtimer_set_timeout_obj); -//| mode: WatchDogMode -//| """The current operating mode of the WatchDogTimer `watchdog.WatchDogMode`. +//| mode: Optional[WatchDogMode] +//| """The current operating mode of the WatchDogTimer `watchdog.WatchDogMode` or `None` when +//| the timer is disabled. //| //| Setting a `WatchDogMode` activates the WatchDog:: //| -//| from microcontroller import watchdog as w +//| from microcontroller import watchdog //| from watchdog import WatchDogMode //| -//| w.timeout = 5 -//| w.mode = WatchDogMode.RESET +//| watchdog.timeout = 5 +//| watchdog.mode = WatchDogMode.RESET //| //| //| Once set, the `WatchDogTimer` will perform the specified action if the timer expires.""" @@ -129,7 +130,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(watchdog_watchdogtimer_get_mode_obj, watchdog_watchdog STATIC mp_obj_t watchdog_watchdogtimer_obj_set_mode(mp_obj_t self_in, mp_obj_t obj) { watchdog_watchdogtimer_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_watchdog_set_mode(self, cp_enum_value(&watchdog_watchdogmode_type, obj, MP_QSTR_mode)); + watchdog_watchdogmode_t mode = (obj == mp_const_none) ? WATCHDOGMODE_NONE : cp_enum_value(&watchdog_watchdogmode_type, obj, MP_QSTR_mode); + common_hal_watchdog_set_mode(self, mode); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(watchdog_watchdogtimer_set_mode_obj, watchdog_watchdogtimer_obj_set_mode); diff --git a/shared-bindings/watchdog/WatchDogTimer.h b/shared-bindings/watchdog/WatchDogTimer.h index 48044748a9..a566b267d6 100644 --- a/shared-bindings/watchdog/WatchDogTimer.h +++ b/shared-bindings/watchdog/WatchDogTimer.h @@ -27,14 +27,14 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_WATCHDOG_WATCHDOGTIMER_H #define MICROPY_INCLUDED_SHARED_BINDINGS_WATCHDOG_WATCHDOGTIMER_H -#include +#include "py/obj.h" #include "shared-bindings/watchdog/WatchDogMode.h" typedef struct _watchdog_watchdogtimer_obj_t watchdog_watchdogtimer_obj_t; extern void common_hal_watchdog_feed(watchdog_watchdogtimer_obj_t *self); -extern void common_hal_watchdog_set_mode(watchdog_watchdogtimer_obj_t *self, watchdog_watchdogmode_t); +extern void common_hal_watchdog_set_mode(watchdog_watchdogtimer_obj_t *self, watchdog_watchdogmode_t mode); extern watchdog_watchdogmode_t common_hal_watchdog_get_mode(watchdog_watchdogtimer_obj_t *self); extern void common_hal_watchdog_set_timeout(watchdog_watchdogtimer_obj_t *self, mp_float_t timeout); diff --git a/shared-module/watchdog/__init__.c b/shared-module/watchdog/__init__.c new file mode 100644 index 0000000000..b348647c06 --- /dev/null +++ b/shared-module/watchdog/__init__.c @@ -0,0 +1,47 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 MicroDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/runtime.h" + +#include "shared/runtime/pyexec.h" + +#include "shared-module/watchdog/__init__.h" + +#include "shared-bindings/watchdog/WatchDogTimer.h" +#include "shared-bindings/microcontroller/__init__.h" + +void watchdog_reset(void) { + watchdog_watchdogtimer_obj_t *self = &common_hal_mcu_watchdogtimer_obj; + if (self->mode == WATCHDOGMODE_RESET) { + mp_obj_t exception = pyexec_result()->exception; + if (exception != MP_OBJ_NULL && + exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) && + exception != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { + return; + } + } + common_hal_watchdog_deinit(self); +} diff --git a/shared-module/watchdog/__init__.h b/shared-module/watchdog/__init__.h new file mode 100644 index 0000000000..219ccfc7b4 --- /dev/null +++ b/shared-module/watchdog/__init__.h @@ -0,0 +1,32 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 MicroDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_WATCHDOG___INIT___H +#define MICROPY_INCLUDED_SHARED_MODULE_WATCHDOG___INIT___H + +extern void watchdog_reset(void); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_WATCHDOG___INIT___H