v1.15: Settings > Experimental Features (delete all contacts, Alt+B-only backlight); TEMP Max charger readout

Version
- MyMesh.h: FIRMWARE_VERSION default "Meck v1.14" -> "Meck v1.15";
  FIRMWARE_BUILD_DATE updated.
- variants/lilygo_tdeck_pro/platformio.ini,
  variants/lilygo_tdeck_max/platformio.ini: FIRMWARE_VERSION strings
  v1.14 -> v1.15.

Settings > Experimental Features
- SettingsScreen.h: new "Experimental Features >>" folder row as the last
  top-level Settings row, opening "Settings > Experimental".
- Delete all contacts (all T-Deck builds), ported from Meck-P4 v0.7.4.
  Flow: "Delete all contacts?" box (Enter:Yes Q:No) -> second "Are you
  sure? This cannot be undone." popup (its Enter is ignored for the
  first second) -> "Purging" -> "Contacts deleted" or "Purge failed" ->
  restart 3 s later. Removes every contact, with favourites and custom
  paths, and the DM history; channel messages are kept. Q cancels at
  either confirmation; keys are ignored once the purge starts.
- MyMesh.h: purgeAllContacts() closes any chunked contact save still in
  progress, empties the contact table and saves the empty set.
- ChannelScreen.h: purgeDMs() marks the DM entries in
  /meshcore/messages.bin empty in place and re-saves, keeping channel
  messages, and clears the DM unread count.
- main.cpp: meckPurgeAllContacts() runs both and checks the contacts file
  is empty afterwards. All touch is ignored while the purge box is open.
- Change Backlight to Alt+B (Max only): ON stops the heart touch key
  toggling the frontlight, and Alt+B then lights it at the Backlight
  Brightness setting. OFF leaves both as before.
- NodePrefs.h, DataStore.cpp: new pref backlight_alt_b_only at byte 1522
  (prefs file now 1523 bytes); older files load it as 0 (heart key on).
  Timezones comment "these final fields" -> "these fields".

TEMPORARY (Max only; remove after the charging investigation)
- TDeckProMaxBoard.h, TDeckProMaxBoard.cpp: chargerDebugPrint(), a
  read-only SY6970 status, fault and register dump plus a BQ27220 gauge
  line on serial.
- UITask.cpp: calls it every 10 s from UITask::loop().
This commit is contained in:
pelgraine committed 2026-10-07 06:33:58 +11:00
1 parent 3fc6e73014
commit 2ca97fa8ce
12 files changed
+360 -21

No files matched your search

+5
View File
@@ -291,6 +291,9 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no
if (file.read((uint8_t *)&_prefs.clock_slot_b, sizeof(_prefs.clock_slot_b)) != sizeof(_prefs.clock_slot_b)) {
_prefs.clock_slot_b = 0; // default: Zone 2 at UTC+0
}
if (file.read((uint8_t *)&_prefs.backlight_alt_b_only, sizeof(_prefs.backlight_alt_b_only)) != sizeof(_prefs.backlight_alt_b_only)) {
_prefs.backlight_alt_b_only = 0; // default: heart key on
}
// Clamp to valid ranges
if (_prefs.dark_mode > 1) _prefs.dark_mode = 0;
@@ -308,6 +311,7 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no
if (_prefs.kb_backlight_pct < 5 || _prefs.kb_backlight_pct > 100) _prefs.kb_backlight_pct = 50;
if (_prefs.clock_slot_a < -12 || _prefs.clock_slot_a > 14) _prefs.clock_slot_a = 0;
if (_prefs.clock_slot_b < -12 || _prefs.clock_slot_b > 14) _prefs.clock_slot_b = 0;
if (_prefs.backlight_alt_b_only > 1) _prefs.backlight_alt_b_only = 0;
// Force NUL termination on each canned message slot in case of garbage
for (int i = 0; i < (int)(sizeof(_prefs.canned_msgs) / sizeof(_prefs.canned_msgs[0])); i++) {
_prefs.canned_msgs[i][sizeof(_prefs.canned_msgs[0]) - 1] = '\0';
@@ -378,6 +382,7 @@ void DataStore::savePrefs(const NodePrefs& _prefs, double node_lat, double node_
file.write((uint8_t *)_prefs.canned_msgs, sizeof(_prefs.canned_msgs)); // 177
file.write((uint8_t *)&_prefs.clock_slot_a, sizeof(_prefs.clock_slot_a)); // 1520
file.write((uint8_t *)&_prefs.clock_slot_b, sizeof(_prefs.clock_slot_b)); // 1521
file.write((uint8_t *)&_prefs.backlight_alt_b_only, sizeof(_prefs.backlight_alt_b_only)); // 1522
file.close();
}
+1
View File
@@ -2950,6 +2950,7 @@ void MyMesh::handleCmdFrame(size_t len) {
// as upstream replies to a command it does not have.
char *text = (char *)&cmd_frame[1];
text[len - 1] = 0; // ensure null
Serial.printf("APP CLI: %s\n", text); // TEMPORARY test print: each command the app sends
while (*text == ' ') text++; // skip leading spaces
char reply_buf[166];
char *reply = reply_buf;
+11 -2
View File
@@ -8,11 +8,11 @@
#define FIRMWARE_VER_CODE 11
#ifndef FIRMWARE_BUILD_DATE
#define FIRMWARE_BUILD_DATE "15 Sept 2026"
#define FIRMWARE_BUILD_DATE "7 Oct 2026"
#endif
#ifndef FIRMWARE_VERSION
#define FIRMWARE_VERSION "Meck v1.14"
#define FIRMWARE_VERSION "Meck v1.15"
#endif
#if defined(STM32_PLATFORM)
@@ -311,6 +311,15 @@ public:
void saveContacts() {
_store->saveContacts(this);
}
// Settings > Experimental Features > Delete all contacts (Meck-P4 port).
// Empties the in-RAM contact table (BaseChatMesh::resetContacts is
// protected) and saves the empty set. A chunked background save still in
// progress is closed first, so it cannot later put an older list back.
void purgeAllContacts() {
if (_store->isSaveInProgress()) _store->finishSaveContacts();
resetContacts();
_store->saveContacts(this);
}
void saveMainIdentity() {
_store->saveMainIdentity(self_id);
}
+7 -1
View File
@@ -92,11 +92,17 @@ struct NodePrefs { // persisted to file
// --- Timezones home page (world clock) ---
// UTC offsets (-12..+14) of the page's two extra zones; its Home row is
// utc_offset_hours. Older prefs files short-read these final fields and
// utc_offset_hours. Older prefs files short-read these fields and
// keep the default 0 (UTC+0).
int8_t clock_slot_a; // Zone 1 UTC offset, default 0
int8_t clock_slot_b; // Zone 2 UTC offset, default 0
// --- Experimental Features ---
// 1 = "Change Backlight to Alt+B" is on: the Max's heart touch key no
// longer toggles the frontlight, leaving Alt+B. Older prefs files
// short-read this final field and keep the default 0 (heart key on).
uint8_t backlight_alt_b_only; // default 0
// --- Font helpers (inline, no overhead) ---
// Returns the DisplayDriver text-size index for "small/body" text.
// T-Deck Pro: 0 = built-in 6×8 (or 7pt with custom fonts), 1 = 9pt.
+35
View File
@@ -896,6 +896,26 @@ MyMesh the_mesh(radio_driver, fast_rng, rtc_clock, tables, store
/* END GLOBAL OBJECTS */
#if defined(LilyGo_TDeck_Pro)
// ---------------------------------------------------------------------------
// Settings > Experimental Features > Delete all contacts (ported from
// Meck-P4 v0.7.4). Empties the contact table and saves the empty set, and
// removes the direct-message history from the SD message store (channel
// messages are kept). SettingsScreen restarts the device afterwards.
// ---------------------------------------------------------------------------
void meckPurgeAllContacts(int* contactsRemoved, bool* contactsOk, int* dmsRemoved) {
*contactsRemoved = the_mesh.getNumContacts();
the_mesh.purgeAllContacts();
File f = SPIFFS.open("/contacts3", "r");
*contactsOk = f && f.size() == 0;
if (f) f.close();
ChannelScreen* chScr = (ChannelScreen*)ui_task.getChannelScreen();
*dmsRemoved = chScr ? chScr->purgeDMs() : -1;
Serial.printf("Purge: %d contacts removed, contacts file %s, DMs removed %d\n",
*contactsRemoved, *contactsOk ? "empty" : "NOT EMPTY", *dmsRemoved);
}
#endif
#if defined(BLE_PIN_CODE) && defined(MECK_WIFI_COMPANION)
// ---------------------------------------------------------------------------
// Combined BLE + WiFi companion (meck_max_ble_wifi test build)
@@ -1302,6 +1322,9 @@ static void openMapScreen() {
if (!pressed) return;
switch (key_id) {
case 0: // heart -- toggle frontlight at the user-set brightness
// Settings > Experimental Features "Change Backlight to Alt+B" turns
// the heart key off, leaving Alt+B as the backlight toggle.
if (the_mesh.getNodePrefs()->backlight_alt_b_only) break;
if (board.isBacklightOn()) {
board.backlightOff();
} else {
@@ -3518,6 +3541,12 @@ void loop() {
{
// Guard: skip touch when locked
bool touchBlocked = ui_task.isLocked();
// Settings > Experimental Features "Delete all contacts" box open: keys
// only, so a stray touch can't confirm it or leave Settings mid-purge
if (ui_task.isOnSettingsScreen()) {
SettingsScreen* purgeSS = (SettingsScreen*)ui_task.getSettingsScreen();
if (purgeSS && purgeSS->isPurgeBoxOpen()) touchBlocked = true;
}
#ifdef HAS_4G_MODEM
// SMS dialer has its own dedicated touch handler — don't consume touch data here
if (smsMode) {
@@ -3855,6 +3884,12 @@ void handleKeyboardInput() {
// Alt+B toggles the e-ink frontlight (MAX only -- working backlight on IO41)
if (key == KB_KEY_BACKLIGHT) {
if (board.isBacklightOn()) board.backlightOff();
else if (the_mesh.getNodePrefs()->backlight_alt_b_only) {
// Experimental "Change Backlight to Alt+B" on: use the Backlight
// Brightness setting, as the heart key does
uint8_t blPct = the_mesh.getNodePrefs()->backlight_brightness_pct;
board.backlightSetBrightness((uint8_t)((blPct * 255 + 50) / 100));
}
else board.backlightOn();
return;
}
@@ -603,6 +603,28 @@ public:
}
// Settings > Experimental Features > Delete all contacts: drop every direct
// message and save, keeping channel messages. The file keeps the circular-
// buffer layout, so DM slots are marked empty in place. Returns how many
// were removed, or -1 if the SD card is not ready (nothing could be saved).
int purgeDMs() {
#if defined(HAS_SDCARD) && defined(ESP32)
if (!_sdReady) return -1;
int removed = 0;
for (int i = 0; i < CHANNEL_MSG_HISTORY_SIZE; i++) {
if (_messages[i].valid && _messages[i].channel_idx == 0xFF) {
_messages[i].valid = false;
removed++;
}
}
_unread[MAX_GROUP_CHANNELS] = 0; // DM unread slot
saveToSD();
return removed;
#else
return -1;
#endif
}
// Load message buffer from SD card. Returns true if messages were loaded.
bool loadFromSD() {
#if defined(HAS_SDCARD) && defined(ESP32)
@@ -195,6 +195,11 @@ enum SettingsRowType : uint8_t {
ROW_OPERATOR_INFO, // Carrier/operator display (read-only)
ROW_APN, // APN setting (editable)
#endif
ROW_EXPERIMENTAL_SUBMENU, // Folder row: enters Experimental Features sub-screen (last row)
#if defined(LilyGo_TDeck_Pro_Max)
ROW_ALT_B_BACKLIGHT, // Toggle: heart touch key off, Alt+B only toggles the backlight (MAX only)
#endif
ROW_PURGE_CONTACTS, // "Delete all contacts": confirm, purge, restart
};
// ---------------------------------------------------------------------------
@@ -216,6 +221,7 @@ enum EditMode : uint8_t {
EDIT_OTA, // OTA firmware update flow (multi-phase overlay)
EDIT_FILEMGR, // SD file manager flow (WiFi file browser)
#endif
EDIT_PURGE, // Delete all contacts: confirm / purging / result overlay
};
// ---------------------------------------------------------------------------
@@ -233,6 +239,15 @@ enum SubScreen : uint8_t {
SUB_EXPORT_IMPORT, // Export/Import menu
SUB_EXPORT_FLAGS, // Export checkboxes + trigger
#endif
SUB_EXPERIMENTAL, // Experimental Features sub-screen
};
// Delete all contacts (Experimental Features) overlay phases
enum PurgePhase : uint8_t {
PURGE_CONFIRM, // "Delete all contacts?" Enter:Yes Q:No
PURGE_CONFIRM2, // second confirmation popup ("Are you sure?"); Enter accepted after 1 s
PURGE_RUNNING, // "Purging" shown; the work runs from poll()
PURGE_DONE, // result shown; restart follows
};
#ifdef MECK_OTA_UPDATE
@@ -317,6 +332,13 @@ private:
// Sub-screen navigation
SubScreen _subScreen;
int _savedTopCursor; // cursor position to restore when leaving sub-screen
// Experimental Features > Delete all contacts (EDIT_PURGE overlay)
uint8_t _purgePhase; // PurgePhase
unsigned long _purgeAt; // CONFIRM2: when Enter is accepted; RUNNING: when the purge runs; DONE: when the restart happens
int _purgeContacts; // contacts removed (count shown on the confirm box)
int _purgeDMs; // direct messages removed, -1 = SD card not ready
bool _purgeContactsOk; // the contacts file is empty afterwards
#ifdef HAS_SDCARD
int _savedExportCursor; // cursor in SUB_EXPORT_IMPORT when entering SUB_EXPORT_FLAGS
uint8_t _exportFlags; // bitmask of MECK_EXPORT_* flags for export checkboxes
@@ -483,6 +505,12 @@ private:
addRow(ROW_EXPORT_AUTOADD);
addRow(ROW_EXPORT_NOW);
#endif
} else if (_subScreen == SUB_EXPERIMENTAL) {
// --- Experimental Features sub-screen ---
#if defined(LilyGo_TDeck_Pro_Max)
addRow(ROW_ALT_B_BACKLIGHT);
#endif
addRow(ROW_PURGE_CONTACTS);
} else {
// --- Top-level settings list ---
#if defined(LilyGo_TDeck_Pro_Max)
@@ -549,6 +577,9 @@ private:
addRow(ROW_OPERATOR_INFO);
addRow(ROW_APN);
#endif
// Experimental Features (last row)
addRow(ROW_EXPERIMENTAL_SUBMENU);
}
// Clamp cursor
@@ -711,6 +742,11 @@ public:
_sharePickerScroll = 0;
_shareRequested = false;
_shareContactIdx = -1;
_purgePhase = PURGE_CONFIRM;
_purgeAt = 0;
_purgeContacts = 0;
_purgeDMs = 0;
_purgeContactsOk = false;
#ifdef MECK_OTA_UPDATE
_otaServer = nullptr;
_otaPhase = OTA_PHASE_CONFIRM;
@@ -768,6 +804,7 @@ public:
bool isOnboarding() const { return _onboarding; }
bool isEditing() const { return _editMode != EDIT_NONE; }
bool isPurgeBoxOpen() const { return _editMode == EDIT_PURGE; } // main.cpp ignores touch while open
bool hasRadioChanges() const { return _radioChanged; }
bool isOnChannelsSubScreen() const { return _subScreen == SUB_CHANNELS; }
bool isOnDeletableChannel() const {
@@ -1736,6 +1773,8 @@ public:
} else if (_subScreen == SUB_OTA_TOOLS) {
display.print("Settings > OTA Tools");
#endif
} else if (_subScreen == SUB_EXPERIMENTAL) {
display.print("Settings > Experimental");
} else {
display.print("Settings");
}
@@ -2225,6 +2264,23 @@ public:
display.print(tmp);
break;
case ROW_EXPERIMENTAL_SUBMENU:
display.setColor(selected ? DisplayDriver::DARK : DisplayDriver::GREEN);
display.print("Experimental Features >>");
break;
#if defined(LilyGo_TDeck_Pro_Max)
case ROW_ALT_B_BACKLIGHT:
snprintf(tmp, sizeof(tmp), "Change Backlight to Alt+B: %s",
_prefs->backlight_alt_b_only ? "ON" : "OFF");
display.print(tmp);
break;
#endif
case ROW_PURGE_CONTACTS:
display.print("Delete all contacts");
break;
#ifdef HAS_4G_MODEM
case ROW_IMEI: {
const char* imei = modemManager.getIMEI();
@@ -2320,6 +2376,85 @@ public:
display.setTextSize(1);
}
// === Delete all contacts overlay (Experimental Features) ===
if (_editMode == EDIT_PURGE) {
int bx = 2, by = 14, bw = display.width() - 4;
int bh = display.height() - 28;
display.setColor(DisplayDriver::DARK);
display.fillRect(bx, by, bw, bh);
display.setColor(DisplayDriver::LIGHT);
display.drawRect(bx, by, bw, bh);
display.setTextSize(_prefs->smallTextSize());
int lh = _prefs->smallLineH();
int cx = display.width() / 2;
int y = by + 4;
if (_purgePhase == PURGE_CONFIRM || _purgePhase == PURGE_CONFIRM2) {
display.setColor(DisplayDriver::YELLOW);
display.drawTextCentered(cx, y, "Delete all contacts?");
y += lh + 2;
display.setColor(DisplayDriver::LIGHT);
snprintf(tmp, sizeof(tmp), "All %d contact%s, with", _purgeContacts, _purgeContacts == 1 ? "" : "s");
display.drawTextCentered(cx, y, tmp); y += lh;
display.drawTextCentered(cx, y, "favourites and custom"); y += lh;
display.drawTextCentered(cx, y, "paths, and the DM history"); y += lh;
display.drawTextCentered(cx, y, "will be deleted. Channel"); y += lh;
display.drawTextCentered(cx, y, "messages are kept."); y += lh + 2;
display.setColor(DisplayDriver::RED);
display.drawTextCentered(cx, y, "The device will RESTART.");
display.setColor(DisplayDriver::LIGHT);
display.drawTextCentered(cx, by + bh - lh - 2, "Enter:Yes Q:No");
if (_purgePhase == PURGE_CONFIRM2) {
// Second confirmation popup, drawn over the first box
int tx = 10, tw = display.width() - 20;
int th = lh * 3 + 12;
int ty = by + (bh - th) / 2;
display.setColor(DisplayDriver::DARK);
display.fillRect(tx, ty, tw, th);
display.setColor(DisplayDriver::LIGHT);
display.drawRect(tx, ty, tw, th);
display.setColor(DisplayDriver::YELLOW);
display.drawTextCentered(cx, ty + 3, "Are you sure?");
display.setColor(DisplayDriver::LIGHT);
display.drawTextCentered(cx, ty + 3 + lh + 2, "This cannot be undone.");
display.drawTextCentered(cx, ty + th - lh - 2, "Enter:Yes Q:No");
}
} else if (_purgePhase == PURGE_RUNNING) {
display.setColor(DisplayDriver::YELLOW);
display.drawTextCentered(cx, y, "Purging");
y += lh + 2;
display.setColor(DisplayDriver::LIGHT);
display.drawTextCentered(cx, y, "Deleting all contacts and"); y += lh;
display.drawTextCentered(cx, y, "the DM history."); y += lh;
display.drawTextCentered(cx, y, "Please wait..."); y += lh + 4;
display.setColor(DisplayDriver::RED);
display.drawTextCentered(cx, y, "Do not switch off. The"); y += lh;
display.drawTextCentered(cx, y, "device restarts when done.");
} else {
bool ok = _purgeContactsOk && _purgeDMs >= 0;
display.setColor(DisplayDriver::YELLOW);
display.drawTextCentered(cx, y, ok ? "Contacts deleted" : "Purge failed");
y += lh + 2;
display.setColor(DisplayDriver::LIGHT);
if (ok) {
snprintf(tmp, sizeof(tmp), "Done. %d contact%s and the", _purgeContacts, _purgeContacts == 1 ? "" : "s");
display.drawTextCentered(cx, y, tmp); y += lh;
display.drawTextCentered(cx, y, "DM history have been"); y += lh;
display.drawTextCentered(cx, y, "deleted from this device."); y += lh + 4;
} else {
snprintf(tmp, sizeof(tmp), "Contacts file: %s", _purgeContactsOk ? "ok" : "failed");
display.drawTextCentered(cx, y, tmp); y += lh;
snprintf(tmp, sizeof(tmp), "DM history: %s", _purgeDMs >= 0 ? "ok" : "SD not ready");
display.drawTextCentered(cx, y, tmp); y += lh;
display.drawTextCentered(cx, y, "The restart reloads what"); y += lh;
display.drawTextCentered(cx, y, "storage still holds."); y += lh + 4;
}
display.setColor(DisplayDriver::RED);
display.drawTextCentered(cx, y, "RESTARTING NOW...");
}
display.setTextSize(1);
}
// === Notification sound picker overlay ===
#if defined(MECK_AUDIO_VARIANT) || defined(HAS_4G_MODEM)
if (_editMode == EDIT_NOTIF_SOUND) {
@@ -2853,6 +2988,29 @@ public:
return true; // consume all keys in confirm mode
}
// --- Delete all contacts (Experimental Features) ---
if (_editMode == EDIT_PURGE) {
if (_purgePhase == PURGE_CONFIRM || _purgePhase == PURGE_CONFIRM2) {
if (c == KEY_CANCEL || c == 'q') {
_editMode = EDIT_NONE;
return true;
}
if (c == '\r' || c == 13) {
if (_purgePhase == PURGE_CONFIRM) {
// First Yes: show the second confirmation. Its Enter is ignored for
// 1 s, so a double press or key bounce can't pass both boxes.
_purgePhase = PURGE_CONFIRM2;
_purgeAt = millis() + 1000;
} else if ((long)(millis() - _purgeAt) >= 0) {
_purgePhase = PURGE_RUNNING;
_purgeAt = millis() + 1500; // let the "Purging" box reach the e-ink first
}
return true;
}
}
return true; // other keys ignored; no dismissing once the purge has started
}
// --- Notification sound picker ---
#if defined(MECK_AUDIO_VARIANT) || defined(HAS_4G_MODEM)
if (_editMode == EDIT_NOTIF_SOUND) {
@@ -3713,6 +3871,27 @@ public:
startEditCanned(_rows[_cursor].param);
break;
case ROW_EXPERIMENTAL_SUBMENU:
_savedTopCursor = _cursor;
_subScreen = SUB_EXPERIMENTAL;
_cursor = 0;
_scrollTop = 0;
rebuildRows();
Serial.println("Settings: entered Experimental Features sub-screen");
break;
#if defined(LilyGo_TDeck_Pro_Max)
case ROW_ALT_B_BACKLIGHT:
_prefs->backlight_alt_b_only = _prefs->backlight_alt_b_only ? 0 : 1;
the_mesh.savePrefs();
Serial.printf("Settings: Change Backlight to Alt+B = %s\n",
_prefs->backlight_alt_b_only ? "ON" : "OFF");
break;
#endif
case ROW_PURGE_CONTACTS:
_purgeContacts = the_mesh.getNumContacts();
_purgePhase = PURGE_CONFIRM;
_editMode = EDIT_PURGE;
break;
#ifdef MECK_OTA_UPDATE
case ROW_OTA_TOOLS_SUBMENU:
#ifndef MECK_40MHZ_TEST
@@ -3965,6 +4144,22 @@ public:
}
// Override handleInput for UIScreen compatibility (used by injectKey)
// Delete all contacts: run the purge once the "Purging" box has been drawn,
// then restart a few seconds after the result is on screen. The restart
// rebuilds everything keyed by contact index from the empty store.
void poll() override {
if (_editMode != EDIT_PURGE) return;
if (_purgePhase == PURGE_RUNNING && (long)(millis() - _purgeAt) >= 0) {
extern void meckPurgeAllContacts(int* contactsRemoved, bool* contactsOk, int* dmsRemoved);
meckPurgeAllContacts(&_purgeContacts, &_purgeContactsOk, &_purgeDMs);
_purgePhase = PURGE_DONE;
_purgeAt = millis() + 3000; // result stays on screen before the restart
} else if (_purgePhase == PURGE_DONE && (long)(millis() - _purgeAt) >= 0) {
Serial.println("Settings: purge done, restarting");
ESP.restart();
}
}
bool handleInput(char c) override {
return handleKeyInput(c);
}
@@ -2426,6 +2426,17 @@ if (curr) curr->poll();
next_batt_chck = millis() + 8000;
}
#endif
#if defined(LilyGo_TDeck_Pro_Max)
// TEMPORARY: charger + fuel gauge readout on serial every 10 s (read-only)
{
static unsigned long nextChargerDump = 0;
if ((long)(millis() - nextChargerDump) >= 0) {
nextChargerDump = millis() + 10000;
board.chargerDebugPrint();
}
}
#endif
}
char UITask::checkDisplayOn(char c) {
@@ -865,4 +865,55 @@ int16_t TDeckProMaxBoard::getBattTemperature() {
#else
return 0;
#endif
}
// ---- TEMPORARY: charger + fuel gauge readout (read-only) ----
// Register decoding follows XPowersLib's PowersSY6970.hpp (lewisxhe). Reading
// REG0C returns the fault bits and clears the latched ones.
static int sy6970_readReg(uint8_t reg) {
Wire.beginTransmission(I2C_ADDR_SY6970);
Wire.write(reg);
if (Wire.endTransmission(false) != 0) return -1;
if (Wire.requestFrom((uint8_t)I2C_ADDR_SY6970, (uint8_t)1) != 1) return -1;
return Wire.read();
}
void TDeckProMaxBoard::chargerDebugPrint() {
static const char* const kInput[8] = { "none", "USB-SDP", "USB-CDP", "USB-DCP",
"HVDCP", "adapter", "non-std-adapter", "OTG" };
static const char* const kState[4] = { "not-charging", "pre-charge", "fast-charge", "charge-done" };
int r[0x15];
for (uint8_t i = 0; i <= 0x14; i++) r[i] = sy6970_readReg(i);
if (r[0x0B] < 0) {
Serial.println("CHG: SY6970 not responding at 0x6A");
} else {
int vregCode = (r[0x06] & 0xFC) >> 2;
int vreg = (vregCode > 0x30) ? 4608 : vregCode * 16 + 3840;
int ntc = r[0x0C] & 0x07;
const char* ntcName = (ntc == 0) ? "normal" : (ntc == 2) ? "warm" : (ntc == 3) ? "cool"
: (ntc == 5) ? "cold" : (ntc == 6) ? "hot" : "other";
Serial.printf("CHG: input=%s pg=%d state=%s hiz=%d chg_en=%d vreg=%dmV ichg=%dmA iinlim=%dmA term_en=%d wdt=%d timer_en=%d\n",
kInput[(r[0x0B] >> 5) & 0x07], (r[0x0B] >> 2) & 1, kState[(r[0x0B] >> 3) & 0x03],
(r[0x00] >> 7) & 1, (r[0x03] >> 4) & 1,
vreg, (r[0x04] & 0x7F) * 64, (r[0x00] & 0x3F) * 50 + 100,
(r[0x07] >> 7) & 1, (r[0x07] >> 4) & 0x03, (r[0x07] >> 3) & 1);
Serial.printf("CHG: fault=0x%02X watchdog=%d boost=%d charge(bits5:4)=%d battery=%d ntc=%s(%d)\n",
r[0x0C] & 0xFF, (r[0x0C] >> 7) & 1, (r[0x0C] >> 6) & 1, (r[0x0C] >> 4) & 0x03,
(r[0x0C] >> 3) & 1, ntcName, ntc);
}
Serial.print("CHG regs:");
for (uint8_t i = 0; i <= 0x14; i++) {
if (r[i] < 0) Serial.printf(" %02X=--", i);
else Serial.printf(" %02X=%02X", i, r[i]);
}
Serial.println();
#if HAS_BQ27220
int16_t t = getBattTemperature();
Serial.printf("GAUGE: V=%umV I=%dmA avgI=%dmA remain=%umAh full=%umAh design=%umAh soc=%u%% T=%d.%dC\n",
getBattMilliVolts(), (int16_t)bq27220_read16(BQ27220_REG_CURRENT), getAvgCurrent(),
getRemainingCapacity(), bq27220_read16(BQ27220_REG_FULL_CAP), getDesignCapacity(),
bq27220_read16(BQ27220_REG_SOC), t / 10, abs(t % 10));
#endif
}
@@ -134,6 +134,10 @@ public:
uint16_t getDesignCapacity();
int16_t getBattTemperature();
bool configureFuelGauge(uint16_t designCapacity_mAh = BQ27220_DESIGN_CAPACITY_MAH);
// TEMPORARY: read-only charger (SY6970) and fuel gauge readout on serial,
// called every 10 s from UITask::loop() while the charging stop is
// investigated. Writes nothing to either chip.
void chargerDebugPrint();
// -------------------------------------------------------------------------
// Sleep / power-off (moved verbatim from TDeckBoard when MAX was decoupled).
+8 -8
View File
@@ -1,5 +1,5 @@
; =============================================================================
; T-Deck Pro MAX V0.1 — Meck Build Environments
; T-Deck Pro MAX V0.1-v0.3 — Meck Build Environments
;
; Hardware: ESP32-S3 + XL9555 I/O expander + combined 4G (A7682E) + Audio (ES8311)
;
@@ -179,7 +179,7 @@ build_flags =
; -D MECK_BLE_SMALL_MTU_SPLIT=1
; -D MECK_WATCH_EXT=1
; -D MECK_BLE_SLOW_INTERVAL=1
-D FIRMWARE_VERSION='"Meck v1.14.MAX"'
-D FIRMWARE_VERSION='"Meck v1.15.MAX"'
build_src_filter = ${LilyGo_TDeck_Pro_Max.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/ui/MomentaryButton.cpp>
@@ -213,7 +213,7 @@ build_flags =
-D MECK_BLE_SMALL_MTU_SPLIT=1
-D MECK_WATCH_EXT=1
-D MECK_BLE_SLOW_INTERVAL=1
-D FIRMWARE_VERSION='"Meck v1.14.MAX"'
-D FIRMWARE_VERSION='"Meck v1.15.MAX"'
build_src_filter = ${LilyGo_TDeck_Pro_Max.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/ui/MomentaryButton.cpp>
@@ -250,7 +250,7 @@ build_flags =
-D MECK_OTA_UPDATE=1
-D EINK_FASTLUT_EXPERIMENT=1
-D FAST_LUT_FRAMES=9
-D FIRMWARE_VERSION='"Meck v1.14.MAX.FASTLUT"'
-D FIRMWARE_VERSION='"Meck v1.15.MAX.FASTLUT"'
build_src_filter = ${LilyGo_TDeck_Pro_Max.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/ui/MomentaryButton.cpp>
@@ -282,7 +282,7 @@ build_flags =
-D MECK_WEB_READER=1
-D MECK_OTA_UPDATE=1
-D HAS_4G_MODEM=1
-D FIRMWARE_VERSION='"Meck v1.14.MAX.WiFi"'
-D FIRMWARE_VERSION='"Meck v1.15.MAX.WiFi"'
build_src_filter = ${LilyGo_TDeck_Pro_Max.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/ui/MomentaryButton.cpp>
@@ -316,7 +316,7 @@ build_flags =
-D MECK_WEB_READER=1
-D MECK_OTA_UPDATE=1
-D HAS_4G_MODEM=1
-D FIRMWARE_VERSION='"Meck v1.14.MAX.BLE-WiFi"'
-D FIRMWARE_VERSION='"Meck v1.15.MAX.BLE-WiFi"'
build_src_filter = ${LilyGo_TDeck_Pro_Max.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/ui/MomentaryButton.cpp>
@@ -342,7 +342,7 @@ build_flags =
-D MECK_OTA_UPDATE=1
-D HAS_4G_MODEM=1
-D MECK_WEB_READER=1
-D FIRMWARE_VERSION='"Meck v1.14.MAX.SA"'
-D FIRMWARE_VERSION='"Meck v1.15.MAX.SA"'
build_src_filter = ${LilyGo_TDeck_Pro_Max.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/ui/MomentaryButton.cpp>
@@ -398,7 +398,7 @@ build_flags =
-D CPU_FREQ_BOOST=40
-D CPU_FREQ_LOW_POWER=40
;-D MESH_DEBUG=1
-D FIRMWARE_VERSION='"Meck v1.14.MAX.SA40"'
-D FIRMWARE_VERSION='"Meck v1.15.MAX.SA40"'
build_src_filter = ${LilyGo_TDeck_Pro_Max.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/ui/MomentaryButton.cpp>
+10 -10
View File
@@ -164,7 +164,7 @@ build_flags =
-D MECK_OTA_UPDATE=1
-D EINK_FASTLUT_EXPERIMENT=1
-D FAST_LUT_FRAMES=9
-D FIRMWARE_VERSION='"Meck v1.14.FASTLUT"'
-D FIRMWARE_VERSION='"Meck v1.15.FASTLUT"'
build_src_filter = ${LilyGo_TDeck_Pro.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/ui/MomentaryButton.cpp>
@@ -211,7 +211,7 @@ build_flags =
-D MECK_WEB_READER=1
-D MECK_OTA_UPDATE=1
-D MECK_PRO_HYN_TOUCH=1
-D FIRMWARE_VERSION='"Meck v1.14.HYN"'
-D FIRMWARE_VERSION='"Meck v1.15.HYN"'
build_src_filter = ${LilyGo_TDeck_Pro.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/ui/MomentaryButton.cpp>
@@ -249,7 +249,7 @@ build_flags =
-D MECK_AUDIO_VARIANT
-D MECK_WEB_READER=1
-D MECK_OTA_UPDATE=1
-D FIRMWARE_VERSION='"Meck v1.14.WiFi"'
-D FIRMWARE_VERSION='"Meck v1.15.WiFi"'
;-D WIFI_DEBUG_LOGGING=1
;-D MESH_PACKET_LOGGING=1
;-D MESH_DEBUG=1
@@ -288,7 +288,7 @@ build_flags =
-D MECK_WEB_READER=1
-D MECK_OTA_UPDATE=1
-D MECK_PRO_HYN_TOUCH=1
-D FIRMWARE_VERSION='"Meck v1.14.WiFi.HYN"'
-D FIRMWARE_VERSION='"Meck v1.15.WiFi.HYN"'
;-D WIFI_DEBUG_LOGGING=1
;-D MESH_PACKET_LOGGING=1
;-D MESH_DEBUG=1
@@ -357,7 +357,7 @@ build_flags =
-D MECK_AUDIO_VARIANT
-D MECK_OTA_UPDATE=1
-D MECK_PRO_HYN_TOUCH=1
-D FIRMWARE_VERSION='"Meck v1.14.A.SA.HYN"'
-D FIRMWARE_VERSION='"Meck v1.15.A.SA.HYN"'
build_src_filter = ${LilyGo_TDeck_Pro.build_src_filter}
+<helpers/esp32/*.cpp>
-<helpers/esp32/SerialBLEInterface.cpp>
@@ -409,7 +409,7 @@ build_flags =
-D CPU_FREQ_BOOST=40
-D CPU_FREQ_LOW_POWER=40
-D MESH_DEBUG=1
-D FIRMWARE_VERSION='"Meck v1.14.A.SA40"'
-D FIRMWARE_VERSION='"Meck v1.15.A.SA40"'
build_src_filter = ${LilyGo_TDeck_Pro.build_src_filter}
+<helpers/esp32/*.cpp>
-<helpers/esp32/SerialBLEInterface.cpp>
@@ -444,7 +444,7 @@ build_flags =
-D HAS_4G_MODEM=1
-D MECK_WEB_READER=1
-D MECK_OTA_UPDATE=1
-D FIRMWARE_VERSION='"Meck v1.14.4G"'
-D FIRMWARE_VERSION='"Meck v1.15.4G"'
build_src_filter = ${LilyGo_TDeck_Pro.build_src_filter}
+<helpers/esp32/*.cpp>
+<helpers/ui/MomentaryButton.cpp>
@@ -480,7 +480,7 @@ build_flags =
-D HAS_4G_MODEM=1
-D MECK_WEB_READER=1
-D MECK_OTA_UPDATE=1
-D FIRMWARE_VERSION='"Meck v1.14.4G.WiFi"'
-D FIRMWARE_VERSION='"Meck v1.15.4G.WiFi"'
build_src_filter = ${LilyGo_TDeck_Pro.build_src_filter}
+<helpers/esp32/*.cpp>
-<helpers/esp32/SerialBLEInterface.cpp>
@@ -514,7 +514,7 @@ build_flags =
-D HAS_4G_MODEM=1
-D MECK_WEB_READER=1
-D MECK_OTA_UPDATE=1
-D FIRMWARE_VERSION='"Meck v1.14.4G.SA"'
-D FIRMWARE_VERSION='"Meck v1.15.4G.SA"'
build_src_filter = ${LilyGo_TDeck_Pro.build_src_filter}
+<helpers/esp32/*.cpp>
-<helpers/esp32/SerialBLEInterface.cpp>
@@ -557,7 +557,7 @@ build_flags =
-D CPU_FREQ_BOOST=40
-D CPU_FREQ_LOW_POWER=40
-D MESH_DEBUG=1
-D FIRMWARE_VERSION='"Meck v1.14.4G.SA40"'
-D FIRMWARE_VERSION='"Meck v1.15.4G.SA40"'
build_src_filter = ${LilyGo_TDeck_Pro.build_src_filter}
+<helpers/esp32/*.cpp>
-<helpers/esp32/SerialBLEInterface.cpp>