qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

rp2040.c (2005B)


      1 // Copyright 2022 Stefan Kerkmann
      2 // SPDX-License-Identifier: GPL-2.0-or-later
      3 
      4 #include "hal.h"
      5 #include "bootloader.h"
      6 #include "gpio.h"
      7 #include "wait.h"
      8 #include "pico/bootrom.h"
      9 
     10 #if !defined(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED)
     11 #    define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED_MASK 0U
     12 #else
     13 #    define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED_MASK (1U << RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED)
     14 #endif
     15 
     16 __attribute__((weak)) void mcu_reset(void) {
     17     NVIC_SystemReset();
     18 }
     19 void bootloader_jump(void) {
     20     reset_usb_boot(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED_MASK, 0U);
     21 }
     22 
     23 void enter_bootloader_mode_if_requested(void) {}
     24 
     25 #if defined(RP2040_BOOTLOADER_DOUBLE_TAP_RESET)
     26 #    if !defined(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT)
     27 #        define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 200U
     28 #    endif
     29 
     30 // Needs to be located in a RAM section that is never initialized on boot to
     31 // preserve its value on reset
     32 static volatile uint32_t __attribute__((section(".ram0.bootloader_magic"))) magic_location;
     33 const uint32_t                                                              magic_token = 0xCAFEB0BA;
     34 
     35 // We can not use the __early_init / enter_bootloader_mode_if_requested hook as
     36 // we depend on an already initialized system with usable memory regions and
     37 // populated function pointer tables to the optimized math functions in the
     38 // bootrom. This function is called just prior to main.
     39 void __late_init(void) {
     40     // All clocks have to be enabled before jumping to the bootloader function,
     41     // otherwise the bootrom will be stuck infinitely.
     42     clocks_init();
     43 
     44     if (magic_location != magic_token) {
     45         magic_location = magic_token;
     46         // ChibiOS is not initialized at this point, so sleeping is only
     47         // possible via busy waiting.
     48         wait_us(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT * 1000U);
     49         magic_location = 0;
     50         return;
     51     }
     52 
     53     magic_location = 0;
     54     reset_usb_boot(RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED_MASK, 0U);
     55 }
     56 
     57 #endif