From a2ba9d3c44d2d95a60fc93605e55f896d3e9ae5d Mon Sep 17 00:00:00 2001 From: geeksville Date: Thu, 30 Apr 2020 13:50:40 -0700 Subject: [PATCH] new receive code works a little better --- docs/software/nrf52-TODO.md | 6 +++++- src/GPS.cpp | 4 ++-- src/rf95/RadioLibInterface.cpp | 19 +++++++++++++------ src/rf95/RadioLibInterface.h | 7 +++++++ src/rf95/SX1262Interface.cpp | 31 +++++++++++++++++++------------ src/rf95/SX1262Interface.h | 3 +++ 6 files changed, 49 insertions(+), 21 deletions(-) diff --git a/docs/software/nrf52-TODO.md b/docs/software/nrf52-TODO.md index e315f923..6a52c471 100644 --- a/docs/software/nrf52-TODO.md +++ b/docs/software/nrf52-TODO.md @@ -9,7 +9,10 @@ Minimum items needed to make sure hardware is good. - DONE basic test of BLE - DONE get a debug 'serial' console working via the ICE passthrough feature - add a hard fault handler -- switch to RadioLab? test it with current radio. https://github.com/jgromes/RadioLib +- DONE switch to RadioLab? test it with current radio. https://github.com/jgromes/RadioLib +- change rx95 to radiolib +- track rxbad, rxgood, txgood +- neg 7 error code from receive - 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 - use SX126x::startReceiveDutyCycleAuto to save power by sleeping and briefly waking to check for preamble bits. Change xmit rules to have more preamble bits. - use "variants" to get all gpio bindings @@ -51,6 +54,7 @@ Needed to be fully functional at least at the same level of the ESP32 boards. At ## Items to be 'feature complete' +- remove the MeshRadio wrapper - we don't need it anymore, just do everythin in RadioInterface subclasses. - figure out what the correct current limit should be for the sx1262, currently we just use the default 100 - put sx1262 in sleepmode when processor gets shutdown (or rebooted), ideally even for critical faults (to keep power draw low). repurpose deepsleep state for this. - good power management tips: https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/optimizing-power-on-nrf52-designs diff --git a/src/GPS.cpp b/src/GPS.cpp index 6386ec81..6a2dad50 100644 --- a/src/GPS.cpp +++ b/src/GPS.cpp @@ -28,7 +28,7 @@ GPS::GPS() : PeriodicTask() {} void GPS::setup() { PeriodicTask::setup(); - + readFromRTC(); // read the main CPU RTC at first #ifdef GPS_RX_PIN @@ -110,7 +110,7 @@ void GPS::perhapsSetRTC(const struct timeval *tv) #ifndef NO_ESP32 settimeofday(tv, NULL); #else - assert(0); + DEBUG_MSG("ERROR TIME SETTING NOT IMPLEMENTED!\n"); #endif readFromRTC(); } diff --git a/src/rf95/RadioLibInterface.cpp b/src/rf95/RadioLibInterface.cpp index 156791ea..f1413fa8 100644 --- a/src/rf95/RadioLibInterface.cpp +++ b/src/rf95/RadioLibInterface.cpp @@ -124,16 +124,24 @@ void RadioLibInterface::handleTransmitInterrupt() { assert(sendingPacket); // Were we sending? - // FIXME - check result code from ISR + completeSending(); +} - // We are done sending that packet, release it - packetPool.release(sendingPacket); - sendingPacket = NULL; - // DEBUG_MSG("Done with send\n"); +void RadioLibInterface::completeSending() +{ + if (sendingPacket) { + // We are done sending that packet, release it + packetPool.release(sendingPacket); + sendingPacket = NULL; + // DEBUG_MSG("Done with send\n"); + } } void RadioLibInterface::handleReceiveInterrupt() { + assert(isReceiving); + isReceiving = false; + // read the number of actually received bytes size_t length = iface.getPacketLength(); @@ -179,4 +187,3 @@ void RadioLibInterface::startSend(MeshPacket *txp) // Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register bits enableInterrupt(isrTxLevel0); } - diff --git a/src/rf95/RadioLibInterface.h b/src/rf95/RadioLibInterface.h index 3d0f8e04..eb512339 100644 --- a/src/rf95/RadioLibInterface.h +++ b/src/rf95/RadioLibInterface.h @@ -49,6 +49,9 @@ class RadioLibInterface : public RadioInterface */ PhysicalLayer &iface; + /// are _trying_ to receive a packet currently (note - we might just be waiting for one) + bool isReceiving; + /** * Glue functions called from ISR land */ @@ -108,4 +111,8 @@ class RadioLibInterface : public RadioInterface * Raw ISR handler that just calls our polymorphic method */ static void isrRxLevel0(); + + /** + * If a send was in progress finish it and return the buffer to the pool */ + void completeSending(); }; \ No newline at end of file diff --git a/src/rf95/SX1262Interface.cpp b/src/rf95/SX1262Interface.cpp index d72c828a..9b59804a 100644 --- a/src/rf95/SX1262Interface.cpp +++ b/src/rf95/SX1262Interface.cpp @@ -30,7 +30,7 @@ bool SX1262Interface::init() if (res == ERR_NONE) startReceive(); // start receiving - return res; + return res == ERR_NONE; } bool SX1262Interface::reconfigure() @@ -38,11 +38,10 @@ bool SX1262Interface::reconfigure() applyModemConfig(); // set mode to standby - int err = lora.standby(); - assert(err == ERR_NONE); + setStandby(); // configure publicly accessible settings - err = lora.setSpreadingFactor(sf); + int err = lora.setSpreadingFactor(sf); assert(err == ERR_NONE); err = lora.setBandwidth(bw); @@ -73,11 +72,24 @@ bool SX1262Interface::reconfigure() return ERR_NONE; } +void SX1262Interface::setStandby() +{ + int err = lora.standby(); + assert(err == ERR_NONE); + + isReceiving = false; // If we were receiving, not any more + completeSending(); // If we were sending, not anymore + disableInterrupt(); +} + void SX1262Interface::startReceive() { + setStandby(); int err = lora.startReceive(); assert(err == ERR_NONE); + isReceiving = true; + // Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register bits enableInterrupt(isrRxLevel0); } @@ -85,15 +97,10 @@ void SX1262Interface::startReceive() /** Could we send right now (i.e. either not actively receving or transmitting)? */ bool SX1262Interface::canSendImmediately() { - return true; // FIXME -#if 0 // We wait _if_ we are partially though receiving a packet (rather than just merely waiting for one). // To do otherwise would be doubly bad because not only would we drop the packet that was on the way in, // we almost certainly guarantee no one outside will like the packet we are sending. - if (_mode == RHModeIdle || isReceiving()) { - // if the radio is idle, we can send right away - DEBUG_MSG("immediate send on mesh fr=0x%x,to=0x%x,id=%d\n (txGood=%d,rxGood=%d,rxBad=%d)\n", p->from, p->to, p->id, - txGood(), rxGood(), rxBad()); - } -#endif + bool busy = sendingPacket != NULL || (isReceiving && lora.getPacketLength() > 0); + + return !busy; } \ No newline at end of file diff --git a/src/rf95/SX1262Interface.h b/src/rf95/SX1262Interface.h index edb7cad7..bacfb69e 100644 --- a/src/rf95/SX1262Interface.h +++ b/src/rf95/SX1262Interface.h @@ -37,4 +37,7 @@ class SX1262Interface : public RadioLibInterface * Start waiting to receive a message */ virtual void startReceive(); + + private: + void setStandby(); }; \ No newline at end of file