aboutsummaryrefslogtreecommitdiffstats
path: root/src/stm32
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2022-12-15 11:23:28 -0500
committerKevin O'Connor <kevin@koconnor.net>2022-12-18 19:50:08 -0500
commit4af87865875755b421873e7e4e43ece958ab00ee (patch)
treefcef44139275082394abfc17257011a5da90566b /src/stm32
parentb6cd77f6e377060d2625126ffef9b2842e1cc25b (diff)
downloadkutter-4af87865875755b421873e7e4e43ece958ab00ee.tar.gz
kutter-4af87865875755b421873e7e4e43ece958ab00ee.tar.xz
kutter-4af87865875755b421873e7e4e43ece958ab00ee.zip
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>
Diffstat (limited to 'src/stm32')
-rw-r--r--src/stm32/Kconfig9
-rw-r--r--src/stm32/Makefile3
-rw-r--r--src/stm32/dfu_reboot.c57
-rw-r--r--src/stm32/internal.h4
-rw-r--r--src/stm32/stm32f0.c31
-rw-r--r--src/stm32/stm32f4.c28
-rw-r--r--src/stm32/stm32g0.c28
-rw-r--r--src/stm32/stm32g4.c29
-rw-r--r--src/stm32/stm32h7.c30
-rw-r--r--src/stm32/stm32l4.c29
10 files changed, 84 insertions, 164 deletions
diff --git a/src/stm32/Kconfig b/src/stm32/Kconfig
index 13cf8d84..dac884a0 100644
--- a/src/stm32/Kconfig
+++ b/src/stm32/Kconfig
@@ -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
diff --git a/src/stm32/Makefile b/src/stm32/Makefile
index d9efd085..15ea4e2b 100644
--- a/src/stm32/Makefile
+++ b/src/stm32/Makefile
@@ -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
diff --git a/src/stm32/dfu_reboot.c b/src/stm32/dfu_reboot.c
new file mode 100644
index 00000000..04952a48
--- /dev/null
+++ b/src/stm32/dfu_reboot.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]));
+}
diff --git a/src/stm32/internal.h b/src/stm32/internal.h
index 2ba7abe2..b5971ed7 100644
--- a/src/stm32/internal.h
+++ b/src/stm32/internal.h
@@ -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);
diff --git a/src/stm32/stm32f0.c b/src/stm32/stm32f0.c
index e63f1b5b..72fc1645 100644
--- a/src/stm32/stm32f0.c
+++ b/src/stm32/stm32f0.c
@@ -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);
diff --git a/src/stm32/stm32f4.c b/src/stm32/stm32f4.c
index 4f1dc084..a2060d76 100644
--- a/src/stm32/stm32f4.c
+++ b/src/stm32/stm32f4.c
@@ -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();
diff --git a/src/stm32/stm32g0.c b/src/stm32/stm32g0.c
index f42ac777..41f7f6f2 100644
--- a/src/stm32/stm32g0.c
+++ b/src/stm32/stm32g0.c
@@ -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;
diff --git a/src/stm32/stm32g4.c b/src/stm32/stm32g4.c
index a0dd32c0..c3cf0969 100644
--- a/src/stm32/stm32g4.c
+++ b/src/stm32/stm32g4.c
@@ -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();
diff --git a/src/stm32/stm32h7.c b/src/stm32/stm32h7.c
index 43b7aa6e..dc9a29d1 100644
--- a/src/stm32/stm32h7.c
+++ b/src/stm32/stm32h7.c
@@ -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();
diff --git a/src/stm32/stm32l4.c b/src/stm32/stm32l4.c
index b5c939bb..709473c8 100644
--- a/src/stm32/stm32l4.c
+++ b/src/stm32/stm32l4.c
@@ -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();