Codex added unified library, all work

This commit is contained in:
John Poole 2026-04-19 10:20:35 -07:00
commit 8370e546ff
25 changed files with 2935 additions and 0 deletions

View file

@ -0,0 +1,92 @@
; Repository-level hardware test for tbeam_display.
[platformio]
default_envs = cy
extra_configs = ../../shared/platformio/tbeam_supreme_units.ini
[display_test_base]
extends = tbeam_supreme_common
lib_deps =
${tbeam_supreme_common.lib_deps}
olikraus/U8g2@^2.36.4
build_flags =
${tbeam_supreme_common.build_flags}
-D DISPLAY_TEST=1
[env:amy]
extends = display_test_base
build_flags =
${display_test_base.build_flags}
-D BOARD_ID=\"AMY\"
-D NODE_LABEL=\"Amy\"
-D NODE_SHORT=\"A\"
-D NODE_SLOT_INDEX=0
-D LOG_AP_IP_OCTET=23
-D GNSS_CHIP_NAME=\"L76K\"
[env:bob]
extends = display_test_base
build_flags =
${display_test_base.build_flags}
-D BOARD_ID=\"BOB\"
-D NODE_LABEL=\"Bob\"
-D NODE_SHORT=\"B\"
-D NODE_SLOT_INDEX=1
-D LOG_AP_IP_OCTET=24
-D GNSS_CHIP_NAME=\"L76K\"
[env:cy]
extends = display_test_base
build_flags =
${display_test_base.build_flags}
-D BOARD_ID=\"CY\"
-D NODE_LABEL=\"Cy\"
-D NODE_SHORT=\"C\"
-D NODE_SLOT_INDEX=2
-D LOG_AP_IP_OCTET=25
-D GNSS_CHIP_NAME=\"L76K\"
[env:dan]
extends = display_test_base
build_flags =
${display_test_base.build_flags}
-D BOARD_ID=\"DAN\"
-D NODE_LABEL=\"Dan\"
-D NODE_SHORT=\"D\"
-D NODE_SLOT_INDEX=3
-D LOG_AP_IP_OCTET=26
-D GNSS_CHIP_NAME=\"L76K\"
[env:ed]
extends = display_test_base
build_flags =
${display_test_base.build_flags}
-D BOARD_ID=\"ED\"
-D NODE_LABEL=\"Ed\"
-D NODE_SHORT=\"E\"
-D NODE_SLOT_INDEX=4
-D LOG_AP_IP_OCTET=27
-D GNSS_CHIP_NAME=\"L76K\"
[env:flo]
extends = display_test_base
build_flags =
${display_test_base.build_flags}
-D BOARD_ID=\"FLO\"
-D NODE_LABEL=\"Flo\"
-D NODE_SHORT=\"F\"
-D NODE_SLOT_INDEX=5
-D LOG_AP_IP_OCTET=28
-D GNSS_CHIP_NAME=\"L76K\"
[env:guy]
extends = display_test_base
build_flags =
${display_test_base.build_flags}
-D BOARD_ID=\"GUY\"
-D NODE_LABEL=\"Guy\"
-D NODE_SHORT=\"G\"
-D NODE_SLOT_INDEX=6
-D LOG_AP_IP_OCTET=29
-D GNSS_CHIP_NAME=\"MAX-M10S\"
-D GPS_UBLOX

View file

@ -0,0 +1,154 @@
#include <Arduino.h>
#include <TBeamClock.h>
#include <TBeamDisplay.h>
#include <TBeamLogger.h>
#include <TBeamStorage.h>
#ifndef BOARD_ID
#define BOARD_ID "UNKNOWN"
#endif
#ifndef NODE_LABEL
#define NODE_LABEL "Unknown"
#endif
namespace {
tbeam::TBeamDisplay display;
tbeam::TBeamClock clockService(Wire1);
tbeam::TBeamStorage storage(Serial);
tbeam::TBeamLogger Log;
uint32_t sampleSeq = 0;
uint32_t lastSampleMs = 0;
uint32_t lastPageMs = 0;
uint8_t page = 0;
void formatRtc(char* out, size_t outSize) {
if (!clockService.ready()) {
strlcpy(out, "RTC read fail", outSize);
return;
}
if (!clockService.valid()) {
strlcpy(out, clockService.lowVoltage() ? "RTC low voltage" : "RTC invalid", outSize);
return;
}
tbeam::TBeamClock::formatIsoUtc(clockService.lastRtc(), out, outSize);
}
void openDisplayLog() {
if (!storage.ready()) {
Serial.printf("Display log skipped: storage error=%s\r\n", storage.lastError());
return;
}
bool opened = false;
if (clockService.valid()) {
char runId[64];
char path[112];
tbeam::TBeamClock::makeRunId(clockService.lastRtc(), BOARD_ID, runId, sizeof(runId));
snprintf(path, sizeof(path), "%s/%s.csv", storage.logDir(), runId);
opened = Log.openLog(path);
}
if (!opened) {
opened = Log.openUniqueLog(BOARD_ID, ".csv");
}
if (!opened) {
Serial.printf("Display log open failed: %s\r\n", storage.lastError());
return;
}
Log.printf("# test: display\r\n");
Log.printf("# board_id: %s\r\n", BOARD_ID);
Log.printf("# node_label: %s\r\n", NODE_LABEL);
Log.printf("# log_path: %s\r\n", Log.currentLogPath());
Log.println("seq,millis,page,display_ready,rtc_valid,sd_ready,free_heap");
Log.flush();
Serial.printf("Display log opened: %s\r\n", Log.currentLogPath());
}
void drawCurrentPage() {
char line1[32];
char line2[32];
char line3[32];
char line4[32];
char line5[32];
char rtc[32];
formatRtc(rtc, sizeof(rtc));
if (page == 0) {
snprintf(line1, sizeof(line1), "Display Test");
snprintf(line2, sizeof(line2), "Board: %s", BOARD_ID);
snprintf(line3, sizeof(line3), "Node: %s", NODE_LABEL);
snprintf(line4, sizeof(line4), "OLED: %s", display.ready() ? "ready" : "fail");
snprintf(line5, sizeof(line5), "Seq: %lu", (unsigned long)sampleSeq);
display.showLines(line1, line2, line3, line4, line5);
} else if (page == 1) {
display.showStatus("Clock", rtc, clockService.valid() ? "OK" : "BAD", storage.ready() ? "SD mounted" : "SD missing");
} else if (page == 2) {
snprintf(line1, sizeof(line1), "Storage");
snprintf(line2, sizeof(line2), "SD: %s", storage.ready() ? "mounted" : "missing");
snprintf(line3, sizeof(line3), "Log: %s", Log.storageReady() ? "open" : "closed");
snprintf(line4, sizeof(line4), "Heap: %lu", (unsigned long)ESP.getFreeHeap());
snprintf(line5, sizeof(line5), "Millis: %lu", (unsigned long)millis());
display.showLines(line1, line2, line3, line4, line5);
} else {
display.setFont(tbeam::DisplayFont::SMALL);
snprintf(line1, sizeof(line1), "Services");
snprintf(line2, sizeof(line2), "clock: %s", clockService.valid() ? "valid" : "bad");
snprintf(line3, sizeof(line3), "storage: %s", storage.ready() ? "ready" : "bad");
snprintf(line4, sizeof(line4), "logger: %s", Log.storageReady() ? "file" : "serial");
snprintf(line5, sizeof(line5), "%s", rtc);
display.showLines(line1, line2, line3, line4, line5, "page 4/4");
display.setFont(tbeam::DisplayFont::NORMAL);
}
}
} // namespace
void setup() {
Serial.begin(115200);
delay(1500);
Serial.println();
Serial.printf("display test boot board=%s label=%s\r\n", BOARD_ID, NODE_LABEL);
const bool displayReady = display.begin();
Serial.printf("display_begin=%s error=%s\r\n", displayReady ? "ok" : "fail", display.lastError());
display.showBoot("Display Test", BOARD_ID, "starting services");
tbeam::StorageConfig storageConfig;
storageConfig.logDir = "/logs/display";
storageConfig.enablePinDumps = false;
storage.begin(storageConfig);
Log.begin(Serial, &storage);
clockService.begin();
openDisplayLog();
drawCurrentPage();
}
void loop() {
storage.update();
clockService.update();
Log.update();
const uint32_t now = millis();
if ((uint32_t)(now - lastSampleMs) >= 1000) {
lastSampleMs = now;
Log.printf("%lu,%lu,%u,%s,%s,%s,%lu\r\n",
(unsigned long)sampleSeq++,
(unsigned long)now,
(unsigned)page,
display.ready() ? "yes" : "no",
clockService.valid() ? "yes" : "no",
storage.ready() ? "yes" : "no",
(unsigned long)ESP.getFreeHeap());
}
if ((uint32_t)(now - lastPageMs) >= 2500) {
lastPageMs = now;
page = (uint8_t)((page + 1U) % 4U);
drawCurrentPage();
}
}