diff --git a/src/helpers/TBeamS3SupremeBoard.h b/src/helpers/TBeamS3SupremeBoard.h index 200756a2..e30c02ed 100644 --- a/src/helpers/TBeamS3SupremeBoard.h +++ b/src/helpers/TBeamS3SupremeBoard.h @@ -27,7 +27,7 @@ #define P_BOARD_SPI_MOSI 35 //SPI for SD Card and QMI8653 (IMU) #define P_BOARD_SPI_MISO 37 //SPI for SD Card and QMI8653 (IMU) #define P_BOARD_SPI_SCK 36 //SPI for SD Card and QMI8653 (IMU) -#define P_BPARD_SPI_CS 47 //SPI for SD Card and QMI8653 (IMU) +#define P_BPARD_SPI_CS 47 //Pin for SD Card CS #define P_BOARD_IMU_CS 34 //Pin for QMI8653 (IMU) CS #define P_BOARD_IMU_INT 33 //IMU Int pin @@ -37,6 +37,7 @@ #define P_GPS_TX 8 //GPS TX pin #define P_GPS_WAKE 7 //GPS Wakeup pin #define P_GPS_1PPS 6 //GPS 1PPS pin +#define GPS_BAUD_RATE 9600 //I2C Wire addresses #define I2C_BME280_ADD 0x76 //BME280 sensor I2C address on Wire diff --git a/variants/lilygo_tbeam_supreme_SX1262/platformio.ini b/variants/lilygo_tbeam_supreme_SX1262/platformio.ini index 407087bb..c53c51ac 100644 --- a/variants/lilygo_tbeam_supreme_SX1262/platformio.ini +++ b/variants/lilygo_tbeam_supreme_SX1262/platformio.ini @@ -9,14 +9,16 @@ build_flags = -D WRAPPER_CLASS=CustomSX1262Wrapper ;-D DISPLAY_CLASS=SSD1306Display ;Needs to be modified for SH1106 -D SX126X_RX_BOOSTED_GAIN=1 + -D HAS_PMU=1 + -D HAS_GPS=1 build_src_filter = ${esp32_base.build_src_filter} +<../variants/lilygo_tbeam_supreme_SX1262> board_build.partitions = min_spiffs.csv ; get around 4mb flash limit lib_deps = ${esp32_base.lib_deps} - lewisxhe/PCF8563_Library@^1.0.1 lewisxhe/XPowersLib @ ^0.2.7 ;adafruit/Adafruit SSD1306 @ ^2.5.13 + stevemarple/MicroNMEA @ ^2.0.6 ; === LILYGO T-Beam S3 Supreme with SX1262 environments === [env:T_Beam_S3_Supreme_SX1262_repeater] diff --git a/variants/lilygo_tbeam_supreme_SX1262/target.cpp b/variants/lilygo_tbeam_supreme_SX1262/target.cpp index fe767729..382d5111 100644 --- a/variants/lilygo_tbeam_supreme_SX1262/target.cpp +++ b/variants/lilygo_tbeam_supreme_SX1262/target.cpp @@ -1,5 +1,6 @@ #include #include "target.h" +#include TBeamS3SupremeBoard board; @@ -20,7 +21,8 @@ WRAPPER_CLASS radio_driver(radio, board); ESP32RTCClock fallback_clock; AutoDiscoverRTCClock rtc_clock(fallback_clock); -SensorManager sensors; +MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); +TbeamSupSensorManager sensors = TbeamSupSensorManager(nmea); static void setPMUIntFlag(){ pmuIntFlag = true; @@ -74,9 +76,9 @@ bool TBeamS3SupremeBoard::power_init() MESH_DEBUG_PRINTLN("Reset a-ldo1&2 and b-ldo1"); if (ESP_SLEEP_WAKEUP_UNDEFINED == esp_sleep_get_wakeup_cause()) { - PMU.enableALDO1(); - PMU.enableALDO2(); - PMU.enableBLDO1(); + PMU.disableALDO1(); + PMU.disableALDO2(); + PMU.disableBLDO1(); delay(250); } @@ -121,7 +123,7 @@ bool TBeamS3SupremeBoard::power_init() // Set charge current to 300mA MESH_DEBUG_PRINTLN("Setting battery charge current limit and voltage"); - PMU.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_300MA); + PMU.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_500MA); PMU.setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2); // enable battery voltage measurement @@ -147,6 +149,59 @@ bool TBeamS3SupremeBoard::power_init() return true; } +bool l76kProbe() +{ + bool result = false; + uint32_t startTimeout ; + Serial1.write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n"); + delay(5); + // Get version information + startTimeout = millis() + 3000; + MESH_DEBUG_PRINTLN("Trying to init L76K GPS"); + // Serial1.flush(); + while (Serial1.available()) { + int c = Serial1.read(); + // Serial.write(c); + // Serial.print("."); + // Serial.flush(); + // Serial1.flush(); + if (millis() > startTimeout) { + MESH_DEBUG_PRINTLN("L76K NMEA timeout!"); + return false; + } + }; + Serial.println(); + Serial1.flush(); + delay(200); + + Serial1.write("$PCAS06,0*1B\r\n"); + startTimeout = millis() + 500; + String ver = ""; + while (!Serial1.available()) { + if (millis() > startTimeout) { + MESH_DEBUG_PRINTLN("Get L76K timeout!"); + return false; + } + } + Serial1.setTimeout(10); + ver = Serial1.readStringUntil('\n'); + if (ver.startsWith("$GPTXT,01,01,02")) { + MESH_DEBUG_PRINTLN("L76K GNSS init succeeded, using L76K GNSS Module\n"); + result = true; + } + delay(500); + + // Initialize the L76K Chip, use GPS + GLONASS + Serial1.write("$PCAS04,5*1C\r\n"); + delay(250); + // only ask for RMC and GGA + Serial1.write("$PCAS03,1,0,0,0,1,0,0,0,0,0,,,0,0*02\r\n"); + delay(250); + // Switch to Vehicle Mode, since SoftRF enables Aviation < 2g + Serial1.write("$PCAS11,3*1E\r\n"); + return result; +} + bool radio_init() { fallback_clock.begin(); Wire1.begin(PIN_BOARD_SDA1,PIN_BOARD_SCL1); @@ -188,6 +243,82 @@ void radio_set_tx_power(uint8_t dbm) { radio.setOutputPower(dbm); } +void TbeamSupSensorManager::start_gps() +{ + gps_active = true; + pinMode(P_GPS_WAKE, OUTPUT); + digitalWrite(P_GPS_WAKE, HIGH); +} + +void TbeamSupSensorManager::sleep_gps() { + gps_active = false; + pinMode(P_GPS_WAKE, OUTPUT); + digitalWrite(P_GPS_WAKE, LOW); +} + +bool TbeamSupSensorManager::begin() { + // init GPS port + + Serial1.begin(GPS_BAUD_RATE, SERIAL_8N1, P_GPS_RX, P_GPS_TX); + + bool result = false; + for ( int i = 0; i < 3; ++i) { + result = l76kProbe(); + if (result) { + gps_active = true; + return result; + } + } + return result; +} + +bool TbeamSupSensorManager::querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) { + if (requester_permissions & TELEM_PERM_LOCATION) { // does requester have permission? + telemetry.addGPS(TELEM_CHANNEL_SELF, node_lat, node_lon, 0.0f); + } + return true; +} + +void TbeamSupSensorManager::loop() { + static long next_gps_update = 0; + + _nmea->loop(); + + if (millis() > next_gps_update) { + if (_nmea->isValid()) { + node_lat = ((double)_nmea->getLatitude())/1000000.; + node_lon = ((double)_nmea->getLongitude())/1000000.; + //Serial.printf("lat %f lon %f\r\n", _lat, _lon); + } + next_gps_update = millis() + 1000; + } +} + +int TbeamSupSensorManager::getNumSettings() const { return 1; } // just one supported: "gps" (power switch) + +const char* TbeamSupSensorManager::getSettingName(int i) const { + return i == 0 ? "gps" : NULL; +} + +const char* TbeamSupSensorManager::getSettingValue(int i) const { + if (i == 0) { + return gps_active ? "1" : "0"; + } + return NULL; +} + +bool TbeamSupSensorManager::setSettingValue(const char* name, const char* value) { + if (strcmp(name, "gps") == 0) { + if (strcmp(value, "0") == 0) { + sleep_gps(); + } else { + start_gps(); + } + return true; + } + return false; // not supported +} + mesh::LocalIdentity radio_new_identity() { RadioNoiseListener rng(radio); return mesh::LocalIdentity(&rng); // create new random identity diff --git a/variants/lilygo_tbeam_supreme_SX1262/target.h b/variants/lilygo_tbeam_supreme_SX1262/target.h index f14b2142..107e2950 100644 --- a/variants/lilygo_tbeam_supreme_SX1262/target.h +++ b/variants/lilygo_tbeam_supreme_SX1262/target.h @@ -1,17 +1,54 @@ #pragma once +#define RADIOLIB_STATIC_ONLY 1 #include #include #include #include #include #include +#include + +class TbeamSupSensorManager: public SensorManager { + bool gps_active = false; + LocationProvider * _nmea; + + void start_gps(); + void sleep_gps(); + public: + TbeamSupSensorManager(LocationProvider &nmea): _nmea(&nmea) { } + bool begin() override; + bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) override; + void loop() override; + int getNumSettings() const override; + const char* getSettingName(int i) const override; + const char* getSettingValue(int i) const override; + bool setSettingValue(const char* name, const char* value) override; + }; extern TBeamS3SupremeBoard board; extern WRAPPER_CLASS radio_driver; extern AutoDiscoverRTCClock rtc_clock; -extern SensorManager sensors; +extern TbeamSupSensorManager sensors; +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(); bool radio_init(); uint32_t radio_get_rng_seed(); void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);