summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan <fauxpark@gmail.com>2021-12-27 21:10:07 +1100
committerGitHub <noreply@github.com>2021-12-27 21:10:07 +1100
commit6bc870d899c474bce82457699ec4b753d1538123 (patch)
tree600b8dda41f4b90f98199d4afd3037374a679a74
parentcffe143ca20d938c910b59410dcd3d96dd7d433b (diff)
downloadqmk_firmware-6bc870d899c474bce82457699ec4b753d1538123.tar.gz
qmk_firmware-6bc870d899c474bce82457699ec4b753d1538123.zip
Refactor `bootloader_jump()` implementations (#15450)
* Refactor `bootloader_jump()` implementations * Fix tests? * Rename `atmel-samba` to `md-boot`
-rw-r--r--build_test.mk1
-rw-r--r--builddefs/bootloader.mk40
-rw-r--r--data/schemas/keyboard.jsonschema2
-rw-r--r--keyboards/handwired/onekey/teensy_32/rules.mk3
-rw-r--r--keyboards/handwired/onekey/teensy_lc/rules.mk3
-rw-r--r--keyboards/massdrop/alt/rules.mk3
-rw-r--r--keyboards/massdrop/ctrl/rules.mk3
-rw-r--r--keyboards/mechlovin/olly/jf/rules.mk4
-rw-r--r--keyboards/rocketboard_16/rules.mk2
-rw-r--r--keyboards/tgr/jane/v2ce/rules.mk2
-rw-r--r--platforms/arm_atsam/bootloaders/md_boot.c (renamed from platforms/arm_atsam/bootloader.c)43
-rw-r--r--platforms/avr/bootloader.c293
-rw-r--r--platforms/avr/bootloaders/bootloadhid.c34
-rw-r--r--platforms/avr/bootloaders/caterina.c39
-rw-r--r--platforms/avr/bootloaders/dfu.c53
-rw-r--r--platforms/avr/bootloaders/halfkay.c129
-rw-r--r--platforms/avr/bootloaders/none.c20
-rw-r--r--platforms/avr/bootloaders/usbasploader.c57
-rw-r--r--platforms/chibios/bootloader.c145
-rw-r--r--platforms/chibios/bootloaders/gd32v_dfu.c40
-rw-r--r--platforms/chibios/bootloaders/halfkay.c26
-rw-r--r--platforms/chibios/bootloaders/kiibohd.c33
-rw-r--r--platforms/chibios/bootloaders/none.c20
-rw-r--r--platforms/chibios/bootloaders/stm32_dfu.c96
-rw-r--r--platforms/chibios/bootloaders/stm32duino.c24
-rw-r--r--platforms/chibios/bootloaders/tinyuf2.c35
-rw-r--r--platforms/common.mk2
-rw-r--r--platforms/test/bootloaders/none.c (renamed from platforms/test/bootloader.c)2
-rw-r--r--tmk_core/protocol/arm_atsam/arm_atsam_protocol.h1
-rw-r--r--tmk_core/protocol/arm_atsam/md_bootloader.h24
-rw-r--r--tmk_core/protocol/arm_atsam/startup.c6
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udc.c5
32 files changed, 699 insertions, 491 deletions
diff --git a/build_test.mk b/build_test.mk
index 136a0455f0..ec6699b4ea 100644
--- a/build_test.mk
+++ b/build_test.mk
@@ -43,6 +43,7 @@ all: elf
VPATH += $(COMMON_VPATH)
PLATFORM:=TEST
PLATFORM_KEY:=test
+BOOTLOADER_TYPE:=none
ifeq ($(strip $(DEBUG)), 1)
CONSOLE_ENABLE = yes
diff --git a/builddefs/bootloader.mk b/builddefs/bootloader.mk
index ccb92392d9..470febc346 100644
--- a/builddefs/bootloader.mk
+++ b/builddefs/bootloader.mk
@@ -30,6 +30,7 @@
# bootloadhid HIDBootFlash compatible (ATmega32A)
# usbasploader USBaspLoader (ATmega328P)
# ARM:
+# halfkay PJRC Teensy
# kiibohd Input:Club Kiibohd bootloader (only used on their boards)
# stm32duino STM32Duino (STM32F103x8)
# stm32-dfu STM32 USB DFU in ROM
@@ -43,6 +44,8 @@
ifeq ($(strip $(BOOTLOADER)), atmel-dfu)
OPT_DEFS += -DBOOTLOADER_ATMEL_DFU
OPT_DEFS += -DBOOTLOADER_DFU
+ BOOTLOADER_TYPE = dfu
+
ifneq (,$(filter $(MCU), at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647))
BOOTLOADER_SIZE = 4096
endif
@@ -53,6 +56,8 @@ endif
ifeq ($(strip $(BOOTLOADER)), lufa-dfu)
OPT_DEFS += -DBOOTLOADER_LUFA_DFU
OPT_DEFS += -DBOOTLOADER_DFU
+ BOOTLOADER_TYPE = dfu
+
ifneq (,$(filter $(MCU), at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647))
BOOTLOADER_SIZE ?= 4096
endif
@@ -63,6 +68,8 @@ endif
ifeq ($(strip $(BOOTLOADER)), qmk-dfu)
OPT_DEFS += -DBOOTLOADER_QMK_DFU
OPT_DEFS += -DBOOTLOADER_DFU
+ BOOTLOADER_TYPE = dfu
+
ifneq (,$(filter $(MCU), at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647))
BOOTLOADER_SIZE ?= 4096
endif
@@ -73,10 +80,14 @@ endif
ifeq ($(strip $(BOOTLOADER)), qmk-hid)
OPT_DEFS += -DBOOTLOADER_QMK_HID
OPT_DEFS += -DBOOTLOADER_HID
+ BOOTLOADER_TYPE = dfu
+
BOOTLOADER_SIZE ?= 4096
endif
ifeq ($(strip $(BOOTLOADER)), halfkay)
OPT_DEFS += -DBOOTLOADER_HALFKAY
+ BOOTLOADER_TYPE = halfkay
+
ifeq ($(strip $(MCU)), atmega32u4)
BOOTLOADER_SIZE = 512
endif
@@ -86,18 +97,26 @@ ifeq ($(strip $(BOOTLOADER)), halfkay)
endif
ifeq ($(strip $(BOOTLOADER)), caterina)
OPT_DEFS += -DBOOTLOADER_CATERINA
+ BOOTLOADER_TYPE = caterina
+
BOOTLOADER_SIZE = 4096
endif
ifneq (,$(filter $(BOOTLOADER), bootloadhid bootloadHID))
OPT_DEFS += -DBOOTLOADER_BOOTLOADHID
+ BOOTLOADER_TYPE = bootloadhid
+
BOOTLOADER_SIZE = 4096
endif
ifneq (,$(filter $(BOOTLOADER), usbasploader USBasp))
OPT_DEFS += -DBOOTLOADER_USBASP
+ BOOTLOADER_TYPE = usbasploader
+
BOOTLOADER_SIZE = 4096
endif
ifeq ($(strip $(BOOTLOADER)), lufa-ms)
OPT_DEFS += -DBOOTLOADER_MS
+ BOOTLOADER_TYPE = dfu
+
BOOTLOADER_SIZE ?= 8192
FIRMWARE_FORMAT = bin
cpfirmware: lufa_warning
@@ -115,6 +134,7 @@ endif
ifeq ($(strip $(BOOTLOADER)), stm32-dfu)
OPT_DEFS += -DBOOTLOADER_STM32_DFU
+ BOOTLOADER_TYPE = stm32_dfu
# Options to pass to dfu-util when flashing
DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
@@ -122,6 +142,7 @@ ifeq ($(strip $(BOOTLOADER)), stm32-dfu)
endif
ifeq ($(strip $(BOOTLOADER)), apm32-dfu)
OPT_DEFS += -DBOOTLOADER_APM32_DFU
+ BOOTLOADER_TYPE = stm32_dfu
# Options to pass to dfu-util when flashing
DFU_ARGS ?= -d 314B:0106 -a 0 -s 0x08000000:leave
@@ -129,6 +150,7 @@ ifeq ($(strip $(BOOTLOADER)), apm32-dfu)
endif
ifeq ($(strip $(BOOTLOADER)), gd32v-dfu)
OPT_DEFS += -DBOOTLOADER_GD32V_DFU
+ BOOTLOADER_TYPE = gd32v_dfu
# Options to pass to dfu-util when flashing
DFU_ARGS ?= -d 28E9:0189 -a 0 -s 0x08000000:leave
@@ -136,6 +158,8 @@ ifeq ($(strip $(BOOTLOADER)), gd32v-dfu)
endif
ifeq ($(strip $(BOOTLOADER)), kiibohd)
OPT_DEFS += -DBOOTLOADER_KIIBOHD
+ BOOTLOADER_TYPE = kiibohd
+
ifeq ($(strip $(MCU_ORIG)), MK20DX128)
MCU_LDSCRIPT = MK20DX128BLDR4
endif
@@ -151,8 +175,7 @@ ifeq ($(strip $(BOOTLOADER)), stm32duino)
OPT_DEFS += -DBOOTLOADER_STM32DUINO
MCU_LDSCRIPT = STM32F103x8_stm32duino_bootloader
BOARD = STM32_F103_STM32DUINO
- # STM32F103 does NOT have an USB bootloader in ROM (only serial), so setting anything here does not make much sense
- STM32_BOOTLOADER_ADDRESS = 0x80000000
+ BOOTLOADER_TYPE = stm32duino
# Options to pass to dfu-util when flashing
DFU_ARGS = -d 1EAF:0003 -a 2 -R
@@ -160,4 +183,17 @@ ifeq ($(strip $(BOOTLOADER)), stm32duino)
endif
ifeq ($(strip $(BOOTLOADER)), tinyuf2)
OPT_DEFS += -DBOOTLOADER_TINYUF2
+ BOOTLOADER_TYPE = tinyuf2
+endif
+ifeq ($(strip $(BOOTLOADER)), halfkay)
+ OPT_DEFS += -DBOOTLOADER_HALFKAY
+ BOOTLOADER_TYPE = halfkay
+endif
+ifeq ($(strip $(BOOTLOADER)), md-boot)
+ OPT_DEFS += -DBOOTLOADER_MD_BOOT
+ BOOTLOADER_TYPE = md_boot
+endif
+
+ifeq ($(strip $(BOOTLOADER_TYPE)),)
+ BOOTLOADER_TYPE = none
endif
diff --git a/data/schemas/keyboard.jsonschema b/data/schemas/keyboard.jsonschema
index 2daeaf04b4..94bbbe7e85 100644
--- a/data/schemas/keyboard.jsonschema
+++ b/data/schemas/keyboard.jsonschema
@@ -57,7 +57,7 @@
},
"bootloader": {
"type": "string",
- "enum": ["atmel-dfu", "bootloadhid", "bootloadHID", "caterina", "halfkay", "kiibohd", "lufa-dfu", "lufa-ms", "micronucleus", "qmk-dfu", "qmk-hid", "stm32-dfu", "stm32duino", "gd32v-dfu", "wb32-dfu", "unknown", "usbasploader", "USBasp", "tinyuf2"],
+ "enum": ["atmel-dfu", "bootloadhid", "bootloadHID", "caterina", "halfkay", "kiibohd", "lufa-dfu", "lufa-ms", "md-boot", "micronucleus", "qmk-dfu", "qmk-hid", "stm32-dfu", "stm32duino", "gd32v-dfu", "wb32-dfu", "unknown", "usbasploader", "USBasp", "tinyuf2"],
},
"bootloader_instructions": {
"type": "string",
diff --git a/keyboards/handwired/onekey/teensy_32/rules.mk b/keyboards/handwired/onekey/teensy_32/rules.mk
index c1b90d0d2b..937c9d5103 100644
--- a/keyboards/handwired/onekey/teensy_32/rules.mk
+++ b/keyboards/handwired/onekey/teensy_32/rules.mk
@@ -1,5 +1,8 @@
# MCU name
MCU = MK20DX256
+# Bootloader selection
+BOOTLOADER = halfkay
+
# Enter lower-power sleep mode when on the ChibiOS idle thread
OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE
diff --git a/keyboards/handwired/onekey/teensy_lc/rules.mk b/keyboards/handwired/onekey/teensy_lc/rules.mk
index b3daabe317..0e3c7edf7a 100644
--- a/keyboards/handwired/onekey/teensy_lc/rules.mk
+++ b/keyboards/handwired/onekey/teensy_lc/rules.mk
@@ -2,5 +2,8 @@
MCU = MKL26Z64
USE_CHIBIOS_CONTRIB = yes
+# Bootloader selection
+BOOTLOADER = halfkay
+
# Enter lower-power sleep mode when on the ChibiOS idle thread
OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE
diff --git a/keyboards/massdrop/alt/rules.mk b/keyboards/massdrop/alt/rules.mk
index 83d4fc590b..f0ff36fa35 100644
--- a/keyboards/massdrop/alt/rules.mk
+++ b/keyboards/massdrop/alt/rules.mk
@@ -5,6 +5,9 @@ SRC += config_led.c
ARM_ATSAM = SAMD51J18A
MCU = cortex-m4
+# Bootloader selection
+BOOTLOADER = md-boot
+
# Build Options
# change yes to no to disable
#
diff --git a/keyboards/massdrop/ctrl/rules.mk b/keyboards/massdrop/ctrl/rules.mk
index 667642f83d..a302c82d86 100644
--- a/keyboards/massdrop/ctrl/rules.mk
+++ b/keyboards/massdrop/ctrl/rules.mk
@@ -5,6 +5,9 @@ SRC += config_led.c
ARM_ATSAM = SAMD51J18A
MCU = cortex-m4
+# Bootloader selection
+BOOTLOADER = md-boot
+
# Build Options
# change yes to no to disable
#
diff --git a/keyboards/mechlovin/olly/jf/rules.mk b/keyboards/mechlovin/olly/jf/rules.mk
index c0c9b2d7ea..2fafe64f12 100644
--- a/keyboards/mechlovin/olly/jf/rules.mk
+++ b/keyboards/mechlovin/olly/jf/rules.mk
@@ -5,7 +5,7 @@ MCU = atmega32a
F_CPU = 16000000
# Bootloader selection
-BOOTLOADER = USBasp
+BOOTLOADER = usbasploader
# Build Options
# change yes to no to disable
@@ -21,4 +21,4 @@ RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow
AUDIO_ENABLE = no # Audio output
CUSTOM_MATRIX = lite
-SRC += matrix.c \ No newline at end of file
+SRC += matrix.c
diff --git a/keyboards/rocketboard_16/rules.mk b/keyboards/rocketboard_16/rules.mk
index d27da2c226..c07ebff427 100644
--- a/keyboards/rocketboard_16/rules.mk
+++ b/keyboards/rocketboard_16/rules.mk
@@ -8,7 +8,7 @@ MCU = STM32F103
MCU_LDSCRIPT = STM32F103xB_stm32duino_bootloader
OPT_DEFS += -DBOOTLOADER_STM32DUINO
BOARD = STM32_F103_STM32DUINO
-STM32_BOOTLOADER_ADDRESS = 0x80000000
+BOOTLOADER_TYPE = stm32duino
DFU_ARGS = -d 1EAF:0003 -a 2 -R
DFU_SUFFIX_ARGS = -v 1EAF -p 0003
diff --git a/keyboards/tgr/jane/v2ce/rules.mk b/keyboards/tgr/jane/v2ce/rules.mk
index 0a865321a6..8fcc8d911f 100644
--- a/keyboards/tgr/jane/v2ce/rules.mk
+++ b/keyboards/tgr/jane/v2ce/rules.mk
@@ -2,7 +2,7 @@
MCU = atmega32a
# Bootloader selection
-BOOTLOADER = bootloadHID
+BOOTLOADER = bootloadhid
# Build Options
# change yes to no to disable
diff --git a/platforms/arm_atsam/bootloader.c b/platforms/arm_atsam/bootloaders/md_boot.c
index 9015b00aab..fe07389487 100644
--- a/platforms/arm_atsam/bootloader.c
+++ b/platforms/arm_atsam/bootloaders/md_boot.c
@@ -15,13 +15,18 @@
*/
#include "bootloader.h"
+
#include "samd51j18a.h"
-#include "md_bootloader.h"
-// Set watchdog timer to reset. Directs the bootloader to stay in programming mode.
-void bootloader_jump(void) {
#ifdef KEYBOARD_massdrop_ctrl
- // CTRL keyboards released with bootloader version below must use RAM method. Otherwise use WDT method.
+// WARNING: These are only for CTRL bootloader release "v2.18Jun 22 2018 17:28:08" for bootloader_jump support
+extern uint32_t _eram;
+
+#define BOOTLOADER_MAGIC 0x3B9ACA00
+#define MAGIC_ADDR (uint32_t *)((intptr_t)(&_eram) - 4)
+
+// CTRL keyboards released with bootloader version below must use RAM method. Otherwise use WDT method.
+void bootloader_jump(void) {
uint8_t ver_ram_method[] = "v2.18Jun 22 2018 17:28:08"; // The version to match (NULL terminated by compiler)
uint8_t *ver_check = ver_ram_method; // Pointer to version match string for traversal
uint8_t *ver_rom = (uint8_t *)0x21A0; // Pointer to address in ROM where this specific bootloader version would exist
@@ -34,24 +39,28 @@ void bootloader_jump(void) {
if (!*ver_check) { // If check version pointer is NULL, all characters have matched
*MAGIC_ADDR = BOOTLOADER_MAGIC; // Set magic number into RAM
NVIC_SystemReset(); // Perform system reset
- while (1) {
- } // Won't get here
+
+ while (1); // Won't get here
}
-#endif
+}
+#else
+
+// Set watchdog timer to reset. Directs the bootloader to stay in programming mode.
+void bootloader_jump(void) {
WDT->CTRLA.bit.ENABLE = 0;
- while (WDT->SYNCBUSY.bit.ENABLE) {
- }
- while (WDT->CTRLA.bit.ENABLE) {
- }
+
+ while (WDT->SYNCBUSY.bit.ENABLE);
+ while (WDT->CTRLA.bit.ENABLE);
+
WDT->CONFIG.bit.WINDOW = 0;
WDT->CONFIG.bit.PER = 0;
WDT->EWCTRL.bit.EWOFFSET = 0;
WDT->CTRLA.bit.ENABLE = 1;
- while (WDT->SYNCBUSY.bit.ENABLE) {
- }
- while (!WDT->CTRLA.bit.ENABLE) {
- }
- while (1) {
- } // Wait on timeout
+
+ while (WDT->SYNCBUSY.bit.ENABLE);
+ while (!WDT->CTRLA.bit.ENABLE);
+
+ while (1); // Wait on timeout
}
+#endif
diff --git a/platforms/avr/bootloader.c b/platforms/avr/bootloader.c
deleted file mode 100644
index c0272903b8..0000000000
--- a/platforms/avr/bootloader.c
+++ /dev/null
@@ -1,293 +0,0 @@
-#include <stdint.h>
-#include <stdbool.h>
-#include <avr/io.h>
-#include <avr/eeprom.h>
-#include <avr/interrupt.h>
-#include <avr/wdt.h>
-#include <util/delay.h>
-#include "bootloader.h"
-#include <avr/boot.h>
-
-#ifdef PROTOCOL_LUFA
-# include <LUFA/Drivers/USB/USB.h>
-#endif
-
-/** \brief Bootloader Size in *bytes*
- *
- * AVR Boot section size are defined by setting BOOTSZ fuse in fact. Consult with your MCU datasheet.
- * Note that 'Word'(2 bytes) size and address are used in datasheet while TMK uses 'Byte'.
- *
- * Size of Bootloaders in bytes:
- * Atmel DFU loader(ATmega32U4) 4096
- * Atmel DFU loader(AT90USB128) 8192
- * LUFA bootloader(ATmega32U4) 4096
- * Arduino Caterina(ATmega32U4) 4096
- * USBaspLoader(ATmega***) 2048
- * Teensy halfKay(ATmega32U4) 512
- * Teensy++ halfKay(AT90USB128) 1024
- *
- * AVR Boot section is located at the end of Flash memory like the followings.
- *
- * byte Atmel/LUFA(ATMega32u4) byte Atmel(AT90SUB128)
- * 0x0000 +---------------+ 0x00000 +---------------+
- * | | | |
- * | | | |
- * | Application | | Application |
- * | | | |
- * = = = =
- * | | 32KB-4KB | | 128KB-8KB
- * 0x7000 +---------------+ 0x1E000 +---------------+
- * | Bootloader | 4KB | Bootloader | 8KB
- * 0x7FFF +---------------+ 0x1FFFF +---------------+
- *
- *
- * byte Teensy(ATMega32u4) byte Teensy++(AT90SUB128)
- * 0x0000 +---------------+ 0x00000 +---------------+
- * | | | |
- * | | | |
- * | Application | | Application |
- * | | | |
- * = = = =
- * | | 32KB-512B | | 128KB-1KB
- * 0x7E00 +---------------+ 0x1FC00 +---------------+
- * | Bootloader | 512B | Bootloader | 1KB
- * 0x7FFF +---------------+ 0x1FFFF +---------------+
- */
-#define FLASH_SIZE (FLASHEND + 1L)
-
-#if !defined(BOOTLOADER_SIZE)
-uint16_t bootloader_start;
-#endif
-
-// compatibility between ATMega8 and ATMega88
-#if !defined(MCUCSR)
-# if defined(MCUSR)
-# define MCUCSR MCUSR
-# endif
-#endif
-
-/** \brief Entering the Bootloader via Software
- *
- * http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html
- */
-#define BOOTLOADER_RESET_KEY 0xB007B007
-uint32_t reset_key __attribute__((section(".noinit,\"aw\",@nobits;")));
-
-/** \brief initialize MCU status by watchdog reset
- *
- * FIXME: needs doc
- */
-__attribute__((weak)) void bootloader_jump(void) {
-#if !defined(BOOTLOADER_SIZE)
- uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
-
- if (high_fuse & ~(FUSE_BOOTSZ0 & FUSE_BOOTSZ1)) {
- bootloader_start = (FLASH_SIZE - 512) >> 1;
- } else if (high_fuse & ~(FUSE_BOOTSZ1)) {
- bootloader_start = (FLASH_SIZE - 1024) >> 1;
- } else if (high_fuse & ~(FUSE_BOOTSZ0)) {
- bootloader_start = (FLASH_SIZE - 2048) >> 1;
- } else {
- bootloader_start = (FLASH_SIZE - 4096) >> 1;
- }
-#endif
-
- // Something like this might work, but it compiled larger than the block above
- // bootloader_start = FLASH_SIZE - (256 << (~high_fuse & 0b110 >> 1));
-
-#if defined(BOOTLOADER_HALFKAY)
- // http://www.pjrc.com/teensy/jump_to_bootloader.html
- cli();
- // disable watchdog, if enabled (it's not)
- // disable all peripherals
- // a shutdown call might make sense here
- UDCON = 1;
- USBCON = (1 << FRZCLK); // disable USB
- UCSR1B = 0;
- _delay_ms(5);
-# if defined(__AVR_AT90USB162__) // Teensy 1.0
- EIMSK = 0;
- PCICR = 0;
- SPCR = 0;
- ACSR = 0;
- EECR = 0;
- TIMSK0 = 0;
- TIMSK1 = 0;
- UCSR1B = 0;
- DDRB = 0;
- DDRC = 0;
- DDRD = 0;
- PORTB = 0;
- PORTC = 0;
- PORTD = 0;
- asm volatile("jmp 0x3E00");
-# elif defined(__AVR_ATmega32U4__) // Teensy 2.0
- EIMSK = 0;
- PCICR = 0;
- SPCR = 0;
- ACSR = 0;
- EECR = 0;
- ADCSRA = 0;
- TIMSK0 = 0;
- TIMSK1 = 0;
- TIMSK3 = 0;
- TIMSK4 = 0;
- UCSR1B = 0;
- TWCR = 0;
- DDRB = 0;
- DDRC = 0;
- DDRD = 0;
- DDRE = 0;
- DDRF = 0;
- TWCR = 0;
- PORTB = 0;
- PORTC = 0;
- PORTD = 0;
- PORTE = 0;
- PORTF = 0;
- asm volatile("jmp 0x7E00");
-# elif defined(__AVR_AT90USB646__) // Teensy++ 1.0
- EIMSK = 0;
- PCICR = 0;
- SPCR = 0;
- ACSR = 0;
- EECR = 0;
- ADCSRA = 0;
- TIMSK0 = 0;
- TIMSK1 = 0;
- TIMSK2 = 0;
- TIMSK3 = 0;
- UCSR1B = 0;
- TWCR = 0;
- DDRA = 0;
- DDRB = 0;
- DDRC = 0;
- DDRD = 0;
- DDRE = 0;
- DDRF = 0;
- PORTA = 0;
- PORTB = 0;
- PORTC = 0;
- PORTD = 0;
- PORTE = 0;
- PORTF = 0;
- asm volatile("jmp 0xFC00");
-# elif defined(__AVR_AT90USB1286__) // Teensy++ 2.0
- EIMSK = 0;
- PCICR = 0;
- SPCR = 0;
- ACSR = 0;
- EECR = 0;
- ADCSRA = 0;
- TIMSK0 = 0;
- TIMSK1 = 0;
- TIMSK2 = 0;
- TIMSK3 = 0;
- UCSR1B = 0;
- TWCR = 0;
- DDRA = 0;
- DDRB = 0;
- DDRC = 0;
- DDRD = 0;
- DDRE = 0;
- DDRF = 0;
- PORTA = 0;
- PORTB = 0;
- PORTC = 0;
- PORTD = 0;
- PORTE = 0;
- PORTF = 0;
- asm volatile("jmp 0x1FC00");
-# endif
-
-#elif defined(BOOTLOADER_CATERINA)
- // this block may be optional
- // TODO: figure it out
-
- uint16_t *const bootKeyPtr = (uint16_t *)0x0800;
-
- // Value used by Caterina bootloader use to determine whether to run the
- // sketch or the bootloader programmer.
- uint16_t bootKey = 0x7777;
-
- *bootKeyPtr = bootKey;
-
- // setup watchdog timeout
- wdt_enable(WDTO_60MS);
-
- while (1) {
- } // wait for watchdog timer to trigger
-
-#elif defined(BOOTLOADER_USBASP)
- // Taken with permission of Stephan Baerwolf from https://github.com/tinyusbboard/API/blob/master/apipage.c
- wdt_enable(WDTO_15MS);
- wdt_reset();
- asm volatile("cli \n\t"
- "ldi r29 , %[ramendhi] \n\t"
- "ldi r28 , %[ramendlo] \n\t"
-# if (FLASHEND > 131071)
- "ldi r18 , %[bootaddrhi] \n\t"
- "st Y+, r18 \n\t"
-# endif
- "ldi r18 , %[bootaddrme] \n\t"
- "st Y+, r18 \n\t"
- "ldi r18 , %[bootaddrlo] \n\t"
- "st Y+, r18 \n\t"
- "out %[mcucsrio], __zero_reg__ \n\t"
- "bootloader_startup_loop%=: \n\t"
- "rjmp bootloader_startup_loop%= \n\t"
- :
- : [mcucsrio] "I"(_SFR_IO_ADDR(MCUCSR)),
-# if (FLASHEND > 131071)
- [ramendhi] "M"(((RAMEND - 2) >> 8) & 0xff), [ramendlo] "M"(((RAMEND - 2) >> 0) & 0xff), [bootaddrhi] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 16) & 0xff),
-# else
- [ramendhi] "M"(((RAMEND - 1) >> 8) & 0xff), [ramendlo] "M"(((RAMEND - 1) >> 0) & 0xff),
-# endif
- [bootaddrme] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 8) & 0xff), [bootaddrlo] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 0) & 0xff));
-
-#else // Assume remaining boards are DFU, even if the flag isn't set
-
-# if !(defined(__AVR_ATmega32A__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) || defined(__AVR_ATtiny85__)) // no USB - maybe BOOTLOADER_BOOTLOADHID instead though?
- UDCON = 1;
- USBCON = (1 << FRZCLK); // disable USB
- UCSR1B = 0;
- _delay_ms(5); // 5 seems to work fine
-# endif
-
-# ifdef BOOTLOADER_BOOTLOADHID
- // force bootloadHID to stay in bootloader mode, so that it waits
- // for a new firmware to be flashed
- eeprom_write_byte((uint8_t *)1, 0x00);
-# endif
-
- // watchdog reset
- reset_key = BOOTLOADER_RESET_KEY;
- wdt_enable(WDTO_250MS);
- for (;;)
- ;
-#endif
-}
-
-/* this runs before main() */
-void bootloader_jump_after_watchdog_reset(void) __attribute__((used, naked, section(".init3")));
-void bootloader_jump_after_watchdog_reset(void) {
-#ifndef BOOTLOADER_HALFKAY
- if ((MCUCSR & (1 << WDRF)) && reset_key == BOOTLOADER_RESET_KEY) {
- reset_key = 0;
-
- // My custom USBasploader requires this to come up.
- MCUCSR = 0;
-
- // Seems like Teensy halfkay loader requires clearing WDRF and disabling watchdog.
- MCUCSR &= ~(1 << WDRF);
- wdt_disable();
-
-// This is compled into 'icall', address should be in word unit, not byte.
-# ifdef BOOTLOADER_SIZE
- ((void (*)(void))((FLASH_SIZE - BOOTLOADER_SIZE) >> 1))();
-# else
- asm("ijmp" ::"z"(bootloader_start));
-# endif
- }
-#endif
-}
diff --git a/platforms/avr/bootloaders/bootloadhid.c b/platforms/avr/bootloaders/bootloadhid.c
new file mode 100644
index 0000000000..8d18114613
--- /dev/null
+++ b/platforms/avr/bootloaders/bootloadhid.c
@@ -0,0 +1,34 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bootloader.h"
+
+#include <avr/eeprom.h>
+#include <avr/wdt.h>
+
+__attribute__((weak))
+void bootloader_jump(void) {
+ // force bootloadHID to stay in bootloader mode, so that it waits
+ // for a new firmware to be flashed
+ // NOTE: this byte is part of QMK's "magic number" - changing it causes the EEPROM to be re-initialized
+ // thus every time the device is flashed the EEPROM will be wiped
+ eeprom_write_byte((uint8_t *)1, 0x00);
+
+ // watchdog reset
+ wdt_enable(WDTO_250MS);
+ for (;;)
+ ;
+}
diff --git a/platforms/avr/bootloaders/caterina.c b/platforms/avr/bootloaders/caterina.c
new file mode 100644
index 0000000000..1b43ed4e44
--- /dev/null
+++ b/platforms/avr/bootloaders/caterina.c
@@ -0,0 +1,39 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bootloader.h"
+
+#include <avr/wdt.h>
+
+__attribute__((weak))
+void bootloader_jump(void) {
+ // this block may be optional
+ // TODO: figure it out
+
+ uint16_t *const bootKeyPtr = (uint16_t *)0x0800;
+
+ // Value used by Caterina bootloader use to determine whether to run the
+ // sketch or the bootloader programmer.
+ uint16_t bootKey = 0x7777;
+
+ *bootKeyPtr = bootKey;
+
+ // setup watchdog timeout
+ wdt_enable(WDTO_60MS);
+
+ // wait for watchdog timer to trigger
+ while (1) { }
+}
diff --git a/platforms/avr/bootloaders/dfu.c b/platforms/avr/bootloaders/dfu.c
new file mode 100644
index 0000000000..bdf5908934
--- /dev/null
+++ b/platforms/avr/bootloaders/dfu.c
@@ -0,0 +1,53 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bootloader.h"
+
+#include <avr/wdt.h>
+#include <util/delay.h>
+
+#define FLASH_SIZE (FLASHEND + 1L)
+
+/** \brief Entering the Bootloader via Software
+ *
+ * http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html
+ */
+#define BOOTLOADER_RESET_KEY 0xB007B007
+uint32_t reset_key __attribute__((section(".noinit,\"aw\",@nobits;")));
+
+__attribute__((weak))
+void bootloader_jump(void) {
+ UDCON = 1;
+ USBCON = (1 << FRZCLK); // disable USB
+ UCSR1B = 0;
+ _delay_ms(5); // 5 seems to work fine
+
+ // watchdog reset
+ reset_key = BOOTLOADER_RESET_KEY;
+ wdt_enable(WDTO_250MS);
+ for (;;)
+ ;
+}
+
+/* this runs before main() */
+void bootloader_jump_after_watchdog_reset(void) __attribute__((used, naked, section(".init3")));
+void bootloader_jump_after_watchdog_reset(void) {
+ if ((MCUSR & (1 << WDRF)) && reset_key == BOOTLOADER_RESET_KEY) {
+ reset_key = 0;
+
+ ((void (*)(void))((FLASH_SIZE - BOOTLOADER_SIZE) >> 1))();
+ }
+}
diff --git a/platforms/avr/bootloaders/halfkay.c b/platforms/avr/bootloaders/halfkay.c
new file mode 100644
index 0000000000..abef86980b
--- /dev/null
+++ b/platforms/avr/bootloaders/halfkay.c
@@ -0,0 +1,129 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bootloader.h"
+
+#include <avr/interrupt.h>
+#include <util/delay.h>
+
+__attribute__((weak))
+void bootloader_jump(void) {
+ // http://www.pjrc.com/teensy/jump_to_bootloader.html
+
+ cli();
+ // disable watchdog, if enabled (it's not)
+ // disable all peripherals
+ // a shutdown call might make sense here
+ UDCON = 1;
+ USBCON = (1 << FRZCLK); // disable USB
+ UCSR1B = 0;
+ _delay_ms(5);
+
+#if defined(__AVR_AT90USB162__) // Teensy 1.0
+ EIMSK = 0;
+ PCICR = 0;
+ SPCR = 0;
+ ACSR = 0;
+ EECR = 0;
+ TIMSK0 = 0;
+ TIMSK1 = 0;
+ UCSR1B = 0;
+ DDRB = 0;
+ DDRC = 0;
+ DDRD = 0;
+ PORTB = 0;
+ PORTC = 0;
+ PORTD = 0;
+ asm volatile("jmp 0x3E00");
+#elif defined(__AVR_ATmega32U4__) // Teensy 2.0
+ EIMSK = 0;
+ PCICR = 0;
+ SPCR = 0;
+ ACSR = 0;
+ EECR = 0;
+ ADCSRA = 0;
+ TIMSK0 = 0;
+ TIMSK1 = 0;
+ TIMSK3 = 0;
+ TIMSK4 = 0;
+ UCSR1B = 0;
+ TWCR = 0;
+ DDRB = 0;
+ DDRC = 0;
+ DDRD = 0;
+ DDRE = 0;
+ DDRF = 0;
+ TWCR = 0;
+ PORTB = 0;
+ PORTC = 0;
+ PORTD = 0;
+ PORTE = 0;
+ PORTF = 0;
+ asm volatile("jmp 0x7E00");
+#elif defined(__AVR_AT90USB646__) // Teensy++ 1.0
+ EIMSK = 0;
+ PCICR = 0;
+ SPCR = 0;
+ ACSR = 0;
+ EECR = 0;
+ ADCSRA = 0;
+ TIMSK0 = 0;
+ TIMSK1 = 0;
+ TIMSK2 = 0;
+ TIMSK3 = 0;
+ UCSR1B = 0;
+ TWCR = 0;
+ DDRA = 0;
+ DDRB = 0;
+ DDRC = 0;
+ DDRD = 0;
+ DDRE = 0;
+ DDRF = 0;
+ PORTA = 0;
+ PORTB = 0;
+ PORTC = 0;
+ PORTD = 0;
+ PORTE = 0;
+ PORTF = 0;
+ asm volatile("jmp 0xFC00");
+#elif defined(__AVR_AT90USB1286__) // Teensy++ 2.0
+ EIMSK = 0;
+ PCICR = 0;
+ SPCR = 0;
+ ACSR = 0;
+ EECR = 0;
+ ADCSRA = 0;
+ TIMSK0 = 0;
+ TIMSK1 = 0;
+ TIMSK2 = 0;
+ TIMSK3 = 0;
+ UCSR1B = 0;
+ TWCR = 0;
+ DDRA = 0;
+ DDRB = 0;
+ DDRC = 0;
+ DDRD = 0;
+ DDRE = 0;
+ DDRF = 0;
+ PORTA = 0;
+ PORTB = 0;
+ PORTC = 0;
+ PORTD = 0;
+ PORTE = 0;
+ PORTF = 0;
+ asm volatile("jmp 0x1FC00");
+#endif
+}
diff --git a/platforms/avr/bootloaders/none.c b/platforms/avr/bootloaders/none.c
new file mode 100644
index 0000000000..8af151c04d
--- /dev/null
+++ b/platforms/avr/bootloaders/none.c
@@ -0,0 +1,20 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bootloader.h"
+
+__attribute__((weak))
+void bootloader_jump(void) { }
diff --git a/platforms/avr/bootloaders/usbasploader.c b/platforms/avr/bootloaders/usbasploader.c
new file mode 100644
index 0000000000..b3e9b2d72d
--- /dev/null
+++ b/platforms/avr/bootloaders/usbasploader.c
@@ -0,0 +1,57 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bootloader.h"
+
+#include <avr/wdt.h>
+
+#define FLASH_SIZE (FLASHEND + 1L)
+
+#if !defined(MCUCSR)
+# if defined(MCUSR)
+# define MCUCSR MCUSR
+# endif
+#endif
+
+__attribute__((weak))
+void bootloader_jump(void) {
+ // Taken with permission of Stephan Baerwolf from https://github.com/tinyusbboard/API/blob/master/apipage.c
+
+ wdt_enable(WDTO_15MS);
+ wdt_reset();
+ asm volatile("cli \n\t"
+ "ldi r29 , %[ramendhi] \n\t"
+ "ldi r28 , %[ramendlo] \n\t"
+#if (FLASHEND > 131071)
+ "ldi r18 , %[bootaddrhi] \n\t"
+ "st Y+, r18 \n\t"
+#endif
+ "ldi r18 , %[bootaddrme] \n\t"
+ "st Y+, r18 \n\t"
+ "ldi r18 , %[bootaddrlo] \n\t"
+ "st Y+, r18 \n\t"
+ "out %[mcucsrio], __zero_reg__ \n\t"
+ "bootloader_startup_loop%=: \n\t"
+ "rjmp bootloader_startup_loop%= \n\t"
+ :
+ : [mcucsrio] "I"(_SFR_IO_ADDR(MCUCSR)),
+#if (FLASHEND > 131071)
+ [ramendhi] "M"(((RAMEND - 2) >> 8) & 0xff), [ramendlo] "M"(((RAMEND - 2) >> 0) & 0xff), [bootaddrhi] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 16) & 0xff),
+#else
+ [ramendhi] "M"(((RAMEND - 1) >> 8) & 0xff), [ramendlo] "M"(((RAMEND - 1) >> 0) & 0xff),
+#endif
+ [bootaddrme] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 8) & 0xff), [bootaddrlo] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 0) & 0xff));
+}
diff --git a/platforms/chibios/bootloader.c b/platforms/chibios/bootloader.c
deleted file mode 100644
index 58212948b0..0000000000
--- a/platforms/chibios/bootloader.c
+++ /dev/null
@@ -1,145 +0,0 @@
-#include "bootloader.h"
-
-#include <ch.h>
-#include <hal.h>
-#include "wait.h"
-
-/* This code should be checked whether it runs correctly on platforms */
-#define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0))
-#define BOOTLOADER_MAGIC 0xDEADBEEF
-#define MAGIC_ADDR (unsigned long *)(SYMVAL(__ram0_end__) - 4)
-
-#ifndef STM32_BOOTLOADER_DUAL_BANK
-# define STM32_BOOTLOADER_DUAL_BANK FALSE
-#endif
-
-#ifdef BOOTLOADER_TINYUF2
-
-# define DBL_TAP_MAGIC 0xf01669ef // From tinyuf2's board_api.h
-
-// defined by linker script
-extern uint32_t _board_dfu_dbl_tap[];
-# define DBL_TAP_REG _board_dfu_dbl_tap[0]
-
-void bootloader_jump(void) {
- DBL_TAP_REG = DBL_TAP_MAGIC;
- NVIC_SystemReset();
-}
-
-void enter_bootloader_mode_if_requested(void) { /* not needed, no two-stage reset */
-}
-
-#elif STM32_BOOTLOADER_DUAL_BANK
-
-// Need pin definitions
-# include "config_common.h"
-
-# ifndef STM32_BOOTLOADER_DUAL_BANK_GPIO
-# error "No STM32_BOOTLOADER_DUAL_BANK_GPIO defined, don't know which pin to toggle"
-# endif
-
-# ifndef STM32_BOOTLOADER_DUAL_BANK_POLARITY
-# define STM32_BOOTLOADER_DUAL_BANK_POLARITY 0
-# endif
-
-# ifndef STM32_BOOTLOADER_DUAL_BANK_DELAY
-# define STM32_BOOTLOADER_DUAL_BANK_DELAY 100000
-# endif
-
-extern uint32_t __ram0_end__;
-
-__attribute__((weak)) void bootloader_jump(void) {
- // For STM32 MCUs with dual-bank flash, and we're incapable of jumping to the bootloader. The first valid flash
- // bank is executed unconditionally after a reset, so it doesn't enter DFU unless BOOT0 is high. Instead, we do
- // it with hardware...in this case, we pull a GPIO high/low depending on the configuration, connects 3.3V to
- // BOOT0's RC charging circuit, lets it charge the capacitor, and issue a system reset. See the QMK discord
- // #hardware channel pins for an example circuit.
- palSetPadMode(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_MODE_OUTPUT_PUSHPULL);
-# if STM32_BOOTLOADER_DUAL_BANK_POLARITY
- palSetPad(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO));
-# else
- palClearPad(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO));
-# endif
-
- // Wait for a while for the capacitor to charge
- wait_ms(100);
-
- // Issue a system reset to get the ROM bootloader to execute, with BOOT0 high
- NVIC_SystemReset();
-}
-
-void enter_bootloader_mode_if_requested(void) {} // not needed at all, but if anybody attempts to invoke it....
-
-#elif defined(STM32_BOOTLOADER_ADDRESS) // STM32_BOOTLOADER_DUAL_BANK
-
-extern uint32_t __ram0_end__;
-
-__attribute__((weak)) void bootloader_jump(void) {
- *MAGIC_ADDR = BOOTLOADER_MAGIC; // set magic flag => reset handler will jump into boot loader
- NVIC_SystemReset();
-}
-
-void enter_bootloader_mode_if_requested(void) {
- unsigned long *check = MAGIC_ADDR;
- if (*check == BOOTLOADER_MAGIC) {
- *check = 0;
- __set_CONTROL(0);
- __set_MSP(*(__IO uint32_t *)STM32_BOOTLOADER_ADDRESS);
- __enable_irq();
-
- typedef void (*BootJump_t)(void);
- BootJump_t boot_jump = *(BootJump_t *)(STM32_BOOTLOADER_ADDRESS + 4);
- boot_jump();
- while (1)
- ;
- }
-}
-
-#elif defined(GD32VF103)
-
-# define DBGMCU_KEY_UNLOCK 0x4B5A6978
-# define DBGMCU_CMD_RESET 0x1
-
-__IO uint32_t *DBGMCU_KEY = (uint32_t *)DBGMCU_BASE + 0x0CU;
-__IO uint32_t *DBGMCU_CMD = (uint32_t *)DBGMCU_BASE + 0x08U;
-
-__attribute__((weak)) void bootloader_jump(void) {
- /* The MTIMER unit of the GD32VF103 doesn't have the MSFRST
- * register to generate a software reset request.
- * BUT instead two undocumented registers in the debug peripheral
- * that allow issueing a software reset. WHO would need the MSFRST
- * register anyway? Source:
- * https://github.com/esmil/gd32vf103inator/blob/master/include/gd32vf103/dbg.h */
- *DBGMCU_KEY = DBGMCU_KEY_UNLOCK;
- *DBGMCU_CMD = DBGMCU_CMD_RESET;
-}
-
-void enter_bootloader_mode_if_requested(void) { /* Jumping to bootloader is not possible from user code. */
-}
-
-#elif defined(KL2x) || defined(K20x) || defined(MK66F18) || defined(MIMXRT1062) // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS
-/* Kinetis */
-
-# if defined(BOOTLOADER_KIIBOHD)
-/* Kiibohd Bootloader (MCHCK and Infinity KB) */
-# define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000
-const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
-__attribute__((weak)) void bootloader_jump(void) {
- void *volatile vbat = (void *)VBAT;
- __builtin_memcpy(vbat, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic));
- // request reset
- SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk;
-}
-
-# else /* defined(BOOTLOADER_KIIBOHD) */
-/* Default for Kinetis - expecting an ARM Teensy */
-# include "wait.h"
-__attribute__((weak)) void bootloader_jump(void) {
- wait_ms(100);
- __BKPT(0);
-}
-# endif /* defined(BOOTLOADER_KIIBOHD) */
-
-#else /* neither STM32 nor KINETIS */
-__attribute__((weak)) void bootloader_jump(void) {}
-#endif
diff --git a/platforms/chibios/bootloaders/gd32v_dfu.c b/platforms/chibios/bootloaders/gd32v_dfu.c
new file mode 100644
index 0000000000..1ab0882084
--- /dev/null
+++ b/platforms/chibios/bootloaders/gd32v_dfu.c
@@ -0,0 +1,40 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bootloader.h"
+
+#include <ch.h>
+
+#define DBGMCU_KEY_UNLOCK 0x4B5A6978
+#define DBGMCU_CMD_RESET 0x1
+
+__IO uint32_t *DBGMCU_KEY = (uint32_t *)DBGMCU_BASE + 0x0CU;
+__IO uint32_t *DBGMCU_CMD = (uint32_t *)DBGMCU_BASE + 0x08U;
+
+__attribute__((weak))
+void bootloader_jump(void) {
+ /* The MTIMER unit of the GD32VF103 doesn't have the MSFRST
+ * register to generate a software reset request.
+ * BUT instead two undocumented registers in the debug peripheral
+ * that allow issueing a software reset. WHO would need the MSFRST
+ * register anyway? Source:
+ * https://github.com/esmil/gd32vf103inator/blob/master/include/gd32vf103/dbg.h */
+ *DBGMCU_KEY = DBGMCU_KEY_UNLOCK;
+ *DBGMCU_CMD = DBGMCU_CMD_RESET;
+}
+
+/* Jumping to bootloader is not possible from user code. */
+void enter_bootloader_mode_if_requested(void) { }
diff --git a/platforms/chibios/bootloaders/halfkay.c b/platforms/chibios/bootloaders/halfkay.c
new file mode 100644
index 0000000000..fb9b73dfb3
--- /dev/null
+++ b/platforms/chibios/bootloaders/halfkay.c
@@ -0,0 +1,26 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bootloader.h"
+
+#include <ch.h>
+#include "wait.h"
+
+__attribute__((weak))
+void bootloader_jump(void) {
+ wait_ms(100);
+ __BKPT(0);
+}
diff --git a/platforms/chibios/bootloaders/kiibohd.c b/platforms/chibios/bootloaders/kiibohd.c
new file mode 100644
index 0000000000..f4bb18f058
--- /dev/null
+++ b/platforms/chibios/bootloaders/kiibohd.c
@@ -0,0 +1,33 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bootloader.h"
+
+#include <ch.h>
+
+/* Kiibohd Bootloader (MCHCK and Infinity KB) */
+#define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000
+
+const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+
+__attribute__((weak))
+void bootloader_jump(void) {
+ void *volatile vbat = (void *)VBAT;
+ __builtin_memcpy(vbat, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic));
+
+ // request reset
+ SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk;
+}
diff --git a/platforms/chibios/bootloaders/none.c b/platforms/chibios/bootloaders/none.c
new file mode 100644
index 0000000000..8af151c04d
--- /dev/null
+++ b/platforms/chibios/bootloaders/none.c
@@ -0,0 +1,20 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bootloader.h"
+
+__attribute__((weak))
+void bootloader_jump(void) { }
diff --git a/platforms/chibios/bootloaders/stm32_dfu.c b/platforms/chibios/bootloaders/stm32_dfu.c
new file mode 100644
index 0000000000..f4bd8554bf
--- /dev/null
+++ b/platforms/chibios/bootloaders/stm32_dfu.c
@@ -0,0 +1,96 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bootloader.h"
+
+#include <ch.h>
+#include <hal.h>
+#include "wait.h"
+
+extern uint32_t __ram0_end__;
+
+#ifndef STM32_BOOTLOADER_DUAL_BANK
+# define STM32_BOOTLOADER_DUAL_BANK FALSE
+#endif
+
+#if STM32_BOOTLOADER_DUAL_BANK
+# include "config_common.h"
+
+# ifndef STM32_BOOTLOADER_DUAL_BANK_GPIO
+# error "No STM32_BOOTLOADER_DUAL_BANK_GPIO defined, don't know which pin to toggle"
+# endif
+
+# ifndef STM32_BOOTLOADER_DUAL_BANK_POLARITY
+# define STM32_BOOTLOADER_DUAL_BANK_POLARITY 0
+# endif
+
+# ifndef STM32_BOOTLOADER_DUAL_BANK_DELAY
+# define STM32_BOOTLOADER_DUAL_BANK_DELAY 100000
+# endif
+
+__attribute__((weak))
+void bootloader_jump(void) {
+ // For STM32 MCUs with dual-bank flash, and we're incapable of jumping to the bootloader. The first valid flash
+ // bank is executed unconditionally after a reset, so it doesn't enter DFU unless BOOT0 is high. Instead, we do
+ // it with hardware...in this case, we pull a GPIO high/low depending on the configuration, connects 3.3V to
+ // BOOT0's RC charging circuit, lets it charge the capacitor, and issue a system reset. See the QMK discord
+ // #hardware channel pins for an example circuit.
+ palSetPadMode(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_MODE_OUTPUT_PUSHPULL);
+# if STM32_BOOTLOADER_DUAL_BANK_POLARITY
+ palSetPad(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO));
+# else
+ palClearPad(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO));
+# endif
+
+ // Wait for a while for the capacitor to charge
+ wait_ms(100);
+
+ // Issue a system reset to get the ROM bootloader to execute, with BOOT0 high
+ NVIC_SystemReset();
+}
+
+// not needed at all, but if anybody attempts to invoke it....
+void enter_bootloader_mode_if_requested(void) { }
+
+#else
+
+/* This code should be checked whether it runs correctly on platforms */
+#define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0))
+#define BOOTLOADER_MAGIC 0xDEADBEEF
+#define MAGIC_ADDR (unsigned long *)(SYMVAL(__ram0_end__) - 4)
+
+__attribute__((weak))
+void bootloader_jump(void) {
+ *MAGIC_ADDR = BOOTLOADER_MAGIC; // set magic flag => reset handler will jump into boot loader
+ NVIC_SystemReset();
+}
+
+void enter_bootloader_mode_if_requested(void) {
+ unsigned long *check = MAGIC_ADDR;
+ if (*check == BOOTLOADER_MAGIC) {
+ *check = 0;
+ __set_CONTROL(0);
+ __set_MSP(*(__IO uint32_t *)STM32_BOOTLOADER_ADDRESS);
+ __enable_irq();
+
+ typedef void (*BootJump_t)(void);
+ BootJump_t boot_jump = *(BootJump_t *)(STM32_BOOTLOADER_ADDRESS + 4);
+ boot_jump();
+ while (1)
+ ;
+ }
+}
+#endif
diff --git a/platforms/chibios/bootloaders/stm32duino.c b/platforms/chibios/bootloaders/stm32duino.c
new file mode 100644
index 0000000000..6ff9e28b4d
--- /dev/null
+++ b/platforms/chibios/bootloaders/stm32duino.c
@@ -0,0 +1,24 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bootloader.h"
+
+#include <ch.h>
+
+__attribute__((weak))
+void bootloader_jump(void) {
+ NVIC_SystemReset();
+}
diff --git a/platforms/chibios/bootloaders/tinyuf2.c b/platforms/chibios/bootloaders/tinyuf2.c
new file mode 100644
index 0000000000..ce82fa0c49
--- /dev/null
+++ b/platforms/chibios/bootloaders/tinyuf2.c
@@ -0,0 +1,35 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bootloader.h"
+
+#include <ch.h>
+
+// From tinyuf2's board_api.h
+#define DBL_TAP_MAGIC 0xF01669EF
+
+// defined by linker script
+extern uint32_t _board_dfu_dbl_tap[];
+#define DBL_TAP_REG _board_dfu_dbl_tap[0]
+
+__attribute__((weak))
+void bootloader_jump(void) {
+ DBL_TAP_REG = DBL_TAP_MAGIC;
+ NVIC_SystemReset();
+}
+
+/* not needed, no two-stage reset */
+void enter_bootloader_mode_if_requested(void) { }
diff --git a/platforms/common.mk b/platforms/common.mk
index f7a0fc7028..12ab45f823 100644
--- a/platforms/common.mk
+++ b/platforms/common.mk
@@ -4,7 +4,7 @@ TMK_COMMON_SRC += \
$(PLATFORM_COMMON_DIR)/platform.c \
$(PLATFORM_COMMON_DIR)/suspend.c \
$(PLATFORM_COMMON_DIR)/timer.c \
- $(PLATFORM_COMMON_DIR)/bootloader.c \
+ $(PLATFORM_COMMON_DIR)/bootloaders/$(BOOTLOADER_TYPE).c
# Search Path
VPATH += $(PLATFORM_PATH)
diff --git a/platforms/test/bootloader.c b/platforms/test/bootloaders/none.c
index 5155d9ff04..2920c68f18 100644
--- a/platforms/test/bootloader.c
+++ b/platforms/test/bootloaders/none.c
@@ -16,4 +16,4 @@
#include "bootloader.h"
-void bootloader_jump(void) {}
+void bootloader_jump(void) { }
diff --git a/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h b/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h
index e1749f872d..319ff8487d 100644
--- a/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h
+++ b/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h
@@ -19,7 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define _ARM_ATSAM_PROTOCOL_H_
#include "samd51j18a.h"
-#include "md_bootloader.h"
#include "timer.h"
#include "d51_util.h"
diff --git a/tmk_core/protocol/arm_atsam/md_bootloader.h b/tmk_core/protocol/arm_atsam/md_bootloader.h
deleted file mode 100644
index 362b9bd52a..0000000000
--- a/tmk_core/protocol/arm_atsam/md_bootloader.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef _MD_BOOTLOADER_H_
-#define _MD_BOOTLOADER_H_
-
-extern uint32_t _srom;
-extern uint32_t _lrom;
-extern uint32_t _erom;
-
-#define BOOTLOADER_SERIAL_MAX_SIZE 20 // DO NOT MODIFY!
-
-#ifdef KEYBOARD_massdrop_ctrl
-// WARNING: These are only for CTRL bootloader release "v2.18Jun 22 2018 17:28:08" for bootloader_jump support
-extern uint32_t _eram;
-# define BOOTLOADER_MAGIC 0x3B9ACA00
-# define MAGIC_ADDR (uint32_t *)((intptr_t)(&_eram) - 4)
-#endif
-
-#ifdef MD_BOOTLOADER
-
-# define MCU_HZ 48000000
-# define I2C_HZ 0 // Not used
-
-#endif // MD_BOOTLOADER
-
-#endif //_MD_BOOTLOADER_H_
diff --git a/tmk_core/protocol/arm_atsam/startup.c b/tmk_core/protocol/arm_atsam/startup.c
index 7a5791ab55..ce043bad51 100644
--- a/tmk_core/protocol/arm_atsam/startup.c
+++ b/tmk_core/protocol/arm_atsam/startup.c
@@ -28,7 +28,6 @@
*/
#include "samd51.h"
-#include "md_bootloader.h"
/* Initialize segments */
extern uint32_t _sfixed;
@@ -496,6 +495,11 @@ __attribute__((section(".vectors"))) const DeviceVectors exception_table = {
#endif
};
+// WARNING: These are only for CTRL bootloader release "v2.18Jun 22 2018 17:28:08" for bootloader_jump support
+extern uint32_t _eram;
+#define BOOTLOADER_MAGIC 0x3B9ACA00
+#define MAGIC_ADDR (uint32_t *)((intptr_t)(&_eram) - 4)
+
/**
* \brief This is the code that gets called on processor reset.
* To initialize the device, and call the main() routine.
diff --git a/tmk_core/protocol/arm_atsam/usb/udc.c b/tmk_core/protocol/arm_atsam/usb/udc.c
index d04e9b7b28..1f0c0d95d6 100644
--- a/tmk_core/protocol/arm_atsam/usb/udc.c
+++ b/tmk_core/protocol/arm_atsam/usb/udc.c
@@ -51,7 +51,8 @@
#include "udi_device_conf.h"
#include "udi.h"
#include "udc.h"
-#include "md_bootloader.h"
+
+#define BOOTLOADER_SERIAL_MAX_SIZE 20 // DO NOT MODIFY!
/**
* \ingroup udc_group
@@ -122,6 +123,8 @@ static uint8_t udc_string_product_name[] = USB_DEVICE_PRODUCT_NAME;
# define USB_DEVICE_SERIAL_NAME_SIZE 0
#endif
+extern uint32_t _srom;
+
uint8_t usb_device_serial_name_size = 0;
#if defined USB_DEVICE_SERIAL_USE_BOOTLOADER_SERIAL
uint8_t bootloader_serial_number[BOOTLOADER_SERIAL_MAX_SIZE + 1] = "";