Max - 4G working!

This commit is contained in:
pelgraine
2026-06-04 20:37:53 +10:00
parent 30d2e6aee7
commit 4db03adb3a
4 changed files with 108 additions and 7 deletions
+9 -5
View File
@@ -82,7 +82,7 @@
// Audiobook player — Audio object is heap-allocated on first use to avoid
// consuming ~40KB of DMA/decode buffers at boot (starves BLE stack).
// Not available on 4G variant (I2S pins conflict with modem control lines).
#ifndef HAS_4G_MODEM
#if !defined(HAS_4G_MODEM) || defined(MECK_AUDIO_VARIANT)
#include "AudiobookPlayerScreen.h"
#include "Audio.h"
Audio* audio = nullptr;
@@ -2444,8 +2444,12 @@ void setup() {
MESH_DEBUG_PRINTLN("setup() - 4G modem manager started");
} else {
// Ensure modem power is off (kills red LED too)
#if defined(LilyGo_TDeck_Pro_Max)
board.modemPowerOff(); // XL9555 6609_EN LOW
#else
pinMode(MODEM_POWER_EN, OUTPUT);
digitalWrite(MODEM_POWER_EN, LOW);
#endif
MESH_DEBUG_PRINTLN("setup() - 4G modem disabled by config");
}
}
@@ -2720,7 +2724,7 @@ void loop() {
#endif
// Audiobook: service audio decode regardless of which screen is active
#if defined(LilyGo_TDeck_Pro) && !defined(HAS_4G_MODEM)
#if defined(LilyGo_TDeck_Pro) && (!defined(HAS_4G_MODEM) || defined(MECK_AUDIO_VARIANT))
{
AudiobookPlayerScreen* abPlayer =
(AudiobookPlayerScreen*)ui_task.getAudiobookScreen();
@@ -4392,7 +4396,7 @@ void handleKeyboardInput() {
}
// *** AUDIOBOOK MODE ***
#ifndef HAS_4G_MODEM
#if !defined(HAS_4G_MODEM) || defined(MECK_AUDIO_VARIANT)
if (audiobookMode) {
AudiobookPlayerScreen* abPlayer =
(AudiobookPlayerScreen*)ui_task.getAudiobookScreen();
@@ -5070,7 +5074,7 @@ void handleKeyboardInput() {
}
break;
}
#ifndef HAS_4G_MODEM
#if !defined(HAS_4G_MODEM) || defined(MECK_AUDIO_VARIANT)
// Otherwise: open audiobook player - lazy-init Audio + screen on first use
Serial.println("Opening audiobook player");
if (!ui_task.getAudiobookScreen()) {
@@ -5955,7 +5959,7 @@ void sendComposedMessage() {
// The audio library calls these global functions - must be defined at file scope.
// Not available on 4G variant (no audio hardware).
#ifndef HAS_4G_MODEM
#if !defined(HAS_4G_MODEM) || defined(MECK_AUDIO_VARIANT)
void audio_info(const char *info) {
Serial.printf("Audio: %s\n", info);
}
@@ -6,6 +6,11 @@
#include <time.h>
#include <sys/time.h>
#if defined(LilyGo_TDeck_Pro_Max)
#include <TDeckProMaxBoard.h> // MAX: XL9555-routed modem power/PWRKEY
extern TDeckProMaxBoard board; // defined in target.cpp
#endif
// Global singleton
ModemManager modemManager;
@@ -93,7 +98,11 @@ void ModemManager::shutdown() {
}
// Cut modem power
#if defined(LilyGo_TDeck_Pro_Max)
board.modemPowerOff(); // XL9555 6609_EN LOW
#else
digitalWrite(MODEM_POWER_EN, LOW);
#endif
// Delete task
vTaskDelete(_taskHandle);
@@ -511,6 +520,11 @@ void ModemManager::processURCLine(const char* line) {
// --- VOICE CALL: BEGIN -- A76xx-specific: audio path established ---
if (strncmp(line, "VOICE CALL: BEGIN", 17) == 0) {
MESH_DEBUG_PRINTLN("[Modem] URC: VOICE CALL: BEGIN");
#if defined(LilyGo_TDeck_Pro_Max)
// MAX: route the shared speaker mux to the modem and enable the amplifier
board.selectAudioModem();
board.amplifierEnable();
#endif
if (_state == ModemState::DIALING) {
_state = ModemState::IN_CALL;
_callStartTime = millis();
@@ -543,6 +557,11 @@ void ModemManager::processURCLine(const char* line) {
_state = ModemState::READY;
_callPhone[0] = '\0';
_callStartTime = 0;
#if defined(LilyGo_TDeck_Pro_Max)
// MAX: call audio path closed -- return the speaker mux to ES8311, amp off
board.selectAudioES8311();
board.amplifierDisable();
#endif
return;
}
@@ -638,6 +657,11 @@ bool ModemManager::doHangup() {
_state = ModemState::READY;
_callPhone[0] = '\0';
_callStartTime = 0;
#if defined(LilyGo_TDeck_Pro_Max)
// MAX: hung up -- return the speaker mux to ES8311, amp off
board.selectAudioES8311();
board.amplifierDisable();
#endif
MESH_DEBUG_PRINTLN("[Modem] Hangup OK");
return true;
}
@@ -679,6 +703,11 @@ void ModemManager::handleRingtone() {
_ringing = true;
_nextRingTone = 0; // Play first burst immediately
_toneActive = false;
#if defined(LilyGo_TDeck_Pro_Max)
// MAX: route the shared speaker to the modem for the ringtone bursts
board.selectAudioModem();
board.amplifierEnable();
#endif
} else if (!nowRinging && _ringing) {
// Ringing stopped (answered, rejected, missed)
_ringing = false;
@@ -686,6 +715,14 @@ void ModemManager::handleRingtone() {
sendAT("AT+SIMTONE=0", "OK", 500);
_toneActive = false;
}
#if defined(LilyGo_TDeck_Pro_Max)
// MAX: if the call was NOT answered (not now in-call), return audio to
// ES8311. If it WAS answered, leave the mux on the modem for call audio.
if (_state != ModemState::IN_CALL) {
board.selectAudioES8311();
board.amplifierDisable();
}
#endif
return;
}
@@ -841,6 +878,11 @@ bool ModemManager::playModemTone(const char* filename) {
// param 2: 0 = no repeat
char cmd[64];
snprintf(cmd, sizeof(cmd), "AT+CCMXPLAY=\"C:/%s\",0,0", filename);
#if defined(LilyGo_TDeck_Pro_Max)
// MAX: route the shared speaker to the modem for tone playback
board.selectAudioModem();
board.amplifierEnable();
#endif
bool ok = sendAT(cmd, "OK", 2000);
if (ok) {
_notifTonePlaying = true;
@@ -856,6 +898,11 @@ bool ModemManager::stopModemTone() {
if (!_notifTonePlaying) return true;
bool ok = sendAT("AT+CCMXSTOP", "OK", 1000);
_notifTonePlaying = false;
#if defined(LilyGo_TDeck_Pro_Max)
// MAX: tone finished -- return the speaker mux to ES8311, amp off
board.selectAudioES8311();
board.amplifierDisable();
#endif
MESH_DEBUG_PRINTLN("[Modem] Tone stop %s", ok ? "OK" : "FAIL");
return ok;
}
@@ -1249,6 +1296,23 @@ restart:
bool ModemManager::modemPowerOn() {
MESH_DEBUG_PRINTLN("[Modem] powering on...");
#if defined(LilyGo_TDeck_Pro_Max)
// MAX: 6609_EN and PWRKEY are XL9555-routed, and there is NO modem reset
// line (IO9 is the e-ink reset on MAX). Drive power/PWRKEY via the board
// helpers and skip the reset pulse entirely.
board.modemPowerOn(); // XL9555 6609_EN HIGH (SGM6609 boost)
vTaskDelay(pdMS_TO_TICKS(500));
MESH_DEBUG_PRINTLN("[Modem] power supply enabled (XL9555 6609_EN)");
board.modemPwrkeyPulse(); // XL9555 PWRKEY HIGH/LOW(1200ms)/HIGH
MESH_DEBUG_PRINTLN("[Modem] PWRKEY pulsed, waiting for boot...");
vTaskDelay(pdMS_TO_TICKS(5000));
// DTR is a direct GPIO on MAX (IO8)
pinMode(MODEM_DTR, OUTPUT);
digitalWrite(MODEM_DTR, LOW);
MESH_DEBUG_PRINTLN("[Modem] DTR asserted LOW (GPIO %d)", MODEM_DTR);
#else
// Enable modem power supply (BOARD_6609_EN)
pinMode(MODEM_POWER_EN, OUTPUT);
digitalWrite(MODEM_POWER_EN, HIGH);
@@ -1278,6 +1342,7 @@ bool ModemManager::modemPowerOn() {
pinMode(MODEM_DTR, OUTPUT);
digitalWrite(MODEM_DTR, LOW);
MESH_DEBUG_PRINTLN("[Modem] DTR asserted LOW (GPIO %d)", MODEM_DTR);
#endif
// Configure UART
MODEM_SERIAL.begin(MODEM_BAUD, SERIAL_8N1, MODEM_TX, MODEM_RX);
+33 -2
View File
@@ -467,6 +467,8 @@ public:
display.drawTextCentered(display.width() / 2, y, tmp);
#if defined(LILYGO_TECHO_LITE)
y += 12; // Compact
#elif defined(LilyGo_TDeck_Pro_Max)
y += 10; // MAX: pull < Connected > up under MSG to make room for [T] Phone
#else
y += 14; // Reduced from 18
#endif
@@ -627,7 +629,19 @@ public:
display.setCursor(col1, y); display.print("[E] Reader");
#endif
y += menuLH;
#if defined(HAS_4G_MODEM) && defined(MECK_WEB_READER)
#if defined(HAS_4G_MODEM) && defined(MECK_AUDIO_VARIANT)
display.setCursor(col1, y); display.print("[P] Audio");
display.setCursor(col2, y); display.print("[K] Alarm");
y += menuLH;
#ifdef MECK_WEB_READER
display.setCursor(col1, y); display.print("[B] Browser");
display.setCursor(col2, y); display.print("[F] Discover");
#else
display.setCursor(col1, y); display.print("[F] Discover");
#endif
y += menuLH;
display.setCursor(col1, y); display.print("[T] Phone");
#elif defined(HAS_4G_MODEM) && defined(MECK_WEB_READER)
display.setCursor(col1, y); display.print("[T] Phone");
display.setCursor(col2, y); display.print("[B] Browser");
#elif defined(HAS_4G_MODEM)
@@ -657,7 +671,11 @@ public:
y += 2;
} else {
// Monospaced built-in font (Classic): centered space-padded strings
#if defined(LilyGo_TDeck_Pro_Max)
y += 2; // MAX: Press sits closer under < Connected >
#else
y += 6;
#endif
display.drawTextCentered(display.width() / 2, y, "Press:");
y += 12;
display.drawTextCentered(display.width() / 2, y, "[M] Messages [C] Contacts ");
@@ -670,7 +688,15 @@ public:
display.drawTextCentered(display.width() / 2, y, "[E] Reader ");
#endif
y += 10;
#if defined(HAS_4G_MODEM) && defined(MECK_WEB_READER)
#if defined(HAS_4G_MODEM) && defined(MECK_AUDIO_VARIANT)
display.drawTextCentered(display.width() / 2, y, "[P] Audiobooks [K] Alarm ");
y += 10;
#ifdef MECK_WEB_READER
display.drawTextCentered(display.width() / 2, y, "[B] Browser [F] Discover ");
#else
display.drawTextCentered(display.width() / 2, y, "[F] Discover ");
#endif
#elif defined(HAS_4G_MODEM) && defined(MECK_WEB_READER)
display.drawTextCentered(display.width() / 2, y, "[T] Phone [B] Browser ");
#elif defined(HAS_4G_MODEM)
display.drawTextCentered(display.width() / 2, y, "[T] Phone [F] Discover ");
@@ -692,6 +718,11 @@ public:
display.drawTextCentered(display.width() / 2, y, "[R] Trace [J] Games ");
display.setColor(DisplayDriver::LIGHT);
y += 14;
#if defined(HAS_4G_MODEM) && defined(MECK_AUDIO_VARIANT)
// Phone on its own line below Trace/Games, centered like the "Press:" header
display.drawTextCentered(display.width() / 2, y, "[T] Phone");
y += 14;
#endif
}
// Nav hint (only if room)
+1
View File
@@ -172,6 +172,7 @@ build_flags =
-D BLE_PIN_CODE=123456
-D OFFLINE_QUEUE_SIZE=256
-D MECK_WEB_READER=1
-D HAS_4G_MODEM=1
-D MECK_OTA_UPDATE=1
-D FIRMWARE_VERSION='"Meck v1.11.MAX"'
build_src_filter = ${LilyGo_TDeck_Pro_Max.build_src_filter}