diff --git a/scripts/buildcommands.py b/scripts/buildcommands.py index 221babe..757535c 100644 --- a/scripts/buildcommands.py +++ b/scripts/buildcommands.py @@ -183,6 +183,47 @@ uint32_t led_gpio = %d, led_gpio_high = %d; // "%s" Handlers.append(HandleStatusLED()) +###################################################################### +# Button entry functionality +###################################################################### + +class HandleButton: + def __init__(self): + self.pin = None + self.ctr_dispatch = { 'DECL_BUTTON': self.decl_button } + def decl_button(self, req): + pin = req.split(None, 1)[1].strip() + if pin.startswith('"') and pin.endswith('"'): + pin = pin[1:-1].strip() + self.pin = pin + def generate_code(self, options): + button_gpio = button_high = button_pullup = 0 + pin = self.pin + if pin: + if pin[0] in "^~": + button_pullup = 1 + if pin[0] == "~": + button_pullup = -1 + pin = pin[1:].strip() + button_high = 1 + if pin[0] == "!": + button_high = 0 + pin = pin[1:].strip() + avail_pins = HandlerEnumerations.get_available_pins() + reserved_pins = HandlerConstants.get_reserved_pins() + button_gpio = avail_pins.get(pin) + if button_gpio is None: + error("Pin %s is not available for this build" % pin) + if pin in reserved_pins: + error("Pin %s is reserved by an active MCU peripheral" % pin) + fmt = """ +int32_t button_gpio = %d, button_high = %d, button_pullup = %d; // "%s" +""" + return fmt % (button_gpio, button_high, button_pullup, self.pin) + + +Handlers.append(HandleButton()) + ###################################################################### # Main code ###################################################################### diff --git a/src/Kconfig b/src/Kconfig index 8fecb9f..4307bc4 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -20,6 +20,14 @@ config ENABLE_DOUBLE_RESET bool "Support bootloader entry on rapid double click of reset button" default y +config ENABLE_BUTTON + bool "Enable bootloader entry on button (or gpio) state" + default n + +config BUTTON_PIN + string "Button GPIO Pin" + depends on ENABLE_BUTTON + config ENABLE_LED bool "Enable Status LED" default n diff --git a/src/canboot_main.c b/src/canboot_main.c index d623be2..9761321 100644 --- a/src/canboot_main.c +++ b/src/canboot_main.c @@ -9,7 +9,9 @@ #include "board/misc.h" // delay_ms #include "board/canbus.h" // canbus_send #include "board/flash.h" // write_page +#include "board/gpio.h" // gpio_in_setup #include "canboot_main.h" // canboot_main +#include "ctr.h" // DECL_CTR #include "led.h" // check_blink_time @@ -219,6 +221,21 @@ check_application_code(void) return 0; } +// Generated by buildcommands.py +DECL_CTR("DECL_BUTTON " __stringify(CONFIG_BUTTON_PIN)); +extern int32_t button_gpio, button_high, button_pullup; + +// Check for a bootloader request via double tap of reset button +static int +check_button_pressed(void) +{ + if (!CONFIG_ENABLE_BUTTON) + return 0; + struct gpio_in button = gpio_in_setup(button_gpio, button_pullup); + udelay(10); + return gpio_in_read(button) == button_high; +} + // Check for a bootloader request via double tap of reset button static void check_double_reset(void) @@ -265,7 +282,8 @@ canboot_main(void) // - The request signature is set in memory (request from app) // - No application code is present uint64_t bootup_code = get_bootup_code(); - if (bootup_code == REQUEST_SIG || !check_application_code()) { + if (bootup_code == REQUEST_SIG || !check_application_code() + || check_button_pressed()) { set_bootup_code(0); enter_bootloader(); }