From 5b64d8c4554ded4aa37b2a71df7c2fefaa80d88a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Garci=CC=81a=20Hierro?= Date: Tue, 24 Mar 2020 20:10:21 +0000 Subject: [PATCH] [STARTUP/BL] Unify startup/reset/bootloader handling across F3/F4/F7 Use MCU-independent versions of systemReset(), systemResetToBootloader() and checkForBootLoaderRequest() based on exchanging data via persistent storage. --- src/main/drivers/system.c | 57 +++++++++++++++++++++++++++-- src/main/drivers/system_stm32f30x.c | 38 ------------------- src/main/drivers/system_stm32f4xx.c | 54 --------------------------- src/main/drivers/system_stm32f7xx.c | 53 --------------------------- 4 files changed, 54 insertions(+), 148 deletions(-) diff --git a/src/main/drivers/system.c b/src/main/drivers/system.c index a94de7ddd5..e3bcdd766c 100644 --- a/src/main/drivers/system.c +++ b/src/main/drivers/system.c @@ -20,12 +20,13 @@ #include "platform.h" -#include "drivers/light_led.h" -#include "sound_beeper.h" -#include "drivers/nvic.h" #include "build/atomic.h" #include "build/build_config.h" +#include "drivers/light_led.h" +#include "drivers/nvic.h" +#include "drivers/persistent.h" +#include "drivers/sound_beeper.h" #include "drivers/system.h" #include "drivers/time.h" @@ -74,6 +75,56 @@ void cycleCounterInit(void) } #endif // UNIT_TEST +static inline void systemDisableAllIRQs(void) +{ + // We access CMSIS NVIC registers directly here + for (int x = 0; x < 8; x++) { + // Mask all IRQs controlled by a ICERx + NVIC->ICER[x] = 0xFFFFFFFF; + // Clear all pending IRQs controlled by a ICPRx + NVIC->ICPR[x] = 0xFFFFFFFF; + } +} + +void systemReset(void) +{ + __disable_irq(); + systemDisableAllIRQs(); + NVIC_SystemReset(); +} + +void systemResetToBootloader(void) +{ + persistentObjectWrite(PERSISTENT_OBJECT_RESET_REASON, RESET_BOOTLOADER_REQUEST_ROM); + systemReset(); +} + +typedef void resetHandler_t(void); + +typedef struct isrVector_s { + __I uint32_t stackEnd; + resetHandler_t *resetHandler; +} isrVector_t; + +#pragma GCC push_options +#pragma GCC optimize ("O0") +void checkForBootLoaderRequest(void) +{ + uint32_t bootloaderRequest = persistentObjectRead(PERSISTENT_OBJECT_RESET_REASON); + + if (bootloaderRequest != RESET_BOOTLOADER_REQUEST_ROM) { + return; + } + persistentObjectWrite(PERSISTENT_OBJECT_RESET_REASON, RESET_NONE); + + extern isrVector_t system_isr_vector_table_base; + + __set_MSP(system_isr_vector_table_base.stackEnd); + system_isr_vector_table_base.resetHandler(); + while (1); +} +#pragma GCC pop_options + // SysTick static volatile int sysTickPending = 0; diff --git a/src/main/drivers/system_stm32f30x.c b/src/main/drivers/system_stm32f30x.c index a31cb08aa9..e8d9d1c651 100644 --- a/src/main/drivers/system_stm32f30x.c +++ b/src/main/drivers/system_stm32f30x.c @@ -24,42 +24,8 @@ #include "drivers/nvic.h" #include "drivers/system.h" -#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) void SetSysClock(uint8_t underclock); -inline static void NVIC_DisableAllIRQs(void) -{ - // We access CMSIS NVIC registers directly here - for (int x = 0; x < 8; x++) { - // Mask all IRQs controlled by a ICERx - NVIC->ICER[x] = 0xFFFFFFFF; - // Clear all pending IRQs controlled by a ICPRx - NVIC->ICPR[x] = 0xFFFFFFFF; - } -} - -void systemReset(void) -{ - // Disable all NVIC interrupts - __disable_irq(); - NVIC_DisableAllIRQs(); - - // Generate system reset - SCB->AIRCR = AIRCR_VECTKEY_MASK | (uint32_t)0x04; -} - -void systemResetToBootloader(void) -{ - __disable_irq(); - NVIC_DisableAllIRQs(); - - *((uint32_t *)0x20009FFC) = 0xDEADBEEF; // 40KB SRAM STM32F30X - - // Generate system reset - SCB->AIRCR = AIRCR_VECTKEY_MASK | (uint32_t)0x04; -} - - void enableGPIOPowerUsageAndNoiseReductions(void) { RCC_AHBPeriphClockCmd( @@ -133,7 +99,3 @@ void systemInit(void) // Pre-setup SysTick and system time - final setup is done in systemClockSetup systemTimekeepingSetup(); } - -void checkForBootLoaderRequest(void) -{ -} diff --git a/src/main/drivers/system_stm32f4xx.c b/src/main/drivers/system_stm32f4xx.c index 47708e67a4..b2adb289cf 100644 --- a/src/main/drivers/system_stm32f4xx.c +++ b/src/main/drivers/system_stm32f4xx.c @@ -23,68 +23,14 @@ #include "drivers/accgyro/accgyro_mpu.h" #include "drivers/exti.h" -#include "drivers/persistent.h" #include "drivers/nvic.h" #include "drivers/system.h" #include "drivers/exti.h" -#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) void SetSysClock(void); -inline static void NVIC_DisableAllIRQs(void) -{ - // We access CMSIS NVIC registers directly here - for (int x = 0; x < 8; x++) { - // Mask all IRQs controlled by a ICERx - NVIC->ICER[x] = 0xFFFFFFFF; - // Clear all pending IRQs controlled by a ICPRx - NVIC->ICPR[x] = 0xFFFFFFFF; - } -} - -typedef void resetHandler_t(void); - -typedef struct isrVector_s { - __I uint32_t stackEnd; - resetHandler_t *resetHandler; -} isrVector_t; - -#pragma GCC push_options -#pragma GCC optimize ("O0") -void checkForBootLoaderRequest(void) -{ - uint32_t bootloaderRequest = persistentObjectRead(PERSISTENT_OBJECT_RESET_REASON); - - if (bootloaderRequest != RESET_BOOTLOADER_REQUEST_ROM) { - return; - } - persistentObjectWrite(PERSISTENT_OBJECT_RESET_REASON, RESET_NONE); - - extern isrVector_t system_isr_vector_table_base; - - __set_MSP(system_isr_vector_table_base.stackEnd); - system_isr_vector_table_base.resetHandler(); - while (1); -} -#pragma GCC pop_options - -void systemReset(void) -{ - __disable_irq(); - NVIC_DisableAllIRQs(); - NVIC_SystemReset(); -} - -void systemResetToBootloader(void) -{ - persistentObjectWrite(PERSISTENT_OBJECT_RESET_REASON, RESET_BOOTLOADER_REQUEST_ROM); - __disable_irq(); - NVIC_DisableAllIRQs(); - NVIC_SystemReset(); -} - void enableGPIOPowerUsageAndNoiseReductions(void) { diff --git a/src/main/drivers/system_stm32f7xx.c b/src/main/drivers/system_stm32f7xx.c index 62ee3b1ae1..92f417bea0 100644 --- a/src/main/drivers/system_stm32f7xx.c +++ b/src/main/drivers/system_stm32f7xx.c @@ -27,38 +27,8 @@ #include "drivers/nvic.h" #include "drivers/system.h" - -#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) void SystemClock_Config(void); -inline static void NVIC_DisableAllIRQs(void) -{ - // We access CMSIS NVIC registers directly here - for (int x = 0; x < 8; x++) { - // Mask all IRQs controlled by a ICERx - NVIC->ICER[x] = 0xFFFFFFFF; - // Clear all pending IRQs controlled by a ICPRx - NVIC->ICPR[x] = 0xFFFFFFFF; - } -} - -void systemReset(void) -{ - __disable_irq(); - NVIC_DisableAllIRQs(); - NVIC_SystemReset(); -} - -void systemResetToBootloader(void) -{ - __disable_irq(); - NVIC_DisableAllIRQs(); - - (*(__IO uint32_t *) (BKPSRAM_BASE + 4)) = 0xDEADBEEF; // flag that will be readable after reboot - - NVIC_SystemReset(); -} - void enableGPIOPowerUsageAndNoiseReductions(void) { @@ -128,26 +98,3 @@ void systemInit(void) HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); } - -void(*bootJump)(void); -void checkForBootLoaderRequest(void) -{ - uint32_t bt; - __PWR_CLK_ENABLE(); - __BKPSRAM_CLK_ENABLE(); - HAL_PWR_EnableBkUpAccess(); - - bt = (*(__IO uint32_t *) (BKPSRAM_BASE + 4)) ; - if ( bt == 0xDEADBEEF ) { - (*(__IO uint32_t *) (BKPSRAM_BASE + 4)) = 0xCAFEFEED; // Reset our trigger - - void (*SysMemBootJump)(void); - __SYSCFG_CLK_ENABLE(); - SYSCFG->MEMRMP |= SYSCFG_MEM_BOOT_ADD0 ; - uint32_t p = (*((uint32_t *) 0x1ff00000)); - __set_MSP(p); //Set the main stack pointer to its defualt values - SysMemBootJump = (void (*)(void)) (*((uint32_t *) 0x1ff00004)); // Point the PC to the System Memory reset vector (+4) - SysMemBootJump(); - while (1); - } -}