diff --git a/libraries/AP_HAL_ChibiOS/hwdef/common/board.c b/libraries/AP_HAL_ChibiOS/hwdef/common/board.c index 1b32766ead..fd3303af0c 100644 --- a/libraries/AP_HAL_ChibiOS/hwdef/common/board.c +++ b/libraries/AP_HAL_ChibiOS/hwdef/common/board.c @@ -18,6 +18,7 @@ #include "hal.h" #include "usbcfg.h" #include "stm32_util.h" +#include "watchdog.h" #if HAL_USE_PAL || defined(__DOXYGEN__) /** @@ -65,6 +66,7 @@ void __early_init(void) { void __late_init(void) { halInit(); chSysInit(); + stm32_watchdog_save_reason(); #if CH_CFG_USE_HEAP == TRUE malloc_init(); #endif diff --git a/libraries/AP_HAL_ChibiOS/hwdef/common/watchdog.c b/libraries/AP_HAL_ChibiOS/hwdef/common/watchdog.c index a7275edd2f..10583fc7b3 100644 --- a/libraries/AP_HAL_ChibiOS/hwdef/common/watchdog.c +++ b/libraries/AP_HAL_ChibiOS/hwdef/common/watchdog.c @@ -8,13 +8,38 @@ #ifndef IWDG_BASE #if defined(STM32H7) #define IWDG_BASE 0x58004800 -#elif defined(STM32F7) || defined(STM32F4) || defined(STM32F1) +#elif defined(STM32F7) || defined(STM32F4) +#define IWDG_BASE 0x40003000 +#elif defined(STM32F1) #define IWDG_BASE 0x40003000 #else -#error "Unknown IWDG_BASE" +#error "Unsupported IWDG MCU config" #endif #endif +#ifndef RCC_BASE +#error "Unsupported IWDG RCC MCU config" +#endif + +/* + defines for working out if the reset was from the watchdog + */ +#if defined(STM32H7) +#define WDG_RESET_STATUS (*(__IO uint32_t *)(RCC_BASE + )) +#define WDG_RESET_CLEAR (1U<<16) +#define WDG_RESET_IS_IWDG (1U<<26) +#elif defined(STM32F7) || defined(STM32F4) +#define WDG_RESET_STATUS (*(__IO uint32_t *)(RCC_BASE + 0x74)) +#define WDG_RESET_CLEAR (1U<<24) +#define WDG_RESET_IS_IWDG (1U<<29) +#elif defined(STM32F1) +#define WDG_RESET_STATUS (*(__IO uint32_t *)(RCC_BASE + 0x24)) +#define WDG_RESET_CLEAR (1U<<24) +#define WDG_RESET_IS_IWDG (1U<<29) +#else +#error "Unsupported IWDG MCU config" +#endif + typedef struct { __IO uint32_t KR; /*!< IWDG Key register, Address offset: 0x00 */ @@ -46,3 +71,25 @@ void stm32_watchdog_pat(void) { IWDGD.KR = 0xAAAA; } + +static bool was_watchdog_reset; + +/* + save reason code for reset + */ +void stm32_watchdog_save_reason(void) +{ + if (WDG_RESET_STATUS & WDG_RESET_IS_IWDG) { + was_watchdog_reset = true; + } + WDG_RESET_STATUS = WDG_RESET_CLEAR; +} + +/* + return true if reboot was from a watchdog reset + */ +bool stm32_was_watchdog_reset(void) +{ + return was_watchdog_reset; +} + diff --git a/libraries/AP_HAL_ChibiOS/hwdef/common/watchdog.h b/libraries/AP_HAL_ChibiOS/hwdef/common/watchdog.h index 9f1dc8417e..3310959626 100644 --- a/libraries/AP_HAL_ChibiOS/hwdef/common/watchdog.h +++ b/libraries/AP_HAL_ChibiOS/hwdef/common/watchdog.h @@ -14,6 +14,16 @@ void stm32_watchdog_init(void); */ void stm32_watchdog_pat(void); +/* + return true if reboot was from a watchdog reset + */ +bool stm32_was_watchdog_reset(void); + +/* + save the reset reason code + */ +void stm32_watchdog_save_reason(void); + #ifdef __cplusplus } #endif