diff --git a/src/main.cpp b/src/main.cpp index 3971ae9b..b6c03846 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -104,8 +104,6 @@ const char *getDeviceName() return name; } -static MeshRadio *radio = NULL; - static uint32_t ledBlinker() { static bool ledOn; @@ -231,10 +229,10 @@ void setup() #else new SimRadio(); #endif - radio = new MeshRadio(rIf); - router.addInterface(&radio->radioIf); - if (radio && !radio->init()) + router.addInterface(rIf); + + if (!rIf->init()) recordCriticalError(ErrNoRadio); // This must be _after_ service.init because we need our preferences loaded from flash to have proper timeout values diff --git a/src/mesh/MeshRadio.cpp b/src/mesh/MeshRadio.cpp deleted file mode 100644 index 53c052be..00000000 --- a/src/mesh/MeshRadio.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include "error.h" -#include -#include - -#include "MeshRadio.h" -#include "MeshService.h" -#include "NodeDB.h" -#include "configuration.h" -#include "sleep.h" -#include -#include - -/** - * ## LoRaWAN for North America - -LoRaWAN defines 64, 125 kHz channels from 902.3 to 914.9 MHz increments. - -The maximum output power for North America is +30 dBM. - -The band is from 902 to 928 MHz. It mentions channel number and its respective channel frequency. All the 13 channels are -separated by 2.16 MHz with respect to the adjacent channels. Channel zero starts at 903.08 MHz center frequency. -*/ - -/// Sometimes while debugging it is useful to set this false, to disable rf95 accesses -bool useHardware = true; - -MeshRadio::MeshRadio(RadioInterface *rIf) : radioIf(*rIf) // , manager(radioIf) -{ - myNodeInfo.num_channels = NUM_CHANNELS; - - // Can't print strings this early - serial not setup yet - // DEBUG_MSG("Set meshradio defaults name=%s\n", channelSettings.name); -} - -bool MeshRadio::init() -{ - if (!useHardware) - return true; - - DEBUG_MSG("Starting meshradio init...\n"); - - configChangedObserver.observe(&service.configChanged); - preflightSleepObserver.observe(&preflightSleep); - notifyDeepSleepObserver.observe(¬ifyDeepSleep); - -#ifdef RESET_GPIO - pinMode(RESET_GPIO, OUTPUT); // Deassert reset - digitalWrite(RESET_GPIO, HIGH); - - // pulse reset - digitalWrite(RESET_GPIO, LOW); - delay(10); - digitalWrite(RESET_GPIO, HIGH); - delay(10); -#endif - - // we now expect interfaces to operate in promiscous mode - // radioIf.setThisAddress(nodeDB.getNodeNum()); // Note: we must do this here, because the nodenum isn't inited at constructor - // time. - - applySettings(); - - if (!radioIf.init()) { - DEBUG_MSG("LoRa radio init failed\n"); - return false; - } - - // No need to call this now, init is supposed to do same. reloadConfig(); - - return true; -} - -/** hash a string into an integer - * - * djb2 by Dan Bernstein. - * http://www.cse.yorku.ca/~oz/hash.html - */ -unsigned long hash(char *str) -{ - unsigned long hash = 5381; - int c; - - while ((c = *str++) != 0) - hash = ((hash << 5) + hash) + (unsigned char)c; /* hash * 33 + c */ - - return hash; -} - -/** - * Pull our channel settings etc... from protobufs to the dumb interface settings - */ -void MeshRadio::applySettings() -{ - // Set up default configuration - // No Sync Words in LORA mode. - radioIf.modemConfig = (ModemConfigChoice)channelSettings.modem_config; - - // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM - int channel_num = hash(channelSettings.name) % NUM_CHANNELS; - radioIf.freq = CH0 + CH_SPACING * channel_num; - radioIf.power = channelSettings.tx_power; - - DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, txpower=%d\n", channelSettings.name, channelSettings.modem_config, - channel_num, channelSettings.tx_power); -} - -int MeshRadio::reloadConfig(void *unused) -{ - applySettings(); - radioIf.reconfigure(); - - return 0; -} diff --git a/src/mesh/MeshRadio.h b/src/mesh/MeshRadio.h index 85c3e77f..3d41d23c 100644 --- a/src/mesh/MeshRadio.h +++ b/src/mesh/MeshRadio.h @@ -2,9 +2,7 @@ #include "MemoryPool.h" #include "MeshTypes.h" -#include "Observer.h" #include "PointerQueue.h" -#include "RadioInterface.h" #include "configuration.h" #include "mesh.pb.h" @@ -61,48 +59,3 @@ #define NUM_CHANNELS NUM_CHANNELS_US #endif -/** - * A raw low level interface to our mesh. Only understands nodenums and bytes (not protobufs or node ids) - * FIXME - REMOVE THIS CLASS - */ -class MeshRadio -{ - public: - // Kinda ugly way of selecting different radio implementations, but soon this MeshRadio class will be going away - // entirely. At that point we can make things pretty. - RadioInterface &radioIf; - - /** pool is the pool we will alloc our rx packets from - * rxDest is where we will send any rx packets, it becomes receivers responsibility to return packet to the pool - */ - MeshRadio(RadioInterface *rIf); - - bool init(); - - private: - CallbackObserver configChangedObserver = - CallbackObserver(this, &MeshRadio::reloadConfig); - - CallbackObserver preflightSleepObserver = - CallbackObserver(this, &MeshRadio::preflightSleepCb); - - CallbackObserver notifyDeepSleepObserver = - CallbackObserver(this, &MeshRadio::notifyDeepSleepDb); - - /// The radioConfig object just changed, call this to force the hw to change to the new settings - int reloadConfig(void *unused = NULL); - - /// Return 0 if sleep is okay - int preflightSleepCb(void *unused = NULL) { return radioIf.canSleep() ? 0 : 1; } - - int notifyDeepSleepDb(void *unused = NULL) - { - radioIf.sleep(); - return 0; - } - - /** - * Pull our channel settings etc... from protobufs to the dumb interface settings - */ - void applySettings(); -}; diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index d4a40842..18d6ec6f 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -1,28 +1,91 @@ #include "RadioInterface.h" +#include "MeshRadio.h" +#include "MeshService.h" #include "NodeDB.h" #include "assert.h" #include "configuration.h" +#include "sleep.h" #include #include #include +/** + * ## LoRaWAN for North America + +LoRaWAN defines 64, 125 kHz channels from 902.3 to 914.9 MHz increments. + +The maximum output power for North America is +30 dBM. + +The band is from 902 to 928 MHz. It mentions channel number and its respective channel frequency. All the 13 channels are +separated by 2.16 MHz with respect to the adjacent channels. Channel zero starts at 903.08 MHz center frequency. +*/ + // 1kb was too small #define RADIO_STACK_SIZE 4096 RadioInterface::RadioInterface() : txQueue(MAX_TX_QUEUE) { assert(sizeof(PacketHeader) == 4); // make sure the compiler did what we expected + + myNodeInfo.num_channels = NUM_CHANNELS; + + // Can't print strings this early - serial not setup yet + // DEBUG_MSG("Set meshradio defaults name=%s\n", channelSettings.name); } bool RadioInterface::init() { - // we want this thread to run at very high priority, because it is effectively running as a user space ISR + DEBUG_MSG("Starting meshradio init...\n"); + + configChangedObserver.observe(&service.configChanged); + preflightSleepObserver.observe(&preflightSleep); + notifyDeepSleepObserver.observe(¬ifyDeepSleep); + + // we now expect interfaces to operate in promiscous mode + // radioIf.setThisAddress(nodeDB.getNodeNum()); // Note: we must do this here, because the nodenum isn't inited at constructor + // time. + + // we want this thread to run at very high priority, because it is effectively running as a user space ISR start("radio", RADIO_STACK_SIZE, configMAX_PRIORITIES - 1); // Start our worker thread return true; } +/** hash a string into an integer + * + * djb2 by Dan Bernstein. + * http://www.cse.yorku.ca/~oz/hash.html + */ +unsigned long hash(char *str) +{ + unsigned long hash = 5381; + int c; + + while ((c = *str++) != 0) + hash = ((hash << 5) + hash) + (unsigned char)c; /* hash * 33 + c */ + + return hash; +} + +/** + * Pull our channel settings etc... from protobufs to the dumb interface settings + */ +void RadioInterface::applyModemConfig() +{ + // Set up default configuration + // No Sync Words in LORA mode. + modemConfig = (ModemConfigChoice)channelSettings.modem_config; + + // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM + int channel_num = hash(channelSettings.name) % NUM_CHANNELS; + freq = CH0 + CH_SPACING * channel_num; + power = channelSettings.tx_power; + + DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, power=%d\n", channelSettings.name, channelSettings.modem_config, channel_num, + channelSettings.tx_power); +} + ErrorCode SimRadio::send(MeshPacket *p) { DEBUG_MSG("SimRadio.send\n"); diff --git a/src/mesh/RadioInterface.h b/src/mesh/RadioInterface.h index cdfae79d..6c7dbd79 100644 --- a/src/mesh/RadioInterface.h +++ b/src/mesh/RadioInterface.h @@ -2,6 +2,7 @@ #include "MemoryPool.h" #include "MeshTypes.h" +#include "Observer.h" #include "PointerQueue.h" #include "WorkerThread.h" #include "mesh.pb.h" @@ -35,6 +36,15 @@ class RadioInterface : protected NotifiedWorkerThread friend class MeshRadio; // for debugging we let that class touch pool PointerQueue *rxDest = NULL; + CallbackObserver configChangedObserver = + CallbackObserver(this, &RadioInterface::reloadConfig); + + CallbackObserver preflightSleepObserver = + CallbackObserver(this, &RadioInterface::preflightSleepCb); + + CallbackObserver notifyDeepSleepObserver = + CallbackObserver(this, &RadioInterface::notifyDeepSleepDb); + protected: MeshPacket *sendingPacket = NULL; // The packet we are currently sending PointerQueue txQueue; @@ -104,6 +114,29 @@ class RadioInterface : protected NotifiedWorkerThread size_t beginSending(MeshPacket *p); virtual void loop() {} // Idle processing + + /** + * Convert our modemConfig enum into wf, sf, etc... + * + * These paramaters will be pull from the channelSettings global + */ + virtual void applyModemConfig(); + + private: + /// Return 0 if sleep is okay + int preflightSleepCb(void *unused = NULL) { return canSleep() ? 0 : 1; } + + int notifyDeepSleepDb(void *unused = NULL) + { + sleep(); + return 0; + } + + int reloadConfig(void *unused) + { + reconfigure(); + return 0; + } }; class SimRadio : public RadioInterface diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp index ada0a337..64e6cd2a 100644 --- a/src/mesh/RadioLibInterface.cpp +++ b/src/mesh/RadioLibInterface.cpp @@ -58,6 +58,8 @@ RadioLibInterface *RadioLibInterface::instance; */ void RadioLibInterface::applyModemConfig() { + RadioInterface::applyModemConfig(); + switch (modemConfig) { case Bw125Cr45Sf128: ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range bw = 125; diff --git a/src/mesh/RadioLibInterface.h b/src/mesh/RadioLibInterface.h index e1e0f1a9..a090d132 100644 --- a/src/mesh/RadioLibInterface.h +++ b/src/mesh/RadioLibInterface.h @@ -99,8 +99,10 @@ class RadioLibInterface : public RadioInterface protected: /** * Convert our modemConfig enum into wf, sf, etc... + * + * These paramaters will be pull from the channelSettings global */ - void applyModemConfig(); + virtual void applyModemConfig(); /** Could we send right now (i.e. either not actively receiving or transmitting)? */ virtual bool canSendImmediately();