summaryrefslogtreecommitdiff
path: root/platforms/chibios/bootloaders/rp2040.c
diff options
context:
space:
mode:
authorStefan Kerkmann <karlk90@pm.me>2022-06-30 13:19:27 +0200
committerGitHub <noreply@github.com>2022-06-30 13:19:27 +0200
commitd7173967087e022d20d1f9c812b1b668e9d3f71b (patch)
tree68198271dd5125193795c399c6478ead0a71b09f /platforms/chibios/bootloaders/rp2040.c
parentd206c1791e5858323cff0664f39f95edc1381ac5 (diff)
[Core] Add Raspberry Pi RP2040 support (#14877)
* Disable RESET keycode because of naming conflicts * Add Pico SDK as submodule * Add RP2040 build support to QMK * Adjust USB endpoint structs for RP2040 * Add RP2040 bootloader and double-tap reset routine * Add generic and pro micro RP2040 boards * Add RP2040 onekey keyboard * Add WS2812 PIO DMA enabled driver and documentation Supports regular and open-drain output configuration. RP2040 GPIOs are sadly not 5V tolerant, so this is a bit use-less or needs extra hardware or you take the risk to fry your hardware. * Adjust SIO Driver for RP2040 * Adjust I2C Driver for RP2040 * Adjust SPI Driver for RP2040 * Add PIO serial driver and documentation * Add general RP2040 documentation * Apply suggestions from code review Co-authored-by: Nick Brassel <nick@tzarc.org> Co-authored-by: Nick Brassel <nick@tzarc.org>
Diffstat (limited to 'platforms/chibios/bootloaders/rp2040.c')
-rw-r--r--platforms/chibios/bootloaders/rp2040.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/platforms/chibios/bootloaders/rp2040.c b/platforms/chibios/bootloaders/rp2040.c
new file mode 100644
index 0000000000..13a54036ef
--- /dev/null
+++ b/platforms/chibios/bootloaders/rp2040.c
@@ -0,0 +1,57 @@
+// Copyright 2022 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "quantum.h"
+#include "hal.h"
+#include "bootloader.h"
+#include "pico/bootrom.h"
+
+#if !defined(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED)
+# define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED_MASK 0U
+#else
+# define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED_MASK (1U << RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED)
+#endif
+
+__attribute__((weak)) void mcu_reset(void) {
+ NVIC_SystemReset();
+}
+void bootloader_jump(void) {
+ reset_usb_boot(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED_MASK, 0U);
+}
+
+void enter_bootloader_mode_if_requested(void) {}
+
+#if defined(RP2040_BOOTLOADER_DOUBLE_TAP_RESET)
+# if !defined(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT)
+# define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 200U
+# endif
+
+// Needs to be located in a RAM section that is never initialized on boot to
+// preserve its value on reset
+static volatile uint32_t __attribute__((section(".ram0.bootloader_magic"))) magic_location;
+const uint32_t magic_token = 0xCAFEB0BA;
+
+// We can not use the __early_init / enter_bootloader_mode_if_requested hook as
+// we depend on an already initialized system with usable memory regions and
+// populated function pointer tables to the optimized math functions in the
+// bootrom. This function is called just prior to main.
+void __late_init(void) {
+ // All clocks have to be enabled before jumping to the bootloader function,
+ // otherwise the bootrom will be stuck infinitely.
+ clocks_init();
+
+ if (magic_location != magic_token) {
+ magic_location = magic_token;
+ // ChibiOS is not initialized at this point, so sleeping is only
+ // possible via busy waiting. The internal timer peripheral is running
+ // at this point with a precision of 1us.
+ chSysPolledDelayX(MS2RTC(1 * MHZ, RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT));
+ magic_location = 0;
+ return;
+ }
+
+ magic_location = 0;
+ reset_usb_boot(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED_MASK, 0U);
+}
+
+#endif