stm32: Move dfu reboot logic to new dfu_reboot.c file
Move the stm32 DFU reboot logic to a new dfu_reboot.c file. This simplifies the per-chip code. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
b6cd77f6e3
commit
4af8786587
|
@ -220,6 +220,15 @@ config STM32F103GD_DISABLE_SWD
|
|||
and PA14 pins from being available. Selecting this option
|
||||
disables SWD at startup and thus makes these pins available.
|
||||
|
||||
config STM32_DFU_ROM_ADDRESS
|
||||
hex
|
||||
default 0 if !USB
|
||||
default 0x1fffc400 if MACH_STM32F042
|
||||
default 0x1fffc800 if MACH_STM32F072
|
||||
default 0x1fff0000 if MACH_STM32F4 || MACH_STM32G0 || MACH_STM32G4 || MACH_STM32L4
|
||||
default 0x1ff09800 if MACH_STM32H7
|
||||
default 0
|
||||
|
||||
|
||||
######################################################################
|
||||
# Bootloader
|
||||
|
|
|
@ -31,7 +31,8 @@ CFLAGS_klipper.elf += -T $(OUT)src/generic/armcm_link.ld
|
|||
$(OUT)klipper.elf: $(OUT)src/generic/armcm_link.ld
|
||||
|
||||
# Add source files
|
||||
src-y += stm32/watchdog.c stm32/gpio.c stm32/clockline.c generic/crc16_ccitt.c
|
||||
src-y += stm32/watchdog.c stm32/gpio.c stm32/clockline.c stm32/dfu_reboot.c
|
||||
src-y += generic/crc16_ccitt.c
|
||||
src-y += generic/armcm_boot.c generic/armcm_irq.c generic/armcm_reset.c
|
||||
src-$(CONFIG_MACH_STM32F0) += ../lib/stm32f0/system_stm32f0xx.c
|
||||
src-$(CONFIG_MACH_STM32F0) += generic/timer_irq.c stm32/stm32f0_timer.c
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
// Reboot into stm32 ROM dfu bootloader
|
||||
//
|
||||
// Copyright (C) 2019-2022 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
#include "internal.h" // NVIC_SystemReset
|
||||
#include "board/irq.h" // irq_disable
|
||||
|
||||
// Many stm32 chips have a USB capable "DFU bootloader" in their ROM.
|
||||
// In order to invoke that bootloader it is necessary to reset the
|
||||
// chip and jump to a chip specific hardware address.
|
||||
//
|
||||
// To reset the chip, the dfu_reboot() code sets a flag in memory (at
|
||||
// an arbitrary position that is unlikely to be overwritten during a
|
||||
// chip reset), and resets the chip. If dfu_reboot_check() sees that
|
||||
// flag on the next boot it will perform a code jump to the ROM
|
||||
// address.
|
||||
|
||||
// Location of ram address to set internal flag
|
||||
#if CONFIG_MACH_STM32H7
|
||||
#define USB_BOOT_FLAG_ADDR (0x24000000 + 0x8000) // Place flag in "AXI SRAM"
|
||||
#else
|
||||
#define USB_BOOT_FLAG_ADDR (CONFIG_RAM_START + CONFIG_RAM_SIZE - 1024)
|
||||
#endif
|
||||
|
||||
// Signature to set in memory to flag that a dfu reboot is requested
|
||||
#define USB_BOOT_FLAG 0x55534220424f4f54 // "USB BOOT"
|
||||
|
||||
// Flag that bootloader is desired and reboot
|
||||
void
|
||||
dfu_reboot(void)
|
||||
{
|
||||
if (!CONFIG_STM32_DFU_ROM_ADDRESS)
|
||||
return;
|
||||
irq_disable();
|
||||
uint64_t *bflag = (void*)USB_BOOT_FLAG_ADDR;
|
||||
*bflag = USB_BOOT_FLAG;
|
||||
#if CONFIG_MACH_STM32H7
|
||||
SCB_CleanDCache_by_Addr((void*)bflag, sizeof(*bflag));
|
||||
#endif
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
// Check if rebooting into system DFU Bootloader
|
||||
void
|
||||
dfu_reboot_check(void)
|
||||
{
|
||||
if (!CONFIG_STM32_DFU_ROM_ADDRESS)
|
||||
return;
|
||||
if (*(uint64_t*)USB_BOOT_FLAG_ADDR != USB_BOOT_FLAG)
|
||||
return;
|
||||
*(uint64_t*)USB_BOOT_FLAG_ADDR = 0;
|
||||
uint32_t *sysbase = (uint32_t*)CONFIG_STM32_DFU_ROM_ADDRESS;
|
||||
asm volatile("mov sp, %0\n bx %1"
|
||||
: : "r"(sysbase[0]), "r"(sysbase[1]));
|
||||
}
|
|
@ -40,6 +40,10 @@ void gpio_peripheral(uint32_t gpio, uint32_t mode, int pullup);
|
|||
void enable_pclock(uint32_t periph_base);
|
||||
int is_enabled_pclock(uint32_t periph_base);
|
||||
|
||||
// dfu_reboot.c
|
||||
void dfu_reboot(void);
|
||||
void dfu_reboot_check(void);
|
||||
|
||||
// stm32??.c
|
||||
struct cline { volatile uint32_t *en, *rst; uint32_t bit; };
|
||||
struct cline lookup_clock_line(uint32_t periph_base);
|
||||
|
|
|
@ -134,39 +134,12 @@ hsi14_setup(void)
|
|||
* Bootloader
|
||||
****************************************************************/
|
||||
|
||||
#define USB_BOOT_FLAG_ADDR (CONFIG_RAM_START + CONFIG_RAM_SIZE - 1024)
|
||||
#define USB_BOOT_FLAG 0x55534220424f4f54 // "USB BOOT"
|
||||
|
||||
// Flag that bootloader is desired and reboot
|
||||
static void
|
||||
usb_reboot_for_dfu_bootloader(void)
|
||||
{
|
||||
irq_disable();
|
||||
*(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 || !CONFIG_MACH_STM32F0x2
|
||||
|| *(uint64_t*)USB_BOOT_FLAG_ADDR != USB_BOOT_FLAG)
|
||||
return;
|
||||
*(uint64_t*)USB_BOOT_FLAG_ADDR = 0;
|
||||
uint32_t *sysbase = (uint32_t*)0x1fffc400;
|
||||
if (CONFIG_MACH_STM32F072)
|
||||
sysbase = (uint32_t*)0x1fffc800;
|
||||
asm volatile("mov sp, %0\n bx %1"
|
||||
: : "r"(sysbase[0]), "r"(sysbase[1]));
|
||||
}
|
||||
|
||||
// Handle reboot requests
|
||||
void
|
||||
bootloader_request(void)
|
||||
{
|
||||
try_request_canboot();
|
||||
usb_reboot_for_dfu_bootloader();
|
||||
dfu_reboot();
|
||||
}
|
||||
|
||||
|
||||
|
@ -193,7 +166,7 @@ enable_ram_vectortable(void)
|
|||
void
|
||||
armcm_main(void)
|
||||
{
|
||||
check_usb_dfu_bootloader();
|
||||
dfu_reboot_check();
|
||||
SystemInit();
|
||||
|
||||
enable_pclock(SYSCFG_BASE);
|
||||
|
|
|
@ -204,30 +204,6 @@ usb_hid_bootloader(void)
|
|||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
#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();
|
||||
*(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 reboot requests
|
||||
void
|
||||
bootloader_request(void)
|
||||
|
@ -235,7 +211,7 @@ bootloader_request(void)
|
|||
try_request_canboot();
|
||||
if (CONFIG_STM32_FLASH_START_4000)
|
||||
usb_hid_bootloader();
|
||||
usb_reboot_for_dfu_bootloader();
|
||||
dfu_reboot();
|
||||
}
|
||||
|
||||
|
||||
|
@ -247,7 +223,7 @@ bootloader_request(void)
|
|||
void
|
||||
armcm_main(void)
|
||||
{
|
||||
check_usb_dfu_bootloader();
|
||||
dfu_reboot_check();
|
||||
|
||||
// Run SystemInit() and then restore VTOR
|
||||
SystemInit();
|
||||
|
|
|
@ -128,36 +128,12 @@ clock_setup(void)
|
|||
* Bootloader
|
||||
****************************************************************/
|
||||
|
||||
#define USB_BOOT_FLAG_ADDR (CONFIG_RAM_START + CONFIG_RAM_SIZE - 1024)
|
||||
#define USB_BOOT_FLAG 0x55534220424f4f54 // "USB BOOT"
|
||||
|
||||
// Flag that bootloader is desired and reboot
|
||||
static void
|
||||
usb_reboot_for_dfu_bootloader(void)
|
||||
{
|
||||
irq_disable();
|
||||
*(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)
|
||||
{
|
||||
try_request_canboot();
|
||||
usb_reboot_for_dfu_bootloader();
|
||||
dfu_reboot();
|
||||
}
|
||||
|
||||
|
||||
|
@ -185,7 +161,7 @@ armcm_main(void)
|
|||
RCC->APBENR1 = 0x00000000;
|
||||
RCC->APBENR2 = 0x00000000;
|
||||
|
||||
check_usb_dfu_bootloader();
|
||||
dfu_reboot_check();
|
||||
|
||||
// Set flash latency, cache and prefetch; use reset value as base
|
||||
uint32_t acr = 0x00040600;
|
||||
|
|
|
@ -139,36 +139,11 @@ 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();
|
||||
dfu_reboot();
|
||||
}
|
||||
|
||||
|
||||
|
@ -180,7 +155,7 @@ bootloader_request(void)
|
|||
void
|
||||
armcm_main(void)
|
||||
{
|
||||
check_usb_dfu_bootloader();
|
||||
dfu_reboot_check();
|
||||
|
||||
// Run SystemInit() and then restore VTOR
|
||||
SystemInit();
|
||||
|
|
|
@ -208,38 +208,12 @@ clock_setup(void)
|
|||
* Bootloader
|
||||
****************************************************************/
|
||||
|
||||
#define USB_BOOT_FLAG_ADDR (0x24000000 + 0x8000) // Place flag in "AXI SRAM"
|
||||
#define USB_BOOT_FLAG 0x55534220424f4f54 // "USB BOOT"
|
||||
|
||||
// Flag that bootloader is desired and reboot
|
||||
static void
|
||||
usb_reboot_for_dfu_bootloader(void)
|
||||
{
|
||||
irq_disable();
|
||||
uint64_t *bflag = (void*)USB_BOOT_FLAG_ADDR;
|
||||
*bflag = USB_BOOT_FLAG;
|
||||
SCB_CleanDCache_by_Addr((void*)bflag, sizeof(*bflag));
|
||||
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*)0x1FF09800;
|
||||
asm volatile("mov sp, %0\n bx %1"
|
||||
: : "r"(sysbase[0]), "r"(sysbase[1]));
|
||||
}
|
||||
|
||||
// Handle reboot requests
|
||||
void
|
||||
bootloader_request(void)
|
||||
{
|
||||
try_request_canboot();
|
||||
usb_reboot_for_dfu_bootloader();
|
||||
dfu_reboot();
|
||||
}
|
||||
|
||||
|
||||
|
@ -259,7 +233,7 @@ armcm_main(void)
|
|||
RCC->D3CCIPR = 0x00000000;
|
||||
SCB->VTOR = (uint32_t)VectorTable;
|
||||
|
||||
check_usb_dfu_bootloader();
|
||||
dfu_reboot_check();
|
||||
|
||||
clock_setup();
|
||||
|
||||
|
|
|
@ -139,36 +139,11 @@ 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();
|
||||
dfu_reboot();
|
||||
}
|
||||
|
||||
|
||||
|
@ -180,7 +155,7 @@ bootloader_request(void)
|
|||
void
|
||||
armcm_main(void)
|
||||
{
|
||||
check_usb_dfu_bootloader();
|
||||
dfu_reboot_check();
|
||||
|
||||
// Run SystemInit() and then restore VTOR
|
||||
SystemInit();
|
||||
|
|
Loading…
Reference in New Issue