Skip to content

Commit dd9b04e

Browse files
committed
Add capability to force stay in DFU and erase app with button
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.
1 parent 08c47b9 commit dd9b04e

File tree

4 files changed

+229
-47
lines changed

4 files changed

+229
-47
lines changed

ports/mimxrt10xx/boards.c

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@
3939
#include "tusb.h"
4040
#endif
4141

42+
// allow board.h to change the pin configuration for the button
43+
#ifndef BUTTON_PIN_CONFIG
44+
// default to 22k pull up
45+
#define BUTTON_PIN_CONFIG ((1<<16) | (3<<14) | (1<<13) | (1<<12) | (4<<3))
46+
#endif
47+
4248
static bool _dfu_mode = false;
4349

4450
// needed by fsl_flexspi_nor_boot
@@ -80,11 +86,32 @@ void board_init(void)
8086
GPIO_PinInit(NEOPIXEL_PORT, NEOPIXEL_PIN, &neopixel_config);
8187
#endif
8288

89+
#if TINYUF2_DFU_BUTTON
90+
// Button
91+
IOMUXC_SetPinMux( BUTTON_PINMUX, 1U);
92+
IOMUXC_SetPinConfig(BUTTON_PINMUX, BUTTON_PIN_CONFIG);
93+
gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0, kGPIO_NoIntmode };
94+
GPIO_PinInit(BUTTON_PORT, BUTTON_PIN, &button_config);
95+
timer_set_ticks(0);
96+
timer_start(1);
97+
while(timer_uptime() < 20);
98+
timer_stop();
99+
timer_set_ticks(0);
100+
#endif
101+
83102
#if TUF2_LOG
84103
board_uart_init(BOARD_UART_BAUDRATE);
85104
#endif
86105
}
87106

107+
#if TINYUF2_DFU_BUTTON
108+
uint32_t board_button_read(void)
109+
{
110+
uint32_t pressed = !!(BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_PORT, BUTTON_PIN));
111+
return pressed;
112+
}
113+
#endif
114+
88115
void board_teardown(void)
89116
{
90117
// no GPIO deinit for GPIO: LED, Neopixel, Button
@@ -241,8 +268,10 @@ void board_app_jump(void)
241268

242269
void board_timer_start(uint32_t ms)
243270
{
244-
// due to highspeed SystemCoreClock = 600 mhz, max interval of 24 bit systick is only 27 ms
245-
const uint32_t tick = (SystemCoreClock/1000) * ms;
271+
uint32_t tick = (SystemCoreClock/1000) * ms;
272+
if (tick > SysTick_LOAD_RELOAD_Msk)
273+
// if requesting too long an interval, just pick the longest we can support.
274+
tick = SysTick_LOAD_RELOAD_Msk;
246275
SysTick_Config( tick );
247276
}
248277

@@ -253,7 +282,7 @@ void board_timer_stop(void)
253282

254283
void SysTick_Handler(void)
255284
{
256-
board_timer_handler();
285+
board_timer_handler();
257286
}
258287

259288
//--------------------------------------------------------------------+

ports/mimxrt10xx/boards/imxrt1010_evk/board.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
//--------------------------------------------------------------------+
7070

7171
// SW8 button
72+
#define TINYUF2_DFU_BUTTON 1
7273
#define BUTTON_PINMUX IOMUXC_GPIO_SD_05_GPIO2_IO05
7374
#define BUTTON_PORT GPIO2
7475
#define BUTTON_PIN 5

src/board_api.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,31 @@ void board_reset(void);
9898
// Write PWM duty value to LED
9999
void board_led_write(uint32_t value);
100100

101+
#ifndef TINYUF2_DFU_BUTTON
102+
#define TINYUF2_DFU_BUTTON 0
103+
#endif
104+
105+
#if TINYUF2_DFU_BUTTON
106+
// Read button. Return a bitmask of which buttons are pressed.
107+
uint32_t board_button_read(void);
108+
109+
// Hold the button for this many milliseconds to erase the app.
110+
#ifndef TINYUF2_DFU_BUTTON_ERASE_TIMEOUT
111+
#define TINYUF2_DFU_BUTTON_ERASE_TIMEOUT (5000)
112+
#endif
113+
114+
// This is a bitmask used to check which button will cause a stay-in-dfu-mode
115+
// default to use any button
116+
// I'm somewhat unsure of how to deal with multiple buttons?
117+
// perhaps instead of (or in addition to) board_button_read, there can be a
118+
// weak function called board_button_read_force_dfu() or something like that
119+
// and that will leave the logic of when to enter the forced DFU mode up to
120+
// the individual boards.
121+
#ifndef TINYUF2_DFU_BUTTON_FORCE_MASK
122+
#define TINYUF2_DFU_BUTTON_FORCE_MASK 0xFFFFFFFF
123+
#endif
124+
#endif
125+
101126
// Write color to rgb strip
102127
void board_rgb_write(uint8_t const rgb[]);
103128

@@ -251,10 +276,28 @@ enum {
251276
STATE_USB_UNPLUGGED, ///< STATE_USB_UNPLUGGED
252277
STATE_WRITING_STARTED, ///< STATE_WRITING_STARTED
253278
STATE_WRITING_FINISHED, ///< STATE_WRITING_FINISHED
279+
STATE_BUTTON_STAY_IN_DFU, ///< STATE_BUTTON_STAY_IN_DFU
280+
STATE_UNUSED, ///< STATE_UNUSED
254281
};
255282

283+
// Set the state of the app, including the indicators
256284
void indicator_set(uint32_t state);
257285

286+
// Get the app state
287+
uint32_t indicator_get(void);
288+
289+
// Start a timer with a tick of interval_ms
290+
void timer_start(uint32_t interval_ms);
291+
292+
// top the timer
293+
void timer_stop(void);
294+
295+
// Set the current tick count
296+
void timer_set_ticks(uint32_t ticks);
297+
298+
// get uptime in ms. Currently, this isn't counted when the timer is stopped.
299+
uint32_t timer_uptime(void);
300+
258301
static inline void rgb_brightness(uint8_t out[3], uint8_t const in[3], uint8_t brightness)
259302
{
260303
for(uint32_t i=0; i<3; i++ )

0 commit comments

Comments
 (0)