From 595f0073f97d00a87b868445b1094f8c6d4c10de Mon Sep 17 00:00:00 2001 From: pelgraine <140762863+pelgraine@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:04:36 +1000 Subject: [PATCH] =?UTF-8?q?TDeckBoard.cpp=20=E2=80=94=20both=20*=203=20/?= =?UTF-8?q?=202=20thresholds=20changed=20to=20>=20designCapacity=5FmAh,=20?= =?UTF-8?q?so=20FCC=3D3000=20with=20DC=3D2500=20now=20triggers=20the=20Qma?= =?UTF-8?q?x=20+=20stored=20FCC=20correction.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SerialBLEInterface.cpp — added esp_bt.h include and three esp_ble_tx_power_set calls at +9 dBm after BLEDevice::init(), covering default, advertising, and scan power types. MyMesh.h — FIRMWARE_VER_CODE bumped from 10 → 11. MyMesh.cpp — The RESP_CODE_DEVICE_INFO frame construction now: Byte 2: sends 0xFF (sentinel) when MAX_CONTACTS > 510, otherwise the normal MAX_CONTACTS / 2. Older apps interpret 0xFF as 510 contacts — completely harmless. Bytes 80-81 (new, appended after the version string): uint16_t little-endian with the true MAX_CONTACTS value. Apps that understand v11+ read it here. Apps < v11 ignore trailing bytes — the BLE/serial frame protocol is length-delimited, so extra bytes at the tail are safe. platformio.ini — Both BLE builds (meck_audio_ble, meck_4g_ble) bumped from 510 → 2000. mymesh.cpp: writeContactRespFrame return type change (return _serial->writeFrame() result) checkSerialInterface() batch-fill loop. --- examples/companion_radio/MyMesh.cpp | 35 ++- examples/companion_radio/MyMesh.h | 8 +- src/helpers/esp32/SerialBLEInterface.cpp | 22 +- src/helpers/esp32/SerialBLEInterface.h | 4 +- src/helpers/esp32/TBeamBoard.cpp | 350 ----------------------- src/helpers/esp32/TBeamBoard.h | 166 ----------- variants/lilygo_tdeck_pro/TDeckBoard.cpp | 4 +- variants/lilygo_tdeck_pro/platformio.ini | 23 +- 8 files changed, 65 insertions(+), 547 deletions(-) delete mode 100644 src/helpers/esp32/TBeamBoard.cpp delete mode 100644 src/helpers/esp32/TBeamBoard.h diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index d85b5a7a..66e8dbe2 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -166,7 +166,7 @@ void MyMesh::writeDisabledFrame() { _serial->writeFrame(buf, 1); } -void MyMesh::writeContactRespFrame(uint8_t code, const ContactInfo &contact) { +size_t MyMesh::writeContactRespFrame(uint8_t code, const ContactInfo &contact) { int i = 0; out_frame[i++] = code; memcpy(&out_frame[i], contact.id.pub_key, PUB_KEY_SIZE); @@ -186,7 +186,7 @@ void MyMesh::writeContactRespFrame(uint8_t code, const ContactInfo &contact) { i += 4; memcpy(&out_frame[i], &contact.lastmod, 4); i += 4; - _serial->writeFrame(out_frame, i); + return _serial->writeFrame(out_frame, i); } void MyMesh::updateContactFromFrame(ContactInfo &contact, uint32_t& last_mod, const uint8_t *frame, int len) { @@ -3142,20 +3142,29 @@ void MyMesh::checkSerialInterface() { } else if (_iter_started // check if our ContactsIterator is 'running' && !_serial->isWriteBusy() // don't spam the Serial Interface too quickly! ) { + // Batch-fill: queue multiple contacts per loop iteration so the BLE + // send queue stays saturated during sync. writeFrame() returns 0 + // when the queue is full, which naturally throttles us. ContactInfo contact; - if (_iter.hasNext(this, contact)) { - if (contact.lastmod > _iter_filter_since) { // apply the 'since' filter - writeContactRespFrame(RESP_CODE_CONTACT, contact); - if (contact.lastmod > _most_recent_lastmod) { - _most_recent_lastmod = contact.lastmod; // save for the RESP_CODE_END_OF_CONTACTS frame + bool done = false; + int queued = 0; + while (!done && queued < 8) { // up to 8 per iteration to avoid starving loop() + if (_iter.hasNext(this, contact)) { + if (contact.lastmod > _iter_filter_since) { // apply the 'since' filter + if (writeContactRespFrame(RESP_CODE_CONTACT, contact) == 0) break; // queue full + queued++; + if (contact.lastmod > _most_recent_lastmod) { + _most_recent_lastmod = contact.lastmod; + } } + } else { // EOF + out_frame[0] = RESP_CODE_END_OF_CONTACTS; + memcpy(&out_frame[1], &_most_recent_lastmod, + 4); // include the most recent lastmod, so app can update their 'since' + _serial->writeFrame(out_frame, 5); + _iter_started = false; + done = true; } - } else { // EOF - out_frame[0] = RESP_CODE_END_OF_CONTACTS; - memcpy(&out_frame[1], &_most_recent_lastmod, - 4); // include the most recent lastmod, so app can update their 'since' - _serial->writeFrame(out_frame, 5); - _iter_started = false; } //} else if (!_serial->isWriteBusy()) { // checkConnections(); // TODO - deprecate the 'Connections' stuff diff --git a/examples/companion_radio/MyMesh.h b/examples/companion_radio/MyMesh.h index 192907ae..50a53211 100644 --- a/examples/companion_radio/MyMesh.h +++ b/examples/companion_radio/MyMesh.h @@ -5,14 +5,14 @@ #include "AbstractUITask.h" /*------------ Frame Protocol --------------*/ -#define FIRMWARE_VER_CODE 10 +#define FIRMWARE_VER_CODE 11 #ifndef FIRMWARE_BUILD_DATE -#define FIRMWARE_BUILD_DATE "31 March 2026" +#define FIRMWARE_BUILD_DATE "7 April 2026" #endif #ifndef FIRMWARE_VERSION -#define FIRMWARE_VERSION "Meck v1.6" +#define FIRMWARE_VERSION "Meck v1.6.1" #endif #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM) @@ -243,7 +243,7 @@ private: void writeOKFrame(); void writeErrFrame(uint8_t err_code); void writeDisabledFrame(); - void writeContactRespFrame(uint8_t code, const ContactInfo &contact); + size_t writeContactRespFrame(uint8_t code, const ContactInfo &contact); void updateContactFromFrame(ContactInfo &contact, uint32_t& last_mod, const uint8_t *frame, int len); void addToOfflineQueue(const uint8_t frame[], int len); int getFromOfflineQueue(uint8_t frame[]); diff --git a/src/helpers/esp32/SerialBLEInterface.cpp b/src/helpers/esp32/SerialBLEInterface.cpp index e6f1bd71..22c44187 100644 --- a/src/helpers/esp32/SerialBLEInterface.cpp +++ b/src/helpers/esp32/SerialBLEInterface.cpp @@ -1,4 +1,6 @@ #include "SerialBLEInterface.h" +#include "esp_bt.h" +#include "esp_gap_ble_api.h" // See the following for generating UUIDs: // https://www.uuidgenerator.net/ @@ -27,6 +29,11 @@ void SerialBLEInterface::begin(const char* prefix, char* name, uint32_t pin_code BLEDevice::setSecurityCallbacks(this); BLEDevice::setMTU(MAX_FRAME_SIZE); + // Boost BLE TX power for improved range (+9 dBm, up from default +3 dBm) + esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT, ESP_PWR_LVL_P9); + esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, ESP_PWR_LVL_P9); + esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_SCAN, ESP_PWR_LVL_P9); + BLESecurity sec; sec.setStaticPIN(pin_code); sec.setAuthenticationMode(ESP_LE_AUTH_REQ_SC_MITM_BOND); @@ -77,6 +84,18 @@ void SerialBLEInterface::onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl) { if (cmpl.success) { BLE_DEBUG_PRINTLN(" - SecurityCallback - Authentication Success"); deviceConnected = true; + + // Request fast connection interval (15ms) for faster contact sync. + // Phone may negotiate higher, but most modern phones accept 15ms. + // Units are 1.25ms, so 12 = 15ms, 16 = 20ms. + esp_ble_conn_update_params_t conn_params; + memcpy(conn_params.bda, _remote_bda, 6); + conn_params.min_int = 12; // 15ms (12 × 1.25ms) + conn_params.max_int = 16; // 20ms (16 × 1.25ms) + conn_params.latency = 0; // no skipped intervals + conn_params.timeout = 400; // 4 seconds supervision timeout + esp_ble_gap_update_conn_params(&conn_params); + BLE_DEBUG_PRINTLN(" - Requested fast connection interval (15-20ms)"); } else { BLE_DEBUG_PRINTLN(" - SecurityCallback - Authentication Failure*"); @@ -94,6 +113,7 @@ void SerialBLEInterface::onConnect(BLEServer* pServer) { void SerialBLEInterface::onConnect(BLEServer* pServer, esp_ble_gatts_cb_param_t *param) { BLE_DEBUG_PRINTLN("onConnect(), conn_id=%d, mtu=%d", param->connect.conn_id, pServer->getPeerMTU(param->connect.conn_id)); last_conn_id = param->connect.conn_id; + memcpy(_remote_bda, param->connect.remote_bda, 6); } void SerialBLEInterface::onMtuChanged(BLEServer* pServer, esp_ble_gatts_cb_param_t* param) { @@ -185,7 +205,7 @@ size_t SerialBLEInterface::writeFrame(const uint8_t src[], size_t len) { return 0; } -#define BLE_WRITE_MIN_INTERVAL 30 +#define BLE_WRITE_MIN_INTERVAL 15 bool SerialBLEInterface::isWriteBusy() const { return millis() < _last_write + BLE_WRITE_MIN_INTERVAL; // still too soon to start another write? diff --git a/src/helpers/esp32/SerialBLEInterface.h b/src/helpers/esp32/SerialBLEInterface.h index e7ca1a14..a453e328 100644 --- a/src/helpers/esp32/SerialBLEInterface.h +++ b/src/helpers/esp32/SerialBLEInterface.h @@ -14,6 +14,7 @@ class SerialBLEInterface : public BaseSerialInterface, BLESecurityCallbacks, BLE bool oldDeviceConnected; bool _isEnabled; uint16_t last_conn_id; + uint8_t _remote_bda[6]; // peer BDA, stored in onConnect for conn param updates uint32_t _pin_code; unsigned long _last_write; unsigned long adv_restart_time; @@ -23,7 +24,7 @@ class SerialBLEInterface : public BaseSerialInterface, BLESecurityCallbacks, BLE uint8_t buf[MAX_FRAME_SIZE]; }; - #define FRAME_QUEUE_SIZE 8 + #define FRAME_QUEUE_SIZE 16 int recv_queue_len; Frame recv_queue[FRAME_QUEUE_SIZE]; int send_queue_len; @@ -58,6 +59,7 @@ public: _isEnabled = false; _last_write = 0; last_conn_id = 0; + memset(_remote_bda, 0, 6); send_queue_len = recv_queue_len = 0; } diff --git a/src/helpers/esp32/TBeamBoard.cpp b/src/helpers/esp32/TBeamBoard.cpp deleted file mode 100644 index 5f708d71..00000000 --- a/src/helpers/esp32/TBeamBoard.cpp +++ /dev/null @@ -1,350 +0,0 @@ -#if defined(TBEAM_SUPREME_SX1262) || defined(TBEAM_SX1262) || defined(TBEAM_SX1276) - -#include -#include "TBeamBoard.h" -//#include - -uint32_t deviceOnline = 0x00; - -bool pmuInterrupt; -static void setPmuFlag() -{ - pmuInterrupt = true; -} - -void TBeamBoard::begin() { - - ESP32Board::begin(); - - power_init(); - - //Configure user button - pinMode(PIN_USER_BTN, INPUT); - - #ifndef TBEAM_SUPREME_SX1262 - digitalWrite(P_LORA_TX_LED, HIGH); //inverted pin for SX1276 - HIGH for off - #endif - - //radiotype_detect(); - - esp_reset_reason_t reason = esp_reset_reason(); - if (reason == ESP_RST_DEEPSLEEP) { - long wakeup_source = esp_sleep_get_ext1_wakeup_status(); - if (wakeup_source & (1 << P_LORA_DIO_1)) { // received a LoRa packet (while in deep sleep) - startup_reason = BD_STARTUP_RX_PACKET; - } - - rtc_gpio_hold_dis((gpio_num_t)P_LORA_NSS); - rtc_gpio_deinit((gpio_num_t)P_LORA_DIO_1); - } -} - -#ifdef MESH_DEBUG -void TBeamBoard::scanDevices(TwoWire *w) -{ - uint8_t err, addr; - int nDevices = 0; - uint32_t start = 0; - - Serial.println("Scanning I2C for Devices"); - for (addr = 1; addr < 127; addr++) { - start = millis(); - w->beginTransmission(addr); delay(2); - err = w->endTransmission(); - if (err == 0) { - nDevices++; - switch (addr) { - case 0x77: - case 0x76: - Serial.println("\tFound BME280 Sensor"); - deviceOnline |= BME280_ONLINE; - break; - case 0x34: - Serial.println("\tFound AXP192/AXP2101 PMU"); - deviceOnline |= POWERMANAGE_ONLINE; - break; - case 0x3C: - Serial.println("\tFound SSD1306/SH1106 display"); - deviceOnline |= DISPLAY_ONLINE; - break; - case 0x51: - Serial.println("\tFound PCF8563 RTC"); - deviceOnline |= PCF8563_ONLINE; - break; - case 0x1C: - Serial.println("\tFound QMC6310 MAG Sensor"); - deviceOnline |= QMC6310_ONLINE; - break; - default: - Serial.print("\tI2C device found at address 0x"); - if (addr < 16) { - Serial.print("0"); - } - Serial.print(addr, HEX); - Serial.println(" !"); - break; - } - - } else if (err == 4) { - Serial.print("Unknow error at address 0x"); - if (addr < 16) { - Serial.print("0"); - } - Serial.println(addr, HEX); - } - } - if (nDevices == 0) - Serial.println("No I2C devices found\n"); - - Serial.println("Scan for devices is complete."); - Serial.println("\n"); - - Serial.printf("GPS RX pin: %d", PIN_GPS_RX); - Serial.printf(" GPS TX pin: %d", PIN_GPS_TX); - Serial.println(); -} -void TBeamBoard::printPMU() -{ - Serial.print("isCharging:"); Serial.println(PMU->isCharging() ? "YES" : "NO"); - Serial.print("isDischarge:"); Serial.println(PMU->isDischarge() ? "YES" : "NO"); - Serial.print("isVbusIn:"); Serial.println(PMU->isVbusIn() ? "YES" : "NO"); - Serial.print("getBattVoltage:"); Serial.print(PMU->getBattVoltage()); Serial.println("mV"); - Serial.print("getVbusVoltage:"); Serial.print(PMU->getVbusVoltage()); Serial.println("mV"); - Serial.print("getSystemVoltage:"); Serial.print(PMU->getSystemVoltage()); Serial.println("mV"); - - // The battery percentage may be inaccurate at first use, the PMU will automatically - // learn the battery curve and will automatically calibrate the battery percentage - // after a charge and discharge cycle - if (PMU->isBatteryConnect()) { - Serial.print("getBatteryPercent:"); Serial.print(PMU->getBatteryPercent()); Serial.println("%"); - } - - Serial.println(); -} -#endif - -bool TBeamBoard::power_init() -{ - if (!PMU) { - #ifdef TBEAM_SUPREME_SX1262 - PMU = new XPowersAXP2101(PMU_WIRE_PORT, PIN_BOARD_SDA1, PIN_BOARD_SCL1, I2C_PMU_ADD); - #else - PMU = new XPowersAXP2101(PMU_WIRE_PORT, PIN_BOARD_SDA, PIN_BOARD_SCL, I2C_PMU_ADD); - #endif - if (!PMU->init()) { - MESH_DEBUG_PRINTLN("Warning: Failed to find AXP2101 power management"); - delete PMU; - PMU = NULL; - } else { - MESH_DEBUG_PRINTLN("AXP2101 PMU init succeeded, using AXP2101 PMU"); - } - } - if (!PMU) { - PMU = new XPowersAXP192(PMU_WIRE_PORT, PIN_BOARD_SDA, PIN_BOARD_SCL, I2C_PMU_ADD); - if (!PMU->init()) { - MESH_DEBUG_PRINTLN("Warning: Failed to find AXP192 power management"); - delete PMU; - PMU = NULL; - } else { - MESH_DEBUG_PRINTLN("AXP192 PMU init succeeded, using AXP192 PMU"); - } - } - - if (!PMU) { - return false; - } - - deviceOnline |= POWERMANAGE_ONLINE; - - PMU->setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG); - - // Set up PMU interrupts - pinMode(PIN_PMU_IRQ, INPUT_PULLUP); - attachInterrupt(PIN_PMU_IRQ, setPmuFlag, FALLING); - - if (PMU->getChipModel() == XPOWERS_AXP192) { - - PMU->setPowerChannelVoltage(XPOWERS_LDO2, 3300); //Set up LoRa power rail - PMU->enablePowerOutput(XPOWERS_LDO2); //Enable the LoRa power rail - - PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300); //Set up OLED power rail - PMU->enablePowerOutput(XPOWERS_DCDC1); //Enable the OLED power rail - - PMU->setPowerChannelVoltage(XPOWERS_LDO3, 3300); //Set up GPS power rail - PMU->enablePowerOutput(XPOWERS_LDO3); //Enable the GPS power rail - - PMU->setProtectedChannel(XPOWERS_DCDC1); //Protect the OLED power rail - PMU->setProtectedChannel(XPOWERS_DCDC3); //Protect the ESP32 power rail - - PMU->disablePowerOutput(XPOWERS_DCDC2); //Disable unsused power rail DC2 - - PMU->disableIRQ(XPOWERS_AXP192_ALL_IRQ); //Disable PMU IRQ - - PMU->setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_450MA); //Set battery charging current - PMU->setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2); //Set battery charge-stop voltage - } - else if(PMU->getChipModel() == XPOWERS_AXP2101){ - #ifdef TBEAM_SUPREME_SX1262 - //Set up the GPS power rail - PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300); - PMU->enablePowerOutput(XPOWERS_ALDO4); - - //Set up the LoRa power rail - PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300); - PMU->enablePowerOutput(XPOWERS_ALDO3); - - //Set up power rail for the M.2 interface - PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300); - PMU->enablePowerOutput(XPOWERS_DCDC3); - - if (ESP_SLEEP_WAKEUP_UNDEFINED == esp_sleep_get_wakeup_cause()) { - MESH_DEBUG_PRINTLN("Power off and restart ALDO BLDO.."); - PMU->disablePowerOutput(XPOWERS_ALDO1); - PMU->disablePowerOutput(XPOWERS_ALDO2); - PMU->disablePowerOutput(XPOWERS_BLDO1); - delay(250); - } - - //Set up power rail for QMC6310U - PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300); - PMU->enablePowerOutput(XPOWERS_ALDO2); - - //Set up power rail for BME280 and OLED - PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300); - PMU->enablePowerOutput(XPOWERS_ALDO1); - - //Set up pwer rail for SD Card - PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300); - PMU->enablePowerOutput(XPOWERS_BLDO1); - - //Set up power rail BLDO2 to headers - PMU->setPowerChannelVoltage(XPOWERS_BLDO2, 3300); - PMU->enablePowerOutput(XPOWERS_BLDO2); - - //Set up power rail DCDC4 to headers - PMU->setPowerChannelVoltage(XPOWERS_DCDC4, XPOWERS_AXP2101_DCDC4_VOL2_MAX); - PMU->enablePowerOutput(XPOWERS_DCDC4); - - //Set up power rail DCDC5 to headers - PMU->setPowerChannelVoltage(XPOWERS_DCDC5, 3300); - PMU->enablePowerOutput(XPOWERS_DCDC5); - - //Disable unused power rails - PMU->disablePowerOutput(XPOWERS_DCDC2); - PMU->disablePowerOutput(XPOWERS_DLDO1); - PMU->disablePowerOutput(XPOWERS_DLDO2); - PMU->disablePowerOutput(XPOWERS_VBACKUP); - #else - //Turn off unused power rails - PMU->disablePowerOutput(XPOWERS_DCDC2); - PMU->disablePowerOutput(XPOWERS_DCDC3); - PMU->disablePowerOutput(XPOWERS_DCDC4); - PMU->disablePowerOutput(XPOWERS_DCDC5); - PMU->disablePowerOutput(XPOWERS_ALDO1); - PMU->disablePowerOutput(XPOWERS_ALDO4); - PMU->disablePowerOutput(XPOWERS_BLDO1); - PMU->disablePowerOutput(XPOWERS_BLDO2); - PMU->disablePowerOutput(XPOWERS_DLDO1); - PMU->disablePowerOutput(XPOWERS_DLDO2); - //PMU->disablePowerOutput(XPOWERS_CPULDO); - - PMU->setPowerChannelVoltage(XPOWERS_VBACKUP, 3300); //Set up GPS RTC power - PMU->enablePowerOutput(XPOWERS_VBACKUP); //Turn on GPS RTC power - - PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300); //Set up LoRa power rail - PMU->enablePowerOutput(XPOWERS_ALDO2); //Enable LoRa power rail - - PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300); //Set up GPS power rail - PMU->enablePowerOutput(XPOWERS_ALDO3); //Enable GPS power rail - - #endif - - PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ); //Disable all PMU interrupts - - PMU->setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_500MA); //Set battery charging current to 500mA - PMU->setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2); //Set battery charging cutoff voltage to 4.2V - - } - - PMU->clearIrqStatus(); //Clear interrupt flags - - PMU->disableTSPinMeasure(); //Disable TS detection, since it is not used - - //Enable voltage measurements - PMU->enableSystemVoltageMeasure(); - PMU->enableVbusVoltageMeasure(); - PMU->enableBattVoltageMeasure(); - -#ifdef MESH_DEBUG - scanDevices(&Wire); - printPMU(); -#endif - - // Set the power key off press time - PMU->setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S); - return true; -} - -#pragma region "Debug code" -// void TBeamBoard::radiotype_detect(){ - -// static SPIClass spi; -// char chipTypeInfo; - -// #if defined(P_LORA_SCLK) -// spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI); -// #endif - -// for(int i = 0; i -#include -#include "XPowersLib.h" -#include "helpers/ESP32Board.h" -#include - -class TBeamBoard : public ESP32Board { -XPowersLibInterface *PMU = NULL; -//PhysicalLayer * pl; -//RadioType * radio = NULL; -// int radioVersions = 2; - -enum { - POWERMANAGE_ONLINE = _BV(0), - DISPLAY_ONLINE = _BV(1), - RADIO_ONLINE = _BV(2), - GPS_ONLINE = _BV(3), - PSRAM_ONLINE = _BV(4), - SDCARD_ONLINE = _BV(5), - AXDL345_ONLINE = _BV(6), - BME280_ONLINE = _BV(7), - BMP280_ONLINE = _BV(8), - BME680_ONLINE = _BV(9), - QMC6310_ONLINE = _BV(10), - QMI8658_ONLINE = _BV(11), - PCF8563_ONLINE = _BV(12), - OSC32768_ONLINE = _BV(13), -}; - -bool power_init(); -//void radiotype_detect(); - -public: - -#ifdef MESH_DEBUG - void printPMU(); - void scanDevices(TwoWire *w); -#endif - void begin(); - - #ifndef TBEAM_SUPREME_SX1262 - void onBeforeTransmit() override{ - digitalWrite(P_LORA_TX_LED, LOW); // turn TX LED on - invert pin for SX1276 - } - void onAfterTransmit() override{ - digitalWrite(P_LORA_TX_LED, HIGH); // turn TX LED off - invert pin for SX1276 - } - #endif - - void enterDeepSleep(uint32_t secs, int pin_wake_btn) { - esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); - - // Make sure the DIO1 and NSS GPIOs are hold on required levels during deep sleep - rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY); - rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1); - - rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS); - - if (pin_wake_btn < 0) { - esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet - } else { - esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn - } - - if (secs > 0) { - esp_sleep_enable_timer_wakeup(secs * 1000000); - } - - // Finally set ESP32 into sleep - esp_deep_sleep_start(); // CPU halts here and never returns! -} - - uint16_t getBattMilliVolts(){ - return PMU->getBattVoltage(); - } - - const char* getManufacturerName() const{ - return "LilyGo T-Beam"; - } -}; - -#endif diff --git a/variants/lilygo_tdeck_pro/TDeckBoard.cpp b/variants/lilygo_tdeck_pro/TDeckBoard.cpp index c6351717..14c58210 100644 --- a/variants/lilygo_tdeck_pro/TDeckBoard.cpp +++ b/variants/lilygo_tdeck_pro/TDeckBoard.cpp @@ -199,7 +199,7 @@ bool TDeckBoard::configureFuelGauge(uint16_t designCapacity_mAh) { // Design Capacity correct, but check if Full Charge Capacity is sane. uint16_t fcc = bq27220_read16(BQ27220_REG_FULL_CAP); Serial.printf("BQ27220: Design Capacity already correct, FCC=%d mAh\n", fcc); - if (fcc >= designCapacity_mAh * 3 / 2) { + if (fcc > designCapacity_mAh) { // FCC is >=150% of design — stale from factory defaults (typically 3000 mAh). uint16_t designEnergy = (uint16_t)((uint32_t)designCapacity_mAh * 37 / 10); Serial.printf("BQ27220: FCC %d >> DC %d, checking Design Energy (target %d mWh)\n", @@ -344,7 +344,7 @@ bool TDeckBoard::configureFuelGauge(uint16_t designCapacity_mAh) { fcc = bq27220_read16(BQ27220_REG_FULL_CAP); Serial.printf("BQ27220: FCC after RESET: %d mAh (target <= %d)\n", fcc, designCapacity_mAh); - if (fcc > designCapacity_mAh * 3 / 2) { + if (fcc > designCapacity_mAh) { // RESET didn't fix FCC — the gauge IT algorithm is stubbornly // retaining its learned value. This typically resolves after one // full charge/discharge cycle. Software clamp in diff --git a/variants/lilygo_tdeck_pro/platformio.ini b/variants/lilygo_tdeck_pro/platformio.ini index 63a38525..2d52967f 100644 --- a/variants/lilygo_tdeck_pro/platformio.ini +++ b/variants/lilygo_tdeck_pro/platformio.ini @@ -105,13 +105,15 @@ lib_deps = ; --------------------------------------------------------------------------- ; Audio + BLE companion (audio-player hardware with BLE phone bridging) -; MAX_CONTACTS=500 is near BLE protocol ceiling (MAX_CONTACTS/2 sent as uint8_t, max 510) +; MAX_CONTACTS=2000 — protocol v11+ sends true capacity in extended DEVICE_INFO field. +; Older apps see 510 (sentinel 0xFF in legacy byte) and still work correctly. +; Contact + sort arrays allocated in PSRAM via BaseChatMesh::initContacts(). [env:meck_audio_ble] extends = LilyGo_TDeck_Pro build_flags = ${LilyGo_TDeck_Pro.build_flags} -I examples/companion_radio/ui-new - -D MAX_CONTACTS=510 + -D MAX_CONTACTS=2000 -D MAX_GROUP_CHANNELS=20 -D BLE_PIN_CODE=123456 -D OFFLINE_QUEUE_SIZE=256 @@ -155,7 +157,7 @@ build_flags = -D MECK_AUDIO_VARIANT -D MECK_WEB_READER=1 -D MECK_OTA_UPDATE=1 - -D FIRMWARE_VERSION='"Meck v1.6.WiFi"' + -D FIRMWARE_VERSION='"Meck v1.6.1.WiFi"' build_src_filter = ${LilyGo_TDeck_Pro.build_src_filter} + + @@ -205,20 +207,22 @@ lib_ignore = ESP32 BLE Arduino ; 4G + BLE companion (4G modem hardware, no audio — GPIO conflict with PCM5102A) -; MAX_CONTACTS=500 is near BLE protocol ceiling (MAX_CONTACTS/2 sent as uint8_t, max 510) +; MAX_CONTACTS=2000 — protocol v11+ sends true capacity in extended DEVICE_INFO field. +; Older apps see 510 (sentinel 0xFF in legacy byte) and still work correctly. +; Contact + sort arrays allocated in PSRAM via BaseChatMesh::initContacts(). [env:meck_4g_ble] extends = LilyGo_TDeck_Pro build_flags = ${LilyGo_TDeck_Pro.build_flags} -I examples/companion_radio/ui-new - -D MAX_CONTACTS=510 + -D MAX_CONTACTS=2000 -D MAX_GROUP_CHANNELS=20 -D BLE_PIN_CODE=123456 -D OFFLINE_QUEUE_SIZE=256 -D HAS_4G_MODEM=1 -D MECK_WEB_READER=1 -D MECK_OTA_UPDATE=1 - -D FIRMWARE_VERSION='"Meck v1.6.4G"' + -D FIRMWARE_VERSION='"Meck v1.6.1.4G"' build_src_filter = ${LilyGo_TDeck_Pro.build_src_filter} + + @@ -254,7 +258,7 @@ build_flags = -D HAS_4G_MODEM=1 -D MECK_WEB_READER=1 -D MECK_OTA_UPDATE=1 - -D FIRMWARE_VERSION='"Meck v1.6.4G.WiFi"' + -D FIRMWARE_VERSION='"Meck v1.6.1.4G.WiFi"' build_src_filter = ${LilyGo_TDeck_Pro.build_src_filter} + + @@ -287,7 +291,7 @@ build_flags = -D HAS_4G_MODEM=1 -D MECK_WEB_READER=1 -D MECK_OTA_UPDATE=1 - -D FIRMWARE_VERSION='"Meck v1.6.4G.SA"' + -D FIRMWARE_VERSION='"Meck v1.6.1.4G.SA"' build_src_filter = ${LilyGo_TDeck_Pro.build_src_filter} + + @@ -422,5 +426,4 @@ lib_ignore = ESPAsyncWebServer AsyncElegantOTA ESP32-audioI2S - esp32_codec2_arduino - \ No newline at end of file + esp32_codec2_arduino \ No newline at end of file