Reset cause for STM32

This commit is contained in:
andreika-git 2023-12-13 00:02:56 +02:00 committed by rusefillc
parent 4d2fab2b0c
commit 60a2aae2e1
6 changed files with 99 additions and 0 deletions

View File

@ -610,3 +610,14 @@ int getSpiPrescaler(spi_speed_e speed, spi_device_e device) {
}
#endif /* HAL_USE_SPI */
void checkLastResetCause() {
Reset_Cause_t cause = getMCUResetCause();
const char *causeStr = getMCUResetCause(cause);
efiPrintf("Last Reset Cause: %s", causeStr);
// if reset by watchdog, signal a fatal error
if (cause == Reset_Cause_IWatchdog || cause == Reset_Cause_WWatchdog) {
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Watchdog Reset");
}
}

View File

@ -52,6 +52,8 @@ void initHardwareNoConfig();
// Initialize hardware with configuration loaded
void initHardware();
void checkLastResetCause();
// todo: can we do simpler here? move conditional compilation into debounce.h?
#if EFI_PROD_CODE
#include "debounce.h"

View File

@ -91,6 +91,22 @@ typedef enum {
BOR_Level_t BOR_Get(void);
BOR_Result_t BOR_Set(BOR_Level_t BORValue);
// Reset Cause
typedef enum {
Reset_Cause_Unknown = 0,
Reset_Cause_IWatchdog, // Independent hardware watchdog (we use it)
Reset_Cause_WWatchdog, // Window watchdog
Reset_Cause_Soft_Reset, // NVIC_SystemReset or by debugger
Reset_Cause_NRST_Pin, // Reset from NRST pin
Reset_Cause_Illegal_Mode, // Reset after illegal Stop, Standby or Shutdown mode entry
Reset_Cause_BOR, // BOR reset
Reset_Cause_Firewall, // Firewall reset
Reset_Cause_Option_Byte, // Option byte load reset
} Reset_Cause_t;
Reset_Cause_t getMCUResetCause();
const char *getMCUResetCause(Reset_Cause_t cause);
#ifdef AT32F4XX
int at32GetMcuType(uint32_t id, const char **pn, const char **package, uint32_t *flashSize);
int at32GetRamSizeKb(void);

View File

@ -10,6 +10,7 @@ HW_LAYER_PORT_CPP += \
$(HW_STM32_PORT_DIR)/stm32_serial.cpp \
$(HW_STM32_PORT_DIR)/stm32_spi.cpp \
$(HW_STM32_PORT_DIR)/stm32_icu.cpp \
$(HW_STM32_PORT_DIR)/stm32_reset_cause.cpp \
$(HW_STM32_PORT_DIR)/backup_ram.cpp \
$(HW_STM32_PORT_DIR)/microsecond_timer_stm32.cpp \
$(HW_STM32_PORT_DIR)/osc_detector.cpp \

View File

@ -0,0 +1,67 @@
/**
* @file stm32_reset_cause.cpp
* @brief Get Reset Cause for STM32 MCUs
*
* @date Dec 10, 2023
* @author Andrey Belomutskiy, (c) 2012-2023
* @author andreika <prometheus.pcb@gmail.com>
*/
#include "pch.h"
#if EFI_PROD_CODE
#include "mpu_util.h"
#endif /* EFI_PROD_CODE */
static Reset_Cause_t readMCUResetCause() {
uint32_t cause = RCC->CSR; // Read the Control/Status Register
// Clear reset flags for future reset detection
RCC->CSR |= RCC_CSR_RMVF;
if (cause & RCC_CSR_IWDGRSTF) {
return Reset_Cause_IWatchdog;
} else if (cause & RCC_CSR_WWDGRSTF) {
return Reset_Cause_WWatchdog;
} else if (cause & RCC_CSR_SFTRSTF) {
return Reset_Cause_Soft_Reset;
} else if (cause & RCC_CSR_PINRSTF) {
return Reset_Cause_NRST_Pin;
} else if (cause & RCC_CSR_LPWRRSTF) {
return Reset_Cause_Illegal_Mode;
} else if (cause & RCC_CSR_BORRSTF) {
return Reset_Cause_BOR;
}
return Reset_Cause_Unknown;
}
// we need to read the reset cause on the early stage, before we setup the rest of MCU hardware
static Reset_Cause_t resetCause = readMCUResetCause();
Reset_Cause_t getMCUResetCause() {
return resetCause;
}
const char *getMCUResetCause(Reset_Cause_t cause) {
switch (cause) {
case Reset_Cause_IWatchdog:
return "Independent hardware watchdog";
case Reset_Cause_WWatchdog:
return "Window watchdog";
case Reset_Cause_Soft_Reset:
return "NVIC_SystemReset or by debugger";
case Reset_Cause_NRST_Pin:
return "Reset from NRST pin";
case Reset_Cause_Illegal_Mode:
return "Reset after illegal Stop, Standby or Shutdown mode entry";
case Reset_Cause_BOR:
return "BOR reset";
case Reset_Cause_Firewall:
return "Firewall reset";
case Reset_Cause_Option_Byte:
return "Option byte load reset";
default:
return "Unknown";
}
}

View File

@ -220,6 +220,8 @@ void runRusEfi() {
*/
initializeConsole();
checkLastResetCause();
// Read configuration from flash memory
loadConfiguration();