diff --git a/docs/software/nrf52-TODO.md b/docs/software/nrf52-TODO.md index 0b0cfb6d..46d32034 100644 --- a/docs/software/nrf52-TODO.md +++ b/docs/software/nrf52-TODO.md @@ -196,7 +196,7 @@ Nice ideas worth considering someday... - DONE neg 7 error code from receive - DONE remove unused sx1262 lib from github - at boot we are starting our message IDs at 1, rather we should start them at a random number. also, seed random based on timer. this could be the cause of our first message not seen bug. -- add a NEMA based GPS driver to test GPS +- add a NMEA based GPS driver to test GPS - DONE use "variants" to get all gpio bindings - DONE plug in correct variants for the real board - turn on DFU assistance in the appload using the nordic DFU helper lib call diff --git a/src/gps/NEMAGPS.cpp b/src/gps/NMEAGPS.cpp similarity index 78% rename from src/gps/NEMAGPS.cpp rename to src/gps/NMEAGPS.cpp index a1d848ad..6b797fd7 100644 --- a/src/gps/NEMAGPS.cpp +++ b/src/gps/NMEAGPS.cpp @@ -1,4 +1,4 @@ -#include "NEMAGPS.h" +#include "NMEAGPS.h" #include "configuration.h" #include "timing.h" @@ -11,7 +11,7 @@ static int32_t toDegInt(RawDegrees d) return r; } -void NEMAGPS::loop() +void NMEAGPS::loop() { while (_serial_gps->available() > 0) { int c = _serial_gps->read(); @@ -44,6 +44,9 @@ void NEMAGPS::loop() isConnected = true; // we seem to have a real GPS (but not necessarily a lock) } + uint8_t fixtype = reader.fixQuality(); + hasValidLocation = ((fixtype >= 1) && (fixtype <= 5)); + if (reader.location.isUpdated()) { if (reader.altitude.isValid()) altitude = reader.altitude.meters(); @@ -58,18 +61,21 @@ void NEMAGPS::loop() dop = reader.hdop.value(); } if (reader.course.isValid()) { - heading = reader.course.value() * 1e3; //Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5 + heading = + reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5 } if (reader.satellites.isValid()) { numSatellites = reader.satellites.value(); } // expect gps pos lat=37.520825, lon=-122.309162, alt=158 - DEBUG_MSG("new NEMA GPS pos lat=%f, lon=%f, alt=%d, hdop=%f, heading=%f\n", latitude * 1e-7, longitude * 1e-7, altitude, dop * 1e-2, heading * 1e-5); + DEBUG_MSG("new NMEA GPS pos lat=%f, lon=%f, alt=%d, hdop=%f, heading=%f\n", latitude * 1e-7, longitude * 1e-7, + altitude, dop * 1e-2, heading * 1e-5); } // Notify any status instances that are observing us - const meshtastic::GPSStatus status = meshtastic::GPSStatus(hasLock(), isConnected, latitude, longitude, altitude, dop, heading, numSatellites); + const meshtastic::GPSStatus status = + meshtastic::GPSStatus(hasLock(), isConnected, latitude, longitude, altitude, dop, heading, numSatellites); newStatus.notifyObservers(&status); } } \ No newline at end of file diff --git a/src/gps/NEMAGPS.h b/src/gps/NMEAGPS.h similarity index 77% rename from src/gps/NEMAGPS.h rename to src/gps/NMEAGPS.h index 2640bcef..71b24a65 100644 --- a/src/gps/NEMAGPS.h +++ b/src/gps/NMEAGPS.h @@ -1,19 +1,19 @@ #pragma once +#include "../concurrency/PeriodicTask.h" #include "GPS.h" #include "Observer.h" -#include "../concurrency/PeriodicTask.h" #include "TinyGPS++.h" /** - * A gps class thatreads from a NEMA GPS stream (and FIXME - eventually keeps the gps powered down except when reading) + * A gps class thatreads from a NMEA GPS stream (and FIXME - eventually keeps the gps powered down except when reading) * * When new data is available it will notify observers. */ -class NEMAGPS : public GPS +class NMEAGPS : public GPS { TinyGPSPlus reader; - + uint32_t lastUpdateMsec = 0; public: diff --git a/src/gps/UBloxGPS.cpp b/src/gps/UBloxGPS.cpp index 624ab77b..93e8a01c 100644 --- a/src/gps/UBloxGPS.cpp +++ b/src/gps/UBloxGPS.cpp @@ -103,7 +103,7 @@ bool UBloxGPS::factoryReset() { bool ok = false; - // It is useful to force back into factory defaults (9600baud, NEMA to test the behavior of boards that don't have + // It is useful to force back into factory defaults (9600baud, NMEA to test the behavior of boards that don't have // GPS_TX connected) ublox.factoryReset(); delay(5000); diff --git a/src/main.cpp b/src/main.cpp index cc0c9a0c..b0d133f2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,7 +23,7 @@ #include "MeshRadio.h" #include "MeshService.h" -#include "NEMAGPS.h" +#include "NMEAGPS.h" #include "NodeDB.h" #include "PowerFSM.h" #include "UBloxGPS.h" @@ -258,16 +258,16 @@ void setup() 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 NEMA at 9600 baud. - DEBUG_MSG("Hoping that NEMA might work\n"); + // assume NMEA at 9600 baud. + DEBUG_MSG("Hoping that NMEA might work\n"); - // dumb NEMA access only work for serial GPSes) - gps = new NEMAGPS(); + // dumb NMEA access only work for serial GPSes) + gps = new NMEAGPS(); gps->setup(); } } #else - gps = new NEMAGPS(); + gps = new NMEAGPS(); gps->setup(); #endif gpsStatus->observe(&gps->newStatus); @@ -412,7 +412,7 @@ void loop() // Update the screen last, after we've figured out what to show. screen.debug_info()->setChannelNameStatus(getChannelName()); - + // No GPS lock yet, let the OS put the main CPU in low power mode for 100ms (or until another interrupt comes in) // i.e. don't just keep spinning in loop as fast as we can. // DEBUG_MSG("msecs %d\n", msecstosleep); diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp index f5d0ac17..c614c086 100644 --- a/src/mesh/MeshService.cpp +++ b/src/mesh/MeshService.cpp @@ -206,6 +206,13 @@ void MeshService::reloadConfig() nodeDB.saveToDisk(); } +/// The owner User record just got updated, update our node DB and broadcast the info into the mesh +void MeshService::reloadOwner() +{ + sendOurOwner(); + nodeDB.saveToDisk(); +} + /** * Given a ToRadio buffer parse it and properly handle it (setup radio, owner or send packet into the mesh) * Called by PhoneAPI.handleToRadio. Note: p is a scratch buffer, this function is allowed to write to it but it can not keep a @@ -292,8 +299,8 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *unused) p->decoded.which_payload = SubPacket_position_tag; Position &pos = p->decoded.position; - // !zero or !zero lat/long means valid - if (gps->latitude != 0 || gps->longitude != 0) { + + if (gps->hasLock()) { if (gps->altitude != 0) pos.altitude = gps->altitude; pos.latitude_i = gps->latitude; diff --git a/src/mesh/MeshService.h b/src/mesh/MeshService.h index 7e881077..a12f087b 100644 --- a/src/mesh/MeshService.h +++ b/src/mesh/MeshService.h @@ -67,7 +67,7 @@ class MeshService void reloadConfig(); /// The owner User record just got updated, update our node DB and broadcast the info into the mesh - void reloadOwner() { sendOurOwner(); } + void reloadOwner(); /// Called when the user wakes up our GUI, normally sends our latest location to the mesh (if we have it), otherwise at least /// sends our owner diff --git a/src/mesh/RF95Interface.cpp b/src/mesh/RF95Interface.cpp index 3d03e403..594cec91 100644 --- a/src/mesh/RF95Interface.cpp +++ b/src/mesh/RF95Interface.cpp @@ -41,6 +41,8 @@ bool RF95Interface::init() if (power > MAX_POWER) // This chip has lower power limits than some power = MAX_POWER; + limitPower(); + iface = lora = new RadioLibRF95(&module); #ifdef RF95_TCXO diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 0cdd4da6..ae4ef421 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -107,7 +107,7 @@ bool RadioInterface::init() * djb2 by Dan Bernstein. * http://www.cse.yorku.ca/~oz/hash.html */ -unsigned long hash(char *str) +unsigned long hash(const char *str) { unsigned long hash = 5381; int c; @@ -136,6 +136,25 @@ void RadioInterface::applyModemConfig() power); } +/** + * Some regulatory regions limit xmit power. + * This function should be called by subclasses after setting their desired power. It might lower it + */ +void RadioInterface::limitPower() +{ + uint8_t maxPower = 255; // No limit + +#ifdef HW_VERSION_JP + maxPower = 13; // See https://github.com/meshtastic/Meshtastic-device/issues/346 +#endif + if (power > maxPower) { + DEBUG_MSG("Lowering transmit power because of regulatory limits\n"); + power = maxPower; + } + + DEBUG_MSG("Set radio: final power level=%d\n", power); +} + ErrorCode SimRadio::send(MeshPacket *p) { DEBUG_MSG("SimRadio.send\n"); diff --git a/src/mesh/RadioInterface.h b/src/mesh/RadioInterface.h index b8cba208..645ee5c0 100644 --- a/src/mesh/RadioInterface.h +++ b/src/mesh/RadioInterface.h @@ -119,6 +119,12 @@ class RadioInterface : protected concurrency::NotifiedWorkerThread virtual void loop() {} // Idle processing + /** + * Some regulatory regions limit xmit power. + * This function should be called by subclasses after setting their desired power. It might lower it + */ + void limitPower(); + /** * Convert our modemConfig enum into wf, sf, etc... * diff --git a/src/mesh/SX1262Interface.cpp b/src/mesh/SX1262Interface.cpp index 75a84034..130f340c 100644 --- a/src/mesh/SX1262Interface.cpp +++ b/src/mesh/SX1262Interface.cpp @@ -43,6 +43,9 @@ bool SX1262Interface::init() if (power > 22) // This chip has lower power limits than some power = 22; + + limitPower(); + int res = lora.begin(freq, bw, sf, cr, syncWord, power, currentLimit, preambleLength, tcxoVoltage, useRegulatorLDO); DEBUG_MSG("SX1262 init result %d\n", res);