logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

rp2040.c (1944B)


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