From 4477d5c812be87a583360f36d5c8193f5e4543b0 Mon Sep 17 00:00:00 2001 From: pelgraine <140762863+pelgraine@users.noreply.github.com> Date: Fri, 20 Feb 2026 22:27:59 +1100 Subject: [PATCH] updated slight eink refresh lag; minor nav bar ui fixes to sms app; added sms app guide --- SMS App Guide.md | 116 ++++++++++++++++++++ examples/companion_radio/main.cpp | 36 +++--- examples/companion_radio/ui-new/SMSScreen.h | 4 +- 3 files changed, 139 insertions(+), 17 deletions(-) create mode 100644 SMS App Guide.md diff --git a/SMS App Guide.md b/SMS App Guide.md new file mode 100644 index 0000000..8559803 --- /dev/null +++ b/SMS App Guide.md @@ -0,0 +1,116 @@ +## SMS App (4G variant only) - Meck v0.9.2 + +Press **T** from the home screen to open the SMS app. +Requires a nano SIM card inserted in the T-Deck Pro V1.1 4G modem slot and an +SD card formatted as FAT32. The modem registers on the cellular network +automatically at boot — the red LED on the board indicates the modem is +powered. The modem (and its red LED) can be switched off and on from the +settings screen. After each modem startup, the system clock syncs from the +cellular network, which takes roughly 15 seconds. + +### Key Mapping + +| Context | Key | Action | +|---------|-----|--------| +| Home screen | T | Open SMS app | +| Inbox | W / S | Scroll conversations | +| Inbox | Enter | Open conversation | +| Inbox | C | Compose new SMS (enter phone number) | +| Inbox | D | Open contacts directory | +| Inbox | Q | Back to home screen | +| Conversation | W / S | Scroll messages | +| Conversation | C | Reply to this conversation | +| Conversation | A | Add or edit contact name for this number | +| Conversation | Q | Back to inbox | +| Compose | Enter | Send SMS (from body) / Confirm phone number (from phone input) | +| Compose | Shift+Del | Cancel and return | +| Contacts | W / S | Scroll contact list | +| Contacts | Enter | Compose SMS to selected contact | +| Contacts | Q | Back to inbox | +| Edit Contact | Enter | Save contact name | +| Edit Contact | Shift+Del | Cancel without saving | + +### Sending an SMS + +There are three ways to start a new message: + +1. **From inbox** — press **C**, type the destination phone number, press + **Enter**, then type your message and press **Enter** to send. +2. **From a conversation** — press **C** to reply. The recipient is + pre-filled so you go straight to typing the message body. +3. **From the contacts directory** — press **D** from the inbox, scroll to a + contact, and press **Enter**. The compose screen opens with the number + pre-filled. + +Messages are limited to 160 characters (standard SMS). A character counter is +shown in the footer while composing. + +### Contacts + +The contacts directory lets you assign display names to phone numbers. +Names appear in the inbox list, conversation headers, and compose screen +instead of raw numbers. + +To add or edit a contact, open a conversation with that number and press **A**. +Type the display name and press **Enter** to save. Names can be up to 23 +characters long. + +Contacts are stored as a plain text file at `/sms/contacts.txt` on the SD card +in `phone=Display Name` format — one per line, human-editable. Up to 30 +contacts are supported. + +### Conversation History + +Messages are saved to the SD card automatically and persist across reboots. +Each phone number gets its own file under `/sms/` on the SD card. The inbox +shows the most recent 20 conversations sorted by last activity. Within a +conversation, the most recent 30 messages are loaded with the newest at the +bottom (chat-style). Sent messages are shown with `>>>` and received messages +with `<<<`. + +Message timestamps use the cellular network clock (synced via NITZ roughly 15 +seconds after each modem startup) and display as relative times (e.g. 5m, 2h, +1d). If the modem is toggled off and back on, the clock re-syncs automatically. + +### Modem Power Control + +The 4G modem can be toggled on or off from the settings screen. Scroll to +**4G Modem: ON/OFF** and press **Enter** to toggle. Switching the modem off +kills its red status LED and stops all cellular activity. The setting persists +to SD card and is respected on subsequent boots — if disabled, the modem and +LED stay off until re-enabled. The SMS app remains accessible when the modem +is off but will not be able to send or receive messages. + +### Signal Indicator + +A signal strength indicator is shown in the top-right corner of all SMS +screens. Bars are derived from the modem's CSQ (signal quality) reading, +updated every 30 seconds. The modem state (REG, READY, OFF, etc.) is shown +when not yet connected. + +### SD Card Structure + +``` +SD Card +├── sms/ +│ ├── contacts.txt (plain text, phone=Name format) +│ ├── modem.cfg (0 or 1, modem enable state) +│ ├── 0412345678.sms (binary message log per phone number) +│ └── 0498765432.sms +├── books/ (text reader) +├── audiobooks/ (audio variant only) +└── ... +``` + +### Troubleshooting + +| Symptom | Likely Cause | +|---------|-------------| +| Modem stays at REG / never reaches READY | SIM not inserted, no signal, or SIM requires PIN unlock (not currently supported) | +| Timestamps show `---` | Modem clock hasn't synced yet (wait ~15 seconds after modem startup), or messages were saved before clock sync was available | +| Red LED stays on after disabling modem | Toggle the setting off, then reboot — the boot sequence ensures power is cut when disabled | +| SMS sends but no delivery | Check signal strength; CSQ below 5 is marginal. Move to better coverage | + +> **Note:** The SMS app is only available on the 4G modem variant of the +> T-Deck Pro. It is not present on the audio or standalone BLE builds due to +> shared GPIO pin conflicts between the A7682E modem and PCM5102A DAC. \ No newline at end of file diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 748e469..95a08d6 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -707,9 +707,12 @@ void loop() { ui_task.forceRefresh(); ui_task.loop(); } else if (smsSuppressLoop) { - // SMS compose renders through UITask - force a refresh cycle - ui_task.forceRefresh(); - ui_task.loop(); + // SMS compose: render directly to display, same as mesh compose + #ifdef DISPLAY_CLASS + display.startFrame(); + ((SMSScreen*)ui_task.getSMSScreen())->render(display); + display.endFrame(); + #endif } lastComposeRefresh = millis(); composeNeedsRefresh = false; @@ -1189,19 +1192,22 @@ void handleKeyboardInput() { return; } - // Shift+Backspace → cancel compose - if (key == 0x18 && smsScr->isComposing()) { - smsScr->handleInput(key); - composeNeedsRefresh = true; - lastComposeRefresh = millis(); - return; - } - - // All other keys → inject to SMS screen - ui_task.injectKey(key); if (smsScr->isComposing()) { - composeNeedsRefresh = true; - lastComposeRefresh = millis(); + // Composing/text input: route directly to screen, bypass injectKey() + // to avoid UITask scheduling its own competing refresh + smsScr->handleInput(key); + if (smsScr->isComposing()) { + // Still composing — debounced refresh + composeNeedsRefresh = true; + lastComposeRefresh = millis(); + } else { + // View changed (sent/cancelled) — immediate UITask refresh + composeNeedsRefresh = false; + ui_task.forceRefresh(); + } + } else { + // Non-compose views (inbox, conversation, contacts): use normal inject + ui_task.injectKey(key); } return; } diff --git a/examples/companion_radio/ui-new/SMSScreen.h b/examples/companion_radio/ui-new/SMSScreen.h index 03510e2..b24e96b 100644 --- a/examples/companion_radio/ui-new/SMSScreen.h +++ b/examples/companion_radio/ui-new/SMSScreen.h @@ -294,7 +294,7 @@ public: display.drawRect(0, footerY - 2, display.width(), 1); display.setColor(DisplayDriver::YELLOW); display.setCursor(0, footerY); - display.print("Q:Bk"); + display.print("Q:Back"); const char* mid = "D:Contacts"; display.setCursor((display.width() - display.getTextWidth(mid)) / 2, footerY); display.print(mid); @@ -408,7 +408,7 @@ public: display.drawRect(0, footerY - 2, display.width(), 1); display.setColor(DisplayDriver::YELLOW); display.setCursor(0, footerY); - display.print("Q:Bk A:Add"); + display.print("Q:Bk A:Add Contact"); const char* rt = "C:Reply"; display.setCursor(display.width() - display.getTextWidth(rt) - 2, footerY); display.print(rt);