diff options
-rw-r--r-- | ports/stm32/mboot/main.c | 118 |
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) |