Skip to content

Commit

Permalink
stm32: Separate out USB DFU reboot logic in stm32g4.c
Browse files Browse the repository at this point in the history
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
  • Loading branch information
KevinOConnor committed Dec 19, 2022
1 parent 2a25733 commit be74c72
Showing 1 changed file with 45 additions and 21 deletions.
66 changes: 45 additions & 21 deletions src/stm32/stm32g4.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include "autoconf.h" // CONFIG_CLOCK_REF_FREQ
#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
#include "sched.h" // sched_main
Expand Down Expand Up @@ -66,19 +65,6 @@ gpio_clock_enable(GPIO_TypeDef *regs)
RCC->AHB2ENR;
}

#define USB_BOOT_FLAG_ADDR (CONFIG_RAM_START + CONFIG_RAM_SIZE - 4096)
#define USB_BOOT_FLAG 0x55534220424f4f54 // "USB BOOT"

// Handle USB reboot requests
void
bootloader_request(void)
{
irq_disable();
// System DFU Bootloader
*(uint64_t*)USB_BOOT_FLAG_ADDR = USB_BOOT_FLAG;
NVIC_SystemReset();
}

#if !CONFIG_STM32_CLOCK_REF_INTERNAL
DECL_CONSTANT_STR("RESERVE_PINS_crystal", "PF0,PF1");
#endif
Expand Down Expand Up @@ -148,15 +134,53 @@ clock_setup(void)
;
}


/****************************************************************
* Bootloader
****************************************************************/

#define USB_BOOT_FLAG_ADDR (CONFIG_RAM_START + CONFIG_RAM_SIZE - 4096)
#define USB_BOOT_FLAG 0x55534220424f4f54 // "USB BOOT"

// Flag that bootloader is desired and reboot
static void
usb_reboot_for_dfu_bootloader(void)
{
irq_disable();
// System DFU Bootloader
*(uint64_t*)USB_BOOT_FLAG_ADDR = USB_BOOT_FLAG;
NVIC_SystemReset();
}

// Check if rebooting into system DFU Bootloader
static void
check_usb_dfu_bootloader(void)
{
if (!CONFIG_USB || *(uint64_t*)USB_BOOT_FLAG_ADDR != USB_BOOT_FLAG)
return;
*(uint64_t*)USB_BOOT_FLAG_ADDR = 0;
uint32_t *sysbase = (uint32_t*)0x1fff0000;
asm volatile("mov sp, %0\n bx %1"
: : "r"(sysbase[0]), "r"(sysbase[1]));
}

// Handle USB reboot requests
void
bootloader_request(void)
{
usb_reboot_for_dfu_bootloader();
}


/****************************************************************
* Startup
****************************************************************/

// Main entry point - called from armcm_boot.c:ResetHandler()
void
armcm_main(void) {
if (CONFIG_USBSERIAL && *(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, %0\n bx %1"
: : "r"(sysbase[0]), "r"(sysbase[1]));
}
armcm_main(void)
{
check_usb_dfu_bootloader();

// Run SystemInit() and then restore VTOR
SystemInit();
Expand Down

0 comments on commit be74c72

Please sign in to comment.