diff --git a/firmware/console/eficonsole.cpp b/firmware/console/eficonsole.cpp index 6e62c9fc48..d56a7e5efc 100644 --- a/firmware/console/eficonsole.cpp +++ b/firmware/console/eficonsole.cpp @@ -36,52 +36,6 @@ static void myerror() { firmwareError(CUSTOM_ERR_TEST_ERROR, "firmwareError: %d", getRusEfiVersion()); } -#if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) - -#define HWREG(x) \ - (*((volatile unsigned long *)(x))) - -#define NVIC_FAULT_STAT 0xE000ED28 // Configurable Fault Status -#define NVIC_FAULT_STAT_BFARV 0x00008000 // Bus Fault Address Register Valid -#define NVIC_CFG_CTRL_BFHFNMIGN 0x00000100 // Ignore Bus Fault in NMI and - // Fault -#define NVIC_CFG_CTRL 0xE000ED14 // Configuration and Control - - -/** - * @brief Probe an address to see if can be read without generating a bus fault - * @details This function must be called with the processor in privileged mode. - * It: - * - Clear any previous indication of a bus fault in the BFARV bit - * - Temporarily sets the processor to Ignore Bus Faults with all interrupts and fault handlers disabled - * - Attempt to read from read_address, ignoring the result - * - Checks to see if the read caused a bus fault, by checking the BFARV bit is set - * - Re-enables Bus Faults and all interrupts and fault handlers - * @param[in] read_address The address to try reading a byte from - * @return Returns true if no bus fault occurred reading from read_address, or false if a bus fault occurred. - */ -bool read_probe (volatile const char *read_address) -{ - bool address_readable = true; - - /* Clear any existing indication of a bus fault - BFARV is write one to clear */ - HWREG (NVIC_FAULT_STAT) |= NVIC_FAULT_STAT_BFARV; - - HWREG (NVIC_CFG_CTRL) |= NVIC_CFG_CTRL_BFHFNMIGN; - asm volatile (" CPSID f;"); - *read_address; - if ((HWREG (NVIC_FAULT_STAT) & NVIC_FAULT_STAT_BFARV) != 0) - { - address_readable = false; - } - asm volatile (" CPSIE f;"); - HWREG (NVIC_CFG_CTRL) &= ~NVIC_CFG_CTRL_BFHFNMIGN; - - return address_readable; -} - -#endif - static void sayHello() { efiPrintf(PROTOCOL_HELLO_PREFIX " rusEFI LLC (c) 2012-2022. All rights reserved."); efiPrintf(PROTOCOL_HELLO_PREFIX " rusEFI v%d@%s", getRusEfiVersion(), VCS_VERSION); @@ -102,9 +56,13 @@ static void sayHello() { uint32_t *uid = ((uint32_t *)UID_BASE); efiPrintf("UID=%x %x %x", uid[0], uid[1], uid[2]); - efiPrintf("can read 0x20000010 %d", read_probe((const char *)0x20000010)); - efiPrintf("can read 0x20020010 %d", read_probe((const char *)0x20020010)); - efiPrintf("can read 0x20070010 %d", read_probe((const char *)0x20070010)); + efiPrintf("can read 0x20000010 %d", ramReadProbe((const char *)0x20000010)); + efiPrintf("can read 0x20020010 %d", ramReadProbe((const char *)0x20020010)); + efiPrintf("can read 0x20070010 %d", ramReadProbe((const char *)0x20070010)); + +#if defined(STM32F4) + efiPrintf("isStm32F42x %s", boolToString(isStm32F42x())); +#endif // STM32F4 #define TM_ID_GetFlashSize() (*(__IO uint16_t *) (FLASHSIZE_BASE)) #define MCU_REVISION_MASK 0xfff diff --git a/firmware/hw_layer/ports/mpu_util.h b/firmware/hw_layer/ports/mpu_util.h index 9783d8d518..1247bbb98e 100644 --- a/firmware/hw_layer/ports/mpu_util.h +++ b/firmware/hw_layer/ports/mpu_util.h @@ -11,6 +11,11 @@ void baseMCUInit(void); void jump_to_bootloader(); bool allowFlashWhileRunning(); +bool ramReadProbe(volatile const char *read_address); +#if defined(STM32F4) +bool isStm32F42x(); +#endif // STM32F4 + // ADC #if HAL_USE_ADC void portInitAdc(); diff --git a/firmware/hw_layer/ports/stm32/stm32_common.cpp b/firmware/hw_layer/ports/stm32/stm32_common.cpp index 10647fc1f3..f109bf30f1 100644 --- a/firmware/hw_layer/ports/stm32/stm32_common.cpp +++ b/firmware/hw_layer/ports/stm32/stm32_common.cpp @@ -796,6 +796,60 @@ CANDriver* detectCanDevice(brain_pin_e pinRx, brain_pin_e pinTx) { #endif /* EFI_CAN_SUPPORT */ +#if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) + +#define HWREG(x) \ + (*((volatile unsigned long *)(x))) + +#define NVIC_FAULT_STAT 0xE000ED28 // Configurable Fault Status +#define NVIC_FAULT_STAT_BFARV 0x00008000 // Bus Fault Address Register Valid +#define NVIC_CFG_CTRL_BFHFNMIGN 0x00000100 // Ignore Bus Fault in NMI and + // Fault +#define NVIC_CFG_CTRL 0xE000ED14 // Configuration and Control + + +/** + * @brief Probe an address to see if can be read without generating a bus fault + * @details This function must be called with the processor in privileged mode. + * It: + * - Clear any previous indication of a bus fault in the BFARV bit + * - Temporarily sets the processor to Ignore Bus Faults with all interrupts and fault handlers disabled + * - Attempt to read from read_address, ignoring the result + * - Checks to see if the read caused a bus fault, by checking the BFARV bit is set + * - Re-enables Bus Faults and all interrupts and fault handlers + * @param[in] read_address The address to try reading a byte from + * @return Returns true if no bus fault occurred reading from read_address, or false if a bus fault occurred. + */ +bool ramReadProbe(volatile const char *read_address) { + bool address_readable = true; + + /* Clear any existing indication of a bus fault - BFARV is write one to clear */ + HWREG (NVIC_FAULT_STAT) |= NVIC_FAULT_STAT_BFARV; + + HWREG (NVIC_CFG_CTRL) |= NVIC_CFG_CTRL_BFHFNMIGN; + asm volatile (" CPSID f;"); + *read_address; + if ((HWREG (NVIC_FAULT_STAT) & NVIC_FAULT_STAT_BFARV) != 0) + { + address_readable = false; + } + asm volatile (" CPSIE f;"); + HWREG (NVIC_CFG_CTRL) &= ~NVIC_CFG_CTRL_BFHFNMIGN; + + return address_readable; +} + +#endif + +#if defined(STM32F4) +bool isStm32F42x() { + // really it's enough to just check 0x20020010 + return ramReadProbe((const char *)0x20000010) && ramReadProbe((const char *)0x20020010) && !ramReadProbe((const char *)0x20070010); +} + +#endif + + // Stubs for per-board low power helpers __attribute__((weak)) void boardPrepareForStop() { // Default implementation - wake up on PA0 - boards should override this