Skip to content

Commit

Permalink
Add capability to force stay in DFU and erase app with button
Browse files Browse the repository at this point in the history
This adds a check to see if a button is pressed. If the board button is pressed, stay if dfu mode.

Behavior is currently:

* If button is pressed at power up, enter DFU mode regardless of whether app is valid.
* If button is held longer than a timeout (Default 5 seconds), the app is erased.
* If button is released within the timeout period, the app is booted, if it's valid.
  • Loading branch information
ccrome committed Mar 11, 2023
1 parent 08c47b9 commit dd9b04e
Show file tree
Hide file tree
Showing 4 changed files with 229 additions and 47 deletions.
35 changes: 32 additions & 3 deletions ports/mimxrt10xx/boards.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@
#include "tusb.h"
#endif

// allow board.h to change the pin configuration for the button
#ifndef BUTTON_PIN_CONFIG
// default to 22k pull up
#define BUTTON_PIN_CONFIG ((1<<16) | (3<<14) | (1<<13) | (1<<12) | (4<<3))
#endif

static bool _dfu_mode = false;

// needed by fsl_flexspi_nor_boot
Expand Down Expand Up @@ -80,11 +86,32 @@ void board_init(void)
GPIO_PinInit(NEOPIXEL_PORT, NEOPIXEL_PIN, &neopixel_config);
#endif

#if TINYUF2_DFU_BUTTON
// Button
IOMUXC_SetPinMux( BUTTON_PINMUX, 1U);
IOMUXC_SetPinConfig(BUTTON_PINMUX, BUTTON_PIN_CONFIG);
gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0, kGPIO_NoIntmode };
GPIO_PinInit(BUTTON_PORT, BUTTON_PIN, &button_config);
timer_set_ticks(0);
timer_start(1);
while(timer_uptime() < 20);
timer_stop();
timer_set_ticks(0);
#endif

#if TUF2_LOG
board_uart_init(BOARD_UART_BAUDRATE);
#endif
}

#if TINYUF2_DFU_BUTTON
uint32_t board_button_read(void)
{
uint32_t pressed = !!(BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_PORT, BUTTON_PIN));
return pressed;
}
#endif

void board_teardown(void)
{
// no GPIO deinit for GPIO: LED, Neopixel, Button
Expand Down Expand Up @@ -241,8 +268,10 @@ void board_app_jump(void)

void board_timer_start(uint32_t ms)
{
// due to highspeed SystemCoreClock = 600 mhz, max interval of 24 bit systick is only 27 ms
const uint32_t tick = (SystemCoreClock/1000) * ms;
uint32_t tick = (SystemCoreClock/1000) * ms;
if (tick > SysTick_LOAD_RELOAD_Msk)
// if requesting too long an interval, just pick the longest we can support.
tick = SysTick_LOAD_RELOAD_Msk;
SysTick_Config( tick );
}

Expand All @@ -253,7 +282,7 @@ void board_timer_stop(void)

void SysTick_Handler(void)
{
board_timer_handler();
board_timer_handler();
}

//--------------------------------------------------------------------+
Expand Down
1 change: 1 addition & 0 deletions ports/mimxrt10xx/boards/imxrt1010_evk/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
//--------------------------------------------------------------------+

// SW8 button
#define TINYUF2_DFU_BUTTON 1
#define BUTTON_PINMUX IOMUXC_GPIO_SD_05_GPIO2_IO05
#define BUTTON_PORT GPIO2
#define BUTTON_PIN 5
Expand Down
43 changes: 43 additions & 0 deletions src/board_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,31 @@ void board_reset(void);
// Write PWM duty value to LED
void board_led_write(uint32_t value);

#ifndef TINYUF2_DFU_BUTTON
#define TINYUF2_DFU_BUTTON 0
#endif

#if TINYUF2_DFU_BUTTON
// Read button. Return a bitmask of which buttons are pressed.
uint32_t board_button_read(void);

// Hold the button for this many milliseconds to erase the app.
#ifndef TINYUF2_DFU_BUTTON_ERASE_TIMEOUT
#define TINYUF2_DFU_BUTTON_ERASE_TIMEOUT (5000)
#endif

// This is a bitmask used to check which button will cause a stay-in-dfu-mode
// default to use any button
// I'm somewhat unsure of how to deal with multiple buttons?
// perhaps instead of (or in addition to) board_button_read, there can be a
// weak function called board_button_read_force_dfu() or something like that
// and that will leave the logic of when to enter the forced DFU mode up to
// the individual boards.
#ifndef TINYUF2_DFU_BUTTON_FORCE_MASK
#define TINYUF2_DFU_BUTTON_FORCE_MASK 0xFFFFFFFF
#endif
#endif

// Write color to rgb strip
void board_rgb_write(uint8_t const rgb[]);

Expand Down Expand Up @@ -251,10 +276,28 @@ enum {
STATE_USB_UNPLUGGED, ///< STATE_USB_UNPLUGGED
STATE_WRITING_STARTED, ///< STATE_WRITING_STARTED
STATE_WRITING_FINISHED, ///< STATE_WRITING_FINISHED
STATE_BUTTON_STAY_IN_DFU, ///< STATE_BUTTON_STAY_IN_DFU
STATE_UNUSED, ///< STATE_UNUSED
};

// Set the state of the app, including the indicators
void indicator_set(uint32_t state);

// Get the app state
uint32_t indicator_get(void);

// Start a timer with a tick of interval_ms
void timer_start(uint32_t interval_ms);

// top the timer
void timer_stop(void);

// Set the current tick count
void timer_set_ticks(uint32_t ticks);

// get uptime in ms. Currently, this isn't counted when the timer is stopped.
uint32_t timer_uptime(void);

static inline void rgb_brightness(uint8_t out[3], uint8_t const in[3], uint8_t brightness)
{
for(uint32_t i=0; i<3; i++ )
Expand Down
Loading

0 comments on commit dd9b04e

Please sign in to comment.