Fix SPI bus contention crash on serial game upload

Serial uploader was crashing the Pico when launching games because
it accessed SD card (SPI) while Core 1 was refreshing display (also SPI).
Display and SD card share the same SPI bus and cannot be accessed
simultaneously.

Split game launch into prepare and execute phases:
- prepare: Re-scan games directory (safe, SD access done immediately)
- execute: Load Lua script from SD (deferred until display is idle)

Main loop now checks !is_refresh_in_progress() before completing
launch, preventing SPI conflicts.

Also updated SD card best practices skill to document SPI bus
contention as the #1 most critical issue to avoid.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Adolfo Reyna
2026-02-12 23:25:31 -05:00
parent f8fb04db1b
commit 518bc054c4
5 changed files with 158 additions and 24 deletions

View File

@@ -572,17 +572,24 @@ int main()
while (1) {
// 0. Process serial uploads (for rapid game iteration)
bool game_launched_via_serial = serial_uploader.process();
if (game_launched_via_serial) {
// A new game was uploaded and launched - trigger redraw
needs_refresh = true;
current_game = launcher.get_selected_game();
// Note: game is already initialized by select_game_by_name()
serial_uploader.process();
// If serial uploader wants to launch a game, wait until it's safe (no display refresh)
if (serial_uploader.wants_to_launch_game() && !is_refresh_in_progress()) {
// Safe to launch now - no SPI conflict with display
bool game_launched = serial_uploader.complete_launch();
if (game_launched) {
// A new game was uploaded and launched - trigger redraw
needs_refresh = true;
current_game = launcher.get_selected_game();
// Note: game is already initialized by select_game_by_name()
}
}
// Determine if we should sleep or stay awake for updates
bool stay_awake = false;
if (pending_refresh) stay_awake = true;
if (serial_uploader.wants_to_launch_game()) stay_awake = true; // Don't sleep while waiting to launch
if (launcher.is_game_selected()) {
Game* g = launcher.get_selected_game();