t5s3 standalone clock sync over serial

This commit is contained in:
pelgraine
2026-03-13 21:39:48 +11:00
parent 120c0a739b
commit a6f0052b89
6 changed files with 233 additions and 3 deletions

View File

@@ -2290,6 +2290,14 @@ void MyMesh::checkCLIRescueCmd() {
char hex[PUB_KEY_SIZE * 2 + 1];
mesh::Utils::toHex(hex, self_id.pub_key, PUB_KEY_SIZE);
Serial.printf(" pubkey: %s\n", hex);
{
uint32_t clk = getRTCClock()->getCurrentTime();
if (clk > 1704067200UL) {
Serial.printf(" clock: %lu (valid)\n", (unsigned long)clk);
} else {
Serial.printf(" clock: not set\n");
}
}
// List channels
Serial.println(" channels:");
bool chFound = false;
@@ -2694,6 +2702,45 @@ void MyMesh::checkCLIRescueCmd() {
Serial.printf(" Error: unknown setting '%s' (try 'help')\n", config);
}
// =====================================================================
// CLOCK commands (standalone — matches repeater admin convention)
// =====================================================================
} else if (memcmp(cli_command, "clock sync ", 11) == 0) {
uint32_t epoch = (uint32_t)strtoul(&cli_command[11], nullptr, 10);
if (epoch > 1704067200UL && epoch < 2082758400UL) {
getRTCClock()->setCurrentTime(epoch);
Serial.printf(" > clock synced to %lu\n", (unsigned long)epoch);
} else {
Serial.println(" Error: invalid epoch (must be 2024-2036 range)");
Serial.println(" Hint: on macOS/Linux run: date +%s");
}
} else if (strcmp(cli_command, "clock sync") == 0) {
// Bare "clock sync" without a value — show usage
Serial.println(" Usage: clock sync <unix_epoch>");
Serial.println(" Hint: clock sync $(date +%s)");
} else if (strcmp(cli_command, "clock") == 0) {
uint32_t t = getRTCClock()->getCurrentTime();
if (t > 1704067200UL) {
// Break epoch into human-readable UTC
uint32_t ep = t;
int s = ep % 60; ep /= 60;
int mi = ep % 60; ep /= 60;
int h = ep % 24; ep /= 24;
int yr = 1970;
while (true) { int d = ((yr%4==0&&yr%100!=0)||yr%400==0)?366:365; if(ep<(uint32_t)d) break; ep-=d; yr++; }
int mo = 1;
while (true) {
static const uint8_t dm[]={31,28,31,30,31,30,31,31,30,31,30,31};
int d = (mo==2&&((yr%4==0&&yr%100!=0)||yr%400==0))?29:dm[mo-1];
if(ep<(uint32_t)d) break; ep-=d; mo++;
}
int dy = ep + 1;
Serial.printf(" > %04d-%02d-%02d %02d:%02d:%02d UTC (epoch: %lu)\n",
yr, mo, dy, h, mi, s, (unsigned long)t);
} else {
Serial.printf(" > not set (epoch: %lu)\n", (unsigned long)t);
}
// =====================================================================
// HELP command
// =====================================================================
@@ -2713,6 +2760,11 @@ void MyMesh::checkCLIRescueCmd() {
Serial.println(" int.thresh <0|14+> Interference threshold dB (0=off, 14=typical)");
Serial.println(" gps.baud <rate> GPS baud (0=default, reboot to apply)");
Serial.println("");
Serial.println(" Clock:");
Serial.println(" clock Show current RTC time (UTC)");
Serial.println(" clock sync <epoch> Set RTC from Unix timestamp");
Serial.println(" Hint: clock sync $(date +%s)");
Serial.println("");
Serial.println(" Compound commands:");
Serial.println(" get all Dump all settings");
Serial.println(" get radio Show all radio params");

View File

@@ -1189,14 +1189,57 @@ void setup() {
}
#endif
// RTC diagnostic — verify the auto-discovered RTC is working
// RTC diagnostic + boot-time serial clock sync (T5S3 has no GPS)
#if defined(LilyGo_T5S3_EPaper_Pro)
{
uint32_t rtcTime = rtc_clock.getCurrentTime();
Serial.printf("setup() - RTC time: %lu (valid=%s)\n", rtcTime,
rtcTime > 1700000000 ? "YES" : "NO");
if (rtcTime < 1700000000) {
Serial.println("setup() - RTC has no valid time (will be set by companion app)");
// No valid time. If a USB host has the serial port open (Serial
// evaluates true on ESP32-S3 native CDC), request an automatic
// clock sync. The PlatformIO monitor filter "clock_sync" watches
// for MECK_CLOCK_REQ and responds immediately with the host time.
// Manual sync is also accepted: type "clock sync <epoch>" in any
// serial terminal.
if (Serial) {
Serial.println("MECK_CLOCK_REQ");
Serial.println(" (Waiting 3s for clock sync from host...)");
char syncBuf[64];
int syncPos = 0;
unsigned long syncDeadline = millis() + 3000;
bool synced = false;
while (millis() < syncDeadline && !synced) {
while (Serial.available() && syncPos < (int)sizeof(syncBuf) - 1) {
char c = Serial.read();
if (c == '\r' || c == '\n') {
if (syncPos > 0) {
syncBuf[syncPos] = '\0';
if (memcmp(syncBuf, "clock sync ", 11) == 0) {
uint32_t epoch = (uint32_t)strtoul(&syncBuf[11], nullptr, 10);
if (epoch > 1704067200UL && epoch < 2082758400UL) {
rtc_clock.setCurrentTime(epoch);
Serial.printf(" > Clock synced to %lu\n", (unsigned long)epoch);
synced = true;
}
}
syncPos = 0;
}
break;
}
syncBuf[syncPos++] = c;
}
if (!synced) delay(10);
}
if (!synced) {
Serial.println(" > No clock sync received, continuing boot");
Serial.println(" > Use 'clock sync <epoch>' any time to sync later");
}
} else {
Serial.println("setup() - RTC not set, no serial host detected (skipping sync window)");
}
}
}
#endif