diff --git a/NANOVNA_STM32_F072/board.c b/NANOVNA_STM32_F072/board.c index bcf8f8a..f7d2f0e 100644 --- a/NANOVNA_STM32_F072/board.c +++ b/NANOVNA_STM32_F072/board.c @@ -70,6 +70,21 @@ const PALConfig pal_default_config = { * any other initialization. */ void __early_init(void) { + if ( *((unsigned long *)BOOT_FROM_SYTEM_MEMORY_MAGIC_ADDRESS) == BOOT_FROM_SYTEM_MEMORY_MAGIC ) { + // require irq + __enable_irq(); + // reset magic bytes + *((unsigned long *)BOOT_FROM_SYTEM_MEMORY_MAGIC_ADDRESS) = 0; + // remap memory. unneeded for F072? + // RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; + // SYSCFG->CFGR1 = 0x01; + // set msp for system memory + __set_MSP(SYSTEM_BOOT_MSP); + // jump to system memory + ( (void (*)(void)) (*((uint32_t *)(STM32F072xB_SYSTEM_MEMORY+4))) )(); + while (1); + } + //si5351_setup(); stm32_clock_init(); } diff --git a/NANOVNA_STM32_F072/board.h b/NANOVNA_STM32_F072/board.h index 5c9e0e4..7ab4c29 100644 --- a/NANOVNA_STM32_F072/board.h +++ b/NANOVNA_STM32_F072/board.h @@ -40,6 +40,11 @@ */ #define STM32F072xB +#define STM32F072xB_SYSTEM_MEMORY 0x1FFFC800 +#define BOOT_FROM_SYTEM_MEMORY_MAGIC_ADDRESS 0x20003FF0 +#define BOOT_FROM_SYTEM_MEMORY_MAGIC 0xDEADBEEF +#define SYSTEM_BOOT_MSP 0x20002250 + /* * IO pins assignments */ diff --git a/main.c b/main.c index a381155..b10de07 100644 --- a/main.c +++ b/main.c @@ -120,6 +120,14 @@ static void cmd_reset(BaseSequentialStream *chp, int argc, char *argv[]) (void)argc; (void)argv; + if (argc == 1) { + if (strcmp(argv[0], "dfu") == 0) { + chprintf(chp, "Performing reset to DFU mode\r\n"); + enter_dfu(); + return; + } + } + chprintf(chp, "Performing reset\r\n"); rccEnableWWDG(FALSE); diff --git a/nanovna.h b/nanovna.h index 6837ee4..4ddebe4 100644 --- a/nanovna.h +++ b/nanovna.h @@ -339,6 +339,7 @@ void handle_touch_interrupt(void); void touch_cal_exec(void); void touch_draw_test(void); +void enter_dfu(void); /* * adc.c diff --git a/ui.c b/ui.c index 010c1db..0012db5 100644 --- a/ui.c +++ b/ui.c @@ -414,6 +414,23 @@ show_version(void) touch_start_watchdog(); } +void +enter_dfu(void) +{ + adc_stop(ADC1); + + int x = 5, y = 5; + + // leave a last message + ili9341_fill(0, 0, 320, 240, 0); + ili9341_drawstring_5x7("DFU: Device Firmware Update Mode", x, y += 10, 0xffff, 0x0000); + ili9341_drawstring_5x7("To exit DFU mode, please reset device yourself.", x, y += 10, 0xffff, 0x0000); + + // see __early_init in ./NANOVNA_STM32_F072/board.c + *((unsigned long *)BOOT_FROM_SYTEM_MEMORY_MAGIC_ADDRESS) = BOOT_FROM_SYTEM_MEMORY_MAGIC; + NVIC_SystemReset(); +} + // type of menu item enum { @@ -528,6 +545,15 @@ menu_config_cb(int item) } } +static void +menu_dfu_cb(int item) +{ + switch (item) { + case 0: + enter_dfu(); + } +} + static void menu_save_cb(int item) { @@ -898,11 +924,18 @@ const menuitem_t menu_recall[] = { { MT_NONE, NULL, NULL } // sentinel }; +const menuitem_t menu_dfu[] = { + { MT_CALLBACK, "\2RESET AND\0ENTER DFU", menu_dfu_cb }, + { MT_CANCEL, S_LARROW"CANCEL", NULL }, + { MT_NONE, NULL, NULL } // sentinel +}; + const menuitem_t menu_config[] = { { MT_CALLBACK, "TOUCH CAL", menu_config_cb }, { MT_CALLBACK, "TOUCH TEST", menu_config_cb }, { MT_CALLBACK, "SAVE", menu_config_cb }, { MT_CALLBACK, "VERSION", menu_config_cb }, + { MT_SUBMENU, S_RARROW"DFU", menu_dfu }, { MT_CANCEL, S_LARROW" BACK", NULL }, { MT_NONE, NULL, NULL } // sentinel };