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