diff --git a/src/Kconfig b/src/Kconfig index f0ac93e..e5babbe 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -120,6 +120,9 @@ config BUILD_DEPLOYER config HAVE_CHIPID bool default n +config HAVE_BOARD_CHECK_DOUBLE_RESET + bool + default n config KATAPULT_VERSION string diff --git a/src/bootentry.c b/src/bootentry.c index e216a39..1325651 100644 --- a/src/bootentry.c +++ b/src/bootentry.c @@ -32,11 +32,14 @@ check_button_pressed(void) #define DOUBLE_CLICK_MAX_US 500000 // Check for a bootloader request via double tap of reset button -static void +static int check_double_reset(void) { if (!CONFIG_ENABLE_DOUBLE_RESET) - return; + return 0; + if (CONFIG_HAVE_BOARD_CHECK_DOUBLE_RESET) + // Use board specific detection mechanism + return board_check_double_reset(); // Set request signature and delay - this enters the bootloader if // the reset button is double clicked udelay(DOUBLE_CLICK_MIN_US); @@ -44,6 +47,7 @@ check_double_reset(void) udelay(DOUBLE_CLICK_MAX_US - DOUBLE_CLICK_MIN_US); // No reset, clear the bootup code set_bootup_code(0); + return 0; } // Check if bootloader or application should be started @@ -60,8 +64,5 @@ bootentry_check(void) set_bootup_code(0); return 1; } - check_double_reset(); - - // jump to app - return 0; + return check_double_reset(); } diff --git a/src/bootentry.h b/src/bootentry.h index e651e40..04a9f3b 100644 --- a/src/bootentry.h +++ b/src/bootentry.h @@ -2,5 +2,6 @@ #define __BOOTENTRY_H int bootentry_check(void); +int board_check_double_reset(void); #endif // bootentry.h diff --git a/src/rp2040/Kconfig b/src/rp2040/Kconfig index 151a555..020fee2 100644 --- a/src/rp2040/Kconfig +++ b/src/rp2040/Kconfig @@ -7,6 +7,7 @@ config RPXXXX_SELECT default y select HAVE_GPIO select HAVE_CHIPID + select HAVE_BOARD_CHECK_DOUBLE_RESET if MACH_RP2350 config BOARD_DIRECTORY string diff --git a/src/rp2040/Makefile b/src/rp2040/Makefile index dfcad30..baf1f5d 100644 --- a/src/rp2040/Makefile +++ b/src/rp2040/Makefile @@ -21,6 +21,7 @@ mcu-y += generic/armcm_irq.c generic/crc16_ccitt.c mcu-y += ../lib/pico-sdk/hardware/flash.c mcu-$(CONFIG_MACH_RP2040) += rp2040/timer.c rp2040/bootrom.c mcu-$(CONFIG_MACH_RP2350) += generic/armcm_timer.c rp2040/rp2350_bootrom.c +mcu-$(CONFIG_MACH_RP2350) += rp2040/rp2350_dblreset.c src-y += generic/armcm_canboot.c $(mcu-y) src-$(CONFIG_USBSERIAL) += rp2040/usbserial.c generic/usb_cdc.c rp2040/chipid.c diff --git a/src/rp2040/rp2350_dblreset.c b/src/rp2040/rp2350_dblreset.c new file mode 100644 index 0000000..f557ce8 --- /dev/null +++ b/src/rp2040/rp2350_dblreset.c @@ -0,0 +1,31 @@ +// rp2350 specific handling for checking if double reset occurred +// +// Copyright (C) 2024 Kevin O'Connor +// +// This file may be distributed under the terms of the GNU GPLv3 license. + +#include // uint32_t +#include "bootentry.h" // board_check_double_reset +#include "canboot.h" // udelay +#include "hardware/structs/powman.h" // powman_hw + +#define DOUBLE_CLICK_MIN_US 10000 +#define DOUBLE_CLICK_MAX_US 500000 + +int +board_check_double_reset(void) +{ + if (powman_hw->chip_reset & POWMAN_CHIP_RESET_DOUBLE_TAP_BITS) { + // Double reset detected - clear flag and enter bootloader + powman_hw->chip_reset = 0x5afe0000; + return 1; + } + // Initial delay (reset in under 10ms isn't a "double tap") + udelay(DOUBLE_CLICK_MIN_US); + // Set the DOUBLE_TAP_BITS bits + powman_hw->chip_reset = 0x5afe0001; + udelay(DOUBLE_CLICK_MAX_US - DOUBLE_CLICK_MIN_US); + // No reset, clear the DOUBLE_TAP_BITS bits + powman_hw->chip_reset = 0x5afe0000; + return 0; +}