aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/Makefile1
-rw-r--r--ports/stm32/boards/PYBD_SF2/f722_qspi.ld2
-rw-r--r--ports/stm32/boards/PYBD_SF6/f767.ld2
-rw-r--r--ports/stm32/boards/STM32F769DISC/f769_qspi.ld2
-rw-r--r--ports/stm32/boards/stm32f091xc.ld2
-rw-r--r--ports/stm32/boards/stm32f401xd.ld2
-rw-r--r--ports/stm32/boards/stm32f401xe.ld2
-rw-r--r--ports/stm32/boards/stm32f405.ld2
-rw-r--r--ports/stm32/boards/stm32f411.ld2
-rw-r--r--ports/stm32/boards/stm32f413xg.ld2
-rw-r--r--ports/stm32/boards/stm32f413xh.ld2
-rw-r--r--ports/stm32/boards/stm32f429.ld2
-rw-r--r--ports/stm32/boards/stm32f439.ld2
-rw-r--r--ports/stm32/boards/stm32f722.ld2
-rw-r--r--ports/stm32/boards/stm32f746.ld2
-rw-r--r--ports/stm32/boards/stm32f767.ld2
-rw-r--r--ports/stm32/boards/stm32f769.ld2
-rw-r--r--ports/stm32/boards/stm32h743.ld2
-rw-r--r--ports/stm32/boards/stm32l432.ld2
-rw-r--r--ports/stm32/boards/stm32l476xe.ld2
-rw-r--r--ports/stm32/boards/stm32l476xg.ld2
-rw-r--r--ports/stm32/boards/stm32l496xg.ld2
-rw-r--r--ports/stm32/main.c4
-rw-r--r--ports/stm32/modmachine.c34
-rw-r--r--ports/stm32/powerctrl.c54
-rw-r--r--ports/stm32/powerctrl.h4
-rw-r--r--ports/stm32/stm32_it.c3
27 files changed, 91 insertions, 51 deletions
diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile
index 31597e88a..153ea4462 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 e9d6fa3c3..b6d3e08e3 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 2a474fba0..1dd4c11ed 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 362fab330..9a0bd56fb 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 5e1e9e7bd..5bcc4c727 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 50cb3c571..f4146abc6 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 78e0dc1cb..e7bd8edfe 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 13133e8c6..b6f5d3057 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 8ae5f6929..50633118e 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 c2719b834..96d6dc5fb 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 017dbbac1..0b28730de 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 35d0736ee..beeaa4df2 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 2b51c3a37..e847646b3 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 8986c68d5..ab41f0ea9 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 330dd9714..0f1de2696 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 47e992c2d..9410b9fa6 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 41bb321a3..ebc6d033d 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 0f1c2b777..69738ab8b 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 40515e75b..5558b13c8 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 330ec96e6..e4bcda1f1 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 7983fb39a..9fe83c74a 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 e1ceb5070..c33990342 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 523034e09..2dcc09ae7 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 cf615ea6a..a4ee47470 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 c3792be3e..2ad242600 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 b26cab391..6eb034228 100644
--- a/ports/stm32/powerctrl.h
+++ b/ports/stm32/powerctrl.h
@@ -28,6 +28,10 @@
#include <stdint.h>
+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 0c5263e05..a3740d59c 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