summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/mboot/dfu.h2
-rw-r--r--ports/stm32/mboot/main.c33
2 files changed, 18 insertions, 17 deletions
diff --git a/ports/stm32/mboot/dfu.h b/ports/stm32/mboot/dfu.h
index 73db3545d..e867a3e22 100644
--- a/ports/stm32/mboot/dfu.h
+++ b/ports/stm32/mboot/dfu.h
@@ -26,6 +26,7 @@
#ifndef MICROPY_INCLUDED_STM32_MBOOT_DFU_H
#define MICROPY_INCLUDED_STM32_MBOOT_DFU_H
+#include <stdbool.h>
#include <stdint.h>
// DFU spec: https://www.usb.org/sites/default/files/DFU_1.1.pdf
@@ -106,6 +107,7 @@ typedef struct _dfu_state_t {
dfu_cmd_t cmd;
dfu_status_t status;
uint8_t error;
+ bool leave_dfu;
uint16_t wBlockNum;
uint16_t wLength;
uint32_t addr;
diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c
index 3a0242a8d..c1e1d59d2 100644
--- a/ports/stm32/mboot/main.c
+++ b/ports/stm32/mboot/main.c
@@ -106,8 +106,6 @@ static volatile uint32_t systick_ms;
// Global dfu state
dfu_context_t dfu_context SECTION_NOZERO_BSS;
-static void do_reset(void);
-
uint32_t get_le32(const uint8_t *b) {
return b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24;
}
@@ -771,7 +769,7 @@ void i2c_slave_process_rx_end(i2c_slave_t *i2c) {
memcpy(buf + 12 + sizeof(MICROPY_HW_MCU_NAME), MICROPY_HW_BOARD_NAME, sizeof(MICROPY_HW_BOARD_NAME) - 1);
len = 12 + sizeof(MICROPY_HW_MCU_NAME) + sizeof(MICROPY_HW_BOARD_NAME) - 1;
} else if (buf[0] == I2C_CMD_RESET && len == 0) {
- do_reset();
+ dfu_context.leave_dfu = true;
} else if (buf[0] == I2C_CMD_GETLAYOUT && len == 0) {
len = strlen(FLASH_LAYOUT_STR);
memcpy(buf, FLASH_LAYOUT_STR, len);
@@ -864,6 +862,7 @@ static void dfu_init(void) {
dfu_context.cmd = DFU_CMD_NONE;
dfu_context.status = DFU_STATUS_OK;
dfu_context.error = 0;
+ dfu_context.leave_dfu = false;
dfu_context.addr = 0x08000000;
}
@@ -931,7 +930,8 @@ static void dfu_handle_rx(int cmd, int arg, int len, const void *buf) {
static void dfu_process(void) {
if (dfu_context.state == DFU_STATE_MANIFEST) {
- do_reset();
+ // Set a flag to leave DFU mode from the main thread (here we are in an IRQ handler).
+ dfu_context.leave_dfu = true;
}
if (dfu_context.state == DFU_STATE_BUSY) {
@@ -1412,17 +1412,6 @@ static void leave_bootloader(void) {
NVIC_SystemReset();
}
-static void do_reset(void) {
- led_state_all(0);
- mp_hal_delay_ms(50);
- pyb_usbdd_shutdown();
- #if defined(MBOOT_I2C_SCL)
- i2c_slave_shutdown(MBOOT_I2Cx, I2Cx_EV_IRQn);
- #endif
- mp_hal_delay_ms(50);
- leave_bootloader();
-}
-
extern PCD_HandleTypeDef pcd_fs_handle;
extern PCD_HandleTypeDef pcd_hs_handle;
@@ -1561,7 +1550,7 @@ enter_bootloader:
#if MBOOT_USB_RESET_ON_DISCONNECT
bool has_connected = false;
#endif
- for (;;) {
+ while (!dfu_context.leave_dfu) {
#if USE_USB_POLLING
#if MBOOT_USB_AUTODETECT_PORT || MICROPY_HW_USB_MAIN_DEV == USB_PHY_FS_ID
if (USB_OTG_FS->GINTSTS & USB_OTG_FS->GINTMSK) {
@@ -1585,10 +1574,20 @@ enter_bootloader:
has_connected = true;
}
if (has_connected && pyb_usbdd.hUSBDDevice.dev_state == USBD_STATE_SUSPENDED) {
- do_reset();
+ break;
}
#endif
}
+
+ // Shutdown and leave the bootloader.
+ led_state_all(0);
+ mp_hal_delay_ms(50);
+ pyb_usbdd_shutdown();
+ #if defined(MBOOT_I2C_SCL)
+ i2c_slave_shutdown(MBOOT_I2Cx, I2Cx_EV_IRQn);
+ #endif
+ mp_hal_delay_ms(50);
+ leave_bootloader();
}
void NMI_Handler(void) {