Start of repeater role with in firmware

This commit is contained in:
Ben Meadors
2023-01-28 06:38:13 -06:00
parent cda7e8b6a5
commit de82119415
7 changed files with 564 additions and 343 deletions

View File

@@ -29,29 +29,38 @@ bool GPS::getACK(uint8_t c, uint8_t i)
uint8_t buf[10] = {0xB5, 0x62, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned long startTime = millis();
for (int j = 2; j < 6; j++) {
for (int j = 2; j < 6; j++)
{
buf[8] += buf[j];
buf[9] += buf[8];
}
for (int j = 0; j < 2; j++) {
for (int j = 0; j < 2; j++)
{
buf[6 + j] = ackP[j];
buf[8] += buf[6 + j];
buf[9] += buf[8];
}
while (1) {
if (ack > 9) {
while (1)
{
if (ack > 9)
{
return true;
}
if (millis() - startTime > 1000) {
if (millis() - startTime > 1000)
{
return false;
}
if (_serial_gps->available()) {
if (_serial_gps->available())
{
b = _serial_gps->read();
if (b == buf[ack]) {
if (b == buf[ack])
{
ack++;
} else {
}
else
{
ack = 0;
}
}
@@ -73,37 +82,50 @@ int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
uint32_t startTime = millis();
uint16_t needRead;
while (millis() - startTime < 800) {
while (_serial_gps->available()) {
while (millis() - startTime < 800)
{
while (_serial_gps->available())
{
int c = _serial_gps->read();
switch (ubxFrameCounter) {
switch (ubxFrameCounter)
{
case 0:
// ubxFrame 'μ'
if (c == 0xB5) {
if (c == 0xB5)
{
ubxFrameCounter++;
}
break;
case 1:
// ubxFrame 'b'
if (c == 0x62) {
if (c == 0x62)
{
ubxFrameCounter++;
} else {
}
else
{
ubxFrameCounter = 0;
}
break;
case 2:
// Class
if (c == requestedClass) {
if (c == requestedClass)
{
ubxFrameCounter++;
} else {
}
else
{
ubxFrameCounter = 0;
}
break;
case 3:
// Message ID
if (c == requestedID) {
if (c == requestedID)
{
ubxFrameCounter++;
} else {
}
else
{
ubxFrameCounter = 0;
}
break;
@@ -119,13 +141,17 @@ int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
break;
case 6:
// Check for buffer overflow
if (needRead >= size) {
if (needRead >= size)
{
ubxFrameCounter = 0;
break;
}
if (_serial_gps->readBytes(buffer, needRead) != needRead) {
if (_serial_gps->readBytes(buffer, needRead) != needRead)
{
ubxFrameCounter = 0;
} else {
}
else
{
// return payload lenght
return needRead;
}
@@ -141,7 +167,8 @@ int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
bool GPS::setupGPS()
{
if (_serial_gps && !didSerialInit) {
if (_serial_gps && !didSerialInit)
{
didSerialInit = true;
#ifdef ARCH_ESP32
@@ -173,7 +200,8 @@ bool GPS::setupGPS()
*/
gnssModel = probe();
if (gnssModel == GNSS_MODEL_MTK) {
if (gnssModel == GNSS_MODEL_MTK)
{
/*
* t-beam-s3-core uses the same L76K GNSS module as t-echo.
* Unlike t-echo, L76K uses 9600 baud rate for communication by default.
@@ -190,8 +218,9 @@ bool GPS::setupGPS()
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
_serial_gps->write("$PCAS11,3*1E\r\n");
delay(250);
} else if (gnssModel == GNSS_MODEL_UBLOX) {
}
else if (gnssModel == GNSS_MODEL_UBLOX)
{
/*
tips: NMEA Only should not be set here, otherwise initializing Ublox gnss module again after
@@ -213,7 +242,8 @@ bool GPS::setupGPS()
byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01,
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x05, 0x3A};
_serial_gps->write(_message_GGL, sizeof(_message_GGL));
if (!getACK(0x06, 0x01)) {
if (!getACK(0x06, 0x01))
{
LOG_WARN("Unable to disable NMEA GGL.\n");
return true;
}
@@ -222,7 +252,8 @@ bool GPS::setupGPS()
byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02,
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x41};
_serial_gps->write(_message_GSA, sizeof(_message_GSA));
if (!getACK(0x06, 0x01)) {
if (!getACK(0x06, 0x01))
{
LOG_WARN("Unable to disable NMEA GSA.\n");
return true;
}
@@ -231,7 +262,8 @@ bool GPS::setupGPS()
byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03,
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x48};
_serial_gps->write(_message_GSV, sizeof(_message_GSV));
if (!getACK(0x06, 0x01)) {
if (!getACK(0x06, 0x01))
{
LOG_WARN("Unable to disable NMEA GSV.\n");
return true;
}
@@ -240,7 +272,8 @@ bool GPS::setupGPS()
byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05,
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x09, 0x56};
_serial_gps->write(_message_VTG, sizeof(_message_VTG));
if (!getACK(0x06, 0x01)) {
if (!getACK(0x06, 0x01))
{
LOG_WARN("Unable to disable NMEA VTG.\n");
return true;
}
@@ -249,7 +282,8 @@ bool GPS::setupGPS()
byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x54};
_serial_gps->write(_message_RMC, sizeof(_message_RMC));
if (!getACK(0x06, 0x01)) {
if (!getACK(0x06, 0x01))
{
LOG_WARN("Unable to enable NMEA RMC.\n");
return true;
}
@@ -258,7 +292,8 @@ bool GPS::setupGPS()
byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x38};
_serial_gps->write(_message_GGA, sizeof(_message_GGA));
if (!getACK(0x06, 0x01)) {
if (!getACK(0x06, 0x01))
{
LOG_WARN("Unable to enable NMEA GGA.\n");
}
}
@@ -276,7 +311,8 @@ bool GPS::setup()
#endif
#ifdef HAS_PMU
if (config.position.gps_enabled) {
if (config.position.gps_enabled)
{
setGPSPower(true);
}
#endif
@@ -290,13 +326,15 @@ bool GPS::setup()
setAwake(true); // Wake GPS power before doing any init
bool ok = setupGPS();
if (ok) {
if (ok)
{
notifySleepObserver.observe(&notifySleep);
notifyDeepSleepObserver.observe(&notifyDeepSleep);
notifyGPSSleepObserver.observe(&notifyGPSSleep);
}
if (config.position.gps_enabled == false && config.position.fixed_position == false) {
if (config.position.gps_enabled == false && config.position.fixed_position == false)
{
setAwake(false);
doGPSpowersave(false);
}
@@ -345,7 +383,8 @@ void GPS::sleep()
/// Record that we have a GPS
void GPS::setConnected()
{
if (!hasGPS) {
if (!hasGPS)
{
hasGPS = true;
shouldPublish = true;
}
@@ -353,7 +392,8 @@ void GPS::setConnected()
void GPS::setNumSatellites(uint8_t n)
{
if (n != numSatellites) {
if (n != numSatellites)
{
numSatellites = n;
shouldPublish = true;
}
@@ -366,17 +406,22 @@ void GPS::setNumSatellites(uint8_t n)
*/
void GPS::setAwake(bool on)
{
if (!wakeAllowed && on) {
if (!wakeAllowed && on)
{
LOG_WARN("Inhibiting because !wakeAllowed\n");
on = false;
}
if (isAwake != on) {
if (isAwake != on)
{
LOG_DEBUG("WANT GPS=%d\n", on);
if (on) {
if (on)
{
lastWakeStartMsec = millis();
wake();
} else {
}
else
{
lastSleepStartMsec = millis();
sleep();
}
@@ -415,7 +460,8 @@ uint32_t GPS::getSleepTime() const
void GPS::publishUpdate()
{
if (shouldPublish) {
if (shouldPublish)
{
shouldPublish = false;
// In debug logs, identify position by @timestamp:stage (stage 2 = publish)
@@ -429,13 +475,22 @@ void GPS::publishUpdate()
int32_t GPS::runOnce()
{
if (whileIdle()) {
// Repeaters have no need for GPS
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER)
disable();
if (whileIdle())
{
// if we have received valid NMEA claim we are connected
setConnected();
} else {
if ((config.position.gps_enabled == 1) && (gnssModel == GNSS_MODEL_UBLOX)) {
}
else
{
if ((config.position.gps_enabled == 1) && (gnssModel == GNSS_MODEL_UBLOX))
{
// reset the GPS on next bootup
if (devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) {
if (devicestate.did_gps_reset && (millis() > 60000) && !hasFlow())
{
LOG_DEBUG("GPS is not communicating, trying factory reset on next bootup.\n");
devicestate.did_gps_reset = false;
nodeDB.saveDeviceStateToDisk();
@@ -448,28 +503,33 @@ int32_t GPS::runOnce()
uint32_t now = millis();
auto sleepTime = getSleepTime();
if (!isAwake && sleepTime != UINT32_MAX && (now - lastSleepStartMsec) > sleepTime) {
if (!isAwake && sleepTime != UINT32_MAX && (now - lastSleepStartMsec) > sleepTime)
{
// We now want to be awake - so wake up the GPS
setAwake(true);
}
// While we are awake
if (isAwake) {
if (isAwake)
{
// LOG_DEBUG("looking for location\n");
if ((now - lastWhileActiveMsec) > 5000) {
if ((now - lastWhileActiveMsec) > 5000)
{
lastWhileActiveMsec = now;
whileActive();
}
// If we've already set time from the GPS, no need to ask the GPS
bool gotTime = (getRTCQuality() >= RTCQualityGPS);
if (!gotTime && lookForTime()) { // Note: we count on this && short-circuiting and not resetting the RTC time
if (!gotTime && lookForTime())
{ // Note: we count on this && short-circuiting and not resetting the RTC time
gotTime = true;
shouldPublish = true;
}
bool gotLoc = lookForLocation();
if (gotLoc && !hasValidLocation) { // declare that we have location ASAP
if (gotLoc && !hasValidLocation)
{ // declare that we have location ASAP
LOG_DEBUG("hasValidLocation RISING EDGE\n");
hasValidLocation = true;
shouldPublish = true;
@@ -482,11 +542,14 @@ int32_t GPS::runOnce()
// Once we get a location we no longer desperately want an update
// LOG_DEBUG("gotLoc %d, tooLong %d, gotTime %d\n", gotLoc, tooLong, gotTime);
if ((gotLoc && gotTime) || tooLong) {
if ((gotLoc && gotTime) || tooLong)
{
if (tooLong) {
if (tooLong)
{
// we didn't get a location during this ack window, therefore declare loss of lock
if (hasValidLocation) {
if (hasValidLocation)
{
LOG_DEBUG("hasValidLocation FALLING EDGE (last read: %d)\n", gotLoc);
}
p = meshtastic_Position_init_default;
@@ -501,10 +564,12 @@ int32_t GPS::runOnce()
// If state has changed do a publish
publishUpdate();
if (!(fixeddelayCtr >= 20) && config.position.fixed_position && hasValidLocation) {
if (!(fixeddelayCtr >= 20) && config.position.fixed_position && hasValidLocation)
{
fixeddelayCtr++;
// LOG_DEBUG("Our delay counter is %d\n", fixeddelayCtr);
if (fixeddelayCtr >= 20) {
if (fixeddelayCtr >= 20)
{
doGPSpowersave(false);
forceWake(false);
}
@@ -516,11 +581,14 @@ int32_t GPS::runOnce()
void GPS::forceWake(bool on)
{
if (on) {
if (on)
{
LOG_DEBUG("Allowing GPS lock\n");
// lastSleepStartMsec = 0; // Force an update ASAP
wakeAllowed = true;
} else {
}
else
{
wakeAllowed = false;
// Note: if the gps was already awake, we DO NOT shut it down, because we want to allow it to complete its lock
@@ -575,15 +643,19 @@ GnssModel_t GPS::probe()
// Get version information
_serial_gps->write("$PCAS06,0*1B\r\n");
uint32_t startTimeout = millis() + 500;
while (millis() < startTimeout) {
if (_serial_gps->available()) {
while (millis() < startTimeout)
{
if (_serial_gps->available())
{
String ver = _serial_gps->readStringUntil('\r');
// Get module info , If the correct header is returned,
// it can be determined that it is the MTK chip
int index = ver.indexOf("$");
if (index != -1) {
if (index != -1)
{
ver = ver.substring(index);
if (ver.startsWith("$GPTXT,01,01,02")) {
if (ver.startsWith("$GPTXT,01,01,02"))
{
LOG_INFO("L76K GNSS init succeeded, using L76K GNSS Module\n");
return GNSS_MODEL_MTK;
}
@@ -594,7 +666,8 @@ GnssModel_t GPS::probe()
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x0E, 0x30};
_serial_gps->write(cfg_rate, sizeof(cfg_rate));
// Check that the returned response class and message ID are correct
if (!getAck(buffer, 256, 0x06, 0x08)) {
if (!getAck(buffer, 256, 0x06, 0x08))
{
LOG_WARN("Failed to find UBlox & MTK GNSS Module\n");
return GNSS_MODEL_UNKONW;
}
@@ -604,20 +677,25 @@ GnssModel_t GPS::probe()
_serial_gps->write(cfg_get_hw, sizeof(cfg_get_hw));
uint16_t len = getAck(buffer, 256, 0x0A, 0x04);
if (len) {
if (len)
{
uint16_t position = 0;
for (int i = 0; i < 30; i++) {
for (int i = 0; i < 30; i++)
{
info.swVersion[i] = buffer[position];
position++;
}
for (int i = 0; i < 10; i++) {
for (int i = 0; i < 10; i++)
{
info.hwVersion[i] = buffer[position];
position++;
}
while (len >= position + 30) {
for (int i = 0; i < 30; i++) {
while (len >= position + 30)
{
for (int i = 0; i < 30; i++)
{
info.extension[info.extensionNo][i] = buffer[position];
position++;
}
@@ -630,24 +708,30 @@ GnssModel_t GPS::probe()
LOG_DEBUG("Soft version: %s\n", info.swVersion);
LOG_DEBUG("Hard version: %s\n", info.hwVersion);
LOG_DEBUG("Extensions:%d\n", info.extensionNo);
for (int i = 0; i < info.extensionNo; i++) {
for (int i = 0; i < info.extensionNo; i++)
{
LOG_DEBUG(" %s\n", info.extension[i]);
}
memset(buffer, 0, sizeof(buffer));
// tips: extensionNo field is 0 on some 6M GNSS modules
for (int i = 0; i < info.extensionNo; ++i) {
if (!strncmp(info.extension[i], "OD=", 3)) {
for (int i = 0; i < info.extensionNo; ++i)
{
if (!strncmp(info.extension[i], "OD=", 3))
{
strncpy((char *)buffer, &(info.extension[i][3]), sizeof(buffer));
LOG_DEBUG("GetModel:%s\n", (char *)buffer);
}
}
}
if (strlen((char *)buffer)) {
if (strlen((char *)buffer))
{
LOG_INFO("UBlox GNSS init succeeded, using UBlox %s GNSS Module\n", buffer);
} else {
}
else
{
LOG_INFO("UBlox GNSS init succeeded, using UBlox GNSS Module\n");
}
@@ -665,20 +749,24 @@ GPS *createGps()
#if !HAS_GPS
return nullptr;
#else
if (config.position.gps_enabled) {
if (config.position.gps_enabled)
{
#ifdef GPS_ALTITUDE_HAE
LOG_DEBUG("Using HAE altitude model\n");
#else
LOG_DEBUG("Using MSL altitude model\n");
#endif
if (GPS::_serial_gps) {
if (GPS::_serial_gps)
{
// Some boards might have only the TX line from the GPS connected, in that case, we can't configure it at all. Just
// assume NMEA at 9600 baud.
GPS *new_gps = new NMEAGPS();
new_gps->setup();
return new_gps;
}
} else {
}
else
{
GPS *new_gps = new NMEAGPS();
new_gps->setup();
return new_gps;