Fixed Issue #1, see explanations

This commit is contained in:
John Poole 2026-02-14 14:17:58 -08:00
commit 0217ece5e5

View file

@ -7,13 +7,14 @@
#include <FS.h> #include <FS.h>
#include <SD.h> #include <SD.h>
#include <SPI.h> #include <SPI.h>
#include "driver/gpio.h" // gpio_get_level()
#include "tbeam_supreme_adapter.h" #include "tbeam_supreme_adapter.h"
// ------------------------- // -------------------------
// Configuration toggles // Configuration toggles
// ------------------------- // -------------------------
#define ENABLE_SD_RAIL_CYCLE 1 // Power-cycle AXP2101 BLDO1 (SD rail) at boot. #define ENABLE_SD_RAIL_CYCLE 1 // Power-cycle AXP2101 BLDO1 (SD rail) at boot.
#define ENABLE_PIN_DUMPS 1 // Log SPI pin logic levels at key points. #define ENABLE_PIN_DUMPS 1 // Log SPI pin logic levels at key points (NON-INTRUSIVE).
#define STARTUP_SERIAL_DELAY_MS 5000 #define STARTUP_SERIAL_DELAY_MS 5000
// ------------------------- // -------------------------
@ -77,8 +78,6 @@ static void dumpPmu(const char* tag, XPowersLibInterface* pmu) {
} }
bool bldo1 = pmu->isPowerChannelEnable(XPOWERS_BLDO1); bool bldo1 = pmu->isPowerChannelEnable(XPOWERS_BLDO1);
// Adapter enables these measures in initPmuForPeripherals().
int vbus = pmu->getVbusVoltage(); int vbus = pmu->getVbusVoltage();
int batt = pmu->getBattVoltage(); int batt = pmu->getBattVoltage();
@ -86,27 +85,20 @@ static void dumpPmu(const char* tag, XPowersLibInterface* pmu) {
tag, bldo1 ? "ON" : "OFF", vbus, batt); tag, bldo1 ? "ON" : "OFF", vbus, batt);
} }
// IMPORTANT: this function MUST NOT modify pin modes (regression cause).
static void dumpSdPins(const char* tag) { static void dumpSdPins(const char* tag) {
#if ENABLE_PIN_DUMPS #if ENABLE_PIN_DUMPS
const int CS = tbeam_supreme::sdCs(); const gpio_num_t CS = (gpio_num_t)tbeam_supreme::sdCs();
const int SCK = tbeam_supreme::sdSck(); const gpio_num_t SCK = (gpio_num_t)tbeam_supreme::sdSck();
const int MISO = tbeam_supreme::sdMiso(); const gpio_num_t MISO = (gpio_num_t)tbeam_supreme::sdMiso();
const int MOSI = tbeam_supreme::sdMosi(); const gpio_num_t MOSI = (gpio_num_t)tbeam_supreme::sdMosi();
// Use pullups to make floating lines visible. int cs = gpio_get_level(CS);
pinMode(CS, INPUT_PULLUP); int sck = gpio_get_level(SCK);
pinMode(SCK, INPUT_PULLUP); int miso = gpio_get_level(MISO);
pinMode(MISO, INPUT_PULLUP); int mosi = gpio_get_level(MOSI);
pinMode(MOSI, INPUT_PULLUP);
delay(2); logf("PINS(%s): CS=%d SCK=%d MISO=%d MOSI=%d", tag, cs, sck, miso, mosi);
logf("PINS(%s): CS=%d SCK=%d MISO=%d MOSI=%d",
tag,
digitalRead(CS),
digitalRead(SCK),
digitalRead(MISO),
digitalRead(MOSI));
#else #else
(void)tag; (void)tag;
#endif #endif
@ -116,7 +108,6 @@ static void dumpSdPins(const char* tag) {
// Power + bus conditioning // Power + bus conditioning
// ------------------------- // -------------------------
static void forceSpiDeselected() { static void forceSpiDeselected() {
// Keep SD and IMU deselected (shared bus risk if IMU CS floats low).
pinMode(tbeam_supreme::sdCs(), OUTPUT); pinMode(tbeam_supreme::sdCs(), OUTPUT);
digitalWrite(tbeam_supreme::sdCs(), HIGH); digitalWrite(tbeam_supreme::sdCs(), HIGH);
@ -126,13 +117,14 @@ static void forceSpiDeselected() {
static bool initPmuForSdPower() { static bool initPmuForSdPower() {
bool ok = tbeam_supreme::initPmuForPeripherals(g_pmu, &Serial); bool ok = tbeam_supreme::initPmuForPeripherals(g_pmu, &Serial);
if (ok) { if (!ok) {
logf("ERROR: PMU init failed");
return false;
}
logf("PMU adapter: AXP2101 ready, BLDO1(SD)=%s", logf("PMU adapter: AXP2101 ready, BLDO1(SD)=%s",
g_pmu && g_pmu->isPowerChannelEnable(XPOWERS_BLDO1) ? "ON" : "OFF"); g_pmu && g_pmu->isPowerChannelEnable(XPOWERS_BLDO1) ? "ON" : "OFF");
} else { return true;
logf("ERROR: PMU init failed");
}
return ok;
} }
static void cycleSdRail(XPowersLibInterface* pmu, static void cycleSdRail(XPowersLibInterface* pmu,
@ -153,7 +145,6 @@ static void cycleSdRail(XPowersLibInterface* pmu,
pmu->disablePowerOutput(XPOWERS_BLDO1); pmu->disablePowerOutput(XPOWERS_BLDO1);
delay(off_ms); delay(off_ms);
// Re-assert voltage and enable.
pmu->setPowerChannelVoltage(XPOWERS_BLDO1, 3300); pmu->setPowerChannelVoltage(XPOWERS_BLDO1, 3300);
pmu->enablePowerOutput(XPOWERS_BLDO1); pmu->enablePowerOutput(XPOWERS_BLDO1);
delay(on_settle_ms); delay(on_settle_ms);
@ -201,9 +192,7 @@ static bool tryMountWithBus(SPIClass& bus, const char* busName, uint32_t hz, boo
} }
if (!SD.begin(tbeam_supreme::sdCs(), bus, hz)) { if (!SD.begin(tbeam_supreme::sdCs(), bus, hz)) {
if (verbose) { if (verbose) logf("SD: mount failed (possible non-FAT format, power, or bus issue)");
logf("SD: mount failed (possible non-FAT format, power, or bus issue)");
}
return false; return false;
} }
@ -220,7 +209,6 @@ static bool tryMountWithBus(SPIClass& bus, const char* busName, uint32_t hz, boo
} }
static bool mountPreferred(bool verbose) { static bool mountPreferred(bool verbose) {
// Conservative: HSPI @ 400kHz is the most forgiving initial probe.
return tryMountWithBus(sdSpiH, "HSPI", 400000, verbose); return tryMountWithBus(sdSpiH, "HSPI", 400000, verbose);
} }
@ -406,7 +394,7 @@ void setup() {
initPmuForSdPower(); initPmuForSdPower();
dumpPmu("post-pmu-init", g_pmu); dumpPmu("post-pmu-init", g_pmu);
// Software equivalent of "remove/insert card" that fixes your issue. // Software equivalent of "remove/insert card".
cycleSdRail(g_pmu); cycleSdRail(g_pmu);
logf("Watcher: waiting %lu ms for SD rail/card stabilization", (unsigned long)kStartupWarmupMs); logf("Watcher: waiting %lu ms for SD rail/card stabilization", (unsigned long)kStartupWarmupMs);
@ -414,7 +402,6 @@ void setup() {
dumpSdPins("pre-warmup-mount"); dumpSdPins("pre-warmup-mount");
// Warm-up attempts before first status decision.
bool warmMounted = false; bool warmMounted = false;
for (uint8_t i = 0; i < 3; ++i) { for (uint8_t i = 0; i < 3; ++i) {
if (mountPreferred(false)) { if (mountPreferred(false)) {