Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/helpers/sensors/AirohaSleep.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once
#include <helpers/sensors/LocationProvider.h>

// Board must keep the GPS RTC backup pin powered and can cut GPS power once we return.
// Returns true if the command was acked within 3 attempts, otherwise returns false.
static inline bool airohaEnterSleep(LocationProvider* nmea) {
for (uint8_t attempt = 0; attempt < 3; attempt++) {
nmea->drain();
nmea->sendSentence("$PAIR650,0");
if (nmea->waitFor("$PAIR001,650,0", 50)) { // wait for the command received signal
#ifdef GPS_NMEA_DEBUG
Serial.printf("Airoha RTC Backup sleep command accepted by GPS after %u attempts\r\n", attempt + 1);
#endif
nmea->waitFor("$PAIR650,0", 50); // give the GPS 50ms grace to signal it is ready for sleep
return true;
}
}
return false;
}
2 changes: 2 additions & 0 deletions src/helpers/sensors/LocationProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class LocationProvider {
virtual bool isValid() = 0;
virtual long getTimestamp() = 0;
virtual void sendSentence(const char * sentence);
virtual bool waitFor(const char* prefix, uint32_t timeout_ms) { return false; }
virtual void drain() { }
virtual void reset() = 0;
virtual void begin() = 0;
virtual void stop() = 0;
Expand Down
21 changes: 21 additions & 0 deletions src/helpers/sensors/MicroNMEALocationProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,31 @@ public :
return dt.unixtime();
}

void drain() { while (_gps_serial->available()) _gps_serial->read(); }

const char* getSentence() const { return nmea.getSentence(); }

void sendSentence(const char *sentence) override {
nmea.sendSentence(*_gps_serial, sentence);
}

bool waitFor(const char* prefix, uint32_t timeout_ms) {
size_t plen = strlen(prefix);
uint32_t timeout = millis() + timeout_ms;
while ((int32_t)(millis() - timeout) < 0) {
if (_gps_serial->available()) {
char c = _gps_serial->read();
#ifdef GPS_NMEA_DEBUG
Serial.print(c);
#endif
if (nmea.process(c) && strncmp(nmea.getSentence(), prefix, plen) == 0) return true;
} else {
yield();
}
}
return false;
}

void loop() override {

while (_gps_serial->available()) {
Expand Down
38 changes: 10 additions & 28 deletions variants/meshtracker_x1/target.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <Arduino.h>
#include "target.h"
#include <helpers/sensors/MicroNMEALocationProvider.h>
#include <helpers/sensors/AirohaSleep.h>

MeshTrackerX1Board board;

Expand All @@ -27,46 +28,27 @@ mesh::LocalIdentity radio_new_identity() {

void MeshTrackerX1SensorManager::start_gps() {
gps_active = true;
// this init sequence comes from seeed examples and deals with all gps pins
pinMode(GPS_EN, OUTPUT);
digitalWrite(GPS_EN, HIGH);
delay(10);
pinMode(GPS_VRTC_EN, OUTPUT);
digitalWrite(GPS_VRTC_EN, HIGH);
delay(10);

pinMode(GPS_RESET, OUTPUT);
digitalWrite(GPS_RESET, HIGH);
delay(10);
digitalWrite(GPS_RESET, LOW);

pinMode(GPS_SLEEP_INT, OUTPUT);
digitalWrite(GPS_SLEEP_INT, HIGH);
pinMode(GPS_RTC_INT, OUTPUT);
digitalWrite(GPS_RTC_INT, LOW);
}

void MeshTrackerX1SensorManager::sleep_gps() {
gps_active = false;
digitalWrite(GPS_VRTC_EN, HIGH); // keep RTC alive for faster fix on wake
digitalWrite(GPS_EN, LOW);
digitalWrite(GPS_RESET, LOW);
digitalWrite(GPS_SLEEP_INT, HIGH);
digitalWrite(GPS_RTC_INT, HIGH);
delay(5);
digitalWrite(GPS_RTC_INT, LOW);
}

void MeshTrackerX1SensorManager::stop_gps() {
gps_active = false;
digitalWrite(GPS_VRTC_EN, LOW);
digitalWrite(GPS_VRTC_EN, HIGH); // keep GPS RTC alive for faster fix on wake
digitalWrite(GPS_RTC_INT, LOW); // make sure this is LOW so we can pulse it to wake
airohaEnterSleep(_nmea);
digitalWrite(GPS_EN, LOW);
digitalWrite(GPS_RESET, LOW);
digitalWrite(GPS_SLEEP_INT, HIGH);
digitalWrite(GPS_RTC_INT, LOW);
}

bool MeshTrackerX1SensorManager::begin() {
// init GPS
Serial1.begin(GPS_BAUD_RATE);
digitalWrite(GPS_RESET, HIGH);
delay(10);
digitalWrite(GPS_RESET, LOW);

// init SPA06-003 barometer
baro_ok = spa06.begin(SPA06_003_DEFAULT_ADDR, &Wire) || spa06.begin(0x76, &Wire);
Expand Down Expand Up @@ -122,7 +104,7 @@ const char* MeshTrackerX1SensorManager::getSettingValue(int i) const {
bool MeshTrackerX1SensorManager::setSettingValue(const char* name, const char* value) {
if (strcmp(name, "gps") == 0) {
if (strcmp(value, "0") == 0) {
sleep_gps(); // sleep for faster fix !
stop_gps();
} else {
start_gps();
}
Expand Down
48 changes: 10 additions & 38 deletions variants/t1000-e/target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "t1000e_sensors.h"
#include "target.h"
#include <helpers/sensors/MicroNMEALocationProvider.h>
#include <helpers/sensors/AirohaSleep.h>

T1000eBoard board;

Expand Down Expand Up @@ -81,56 +82,28 @@ mesh::LocalIdentity radio_new_identity() {

void T1000SensorManager::start_gps() {
gps_active = true;
//_nmea->begin();
// this init sequence should be better
// comes from seeed examples and deals with all gps pins
pinMode(GPS_EN, OUTPUT);
digitalWrite(GPS_EN, HIGH);
delay(10);
pinMode(GPS_VRTC_EN, OUTPUT);
digitalWrite(GPS_VRTC_EN, HIGH);
delay(10);

pinMode(GPS_RESET, OUTPUT);
digitalWrite(GPS_RESET, HIGH);
delay(10);
digitalWrite(GPS_RESET, LOW);

pinMode(GPS_SLEEP_INT, OUTPUT);
digitalWrite(GPS_SLEEP_INT, HIGH);
pinMode(GPS_RTC_INT, OUTPUT);
digitalWrite(GPS_RTC_INT, HIGH);
delay(5);
digitalWrite(GPS_RTC_INT, LOW);
pinMode(GPS_RESETB, INPUT_PULLUP);
}

void T1000SensorManager::sleep_gps() {
gps_active = false;
digitalWrite(GPS_VRTC_EN, HIGH);
digitalWrite(GPS_EN, LOW);
digitalWrite(GPS_RESET, HIGH);
digitalWrite(GPS_SLEEP_INT, HIGH);
digitalWrite(GPS_RTC_INT, LOW);
pinMode(GPS_RESETB, OUTPUT);
digitalWrite(GPS_RESETB, LOW);
//_nmea->stop();
}

void T1000SensorManager::stop_gps() {
gps_active = false;
digitalWrite(GPS_VRTC_EN, LOW);
digitalWrite(GPS_VRTC_EN, HIGH); // keep GPS RTC alive for faster fix on wake
digitalWrite(GPS_RTC_INT, LOW); // make sure this is LOW so we can pulse it to wake
airohaEnterSleep(_nmea); // send command to put the GPS into RTC backup sleep
digitalWrite(GPS_EN, LOW);
digitalWrite(GPS_RESET, HIGH);
digitalWrite(GPS_SLEEP_INT, HIGH);
digitalWrite(GPS_RTC_INT, LOW);
pinMode(GPS_RESETB, OUTPUT);
digitalWrite(GPS_RESETB, LOW);
//_nmea->stop();
}


bool T1000SensorManager::begin() {
// init GPS
Serial1.begin(115200);
digitalWrite(GPS_RESET, HIGH);
delay(10);
digitalWrite(GPS_RESET, LOW);
return true;
}

Expand All @@ -156,7 +129,6 @@ void T1000SensorManager::loop() {
node_lat = ((double)_nmea->getLatitude())/1000000.;
node_lon = ((double)_nmea->getLongitude())/1000000.;
node_altitude = ((double)_nmea->getAltitude()) / 1000.0;
//Serial.printf("lat %f lon %f\r\n", _lat, _lon);
}
next_gps_update = millis() + 1000;
}
Expand All @@ -176,7 +148,7 @@ const char* T1000SensorManager::getSettingValue(int i) const {
bool T1000SensorManager::setSettingValue(const char* name, const char* value) {
if (strcmp(name, "gps") == 0) {
if (strcmp(value, "0") == 0) {
sleep_gps(); // sleep for faster fix !
stop_gps();
} else {
start_gps();
}
Expand Down
8 changes: 4 additions & 4 deletions variants/t1000-e/variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ void initVariant()
pinMode(LUX_SENSOR, INPUT);
pinMode(EXT_CHRG_DETECT, INPUT);
pinMode(EXT_PWR_DETECT, INPUT);
pinMode(GPS_RESETB, INPUT);
pinMode(GPS_RESETB, INPUT_PULLUP);
pinMode(PIN_BUTTON1, INPUT);

pinMode(PIN_3V3_EN, OUTPUT);
Expand All @@ -89,10 +89,10 @@ void initVariant()
digitalWrite(PIN_3V3_ACC_EN, LOW);
digitalWrite(BUZZER_EN, LOW);
digitalWrite(SENSOR_EN, LOW);
digitalWrite(GPS_EN, LOW);
digitalWrite(GPS_EN, HIGH);
digitalWrite(GPS_RESET, LOW);
digitalWrite(GPS_VRTC_EN, LOW);
digitalWrite(GPS_SLEEP_INT, HIGH);
digitalWrite(GPS_VRTC_EN, HIGH);
digitalWrite(GPS_SLEEP_INT, LOW);
digitalWrite(GPS_RTC_INT, LOW);
digitalWrite(LED_PIN, LOW);
}
Loading