From 04c7cdb668cc7ee391ef5fe000f825389197f7e2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 22 Jun 2019 21:26:03 +1000 Subject: [PATCH] stm32: Enter bootloader via a system reset. Entering a bootloader (ST system bootloader, or custom mboot) from software by directly branching to it is not reliable, and the reliability of it working can depend on the peripherals that were enabled by the application code. It's also not possible to branch to a bootloader if the WDT is enabled (unless the bootloader has specific provisions to feed the WDT). This patch changes the way a bootloader is entered from software by first doing a complete system reset, then branching to the desired bootloader early on in the start-up process. The top two words of RAM (of the stack) are reserved to store flags indicating that the bootloader should be entered after a reset. --- ports/stm32/Makefile | 1 + ports/stm32/boards/PYBD_SF2/f722_qspi.ld | 2 +- ports/stm32/boards/PYBD_SF6/f767.ld | 2 +- ports/stm32/boards/STM32F769DISC/f769_qspi.ld | 2 +- ports/stm32/boards/stm32f091xc.ld | 2 +- ports/stm32/boards/stm32f401xd.ld | 2 +- ports/stm32/boards/stm32f401xe.ld | 2 +- ports/stm32/boards/stm32f405.ld | 2 +- ports/stm32/boards/stm32f411.ld | 2 +- ports/stm32/boards/stm32f413xg.ld | 2 +- ports/stm32/boards/stm32f413xh.ld | 2 +- ports/stm32/boards/stm32f429.ld | 2 +- ports/stm32/boards/stm32f439.ld | 2 +- ports/stm32/boards/stm32f722.ld | 2 +- ports/stm32/boards/stm32f746.ld | 2 +- ports/stm32/boards/stm32f767.ld | 2 +- ports/stm32/boards/stm32f769.ld | 2 +- ports/stm32/boards/stm32h743.ld | 2 +- ports/stm32/boards/stm32l432.ld | 2 +- ports/stm32/boards/stm32l476xe.ld | 2 +- ports/stm32/boards/stm32l476xg.ld | 2 +- ports/stm32/boards/stm32l496xg.ld | 2 +- ports/stm32/main.c | 4 ++ ports/stm32/modmachine.c | 34 ++---------- ports/stm32/powerctrl.c | 54 +++++++++++++++++++ ports/stm32/powerctrl.h | 4 ++ ports/stm32/stm32_it.c | 3 +- 27 files changed, 91 insertions(+), 51 deletions(-) diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 31597e88a5..153ea44626 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -92,6 +92,7 @@ CFLAGS += -fsingle-precision-constant -Wdouble-promotion endif LDFLAGS = -nostdlib -L $(LD_DIR) $(addprefix -T,$(LD_FILES)) -Map=$(@:.elf=.map) --cref +LDFLAGS += --defsym=_estack_reserve=8 LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) # Remove uncalled code from the final image. diff --git a/ports/stm32/boards/PYBD_SF2/f722_qspi.ld b/ports/stm32/boards/PYBD_SF2/f722_qspi.ld index e9d6fa3c39..b6d3e08e30 100644 --- a/ports/stm32/boards/PYBD_SF2/f722_qspi.ld +++ b/ports/stm32/boards/PYBD_SF2/f722_qspi.ld @@ -31,7 +31,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 16K; /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/PYBD_SF6/f767.ld b/ports/stm32/boards/PYBD_SF6/f767.ld index 2a474fba07..1dd4c11ed9 100644 --- a/ports/stm32/boards/PYBD_SF6/f767.ld +++ b/ports/stm32/boards/PYBD_SF6/f767.ld @@ -30,7 +30,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 24K; /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/STM32F769DISC/f769_qspi.ld b/ports/stm32/boards/STM32F769DISC/f769_qspi.ld index 362fab3305..9a0bd56fb3 100644 --- a/ports/stm32/boards/STM32F769DISC/f769_qspi.ld +++ b/ports/stm32/boards/STM32F769DISC/f769_qspi.ld @@ -29,7 +29,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 32K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32f091xc.ld b/ports/stm32/boards/stm32f091xc.ld index 5e1e9e7bd3..5bcc4c7275 100644 --- a/ports/stm32/boards/stm32f091xc.ld +++ b/ports/stm32/boards/stm32f091xc.ld @@ -16,7 +16,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 6K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32f401xd.ld b/ports/stm32/boards/stm32f401xd.ld index 50cb3c571b..f4146abc6d 100644 --- a/ports/stm32/boards/stm32f401xd.ld +++ b/ports/stm32/boards/stm32f401xd.ld @@ -18,7 +18,7 @@ _minimum_heap_size = 16K; /* tunable */ /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 16K; /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32f401xe.ld b/ports/stm32/boards/stm32f401xe.ld index 78e0dc1cba..e7bd8edfed 100644 --- a/ports/stm32/boards/stm32f401xe.ld +++ b/ports/stm32/boards/stm32f401xe.ld @@ -18,7 +18,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 16K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32f405.ld b/ports/stm32/boards/stm32f405.ld index 13133e8c6d..b6f5d30578 100644 --- a/ports/stm32/boards/stm32f405.ld +++ b/ports/stm32/boards/stm32f405.ld @@ -19,7 +19,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 16K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32f411.ld b/ports/stm32/boards/stm32f411.ld index 8ae5f6929c..50633118eb 100644 --- a/ports/stm32/boards/stm32f411.ld +++ b/ports/stm32/boards/stm32f411.ld @@ -18,7 +18,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 16K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32f413xg.ld b/ports/stm32/boards/stm32f413xg.ld index c2719b834f..96d6dc5fb0 100644 --- a/ports/stm32/boards/stm32f413xg.ld +++ b/ports/stm32/boards/stm32f413xg.ld @@ -21,7 +21,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 16K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32f413xh.ld b/ports/stm32/boards/stm32f413xh.ld index 017dbbac17..0b28730de5 100644 --- a/ports/stm32/boards/stm32f413xh.ld +++ b/ports/stm32/boards/stm32f413xh.ld @@ -21,7 +21,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 16K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32f429.ld b/ports/stm32/boards/stm32f429.ld index 35d0736eef..beeaa4df21 100644 --- a/ports/stm32/boards/stm32f429.ld +++ b/ports/stm32/boards/stm32f429.ld @@ -19,7 +19,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 16K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32f439.ld b/ports/stm32/boards/stm32f439.ld index 2b51c3a371..e847646b35 100644 --- a/ports/stm32/boards/stm32f439.ld +++ b/ports/stm32/boards/stm32f439.ld @@ -20,7 +20,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 16K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32f722.ld b/ports/stm32/boards/stm32f722.ld index 8986c68d52..ab41f0ea90 100644 --- a/ports/stm32/boards/stm32f722.ld +++ b/ports/stm32/boards/stm32f722.ld @@ -17,7 +17,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 32K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32f746.ld b/ports/stm32/boards/stm32f746.ld index 330dd97141..0f1de26964 100644 --- a/ports/stm32/boards/stm32f746.ld +++ b/ports/stm32/boards/stm32f746.ld @@ -19,7 +19,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 16K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32f767.ld b/ports/stm32/boards/stm32f767.ld index 47e992c2dd..9410b9fa6b 100644 --- a/ports/stm32/boards/stm32f767.ld +++ b/ports/stm32/boards/stm32f767.ld @@ -20,7 +20,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 32K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32f769.ld b/ports/stm32/boards/stm32f769.ld index 41bb321a37..ebc6d033d9 100644 --- a/ports/stm32/boards/stm32f769.ld +++ b/ports/stm32/boards/stm32f769.ld @@ -19,7 +19,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 32K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32h743.ld b/ports/stm32/boards/stm32h743.ld index 0f1c2b777e..69738ab8b9 100644 --- a/ports/stm32/boards/stm32h743.ld +++ b/ports/stm32/boards/stm32h743.ld @@ -19,7 +19,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 16K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32l432.ld b/ports/stm32/boards/stm32l432.ld index 40515e75b3..5558b13c89 100644 --- a/ports/stm32/boards/stm32l432.ld +++ b/ports/stm32/boards/stm32l432.ld @@ -17,7 +17,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 6K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32l476xe.ld b/ports/stm32/boards/stm32l476xe.ld index 330ec96e67..e4bcda1f16 100644 --- a/ports/stm32/boards/stm32l476xe.ld +++ b/ports/stm32/boards/stm32l476xe.ld @@ -20,7 +20,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 16K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32l476xg.ld b/ports/stm32/boards/stm32l476xg.ld index 7983fb39a1..9fe83c74a4 100644 --- a/ports/stm32/boards/stm32l476xg.ld +++ b/ports/stm32/boards/stm32l476xg.ld @@ -20,7 +20,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM); +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; _sstack = _estack - 16K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/boards/stm32l496xg.ld b/ports/stm32/boards/stm32l496xg.ld index e1ceb50707..c339903422 100644 --- a/ports/stm32/boards/stm32l496xg.ld +++ b/ports/stm32/boards/stm32l496xg.ld @@ -20,7 +20,7 @@ _minimum_heap_size = 16K; /* Define the stack. The stack is full descending so begins just above last byte of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ -_estack = ORIGIN(RAM) + LENGTH(RAM) + LENGTH(SRAM2); +_estack = ORIGIN(RAM) + LENGTH(RAM) + LENGTH(SRAM2) - _estack_reserve; _sstack = _estack - 206K; /* tunable */ /* RAM extents for the garbage collector */ diff --git a/ports/stm32/main.c b/ports/stm32/main.c index 523034e097..2dcc09ae7a 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -45,6 +45,7 @@ #include "systick.h" #include "pendsv.h" +#include "powerctrl.h" #include "pybthread.h" #include "gccollect.h" #include "factoryreset.h" @@ -368,6 +369,9 @@ STATIC uint update_reset_mode(uint reset_mode) { #endif void stm32_main(uint32_t reset_mode) { + // Check if bootloader should be entered instead of main application + powerctrl_check_enter_bootloader(); + // Enable caches and prefetch buffers #if defined(STM32F4) diff --git a/ports/stm32/modmachine.c b/ports/stm32/modmachine.c index cf615ea6aa..a4ee47470b 100644 --- a/ports/stm32/modmachine.c +++ b/ports/stm32/modmachine.c @@ -237,7 +237,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(machine_unique_id_obj, machine_unique_id); // Resets the pyboard in a manner similar to pushing the external RESET button. STATIC mp_obj_t machine_reset(void) { - NVIC_SystemReset(); + powerctrl_mcu_reset(); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_obj, machine_reset); @@ -248,15 +248,6 @@ STATIC mp_obj_t machine_soft_reset(void) { } MP_DEFINE_CONST_FUN_OBJ_0(machine_soft_reset_obj, machine_soft_reset); -__attribute__((naked)) void branch_to_bootloader(uint32_t r0, uint32_t addr) { - __asm volatile ( - "ldr r2, [r1, #0]\n" // get address of stack pointer - "msr msp, r2\n" // get stack pointer - "ldr r2, [r1, #4]\n" // get address of destination - "bx r2\n" // branch to bootloader - ); -} - // Activate the bootloader without BOOT* pins. STATIC NORETURN mp_obj_t machine_bootloader(size_t n_args, const mp_obj_t *args) { #if MICROPY_HW_ENABLE_USB @@ -266,24 +257,10 @@ STATIC NORETURN mp_obj_t machine_bootloader(size_t n_args, const mp_obj_t *args) storage_flush(); #endif - #if __DCACHE_PRESENT == 1 - // Flush and disable caches before turning off peripherals (eg SDRAM) - SCB_DisableICache(); - SCB_DisableDCache(); - #endif - - HAL_RCC_DeInit(); - HAL_DeInit(); - - #if (__MPU_PRESENT == 1) - // MPU must be disabled for bootloader to function correctly - HAL_MPU_Disable(); - #endif - #if MICROPY_HW_USES_BOOTLOADER if (n_args == 0 || !mp_obj_is_true(args[0])) { // By default, with no args given, we enter the custom bootloader (mboot) - branch_to_bootloader(0x70ad0000, 0x08000000); + powerctrl_enter_bootloader(0x70ad0000, 0x08000000); } if (n_args == 1 && mp_obj_is_str_or_bytes(args[0])) { @@ -292,15 +269,14 @@ STATIC NORETURN mp_obj_t machine_bootloader(size_t n_args, const mp_obj_t *args) const char *data = mp_obj_str_get_data(args[0], &len); void *mboot_region = (void*)*((volatile uint32_t*)0x08000000); memmove(mboot_region, data, len); - branch_to_bootloader(0x70ad0080, 0x08000000); + powerctrl_enter_bootloader(0x70ad0080, 0x08000000); } #endif #if defined(STM32F7) || defined(STM32H7) - branch_to_bootloader(0, 0x1ff00000); + powerctrl_enter_bootloader(0, 0x1ff00000); #else - __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH(); - branch_to_bootloader(0, 0x00000000); + powerctrl_enter_bootloader(0, 0x00000000); #endif while (1); diff --git a/ports/stm32/powerctrl.c b/ports/stm32/powerctrl.c index c3792be3ed..2ad2426005 100644 --- a/ports/stm32/powerctrl.c +++ b/ports/stm32/powerctrl.c @@ -30,6 +30,60 @@ #include "rtc.h" #include "genhdr/pllfreqtable.h" +#if defined(STM32H7) +#define RCC_SR RSR +#define RCC_SR_SFTRSTF RCC_RSR_SFTRSTF +#define RCC_SR_RMVF RCC_RSR_RMVF +#else +#define RCC_SR CSR +#define RCC_SR_SFTRSTF RCC_CSR_SFTRSTF +#define RCC_SR_RMVF RCC_CSR_RMVF +#endif + +// Location in RAM of bootloader state (just after the top of the stack) +extern uint32_t _estack[]; +#define BL_STATE ((uint32_t*)&_estack) + +NORETURN void powerctrl_mcu_reset(void) { + BL_STATE[1] = 1; // invalidate bootloader address + #if __DCACHE_PRESENT == 1 + SCB_CleanDCache(); + #endif + NVIC_SystemReset(); +} + +NORETURN void powerctrl_enter_bootloader(uint32_t r0, uint32_t bl_addr) { + BL_STATE[0] = r0; + BL_STATE[1] = bl_addr; + #if __DCACHE_PRESENT == 1 + SCB_CleanDCache(); + #endif + NVIC_SystemReset(); +} + +static __attribute__((naked)) void branch_to_bootloader(uint32_t r0, uint32_t bl_addr) { + __asm volatile ( + "ldr r2, [r1, #0]\n" // get address of stack pointer + "msr msp, r2\n" // get stack pointer + "ldr r2, [r1, #4]\n" // get address of destination + "bx r2\n" // branch to bootloader + ); +} + +void powerctrl_check_enter_bootloader(void) { + uint32_t bl_addr = BL_STATE[1]; + BL_STATE[1] = 1; // invalidate bootloader address + if ((bl_addr & 0xfff) == 0 && (RCC->RCC_SR & RCC_SR_SFTRSTF)) { + // Reset by NVIC_SystemReset with bootloader data set -> branch to bootloader + RCC->RCC_SR = RCC_SR_RMVF; + #if defined(STM32F0) || defined(STM32F4) || defined(STM32L4) + __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH(); + #endif + uint32_t r0 = BL_STATE[0]; + branch_to_bootloader(r0, bl_addr); + } +} + #if !defined(STM32F0) // Assumes that PLL is used as the SYSCLK source diff --git a/ports/stm32/powerctrl.h b/ports/stm32/powerctrl.h index b26cab391c..6eb0342287 100644 --- a/ports/stm32/powerctrl.h +++ b/ports/stm32/powerctrl.h @@ -28,6 +28,10 @@ #include +NORETURN void powerctrl_mcu_reset(void); +NORETURN void powerctrl_enter_bootloader(uint32_t r0, uint32_t bl_addr); +void powerctrl_check_enter_bootloader(void); + int powerctrl_rcc_clock_config_pll(RCC_ClkInitTypeDef *rcc_init, uint32_t sysclk_mhz, bool need_pllsai); int powerctrl_set_sysclk(uint32_t sysclk, uint32_t ahb, uint32_t apb1, uint32_t apb2); void powerctrl_enter_stop_mode(void); diff --git a/ports/stm32/stm32_it.c b/ports/stm32/stm32_it.c index 0c5263e053..a3740d59cd 100644 --- a/ports/stm32/stm32_it.c +++ b/ports/stm32/stm32_it.c @@ -72,6 +72,7 @@ #include "stm32_it.h" #include "pendsv.h" #include "irq.h" +#include "powerctrl.h" #include "pybthread.h" #include "gccollect.h" #include "extint.h" @@ -144,7 +145,7 @@ int pyb_hard_fault_debug = 0; void HardFault_C_Handler(ExceptionRegisters_t *regs) { if (!pyb_hard_fault_debug) { - NVIC_SystemReset(); + powerctrl_mcu_reset(); } #if MICROPY_HW_ENABLE_USB