added retry wrapper, made sure SM2 was disabled and not left running

This commit is contained in:
DefenderOfHyrule 2026-02-06 11:11:35 +01:00
parent b23720b976
commit 6cecd25f22
2 changed files with 83 additions and 50 deletions

View file

@ -6,11 +6,17 @@
#include "glitch.h" #include "glitch.h"
#include "misc.h" #include "misc.h"
#include "fuses.h" #include "fuses.h"
#include "board_detect.h"
bool mariko = true; bool mariko = true;
bool board_detected = false; bool board_detected = false;
// maximum number of retries for boot detection before giving up
#define BOOT_DETECT_MAX_RETRIES 4
bool wait_for_boot(int timeout_ms) { bool wait_for_boot(int timeout_ms) {
// retry the entire boot detection sequence up to BOOT_DETECT_MAX_RETRIES times
for (int retry = 0; retry < BOOT_DETECT_MAX_RETRIES; retry++) {
absolute_time_t tio_full = make_timeout_time_ms(timeout_ms); absolute_time_t tio_full = make_timeout_time_ms(timeout_ms);
absolute_time_t tio_cmd1 = tio_full; absolute_time_t tio_cmd1 = tio_full;
init_glitch_pio(); init_glitch_pio();
@ -25,7 +31,8 @@ bool wait_for_boot(int timeout_ms) {
{ {
if (reset_attempts > 4) if (reset_attempts > 4)
{ {
halt_with_error(0, 3); // internal timeout, break and retry the whole sequence
break;
} }
reset_attempts++; reset_attempts++;
reset_cpu(); reset_cpu();
@ -45,7 +52,9 @@ bool wait_for_boot(int timeout_ms) {
} }
else if (last_word == 0x51000000 && word == 0x0055) //read block 0 else if (last_word == 0x51000000 && word == 0x0055) //read block 0
{ {
tio_full = make_timeout_time_ms(100); // OLED models sometimes need more time between block 0 and block 1
// original was 100ms, increased to 250ms for (hopefully) better OLED compatibility
tio_full = make_timeout_time_ms(250);
was_read_zero = true; was_read_zero = true;
} else if (was_read_zero && last_word == 0x4D000200 && word == 0x00B1) // read status - erista only } else if (was_read_zero && last_word == 0x4D000200 && word == 0x00B1) // read status - erista only
{ {
@ -58,6 +67,22 @@ bool wait_for_boot(int timeout_ms) {
last_word = word; last_word = word;
} }
} }
// properly clean up all state machines before retrying
// original deinit only disabled SM 0 and 1, but SM 2 (G_DAT0_SM) was left running
pio_set_sm_mask_enabled(pio1, 0x7, false); // Disable SM 0, 1, AND 2 (0x7 = 0b111)
// clean up GPIO pins
for (int i = PIN_CLK; i <= PIN_DAT; i++)
{
gpio_deinit(i);
gpio_disable_pulls(i);
gpio_disable_input_output(i);
}
gpio_deinit(gli_pin());
// only halt with error if all retries are exhausted
if (retry == BOOT_DETECT_MAX_RETRIES - 1) {
if (was_read_zero) { if (was_read_zero) {
halt_with_error(1, 3); halt_with_error(1, 3);
} }
@ -66,5 +91,11 @@ bool wait_for_boot(int timeout_ms) {
} else { } else {
halt_with_error(3, 3); halt_with_error(3, 3);
} }
}
// small delay before retrying to let hardware settle
sleep_ms(50);
}
return false; return false;
} }

View file

@ -65,7 +65,9 @@ void init_glitch_pio() {
} }
void deinit_glitch_pio() { void deinit_glitch_pio() {
pio_set_sm_mask_enabled(pio1, 0x3, false); // original code only disabled SM 0 and 1 (mask 0x3 = 0b011)
// SM 2 (G_DAT0_SM) is also used, so all 3 (mask 0x7 = 0b111) need to be disabled
pio_set_sm_mask_enabled(pio1, 0x7, false);
for (int i = PIN_CLK; i <= PIN_DAT; i++) for (int i = PIN_CLK; i <= PIN_DAT; i++)
{ {
gpio_deinit(i); gpio_deinit(i);