diff --git a/application.c b/application.c index 3a449de..61248ba 100644 --- a/application.c +++ b/application.c @@ -133,7 +133,12 @@ static void command_reset(void* argument); /** switch to DFU bootloader * @param[in] argument no argument required */ -static void command_bootloader(void* argument); +static void command_bootloader_dfu(void* argument); + +/** switch to system memory / embedded USART bootloader + * @param[in] argument no argument required + */ +static void command_bootloader_embedded(void* argument); /** list of all supported commands */ static const struct menu_command_t menu_commands[] = { @@ -185,7 +190,15 @@ static const struct menu_command_t menu_commands[] = { .command_description = "reboot into DFU bootloader", .argument = MENU_ARGUMENT_NONE, .argument_description = NULL, - .command_handler = &command_bootloader, + .command_handler = &command_bootloader_dfu, + }, + { + .shortcut = 'B', + .name = "embedded", + .command_description = "boot embedded USART bootloader", + .argument = MENU_ARGUMENT_NONE, + .argument_description = NULL, + .command_handler = &command_bootloader_embedded, }, }; @@ -479,7 +492,7 @@ static void command_reset(void* argument) while (true); // wait for the reset to happen } -static void command_bootloader(void* argument) +static void command_bootloader_dfu(void* argument) { (void)argument; // we won't use the argument // set DFU magic to specific RAM location @@ -491,6 +504,21 @@ static void command_bootloader(void* argument) while (true); // wait for the reset to happen } +static void command_bootloader_embedded(void* argument) +{ + (void)argument; // we won't use the argument + // set watchdog to exit system memory after some time + iwdg_set_period_ms(25000); // set independent watchdog period (26214.4 ms if the max timeout) + iwdg_start(); // start independent watchdog + iwdg_reset(); // restart timer + // start system memory + const uint32_t address = 0x1FFFF000; // system memory address + SCB_VTOR = (volatile uint32_t)(address); // set vector table to application vector table (store at the beginning of the application) + __asm__ volatile ("MSR msp,%0" : :"r"(*(uint32_t*)address)); // set stack pointer to address provided in the beginning of the application (loaded into a register first) + (*(void(**)(void))((uint32_t)address + 4))(); // start system memory (by jumping to the reset function which address is stored as second entry of the vector table) + while (true); // this should not be reached +} + /** process user command * @param[in] str user command string (\0 ended) */