From 65f8804816172b7f8a60e0993db92183bd82f3d8 Mon Sep 17 00:00:00 2001 From: Robert Pafford <19439938+rjp5th@users.noreply.github.com> Date: Wed, 8 Sep 2021 18:34:34 -0400 Subject: [PATCH] Implement reset_reason for raspberrypi port --- .../common-hal/microcontroller/Processor.c | 36 ++++++++++++++++++- shared-bindings/microcontroller/ResetReason.c | 5 +++ shared-bindings/microcontroller/ResetReason.h | 1 + 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/ports/raspberrypi/common-hal/microcontroller/Processor.c b/ports/raspberrypi/common-hal/microcontroller/Processor.c index e22286ca3d..68518d75b3 100644 --- a/ports/raspberrypi/common-hal/microcontroller/Processor.c +++ b/ports/raspberrypi/common-hal/microcontroller/Processor.c @@ -34,6 +34,11 @@ #include "src/rp2_common/hardware_adc/include/hardware/adc.h" #include "src/rp2_common/hardware_clocks/include/hardware/clocks.h" +#include "src/rp2040/hardware_regs/include/hardware/regs/vreg_and_chip_reset.h" +#include "src/rp2040/hardware_regs/include/hardware/regs/watchdog.h" +#include "src/rp2040/hardware_structs/include/hardware/structs/vreg_and_chip_reset.h" +#include "src/rp2040/hardware_structs/include/hardware/structs/watchdog.h" + float common_hal_mcu_processor_get_temperature(void) { adc_init(); adc_set_temp_sensor_enabled(true); @@ -60,5 +65,34 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - return RESET_REASON_UNKNOWN; + mcu_reset_reason_t reason = RESET_REASON_UNKNOWN; + + uint32_t watchdog_reset_reg = watchdog_hw->reason; + uint32_t chip_reset_reg = vreg_and_chip_reset_hw->chip_reset; + + if (chip_reset_reg & VREG_AND_CHIP_RESET_CHIP_RESET_HAD_PSM_RESTART_BITS) { + reason = RESET_REASON_RESCUE_DEBUG; + } + + if (chip_reset_reg & VREG_AND_CHIP_RESET_CHIP_RESET_HAD_RUN_BITS) { + reason = RESET_REASON_RESET_PIN; + } + + if (chip_reset_reg & VREG_AND_CHIP_RESET_CHIP_RESET_HAD_POR_BITS) { + // NOTE: This register is also used for brownout, but there is no way to differentiate between power on and brown out + reason = RESET_REASON_POWER_ON; + } + + // Check watchdog after chip reset since watchdog doesn't clear chip_reset, while chip_reset clears the watchdog + + if (watchdog_reset_reg & WATCHDOG_REASON_TIMER_BITS) { + // This bit can also be set during a software reset because the pico-sdk performs a software reset by setting an extremely low timeout on the watchdog, rather than triggering a watchdog reset manually + reason = RESET_REASON_WATCHDOG; + } + + if (watchdog_reset_reg & WATCHDOG_REASON_FORCE_BITS) { + reason = RESET_REASON_SOFTWARE; + } + + return reason; } diff --git a/shared-bindings/microcontroller/ResetReason.c b/shared-bindings/microcontroller/ResetReason.c index 1750e55204..905c19f83f 100644 --- a/shared-bindings/microcontroller/ResetReason.c +++ b/shared-bindings/microcontroller/ResetReason.c @@ -36,6 +36,7 @@ MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, DEEP_SLEEP_ALARM, RESET_REA MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, RESET_PIN, RESET_REASON_RESET_PIN); MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, WATCHDOG, RESET_REASON_WATCHDOG); MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, UNKNOWN, RESET_REASON_UNKNOWN); +MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, RESCUE_DEBUG, RESET_REASON_RESCUE_DEBUG); //| class ResetReason: //| """The reason the microntroller was last reset""" @@ -61,6 +62,9 @@ MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, UNKNOWN, RESET_REASON_UNKNO //| UNKNOWN: object //| """The microntroller restarted for an unknown reason.""" //| +//| RESCUE_DEBUG: object +//| """The microntroller was reset by the rescue debug port.""" +//| MAKE_ENUM_MAP(mcu_reset_reason) { MAKE_ENUM_MAP_ENTRY(reset_reason, POWER_ON), MAKE_ENUM_MAP_ENTRY(reset_reason, BROWNOUT), @@ -69,6 +73,7 @@ MAKE_ENUM_MAP(mcu_reset_reason) { MAKE_ENUM_MAP_ENTRY(reset_reason, RESET_PIN), MAKE_ENUM_MAP_ENTRY(reset_reason, WATCHDOG), MAKE_ENUM_MAP_ENTRY(reset_reason, UNKNOWN), + MAKE_ENUM_MAP_ENTRY(reset_reason, RESCUE_DEBUG), }; STATIC MP_DEFINE_CONST_DICT(mcu_reset_reason_locals_dict, mcu_reset_reason_locals_table); diff --git a/shared-bindings/microcontroller/ResetReason.h b/shared-bindings/microcontroller/ResetReason.h index 8ed5e48315..7abc54c00b 100644 --- a/shared-bindings/microcontroller/ResetReason.h +++ b/shared-bindings/microcontroller/ResetReason.h @@ -38,6 +38,7 @@ typedef enum { RESET_REASON_RESET_PIN, RESET_REASON_WATCHDOG, RESET_REASON_UNKNOWN, + RESET_REASON_RESCUE_DEBUG, } mcu_reset_reason_t; extern const mp_obj_type_t mcu_reset_reason_type;