[native] Make the native bootloader bit more flashy.

This change has also a practical reason. When flashing and testing the
hardware this change makes it easier to make sure all the LEDs work. Now
when the DFU bootloader is idle it is scanning the LEDs making it easy
to see if one of them has an issue.

In addition to that, the bootloader now indicates when there is data
being flashed using the DFU interface. In cases when one has more than
one device connected and accidently starts flashing a wrong device this
is very useful feature to have.
This commit is contained in:
Piotr Esden-Tempski 2016-02-14 23:38:26 -08:00
parent ac9d87635c
commit c0c8bade6f
7 changed files with 73 additions and 9 deletions

View File

@ -90,9 +90,12 @@
#define LED_PORT GPIOB #define LED_PORT GPIOB
#define LED_PORT_UART GPIOB #define LED_PORT_UART GPIOB
#define LED_UART GPIO2 #define LED_0 GPIO2
#define LED_IDLE_RUN GPIO10 #define LED_1 GPIO10
#define LED_ERROR GPIO11 #define LED_2 GPIO11
#define LED_UART LED_2
#define LED_IDLE_RUN LED_1
#define LED_ERROR LED_0
#define TMS_SET_MODE() \ #define TMS_SET_MODE() \
gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_50_MHZ, \ gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_50_MHZ, \

View File

@ -24,8 +24,10 @@
#include <libopencm3/cm3/scb.h> #include <libopencm3/cm3/scb.h>
#include "usbdfu.h" #include "usbdfu.h"
#include "platform.h"
uint32_t app_address = 0x08002000; uint32_t app_address = 0x08002000;
int dfu_activity_counter = 0;
void dfu_detach(void) void dfu_detach(void)
{ {
@ -46,6 +48,7 @@ int main(void)
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8);
systick_set_reload(900000); systick_set_reload(900000);
/* Configure USB related clocks and pins. */
rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_GPIOA);
rcc_periph_clock_enable(RCC_USB); rcc_periph_clock_enable(RCC_USB);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO8); gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO8);
@ -53,13 +56,13 @@ int main(void)
systick_interrupt_enable(); systick_interrupt_enable();
systick_counter_enable(); systick_counter_enable();
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_2_MHZ, /* Configure the LED pins. */
GPIO_CNF_OUTPUT_PUSHPULL, GPIO11); gpio_set_mode(LED_PORT, GPIO_MODE_OUTPUT_2_MHZ,
gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_OUTPUT_PUSHPULL, LED_0 | LED_1 | LED_2);
GPIO_CNF_INPUT_FLOAT, GPIO2 | GPIO10);
dfu_init(&stm32f103_usb_driver, DFU_MODE); dfu_init(&stm32f103_usb_driver, DFU_MODE);
/* Configure the USB pull up pin. */
gpio_set(GPIOA, GPIO8); gpio_set(GPIOA, GPIO8);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO8); GPIO_CNF_OUTPUT_PUSHPULL, GPIO8);
@ -67,8 +70,50 @@ int main(void)
dfu_main(); dfu_main();
} }
void sys_tick_handler(void) void dfu_event(void)
{ {
gpio_toggle(GPIOB, GPIO11); /* LED2 on/off */ /* If the counter was at 0 before we should reset LED status. */
if (dfu_activity_counter == 0) {
gpio_clear(LED_PORT, LED_0 | LED_1 | LED_2);
}
/* Prevent the sys_tick_handler from blinking leds for a bit. */
dfu_activity_counter = 10;
/* Toggle the DFU activity LED. */
gpio_toggle(LED_PORT, LED_1);
}
void sys_tick_handler(void)
{
static int count = 0;
static bool reset = true;
/* Run the LED show only if there is no DFU activity. */
if (dfu_activity_counter != 0) {
dfu_activity_counter--;
reset = true;
} else {
if (reset) {
gpio_clear(LED_PORT, LED_0 | LED_1 | LED_2);
count = 0;
reset = false;
}
switch (count) {
case 0:
gpio_toggle(LED_PORT, LED_2); /* LED2 on/off */
count++;
break;
case 1:
gpio_toggle(LED_PORT, LED_1); /* LED1 on/off */
count++;
break;
case 2:
gpio_toggle(LED_PORT, LED_0); /* LED0 on/off */
count=0;
break;
}
}
} }

View File

@ -107,6 +107,10 @@ int main(void)
dfu_main(); dfu_main();
} }
void dfu_event(void)
{
}
void sys_tick_handler(void) void sys_tick_handler(void)
{ {
if (rev == 0) { if (rev == 0) {

View File

@ -125,6 +125,10 @@ int main(void)
dfu_main(); dfu_main();
} }
void dfu_event(void)
{
}
void sys_tick_handler(void) void sys_tick_handler(void)
{ {
if (rev == 0) { if (rev == 0) {

View File

@ -49,6 +49,9 @@ void dfu_flash_program_buffer(uint32_t baseaddr, void *buf, int len)
for(int i = 0; i < len; i += 2) for(int i = 0; i < len; i += 2)
flash_program_half_word(baseaddr + i, flash_program_half_word(baseaddr + i,
*(uint16_t*)(buf+i)); *(uint16_t*)(buf+i));
/* Call the platform specific dfu event callback. */
dfu_event();
} }
uint32_t dfu_poll_timeout(uint8_t cmd, uint32_t addr, uint16_t blocknum) uint32_t dfu_poll_timeout(uint8_t cmd, uint32_t addr, uint16_t blocknum)

View File

@ -39,6 +39,7 @@ void dfu_flash_program_buffer(uint32_t baseaddr, void *buf, int len);
uint32_t dfu_poll_timeout(uint8_t cmd, uint32_t addr, uint16_t blocknum); uint32_t dfu_poll_timeout(uint8_t cmd, uint32_t addr, uint16_t blocknum);
void dfu_protect(dfu_mode_t mode); void dfu_protect(dfu_mode_t mode);
void dfu_jump_app_if_valid(void); void dfu_jump_app_if_valid(void);
void dfu_event(void);
/* Platform specific function */ /* Platform specific function */
void dfu_detach(void); void dfu_detach(void);

View File

@ -88,6 +88,10 @@ int main(void)
dfu_main(); dfu_main();
} }
void dfu_event(void)
{
}
void sys_tick_handler(void) void sys_tick_handler(void)
{ {
gpio_toggle(GPIOA, GPIO8); gpio_toggle(GPIOA, GPIO8);