forked from jappel/VersaMCU
Fix bootloader hardware bring-up and add key-based boot entry
Hardware-tested the UF2 bootloader end to end on a real VersaPad v2 board. Found and fixed a real bug: the bootloader's jump into the app (__set_MSP -> SCB->VTOR -> bx) hard-faulted on every standalone boot, even with the debugger fully disconnected; identical register/VTOR values injected directly by a halted debugger ran fine, which pointed at the missing __DSB()/__ISB() barriers ARM's own guidance requires for this exact pattern. Also fixed a USB PID collision (0x0011 is Adafruit's own Gemma M0 bootloader PID, misidentified by Windows as a Circuit Playground COM port instead of exposing VERSABOOT). This board has no dedicated reset/boot button, so add a hardware boot entry that doesn't need one: holding the bottom-right Cherry MX key (key_id 24) during reset/power-on drives its matrix row and reads its column directly in the bootloader, before the app is even validated. Also corrected the app-side flash_with_bootloader.ld (was missing the NVM carve-out flash_without_bootloader.ld already has) and boards/versapad.json (wrong flash/RAM size, wrong MCU macro, stale PID), and enabled the previously-commented-out env:versapad_usb. Documented findings in bootloader/README.md, bootloader/TESTING.md, and doc/09_known_limitations.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
4749adcd1d
commit
f60a29137c
8 changed files with 234 additions and 82 deletions
|
|
@ -87,6 +87,38 @@ extern int8_t led_tick_step;
|
|||
#define RESET_CONTROLLER RSTC
|
||||
#endif
|
||||
|
||||
#if defined(BOOT_KEY_ROW_PIN) && defined(BOOT_KEY_COL_PIN)
|
||||
/**
|
||||
* \brief Check whether the boot-hold key (bottom-right Cherry MX button) is
|
||||
* held down. Drives its matrix row low and reads its matrix column back,
|
||||
* the same polarity the app firmware's own matrix scan uses.
|
||||
*/
|
||||
static bool boot_key_pressed(void) {
|
||||
PORT_PINCFG_Type col_cfg = {0};
|
||||
col_cfg.bit.PMUXEN = false;
|
||||
col_cfg.bit.INEN = true; // external 10k pull-up already on the board
|
||||
|
||||
PORT_PINCFG_Type row_cfg = {0};
|
||||
row_cfg.bit.PMUXEN = false;
|
||||
row_cfg.bit.DRVSTR = true;
|
||||
|
||||
PINCFG(BOOT_KEY_COL_PIN) = col_cfg.reg;
|
||||
PINOP(BOOT_KEY_COL_PIN, DIRCLR); // column stays an input
|
||||
|
||||
PINOP(BOOT_KEY_ROW_PIN, OUTCLR); // pre-set drive level before enabling output
|
||||
PINCFG(BOOT_KEY_ROW_PIN) = row_cfg.reg;
|
||||
PINOP(BOOT_KEY_ROW_PIN, DIRSET); // row -> output, driving low
|
||||
|
||||
for (volatile int i = 0; i < 200; i++) {
|
||||
} // let the row settle through the diode/pull-up RC
|
||||
|
||||
bool pressed = (PINIP(BOOT_KEY_COL_PIN) == 0);
|
||||
|
||||
PINOP(BOOT_KEY_ROW_PIN, DIRCLR); // release row back to high-Z
|
||||
return pressed;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Check the application startup condition
|
||||
*
|
||||
|
|
@ -94,6 +126,13 @@ extern int8_t led_tick_step;
|
|||
static void check_start_application(void) {
|
||||
uint32_t app_start_address;
|
||||
|
||||
#if defined(BOOT_KEY_ROW_PIN) && defined(BOOT_KEY_COL_PIN)
|
||||
if (boot_key_pressed()) {
|
||||
/* Stay in bootloader */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check if there is an IO which will hold us inside the bootloader.
|
||||
#if defined(HOLD_PIN) && defined(HOLD_STATE)
|
||||
PORT_PINCFG_Type pincfg = {0};
|
||||
|
|
@ -167,6 +206,14 @@ static void check_start_application(void) {
|
|||
/* Rebase the vector table base address */
|
||||
SCB->VTOR = ((uint32_t)APP_START_ADDRESS & SCB_VTOR_TBLOFF_Msk);
|
||||
|
||||
/* Ensure the MSP/VTOR writes are visible before jumping; without these
|
||||
* barriers the app's first fetch can race the pipeline (observed on
|
||||
* real hardware: identical MSP/VTOR/PC values injected by a halted
|
||||
* debugger boot fine, but the bootloader's own running jump hard-faults
|
||||
* every time). */
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
/* Jump to application Reset Handler in the application */
|
||||
asm("bx %0" ::"r"(app_start_address));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue