summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/mboot/main.c118
1 files changed, 70 insertions, 48 deletions
diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c
index b24fa7daa..caaf39468 100644
--- a/ports/stm32/mboot/main.c
+++ b/ports/stm32/mboot/main.c
@@ -416,6 +416,19 @@ void mp_hal_pin_config_speed(uint32_t port_pin, uint32_t speed) {
#define LED3 MICROPY_HW_LED4
#endif
+// For flashing states: bit 0 is "active", bit 1 is "inactive", bits 2-6 are flash rate.
+typedef enum {
+ LED0_STATE_OFF = 0,
+ LED0_STATE_ON = 1,
+ LED0_STATE_SLOW_FLASH = (20 << 2) | 1,
+ LED0_STATE_FAST_FLASH = (2 << 2) | 1,
+ LED0_STATE_SLOW_INVERTED_FLASH = (20 << 2) | 2,
+} led0_state_t;
+
+static led0_state_t led0_cur_state = LED0_STATE_OFF;
+static uint32_t led0_ms_interval = 0;
+static int led0_toggle_count = 0;
+
MP_WEAK void led_init(void) {
mp_hal_pin_output(LED0);
mp_hal_pin_output(LED1);
@@ -425,6 +438,7 @@ MP_WEAK void led_init(void) {
#ifdef LED3
mp_hal_pin_output(LED3);
#endif
+ led0_cur_state = LED0_STATE_OFF;
}
MP_WEAK void led_state(int led, int val) {
@@ -449,6 +463,24 @@ void led_state_all(unsigned int mask) {
#endif
}
+void led0_state(led0_state_t state) {
+ led0_cur_state = state;
+ if (state == LED0_STATE_OFF || state == LED0_STATE_ON) {
+ led_state(LED0, state);
+ }
+}
+
+void led0_update() {
+ if (led0_cur_state != LED0_STATE_OFF && systick_ms - led0_ms_interval > 50) {
+ uint8_t rate = (led0_cur_state >> 2) & 0x1f;
+ led0_ms_interval += 50;
+ if (++led0_toggle_count >= rate) {
+ led0_toggle_count = 0;
+ }
+ led_state(LED0, (led0_cur_state & (led0_toggle_count == 0 ? 1 : 2)));
+ }
+}
+
/******************************************************************************/
// USR BUTTON
@@ -688,68 +720,72 @@ static int spiflash_page_erase(mp_spiflash_t *spif, uint32_t addr, uint32_t n_bl
#endif
int do_page_erase(uint32_t addr, uint32_t *next_addr) {
- led_state(LED0, 1);
+ int ret = -1;
+ led0_state(LED0_STATE_ON);
#if defined(MBOOT_SPIFLASH_ADDR)
if (MBOOT_SPIFLASH_ADDR <= addr && addr < MBOOT_SPIFLASH_ADDR + MBOOT_SPIFLASH_BYTE_SIZE) {
*next_addr = addr + MBOOT_SPIFLASH_ERASE_BLOCKS_PER_PAGE * MP_SPIFLASH_ERASE_BLOCK_SIZE;
- return spiflash_page_erase(MBOOT_SPIFLASH_SPIFLASH,
+ ret = spiflash_page_erase(MBOOT_SPIFLASH_SPIFLASH,
addr - MBOOT_SPIFLASH_ADDR, MBOOT_SPIFLASH_ERASE_BLOCKS_PER_PAGE);
- }
+ } else
#endif
-
#if defined(MBOOT_SPIFLASH2_ADDR)
if (MBOOT_SPIFLASH2_ADDR <= addr && addr < MBOOT_SPIFLASH2_ADDR + MBOOT_SPIFLASH2_BYTE_SIZE) {
*next_addr = addr + MBOOT_SPIFLASH2_ERASE_BLOCKS_PER_PAGE * MP_SPIFLASH_ERASE_BLOCK_SIZE;
- return spiflash_page_erase(MBOOT_SPIFLASH2_SPIFLASH,
+ ret = spiflash_page_erase(MBOOT_SPIFLASH2_SPIFLASH,
addr - MBOOT_SPIFLASH2_ADDR, MBOOT_SPIFLASH2_ERASE_BLOCKS_PER_PAGE);
- }
+ } else
#endif
+ {
+ ret = flash_page_erase(addr, next_addr);
+ }
- return flash_page_erase(addr, next_addr);
+ led0_state((ret == 0) ? LED0_STATE_SLOW_FLASH : LED0_STATE_SLOW_INVERTED_FLASH);
+ return ret;
}
void do_read(uint32_t addr, int len, uint8_t *buf) {
+ led0_state(LED0_STATE_FAST_FLASH);
#if defined(MBOOT_SPIFLASH_ADDR)
if (MBOOT_SPIFLASH_ADDR <= addr && addr < MBOOT_SPIFLASH_ADDR + MBOOT_SPIFLASH_BYTE_SIZE) {
mp_spiflash_read(MBOOT_SPIFLASH_SPIFLASH, addr - MBOOT_SPIFLASH_ADDR, len, buf);
- return;
- }
+ } else
#endif
#if defined(MBOOT_SPIFLASH2_ADDR)
if (MBOOT_SPIFLASH2_ADDR <= addr && addr < MBOOT_SPIFLASH2_ADDR + MBOOT_SPIFLASH2_BYTE_SIZE) {
mp_spiflash_read(MBOOT_SPIFLASH2_SPIFLASH, addr - MBOOT_SPIFLASH2_ADDR, len, buf);
- return;
- }
+ } else
#endif
-
- // Other addresses, just read directly from memory
- memcpy(buf, (void*)addr, len);
+ {
+ // Other addresses, just read directly from memory
+ memcpy(buf, (void*)addr, len);
+ }
+ led0_state(LED0_STATE_SLOW_FLASH);
}
int do_write(uint32_t addr, const uint8_t *src8, size_t len) {
- static uint32_t led_tog = 0;
- led_state(LED0, (led_tog++) & 4);
-
+ int ret = -1;
+ led0_state(LED0_STATE_FAST_FLASH);
#if defined(MBOOT_SPIFLASH_ADDR)
if (MBOOT_SPIFLASH_ADDR <= addr && addr < MBOOT_SPIFLASH_ADDR + MBOOT_SPIFLASH_BYTE_SIZE) {
- return mp_spiflash_write(MBOOT_SPIFLASH_SPIFLASH, addr - MBOOT_SPIFLASH_ADDR, len, src8);
- }
+ ret = mp_spiflash_write(MBOOT_SPIFLASH_SPIFLASH, addr - MBOOT_SPIFLASH_ADDR, len, src8);
+ } else
#endif
-
#if defined(MBOOT_SPIFLASH2_ADDR)
if (MBOOT_SPIFLASH2_ADDR <= addr && addr < MBOOT_SPIFLASH2_ADDR + MBOOT_SPIFLASH2_BYTE_SIZE) {
- return mp_spiflash_write(MBOOT_SPIFLASH2_SPIFLASH, addr - MBOOT_SPIFLASH2_ADDR, len, src8);
- }
+ ret = mp_spiflash_write(MBOOT_SPIFLASH2_SPIFLASH, addr - MBOOT_SPIFLASH2_ADDR, len, src8);
+ } else
#endif
-
if (flash_is_valid_addr(addr)) {
- return flash_write(addr, src8, len);
+ ret = flash_write(addr, src8, len);
+ } else {
+ dfu_context.status = DFU_STATUS_ERROR_ADDRESS;
+ dfu_context.error = MBOOT_ERROR_STR_INVALID_ADDRESS_IDX;
}
- dfu_context.status = DFU_STATUS_ERROR_ADDRESS;
- dfu_context.error = MBOOT_ERROR_STR_INVALID_ADDRESS_IDX;
- return -1;
+ led0_state((ret == 0) ? LED0_STATE_SLOW_FLASH : LED0_STATE_SLOW_INVERTED_FLASH);
+ return ret;
}
/******************************************************************************/
@@ -1518,11 +1554,8 @@ enter_bootloader:
#endif
led_state_all(0);
+ led0_state(LED0_STATE_SLOW_FLASH);
- #if USE_USB_POLLING
- uint32_t ss = systick_ms;
- int ss2 = -1;
- #endif
#if MBOOT_USB_RESET_ON_DISCONNECT
bool has_connected = false;
#endif
@@ -1541,23 +1574,8 @@ enter_bootloader:
if (!pyb_usbdd.tx_pending) {
dfu_process();
}
- #endif
-
- #if USE_USB_POLLING
- //__WFI(); // slows it down way too much; might work with 10x faster systick
- if (systick_ms - ss > 50) {
- ss += 50;
- ss2 = (ss2 + 1) % 20;
- switch (ss2) {
- case 0: led_state(LED0, 1); break;
- case 1: led_state(LED0, 0); break;
- }
- }
- #else
- led_state(LED0, 1);
- mp_hal_delay_ms(50);
- led_state(LED0, 0);
- mp_hal_delay_ms(950);
+ #else // !USE_USB_POLLING
+ __WFI();
#endif
#if MBOOT_USB_RESET_ON_DISCONNECT
@@ -1608,6 +1626,10 @@ void SysTick_Handler(void) {
// the COUNTFLAG bit, which makes the logic in mp_hal_ticks_us
// work properly.
SysTick->CTRL;
+
+ // Update the LED0 state from here to ensure it's consistent regardless of
+ // other processing going on in interrupts or main.
+ led0_update();
}
#if defined(MBOOT_I2C_SCL)