Merge pull request #3525 from oltaco/airoha-sleep
Use Airoha AG3335 backup mode sleep for faster GPS fix time
This commit is contained in:
6 files changed
+66
-70
No files matched your search
@@ -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;
|
||||||
|
}
|
||||||
@@ -19,6 +19,8 @@ public:
|
|||||||
virtual bool isValid() = 0;
|
virtual bool isValid() = 0;
|
||||||
virtual long getTimestamp() = 0;
|
virtual long getTimestamp() = 0;
|
||||||
virtual void sendSentence(const char * sentence);
|
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 reset() = 0;
|
||||||
virtual void begin() = 0;
|
virtual void begin() = 0;
|
||||||
virtual void stop() = 0;
|
virtual void stop() = 0;
|
||||||
|
|||||||
@@ -173,10 +173,31 @@ public :
|
|||||||
return dt.unixtime();
|
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 {
|
void sendSentence(const char *sentence) override {
|
||||||
nmea.sendSentence(*_gps_serial, sentence);
|
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 {
|
void loop() override {
|
||||||
|
|
||||||
while (_gps_serial->available()) {
|
while (_gps_serial->available()) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include <helpers/sensors/MicroNMEALocationProvider.h>
|
#include <helpers/sensors/MicroNMEALocationProvider.h>
|
||||||
|
#include <helpers/sensors/AirohaSleep.h>
|
||||||
|
|
||||||
MeshTrackerX1Board board;
|
MeshTrackerX1Board board;
|
||||||
|
|
||||||
@@ -27,46 +28,27 @@ mesh::LocalIdentity radio_new_identity() {
|
|||||||
|
|
||||||
void MeshTrackerX1SensorManager::start_gps() {
|
void MeshTrackerX1SensorManager::start_gps() {
|
||||||
gps_active = true;
|
gps_active = true;
|
||||||
// this init sequence comes from seeed examples and deals with all gps pins
|
|
||||||
pinMode(GPS_EN, OUTPUT);
|
|
||||||
digitalWrite(GPS_EN, HIGH);
|
digitalWrite(GPS_EN, HIGH);
|
||||||
delay(10);
|
delay(10);
|
||||||
pinMode(GPS_VRTC_EN, OUTPUT);
|
digitalWrite(GPS_RTC_INT, HIGH);
|
||||||
digitalWrite(GPS_VRTC_EN, HIGH);
|
delay(5);
|
||||||
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, LOW);
|
digitalWrite(GPS_RTC_INT, LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshTrackerX1SensorManager::stop_gps() {
|
void MeshTrackerX1SensorManager::stop_gps() {
|
||||||
gps_active = false;
|
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_EN, LOW);
|
||||||
digitalWrite(GPS_RESET, LOW);
|
|
||||||
digitalWrite(GPS_SLEEP_INT, HIGH);
|
|
||||||
digitalWrite(GPS_RTC_INT, LOW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MeshTrackerX1SensorManager::begin() {
|
bool MeshTrackerX1SensorManager::begin() {
|
||||||
// init GPS
|
// init GPS
|
||||||
Serial1.begin(GPS_BAUD_RATE);
|
Serial1.begin(GPS_BAUD_RATE);
|
||||||
|
digitalWrite(GPS_RESET, HIGH);
|
||||||
|
delay(10);
|
||||||
|
digitalWrite(GPS_RESET, LOW);
|
||||||
|
|
||||||
// init SPA06-003 barometer
|
// init SPA06-003 barometer
|
||||||
baro_ok = spa06.begin(SPA06_003_DEFAULT_ADDR, &Wire) || spa06.begin(0x76, &Wire);
|
baro_ok = spa06.begin(SPA06_003_DEFAULT_ADDR, &Wire) || spa06.begin(0x76, &Wire);
|
||||||
@@ -122,7 +104,7 @@ const char* MeshTrackerX1SensorManager::getSettingValue(int i) const {
|
|||||||
bool MeshTrackerX1SensorManager::setSettingValue(const char* name, const char* value) {
|
bool MeshTrackerX1SensorManager::setSettingValue(const char* name, const char* value) {
|
||||||
if (strcmp(name, "gps") == 0) {
|
if (strcmp(name, "gps") == 0) {
|
||||||
if (strcmp(value, "0") == 0) {
|
if (strcmp(value, "0") == 0) {
|
||||||
sleep_gps(); // sleep for faster fix !
|
stop_gps();
|
||||||
} else {
|
} else {
|
||||||
start_gps();
|
start_gps();
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-38
@@ -2,6 +2,7 @@
|
|||||||
#include "t1000e_sensors.h"
|
#include "t1000e_sensors.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include <helpers/sensors/MicroNMEALocationProvider.h>
|
#include <helpers/sensors/MicroNMEALocationProvider.h>
|
||||||
|
#include <helpers/sensors/AirohaSleep.h>
|
||||||
|
|
||||||
T1000eBoard board;
|
T1000eBoard board;
|
||||||
|
|
||||||
@@ -81,56 +82,28 @@ mesh::LocalIdentity radio_new_identity() {
|
|||||||
|
|
||||||
void T1000SensorManager::start_gps() {
|
void T1000SensorManager::start_gps() {
|
||||||
gps_active = true;
|
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);
|
digitalWrite(GPS_EN, HIGH);
|
||||||
delay(10);
|
delay(10);
|
||||||
pinMode(GPS_VRTC_EN, OUTPUT);
|
digitalWrite(GPS_RTC_INT, HIGH);
|
||||||
digitalWrite(GPS_VRTC_EN, HIGH);
|
delay(5);
|
||||||
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);
|
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() {
|
void T1000SensorManager::stop_gps() {
|
||||||
gps_active = false;
|
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_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() {
|
bool T1000SensorManager::begin() {
|
||||||
// init GPS
|
// init GPS
|
||||||
Serial1.begin(115200);
|
Serial1.begin(115200);
|
||||||
|
digitalWrite(GPS_RESET, HIGH);
|
||||||
|
delay(10);
|
||||||
|
digitalWrite(GPS_RESET, LOW);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +129,6 @@ void T1000SensorManager::loop() {
|
|||||||
node_lat = ((double)_nmea->getLatitude())/1000000.;
|
node_lat = ((double)_nmea->getLatitude())/1000000.;
|
||||||
node_lon = ((double)_nmea->getLongitude())/1000000.;
|
node_lon = ((double)_nmea->getLongitude())/1000000.;
|
||||||
node_altitude = ((double)_nmea->getAltitude()) / 1000.0;
|
node_altitude = ((double)_nmea->getAltitude()) / 1000.0;
|
||||||
//Serial.printf("lat %f lon %f\r\n", _lat, _lon);
|
|
||||||
}
|
}
|
||||||
next_gps_update = millis() + 1000;
|
next_gps_update = millis() + 1000;
|
||||||
}
|
}
|
||||||
@@ -176,7 +148,7 @@ const char* T1000SensorManager::getSettingValue(int i) const {
|
|||||||
bool T1000SensorManager::setSettingValue(const char* name, const char* value) {
|
bool T1000SensorManager::setSettingValue(const char* name, const char* value) {
|
||||||
if (strcmp(name, "gps") == 0) {
|
if (strcmp(name, "gps") == 0) {
|
||||||
if (strcmp(value, "0") == 0) {
|
if (strcmp(value, "0") == 0) {
|
||||||
sleep_gps(); // sleep for faster fix !
|
stop_gps();
|
||||||
} else {
|
} else {
|
||||||
start_gps();
|
start_gps();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ void initVariant()
|
|||||||
pinMode(LUX_SENSOR, INPUT);
|
pinMode(LUX_SENSOR, INPUT);
|
||||||
pinMode(EXT_CHRG_DETECT, INPUT);
|
pinMode(EXT_CHRG_DETECT, INPUT);
|
||||||
pinMode(EXT_PWR_DETECT, INPUT);
|
pinMode(EXT_PWR_DETECT, INPUT);
|
||||||
pinMode(GPS_RESETB, INPUT);
|
pinMode(GPS_RESETB, INPUT_PULLUP);
|
||||||
pinMode(PIN_BUTTON1, INPUT);
|
pinMode(PIN_BUTTON1, INPUT);
|
||||||
|
|
||||||
pinMode(PIN_3V3_EN, OUTPUT);
|
pinMode(PIN_3V3_EN, OUTPUT);
|
||||||
@@ -89,10 +89,10 @@ void initVariant()
|
|||||||
digitalWrite(PIN_3V3_ACC_EN, LOW);
|
digitalWrite(PIN_3V3_ACC_EN, LOW);
|
||||||
digitalWrite(BUZZER_EN, LOW);
|
digitalWrite(BUZZER_EN, LOW);
|
||||||
digitalWrite(SENSOR_EN, LOW);
|
digitalWrite(SENSOR_EN, LOW);
|
||||||
digitalWrite(GPS_EN, LOW);
|
digitalWrite(GPS_EN, HIGH);
|
||||||
digitalWrite(GPS_RESET, LOW);
|
digitalWrite(GPS_RESET, LOW);
|
||||||
digitalWrite(GPS_VRTC_EN, LOW);
|
digitalWrite(GPS_VRTC_EN, HIGH);
|
||||||
digitalWrite(GPS_SLEEP_INT, HIGH);
|
digitalWrite(GPS_SLEEP_INT, LOW);
|
||||||
digitalWrite(GPS_RTC_INT, LOW);
|
digitalWrite(GPS_RTC_INT, LOW);
|
||||||
digitalWrite(LED_PIN, LOW);
|
digitalWrite(LED_PIN, LOW);
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user