stm32/mboot: Update LED0 state from systick handler.
Updating the LED0 state from systick handler ensures LED0 is always consistent with its flash rate regardless of other processing going on in either interrupts or main. This improves the visible stability of the bootloader, rather than LED0 flashing somewhat randomly at times. This commit also changes the LED0 flash rate depending on the current state of DFU, giving slightly more visual feedback on what the device is doing.
This commit is contained in:
parent
38ccb4c643
commit
9dd470b768
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue