Safety, testing Exercise 21 README internal linking on Forgejo

This commit is contained in:
John Poole 2026-04-14 11:16:54 -07:00
commit 1d0a29f2a3
18 changed files with 2098 additions and 1 deletions

View file

@ -339,6 +339,7 @@ void StartupSdManager::permissionsDemo(const char* path) {
void StartupSdManager::setStateMounted() {
if (watchState_ != SdWatchState::MOUNTED) {
dumpSdPins("mounted");
logf("EVENT: card inserted/mounted");
mountedEventPending_ = true;
notify(SdEvent::CARD_MOUNTED, "SD card mounted");
@ -348,10 +349,12 @@ void StartupSdManager::setStateMounted() {
void StartupSdManager::setStateAbsent() {
if (watchState_ == SdWatchState::MOUNTED) {
dumpSdPins("removed");
logf("EVENT: card removed/unavailable");
removedEventPending_ = true;
notify(SdEvent::CARD_REMOVED, "SD card removed");
} else if (watchState_ != SdWatchState::ABSENT) {
dumpSdPins("absent");
logf("EVENT: no card detected");
notify(SdEvent::NO_CARD, "Missing SD card or invalid FAT16/FAT32 format");
}

View file

@ -44,9 +44,11 @@
static const uint32_t kSerialDelayMs = 5000;
static const uint32_t kLoopMsDiscipline = 60000;
static const uint32_t kNoTimeDelayMs = 30000;
static const uint32_t kNoTimeDelayMs = 12000;
static const uint32_t kGpsStartupProbeMs = 20000;
static const uint32_t kPpsWaitTimeoutMs = 1500;
static const bool kTemporaryAllowSdLogWithoutGps = true;
static const uint32_t kGpsDisciplineGraceMs = 12000;
static XPowersLibInterface* g_pmu = nullptr;
static StartupSdManager g_sd(Serial);
@ -55,6 +57,7 @@ static HardwareSerial g_gpsSerial(1);
static uint32_t g_logSeq = 0;
static uint32_t g_nextDisciplineMs = 0;
static uint32_t g_bootMs = 0;
static bool g_gpsPathReady = false;
static char g_gpsLine[128];
@ -646,6 +649,37 @@ static void waitWithUpdates(uint32_t delayMs) {
}
}
static bool appendFallbackLogNoGps(const char* reason) {
logf("Attempting write to SD Card");
if (!ensureGpsLogPathReady()) {
logf("SD not mounted, skipping fallback append to gps/discipline_rtc.log");
return false;
}
File f = SD.open("/gps/discipline_rtc.log", FILE_APPEND);
if (!f) {
logf("Could not open /gps/discipline_rtc.log for fallback append");
return false;
}
char line[256];
snprintf(line,
sizeof(line),
"NO_GPS_UTC\t millis=%lu\t reason=%s\t this is a test write\t sd_probe_only=1\t fw_epoch=%lu; fw_build_utc=%s",
(unsigned long)millis(),
reason ? reason : "unknown",
(unsigned long)FW_BUILD_EPOCH,
FW_BUILD_UTC);
size_t wrote = f.println(line);
f.close();
if (wrote == 0) {
logf("Fallback append failed: /gps/discipline_rtc.log");
return false;
}
logf("Write to SD Card successful");
return true;
}
static void showNoTimeAndDelay() {
uint8_t sats = bestSatelliteCount();
char l3[24];
@ -657,6 +691,14 @@ static void showNoTimeAndDelay() {
static bool disciplineRtcToGps() {
if (!gpsUtcIsFresh()) {
if (kTemporaryAllowSdLogWithoutGps &&
(uint32_t)(millis() - g_bootMs) >= kGpsDisciplineGraceMs) {
const bool ok = appendFallbackLogNoGps("gps_utc_unavailable_after_grace");
oledShowLines("GPS time unavailable", "SD fallback log only", ok ? "Fallback write ok" : "Fallback write fail");
logf("Temporary bypass: GPS UTC unavailable after grace; fallback log %s", ok ? "ok" : "failed");
waitWithUpdates(kNoTimeDelayMs);
return false;
}
showNoTimeAndDelay();
return false;
}
@ -670,6 +712,14 @@ static bool disciplineRtcToGps() {
DateTime gpsSnap = g_gps.utc;
if (!waitForNextPps(kPpsWaitTimeoutMs)) {
if (kTemporaryAllowSdLogWithoutGps &&
(uint32_t)(millis() - g_bootMs) >= kGpsDisciplineGraceMs) {
const bool ok = appendFallbackLogNoGps("pps_missing_after_grace");
oledShowLines("GPS 1PPS missing", "SD fallback log only", ok ? "Fallback write ok" : "Fallback write fail");
logf("Temporary bypass: 1PPS missing after grace; fallback log %s", ok ? "ok" : "failed");
waitWithUpdates(kNoTimeDelayMs);
return false;
}
oledShowLines("GPS 1PPS missing", "RTC NOT disciplined", "Retry in 30 seconds");
logf("No 1PPS edge observed within timeout. Waiting 30 seconds.");
waitWithUpdates(kNoTimeDelayMs);
@ -726,6 +776,7 @@ static bool disciplineRtcToGps() {
void setup() {
Serial.begin(115200);
delay(kSerialDelayMs);
g_bootMs = millis();
Serial.println("\r\n==================================================");
Serial.println("Exercise 11: Set RTC to GPS with 1PPS discipline");
@ -770,6 +821,7 @@ void loop() {
if (g_sd.consumeMountedEvent()) {
g_gpsPathReady = false;
g_sd.printCardInfo();
(void)ensureGpsLogPathReady();
}
if (g_sd.consumeRemovedEvent()) {