diff --git a/scripts/flash_usb.py b/scripts/flash_usb.py index 4fc72716..bb1afcce 100755 --- a/scripts/flash_usb.py +++ b/scripts/flash_usb.py @@ -189,7 +189,11 @@ def flash_stm32f1(options, binfile): sys.exit(-1) STM32F4_HELP = """ -USB flash is not supported on the STM32F4! +Failed to flash to %s: %s + +If the device is already in bootloader mode it can be flashed with the +following command: + make flash FLASH_DEVICE=0483:df11 If attempting to flash via 3.3V serial, then use: make serialflash FLASH_DEVICE=%s @@ -197,8 +201,13 @@ If attempting to flash via 3.3V serial, then use: """ def flash_stm32f4(options, binfile): - sys.stderr.write(STM32F4_HELP % (options.device,)) - sys.exit(-1) + try: + flash_dfuutil(options.device, binfile, + ["-R", "-a", "0", "-s", str(options.start)], options.sudo) + except error as e: + sys.stderr.write(STM32F4_HELP % ( + options.device, str(e), options.device)) + sys.exit(-1) MCUTYPES = { 'atsam3': flash_atsam3, 'atsam4': flash_atsam4, 'atsamd': flash_atsamd, @@ -219,6 +228,8 @@ def main(): help="serial port device") opts.add_option("-o", "--offset", type="string", dest="offset", help="flash offset") + opts.add_option("-s", "--start", type="int", dest="start", + help="start address in flash") opts.add_option("--no-sudo", action="store_false", dest="sudo", default=True, help="do not run sudo") options, args = opts.parse_args() diff --git a/src/stm32/Makefile b/src/stm32/Makefile index c607328b..3ff257a7 100644 --- a/src/stm32/Makefile +++ b/src/stm32/Makefile @@ -54,7 +54,7 @@ FLASH_TYPE-$(CONFIG_MACH_STM32F4) := stm32f4 flash: $(OUT)klipper.bin @echo " Flashing $< to $(FLASH_DEVICE)" - $(Q)$(PYTHON) ./scripts/flash_usb.py -t $(FLASH_TYPE-y) -d "$(FLASH_DEVICE)" $(if $(NOSUDO),--no-sudo) $(OUT)klipper.bin + $(Q)$(PYTHON) ./scripts/flash_usb.py -t $(FLASH_TYPE-y) -d "$(FLASH_DEVICE)" -s "$(CONFIG_FLASH_START)" $(if $(NOSUDO),--no-sudo) $(OUT)klipper.bin serialflash: $(OUT)klipper.bin @echo " Flashing $< to $(FLASH_DEVICE) via stm32flash" diff --git a/src/stm32/stm32f4.c b/src/stm32/stm32f4.c index e1f22b2f..92c40b22 100644 --- a/src/stm32/stm32f4.c +++ b/src/stm32/stm32f4.c @@ -6,6 +6,7 @@ #include "autoconf.h" // CONFIG_CLOCK_REF_8M #include "board/armcm_boot.h" // VectorTable +#include "board/irq.h" // irq_disable #include "board/usb_cdc.h" // usb_request_bootloader #include "command.h" // DECL_CONSTANT_STR #include "internal.h" // enable_pclock @@ -88,10 +89,16 @@ gpio_peripheral(uint32_t gpio, uint32_t mode, int pullup) regs->OSPEEDR = (regs->OSPEEDR & ~m_msk) | (0x02 << m_shift); } +#define USB_BOOT_FLAG_ADDR (CONFIG_RAM_START + CONFIG_RAM_SIZE - 4096) +#define USB_BOOT_FLAG 0x55534220424f4f54 // "USB BOOT" + // Handle USB reboot requests void usb_request_bootloader(void) { + irq_disable(); + *(uint64_t*)USB_BOOT_FLAG_ADDR = USB_BOOT_FLAG; + NVIC_SystemReset(); } #if CONFIG_CLOCK_REF_8M @@ -202,6 +209,13 @@ clock_setup(void) void armcm_main(void) { + if (*(uint64_t*)USB_BOOT_FLAG_ADDR == USB_BOOT_FLAG) { + *(uint64_t*)USB_BOOT_FLAG_ADDR = 0; + uint32_t *sysbase = (uint32_t*)0x1fff0000; + asm volatile("mov sp, %r0\n bx %r1" + : : "r"(sysbase[0]), "r"(sysbase[1])); + } + // Run SystemInit() and then restore VTOR SystemInit(); SCB->VTOR = (uint32_t)VectorTable;