Browse Source

t-beam supreme: added GPS functionality

Enabled GPS and verified with meshcli.
All supreme envs build.
cod3doomy 1 year ago
parent
commit
2ea05a5182

+ 2 - 1
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

+ 3 - 1
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]

+ 136 - 5
variants/lilygo_tbeam_supreme_SX1262/target.cpp

@@ -1,5 +1,6 @@
 #include <Arduino.h>
 #include "target.h"
+#include <helpers/sensors/MicroNMEALocationProvider.h>
 
 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

+ 38 - 1
variants/lilygo_tbeam_supreme_SX1262/target.h

@@ -1,17 +1,54 @@
 #pragma once
 
+#define RADIOLIB_STATIC_ONLY 1
 #include <RadioLib.h>
 #include <helpers/RadioLibWrappers.h>
 #include <helpers/TBeamS3SupremeBoard.h>
 #include <helpers/CustomSX1262Wrapper.h>
 #include <helpers/AutoDiscoverRTCClock.h>
 #include <helpers/SensorManager.h>
+#include <helpers/sensors/LocationProvider.h>
+
+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);