From 3cc299d17be4ea6a3ea2a6e33f57ccf72839bc33 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Thu, 13 Jan 2022 12:25:02 -0700 Subject: [PATCH 1/4] Add FHSS support --- .../SX127x_Receive_FHSS.ino | 122 +++++++++++++++++ .../SX127x_Transmit_FHSS.ino | 124 ++++++++++++++++++ keywords.txt | 4 + src/modules/SX127x/SX1276.cpp | 22 ++++ src/modules/SX127x/SX1276.h | 28 ++++ src/modules/SX127x/SX127x.cpp | 17 ++- 6 files changed, 313 insertions(+), 4 deletions(-) create mode 100644 examples/SX127x/SX127x_Receive_FHSS/SX127x_Receive_FHSS.ino create mode 100644 examples/SX127x/SX127x_Transmit_FHSS/SX127x_Transmit_FHSS.ino diff --git a/examples/SX127x/SX127x_Receive_FHSS/SX127x_Receive_FHSS.ino b/examples/SX127x/SX127x_Receive_FHSS/SX127x_Receive_FHSS.ino new file mode 100644 index 00000000..d45bec3b --- /dev/null +++ b/examples/SX127x/SX127x_Receive_FHSS/SX127x_Receive_FHSS.ino @@ -0,0 +1,122 @@ +/* + RadioLib SX127x Transmit with Frequency Hopping Example + + This example transmits packets using SX1278 LoRa radio module. + Each packet contains up to 256 bytes of data, in the form of: + - Arduino String + - null-terminated char array (C-string) + - arbitrary binary data (byte array) + + Other modules from SX127x/RFM9x family can also be used. + + For default module settings, see the wiki page + https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem + + For full API reference, see the GitHub Pages + https://jgromes.github.io/RadioLib/ + + The SX1276 / 7 / 8 / 9 supports FHSS or Frequency Hopping Spread Spectrum. + Once a hopping period is set and a transmission is started the radio + will begin triggering interrupts every hop period where the radio frequency + is changed to the next channel. This allows a simple mechanism to abide by + the FCC 400ms max dwell time rule. + https://www.govinfo.gov/content/pkg/CFR-2019-title47-vol1/pdf/CFR-2019-title47-vol1-sec15-247.pdf +*/ + +#include //Click here to get the library: http://librarymanager/All#RadioLib + +//Pins for RFM97 100mW Shield to SparkFun ESP32 Thing Plus C +int pin_cs = 15; +int pin_dio0 = 26; +int pin_dio1 = 25; +int pin_rst = 32; +SX1276 radio = new Module(pin_cs, pin_dio0, pin_rst, pin_dio1); + +int counter = 0; + +volatile bool rxComplete = false; +volatile bool fhssChange = false; + +//The channel frequencies can be generated randomly or hard coded +float channels[] = {908.0, 906.0, 907.0, 905.0, 903.0, 910.0, 909.0}; +int numberOfChannels = sizeof(channels) / sizeof(float); + +int hopsCompleted = 0; + +void setup() +{ + Serial.begin(115200); + + //Begin radio on home channel + Serial.print(F("[SX127x] Initializing ... ")); + int state = radio.begin(channels[0]); + if (state != RADIOLIB_ERR_NONE) + { + Serial.print(F("Failed with code: ")); + Serial.println(state); + } + else + Serial.println(F("Success!")); + + // Set hop period to enable FHSS + // We set an artifically short period to show lots of hops + // HoppingPeriod = Tsym * FreqHoppingPeriod + // Given defaults of spreadfactor = 9, bandwidth = 125, it follows Tsym = 4.10ms + // HoppingPeriod = 4.10 * 9 = 36.9ms. Can be as high as 400ms to be within regulatory limits + radio.setFHSSHoppingPeriod(9); + + Serial.print(F("Hopping period: ")); + Serial.println(radio.getFHSSHoppingPeriod()); + + radio.setDio0Action(dio0ISR); //Called when transmission is finished + radio.setDio1Action(dio1ISR); //Called after a transmission has started, so we can move to next freq + + radio.startReceive(); + + Serial.println(F("Waiting for new packet")); +} + +void loop() +{ + if (rxComplete == true) + { + uint8_t incomingBuffer[255]; + radio.readData(incomingBuffer, 255); + uint8_t receivedBytes = radio.getPacketLength(); + Serial.write(incomingBuffer, receivedBytes); + Serial.println(); + + Serial.print(F("Hops completed: ")); + Serial.println(hopsCompleted); + hopsCompleted = 0; + + radio.startReceive(); + + rxComplete = false; + } + + if (fhssChange == true) + { + radio.setFrequency(channels[radio.getFHSSChannel() % numberOfChannels]); + //Serial.print(F("Radio on channel: ")); + //Serial.println(radio.getFHSSChannel()); + + hopsCompleted++; + radio.clearFHSSInt(); + fhssChange = false; + } +} + +//ISR when DIO0 goes low +//Called when transmission is complete or when RX is received +void dio0ISR(void) +{ + rxComplete = true; +} + +//ISR when DIO1 goes low +//Called when FhssChangeChannel interrupt occurs (at the beginning of each transmission) +void dio1ISR(void) +{ + fhssChange = true; +} diff --git a/examples/SX127x/SX127x_Transmit_FHSS/SX127x_Transmit_FHSS.ino b/examples/SX127x/SX127x_Transmit_FHSS/SX127x_Transmit_FHSS.ino new file mode 100644 index 00000000..504852e0 --- /dev/null +++ b/examples/SX127x/SX127x_Transmit_FHSS/SX127x_Transmit_FHSS.ino @@ -0,0 +1,124 @@ +/* + RadioLib SX127x Transmit with Frequency Hopping Example + + This example transmits packets using SX1278 LoRa radio module. + Each packet contains up to 256 bytes of data, in the form of: + - Arduino String + - null-terminated char array (C-string) + - arbitrary binary data (byte array) + + Other modules from SX127x/RFM9x family can also be used. + + For default module settings, see the wiki page + https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem + + For full API reference, see the GitHub Pages + https://jgromes.github.io/RadioLib/ + + The SX1276 / 7 / 8 / 9 supports FHSS or Frequency Hopping Spread Spectrum. + Once a hopping period is set and a transmission is started the radio + will begin triggering interrupts every hop period where the radio frequency + is changed to the next channel. This allows a simple mechanism to abide by + the FCC 400ms max dwell time rule. + https://www.govinfo.gov/content/pkg/CFR-2019-title47-vol1/pdf/CFR-2019-title47-vol1-sec15-247.pdf +*/ + +#include //Click here to get the library: http://librarymanager/All#RadioLib + +//Pins for SparkFun 1W EBYTE Breakout to Uno +int pin_cs = 7; +int pin_dio0 = 3; +int pin_dio1 = 2; +int pin_rst = A2; +SX1276 radio = new Module(pin_cs, pin_dio0, pin_rst, pin_dio1); + +volatile bool xmitComplete = false; +volatile bool fhssChange = false; + +//The channel frequencies can be generated randomly or hard coded +float channels[] = {908.0, 906.0, 907.0, 905.0, 903.0, 910.0, 909.0}; +int numberOfChannels = sizeof(channels) / sizeof(float); + +int hopsCompleted = 0; +int counter = 0; + +void setup() +{ + Serial.begin(115200); + + //Begin radio on home channel + Serial.print(F("[SX127x] Initializing ... ")); + int state = radio.begin(channels[0]); + if (state != RADIOLIB_ERR_NONE) + { + Serial.print(F("Failed with code: ")); + Serial.println(state); + } + else + Serial.println(F("Success!")); + + // Set hop period to enable FHSS + // We set an artifically short period to show lots of hops + // HoppingPeriod = Tsym * FreqHoppingPeriod + // Given defaults of spreadfactor = 9, bandwidth = 125, it follows Tsym = 4.10ms + // HoppingPeriod = 4.10 * 9 = 36.9ms. Can be as high as 400ms to be within regulatory limits + radio.setFHSSHoppingPeriod(9); + + Serial.print(F("Hopping period: ")); + Serial.println(radio.getFHSSHoppingPeriod()); + + radio.setDio0Action(dio0ISR); //Called when transmission is finished + radio.setDio1Action(dio1ISR); //Called after a transmission has started, so we can move to next freq + + Serial.print(F("Transmitting packet...")); + + char output[256]; + sprintf(output, "Let's create a really long packet to trigger lots of hop interrupts. A packet can be up to 256 bytes long. This packet is 222 bytes so using sf = 9, bw = 125, timeOnAir is 1488ms. 1488ms / (9*4.10ms) = 40 hops. Counter: %d", counter++); + + radio.startTransmit(output, strlen(output) - 1); +} + +void loop() +{ + if (xmitComplete == true) + { + xmitComplete = false; + Serial.println(F("Transmit complete")); + Serial.print(F("Radio after xmit is on channel: ")); + Serial.println(radio.getFHSSChannel()); + //The FHSS channel is automatically reset to 0 upon end of transmission + + radio.setFrequency(channels[radio.getFHSSChannel() % numberOfChannels]); //Return to home channel before next transaction + + Serial.print(F("Hops completed: ")); + Serial.println(hopsCompleted); + hopsCompleted = 0; + + radio.startReceive(); + } + + if (fhssChange == true) + { + radio.setFrequency(channels[radio.getFHSSChannel() % numberOfChannels]); + //Serial.print(F("Radio on channel: ")); + //Serial.println(radio.getFHSSChannel()); + + hopsCompleted++; + fhssChange = false; + radio.clearFHSSInt(); + } +} + +//ISR when DIO0 goes low +//Called when transmission is complete or when RX is received +void dio0ISR(void) +{ + xmitComplete = true; +} + +//ISR when DIO1 goes low +//Called when FhssChangeChannel interrupt occurs (at regular HoppingPeriods) +void dio1ISR(void) +{ + fhssChange = true; +} diff --git a/keywords.txt b/keywords.txt index 9167c2a6..31db163d 100644 --- a/keywords.txt +++ b/keywords.txt @@ -142,6 +142,10 @@ setDirectAction KEYWORD2 readBit KEYWORD2 enableBitSync KEYWORD2 disableBitSync KEYWORD2 +setFHSSHoppingPeriod KEYWORD2 +getFHSSHoppingPeriod KEYWORD2 +getFHSSChannel KEYWORD2 +clearFHSSInt KEYWORD2 # RF69-specific setAESKey KEYWORD2 diff --git a/src/modules/SX127x/SX1276.cpp b/src/modules/SX127x/SX1276.cpp index c4c32f9c..fa1b46b8 100644 --- a/src/modules/SX127x/SX1276.cpp +++ b/src/modules/SX127x/SX1276.cpp @@ -70,4 +70,26 @@ int16_t SX1276::setFrequency(float freq) { return(state); } +int16_t SX1276::setFHSSHoppingPeriod(uint8_t freqHoppingPeriod) { + return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD, freqHoppingPeriod)); +} + +uint8_t SX1276::getFHSSHoppingPeriod(void) { + return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD)); +} + +uint8_t SX1276::getFHSSChannel(void) { + return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_CHANNEL, 5, 0)); +} + +void SX1276::clearFHSSInt(void) { + int16_t modem = getActiveModem(); + if(modem == RADIOLIB_SX127X_LORA) { + _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS, getIRQFlags() | RADIOLIB_SX127X_CLEAR_IRQ_FLAG_FHSS_CHANGE_CHANNEL); + } else if(modem == RADIOLIB_SX127X_FSK_OOK) { + return; //These are not the interrupts you are looking for + } +} + + #endif diff --git a/src/modules/SX127x/SX1276.h b/src/modules/SX127x/SX1276.h index cdc4cac5..15006ce3 100644 --- a/src/modules/SX127x/SX1276.h +++ b/src/modules/SX127x/SX1276.h @@ -84,6 +84,34 @@ class SX1276: public SX1278 { */ int16_t setFrequency(float freq); + /*! + \brief Sets the hopping period and enables FHSS + + \param freqHoppingPeriod Integer multiple of symbol periods between hops + + \returns \ref status_codes + */ + int16_t setFHSSHoppingPeriod(uint8_t freqHoppingPeriod); + + /*! + \brief Gets FHSS hopping period + + \returns 8 bit period + */ + uint8_t getFHSSHoppingPeriod(void); + + /*! + \brief Gets the FHSS channel in use + + \returns 6 bit channel number + */ + uint8_t getFHSSChannel(void); + + /*! + \brief Clear the FHSS interrupt + */ + void clearFHSSInt(void); + #if !defined(RADIOLIB_GODMODE) private: #endif diff --git a/src/modules/SX127x/SX127x.cpp b/src/modules/SX127x/SX127x.cpp index 24323447..9b099bbc 100644 --- a/src/modules/SX127x/SX127x.cpp +++ b/src/modules/SX127x/SX127x.cpp @@ -375,7 +375,10 @@ int16_t SX127x::startReceive(uint8_t len, uint8_t mode) { int16_t modem = getActiveModem(); if(modem == RADIOLIB_SX127X_LORA) { // set DIO pin mapping - state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_RX_DONE | RADIOLIB_SX127X_DIO1_RX_TIMEOUT, 7, 4); + if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) + state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_RX_DONE | RADIOLIB_SX127X_DIO1_FHSS_CHANGE_CHANNEL, 7, 4); + else + state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_RX_DONE | RADIOLIB_SX127X_DIO1_RX_TIMEOUT, 7, 4); // set expected packet length for SF6 if(_sf == 6) { @@ -448,7 +451,10 @@ int16_t SX127x::startTransmit(uint8_t* data, size_t len, uint8_t addr) { } // set DIO mapping - _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_TX_DONE, 7, 6); + if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) + _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_TX_DONE | RADIOLIB_SX127X_DIO1_FHSS_CHANGE_CHANNEL, 7, 4); + else + _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_TX_DONE, 7, 6); // apply fixes to errata RADIOLIB_ERRATA_SX127X(false); @@ -987,8 +993,11 @@ int16_t SX127x::setOOK(bool enableOOK) { } int16_t SX127x::setFrequencyRaw(float newFreq) { - // set mode to standby - int16_t state = setMode(RADIOLIB_SX127X_STANDBY); + int16_t state = RADIOLIB_ERR_NONE; + + // set mode to standby if not FHSS + if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) == RADIOLIB_SX127X_HOP_PERIOD_OFF) + state = setMode(RADIOLIB_SX127X_STANDBY); // calculate register values uint32_t FRF = (newFreq * (uint32_t(1) << RADIOLIB_SX127X_DIV_EXPONENT)) / RADIOLIB_SX127X_CRYSTAL_FREQ; From 20e1ab23dfff7b9214079d053f1150fce7283cef Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 17 Jan 2022 11:35:19 -0700 Subject: [PATCH 2/4] Add helper functions for SX1277, SX1278, SX1279 --- src/modules/SX127x/SX1277.cpp | 20 ++++++++++++++++++++ src/modules/SX127x/SX1277.h | 28 ++++++++++++++++++++++++++++ src/modules/SX127x/SX1278.cpp | 21 +++++++++++++++++++++ src/modules/SX127x/SX1278.h | 28 ++++++++++++++++++++++++++++ src/modules/SX127x/SX1279.cpp | 21 +++++++++++++++++++++ src/modules/SX127x/SX1279.h | 28 ++++++++++++++++++++++++++++ src/modules/SX127x/SX127x.cpp | 15 ++++++++++----- 7 files changed, 156 insertions(+), 5 deletions(-) diff --git a/src/modules/SX127x/SX1277.cpp b/src/modules/SX127x/SX1277.cpp index 59250e45..2bc2790a 100644 --- a/src/modules/SX127x/SX1277.cpp +++ b/src/modules/SX127x/SX1277.cpp @@ -100,4 +100,24 @@ int16_t SX1277::setSpreadingFactor(uint8_t sf) { return(state); } +int16_t SX1277::setFHSSHoppingPeriod(uint8_t freqHoppingPeriod) { + return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD, freqHoppingPeriod)); +} + +uint8_t SX1277::getFHSSHoppingPeriod(void) { + return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD)); +} + +uint8_t SX1277::getFHSSChannel(void) { + return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_CHANNEL, 5, 0)); +} + +void SX1277::clearFHSSInt(void) { + int16_t modem = getActiveModem(); + if(modem == RADIOLIB_SX127X_LORA) { + _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS, getIRQFlags() | RADIOLIB_SX127X_CLEAR_IRQ_FLAG_FHSS_CHANGE_CHANNEL); + } else if(modem == RADIOLIB_SX127X_FSK_OOK) { + return; //These are not the interrupts you are looking for + } +} #endif diff --git a/src/modules/SX127x/SX1277.h b/src/modules/SX127x/SX1277.h index b9f7a5cf..fed18de5 100644 --- a/src/modules/SX127x/SX1277.h +++ b/src/modules/SX127x/SX1277.h @@ -93,6 +93,34 @@ class SX1277: public SX1278 { */ int16_t setSpreadingFactor(uint8_t sf); + /*! + \brief Sets the hopping period and enables FHSS + + \param freqHoppingPeriod Integer multiple of symbol periods between hops + + \returns \ref status_codes + */ + int16_t setFHSSHoppingPeriod(uint8_t freqHoppingPeriod); + + /*! + \brief Gets FHSS hopping period + + \returns 8 bit period + */ + uint8_t getFHSSHoppingPeriod(void); + + /*! + \brief Gets the FHSS channel in use + + \returns 6 bit channel number + */ + uint8_t getFHSSChannel(void); + + /*! + \brief Clear the FHSS interrupt + */ + void clearFHSSInt(void); + #if !defined(RADIOLIB_GODMODE) private: #endif diff --git a/src/modules/SX127x/SX1278.cpp b/src/modules/SX127x/SX1278.cpp index 317c38ee..71ba02e1 100644 --- a/src/modules/SX127x/SX1278.cpp +++ b/src/modules/SX127x/SX1278.cpp @@ -623,4 +623,25 @@ void SX1278::errataFix(bool rx) { _mod->SPIsetRegValue(0x30, fixedRegs[2]); } +int16_t SX1278::setFHSSHoppingPeriod(uint8_t freqHoppingPeriod) { + return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD, freqHoppingPeriod)); +} + +uint8_t SX1278::getFHSSHoppingPeriod(void) { + return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD)); +} + +uint8_t SX1278::getFHSSChannel(void) { + return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_CHANNEL, 5, 0)); +} + +void SX1278::clearFHSSInt(void) { + int16_t modem = getActiveModem(); + if(modem == RADIOLIB_SX127X_LORA) { + _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS, getIRQFlags() | RADIOLIB_SX127X_CLEAR_IRQ_FLAG_FHSS_CHANGE_CHANNEL); + } else if(modem == RADIOLIB_SX127X_FSK_OOK) { + return; //These are not the interrupts you are looking for + } +} + #endif diff --git a/src/modules/SX127x/SX1278.h b/src/modules/SX127x/SX1278.h index 150b97c3..533a0da9 100644 --- a/src/modules/SX127x/SX1278.h +++ b/src/modules/SX127x/SX1278.h @@ -302,6 +302,34 @@ class SX1278: public SX127x { */ int16_t explicitHeader(); + /*! + \brief Sets the hopping period and enables FHSS + + \param freqHoppingPeriod Integer multiple of symbol periods between hops + + \returns \ref status_codes + */ + int16_t setFHSSHoppingPeriod(uint8_t freqHoppingPeriod); + + /*! + \brief Gets FHSS hopping period + + \returns 8 bit period + */ + uint8_t getFHSSHoppingPeriod(void); + + /*! + \brief Gets the FHSS channel in use + + \returns 6 bit channel number + */ + uint8_t getFHSSChannel(void); + + /*! + \brief Clear the FHSS interrupt + */ + void clearFHSSInt(void); + #if !defined(RADIOLIB_GODMODE) protected: #endif diff --git a/src/modules/SX127x/SX1279.cpp b/src/modules/SX127x/SX1279.cpp index 1eac9dc9..286d0f47 100644 --- a/src/modules/SX127x/SX1279.cpp +++ b/src/modules/SX127x/SX1279.cpp @@ -70,4 +70,25 @@ int16_t SX1279::setFrequency(float freq) { return(state); } +int16_t SX1279::setFHSSHoppingPeriod(uint8_t freqHoppingPeriod) { + return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD, freqHoppingPeriod)); +} + +uint8_t SX1279::getFHSSHoppingPeriod(void) { + return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD)); +} + +uint8_t SX1279::getFHSSChannel(void) { + return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_CHANNEL, 5, 0)); +} + +void SX1279::clearFHSSInt(void) { + int16_t modem = getActiveModem(); + if(modem == RADIOLIB_SX127X_LORA) { + _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS, getIRQFlags() | RADIOLIB_SX127X_CLEAR_IRQ_FLAG_FHSS_CHANGE_CHANNEL); + } else if(modem == RADIOLIB_SX127X_FSK_OOK) { + return; //These are not the interrupts you are looking for + } +} + #endif diff --git a/src/modules/SX127x/SX1279.h b/src/modules/SX127x/SX1279.h index c9ff8ab0..5328213b 100644 --- a/src/modules/SX127x/SX1279.h +++ b/src/modules/SX127x/SX1279.h @@ -84,6 +84,34 @@ class SX1279: public SX1278 { */ int16_t setFrequency(float freq); + /*! + \brief Sets the hopping period and enables FHSS + + \param freqHoppingPeriod Integer multiple of symbol periods between hops + + \returns \ref status_codes + */ + int16_t setFHSSHoppingPeriod(uint8_t freqHoppingPeriod); + + /*! + \brief Gets FHSS hopping period + + \returns 8 bit period + */ + uint8_t getFHSSHoppingPeriod(void); + + /*! + \brief Gets the FHSS channel in use + + \returns 6 bit channel number + */ + uint8_t getFHSSChannel(void); + + /*! + \brief Clear the FHSS interrupt + */ + void clearFHSSInt(void); + #if !defined(RADIOLIB_GODMODE) private: #endif diff --git a/src/modules/SX127x/SX127x.cpp b/src/modules/SX127x/SX127x.cpp index 9b099bbc..15736a0a 100644 --- a/src/modules/SX127x/SX127x.cpp +++ b/src/modules/SX127x/SX127x.cpp @@ -375,10 +375,12 @@ int16_t SX127x::startReceive(uint8_t len, uint8_t mode) { int16_t modem = getActiveModem(); if(modem == RADIOLIB_SX127X_LORA) { // set DIO pin mapping - if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) + if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) { state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_RX_DONE | RADIOLIB_SX127X_DIO1_FHSS_CHANGE_CHANNEL, 7, 4); - else + } + else { state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_RX_DONE | RADIOLIB_SX127X_DIO1_RX_TIMEOUT, 7, 4); + } // set expected packet length for SF6 if(_sf == 6) { @@ -451,10 +453,12 @@ int16_t SX127x::startTransmit(uint8_t* data, size_t len, uint8_t addr) { } // set DIO mapping - if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) + if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) { _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_TX_DONE | RADIOLIB_SX127X_DIO1_FHSS_CHANGE_CHANNEL, 7, 4); - else + } + else { _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_TX_DONE, 7, 6); + } // apply fixes to errata RADIOLIB_ERRATA_SX127X(false); @@ -996,8 +1000,9 @@ int16_t SX127x::setFrequencyRaw(float newFreq) { int16_t state = RADIOLIB_ERR_NONE; // set mode to standby if not FHSS - if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) == RADIOLIB_SX127X_HOP_PERIOD_OFF) + if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) == RADIOLIB_SX127X_HOP_PERIOD_OFF) { state = setMode(RADIOLIB_SX127X_STANDBY); + } // calculate register values uint32_t FRF = (newFreq * (uint32_t(1) << RADIOLIB_SX127X_DIV_EXPONENT)) / RADIOLIB_SX127X_CRYSTAL_FREQ; From c4fec32965abd7e81ce4e6b7f6fbf1abfcfddefd Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 17 Jan 2022 11:43:13 -0700 Subject: [PATCH 3/4] Change coding style to match library style guide. --- .../SX127x_Receive_FHSS.ino | 86 ++++++++----------- .../SX127x_Transmit_FHSS.ino | 83 ++++++++---------- 2 files changed, 73 insertions(+), 96 deletions(-) diff --git a/examples/SX127x/SX127x_Receive_FHSS/SX127x_Receive_FHSS.ino b/examples/SX127x/SX127x_Receive_FHSS/SX127x_Receive_FHSS.ino index d45bec3b..7ee31b83 100644 --- a/examples/SX127x/SX127x_Receive_FHSS/SX127x_Receive_FHSS.ino +++ b/examples/SX127x/SX127x_Receive_FHSS/SX127x_Receive_FHSS.ino @@ -18,68 +18,61 @@ The SX1276 / 7 / 8 / 9 supports FHSS or Frequency Hopping Spread Spectrum. Once a hopping period is set and a transmission is started the radio will begin triggering interrupts every hop period where the radio frequency - is changed to the next channel. This allows a simple mechanism to abide by - the FCC 400ms max dwell time rule. - https://www.govinfo.gov/content/pkg/CFR-2019-title47-vol1/pdf/CFR-2019-title47-vol1-sec15-247.pdf + is changed to the next channel. */ #include //Click here to get the library: http://librarymanager/All#RadioLib -//Pins for RFM97 100mW Shield to SparkFun ESP32 Thing Plus C -int pin_cs = 15; -int pin_dio0 = 26; -int pin_dio1 = 25; -int pin_rst = 32; +// SX1276 has the following connections: +const int pin_cs = 10; +const int pin_dio0 = 2; +const int pin_dio1 = 9; +const int pin_rst = 3; SX1276 radio = new Module(pin_cs, pin_dio0, pin_rst, pin_dio1); -int counter = 0; - volatile bool rxComplete = false; volatile bool fhssChange = false; -//The channel frequencies can be generated randomly or hard coded +// the channel frequencies can be generated randomly or hard coded float channels[] = {908.0, 906.0, 907.0, 905.0, 903.0, 910.0, 909.0}; int numberOfChannels = sizeof(channels) / sizeof(float); int hopsCompleted = 0; -void setup() -{ - Serial.begin(115200); +void setup() { + Serial.begin(9600); - //Begin radio on home channel + // begin radio on home channel Serial.print(F("[SX127x] Initializing ... ")); int state = radio.begin(channels[0]); - if (state != RADIOLIB_ERR_NONE) - { + if (state != RADIOLIB_ERR_NONE) { Serial.print(F("Failed with code: ")); Serial.println(state); } else Serial.println(F("Success!")); - // Set hop period to enable FHSS - // We set an artifically short period to show lots of hops - // HoppingPeriod = Tsym * FreqHoppingPeriod - // Given defaults of spreadfactor = 9, bandwidth = 125, it follows Tsym = 4.10ms - // HoppingPeriod = 4.10 * 9 = 36.9ms. Can be as high as 400ms to be within regulatory limits - radio.setFHSSHoppingPeriod(9); + // set hop period to enable FHSS + state = radio.setFHSSHoppingPeriod(9); + if (state != RADIOLIB_ERR_NONE) { + Serial.print(F("Error setting hopping period: ")); + Serial.println(state); + } + radio.setDio0Action(dio0ISR); // called when transmission is finished + radio.setDio1Action(dio1ISR); // called after a transmission has started, so we can move to next freq - Serial.print(F("Hopping period: ")); - Serial.println(radio.getFHSSHoppingPeriod()); - - radio.setDio0Action(dio0ISR); //Called when transmission is finished - radio.setDio1Action(dio1ISR); //Called after a transmission has started, so we can move to next freq - - radio.startReceive(); - - Serial.println(F("Waiting for new packet")); + // start listening for LoRa packets + Serial.print(F("[SX1278] Starting to listen ... ")); + state = radio.startReceive(); + if (state != RADIOLIB_ERR_NONE) { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } } -void loop() -{ - if (rxComplete == true) - { +void loop() { + if (rxComplete == true) { uint8_t incomingBuffer[255]; radio.readData(incomingBuffer, 255); uint8_t receivedBytes = radio.getPacketLength(); @@ -95,11 +88,8 @@ void loop() rxComplete = false; } - if (fhssChange == true) - { + if (fhssChange == true) { radio.setFrequency(channels[radio.getFHSSChannel() % numberOfChannels]); - //Serial.print(F("Radio on channel: ")); - //Serial.println(radio.getFHSSChannel()); hopsCompleted++; radio.clearFHSSInt(); @@ -107,16 +97,14 @@ void loop() } } -//ISR when DIO0 goes low -//Called when transmission is complete or when RX is received -void dio0ISR(void) -{ +// ISR when DIO0 goes low +// called when transmission is complete or when RX is received +void dio0ISR(void) { rxComplete = true; } -//ISR when DIO1 goes low -//Called when FhssChangeChannel interrupt occurs (at the beginning of each transmission) -void dio1ISR(void) -{ +// ISR when DIO1 goes low +// called when FhssChangeChannel interrupt occurs (at the beginning of each transmission) +void dio1ISR(void) { fhssChange = true; -} +} \ No newline at end of file diff --git a/examples/SX127x/SX127x_Transmit_FHSS/SX127x_Transmit_FHSS.ino b/examples/SX127x/SX127x_Transmit_FHSS/SX127x_Transmit_FHSS.ino index 504852e0..f1ecbaf8 100644 --- a/examples/SX127x/SX127x_Transmit_FHSS/SX127x_Transmit_FHSS.ino +++ b/examples/SX127x/SX127x_Transmit_FHSS/SX127x_Transmit_FHSS.ino @@ -18,77 +18,71 @@ The SX1276 / 7 / 8 / 9 supports FHSS or Frequency Hopping Spread Spectrum. Once a hopping period is set and a transmission is started the radio will begin triggering interrupts every hop period where the radio frequency - is changed to the next channel. This allows a simple mechanism to abide by - the FCC 400ms max dwell time rule. - https://www.govinfo.gov/content/pkg/CFR-2019-title47-vol1/pdf/CFR-2019-title47-vol1-sec15-247.pdf + is changed to the next channel. */ #include //Click here to get the library: http://librarymanager/All#RadioLib -//Pins for SparkFun 1W EBYTE Breakout to Uno -int pin_cs = 7; -int pin_dio0 = 3; -int pin_dio1 = 2; -int pin_rst = A2; +// SX1276 has the following connections: +const int pin_cs = 10; +const int pin_dio0 = 2; +const int pin_dio1 = 9; +const int pin_rst = 3; SX1276 radio = new Module(pin_cs, pin_dio0, pin_rst, pin_dio1); volatile bool xmitComplete = false; volatile bool fhssChange = false; -//The channel frequencies can be generated randomly or hard coded +// the channel frequencies can be generated randomly or hard coded float channels[] = {908.0, 906.0, 907.0, 905.0, 903.0, 910.0, 909.0}; int numberOfChannels = sizeof(channels) / sizeof(float); int hopsCompleted = 0; int counter = 0; -void setup() -{ - Serial.begin(115200); +void setup() { + Serial.begin(9600); - //Begin radio on home channel + // begin radio on home channel Serial.print(F("[SX127x] Initializing ... ")); int state = radio.begin(channels[0]); - if (state != RADIOLIB_ERR_NONE) - { + if (state != RADIOLIB_ERR_NONE) { Serial.print(F("Failed with code: ")); Serial.println(state); } else Serial.println(F("Success!")); - // Set hop period to enable FHSS - // We set an artifically short period to show lots of hops - // HoppingPeriod = Tsym * FreqHoppingPeriod - // Given defaults of spreadfactor = 9, bandwidth = 125, it follows Tsym = 4.10ms - // HoppingPeriod = 4.10 * 9 = 36.9ms. Can be as high as 400ms to be within regulatory limits - radio.setFHSSHoppingPeriod(9); + // set hop period to enable FHSS + state = radio.setFHSSHoppingPeriod(9); + if(state != RADIOLIB_ERR_NONE) { + Serial.print(F("Error setting hopping period: ")); + Serial.println(state); + } - Serial.print(F("Hopping period: ")); - Serial.println(radio.getFHSSHoppingPeriod()); - - radio.setDio0Action(dio0ISR); //Called when transmission is finished - radio.setDio1Action(dio1ISR); //Called after a transmission has started, so we can move to next freq + radio.setDio0Action(dio0ISR); // called when transmission is finished + radio.setDio1Action(dio1ISR); // called after a transmission has started, so we can move to next freq Serial.print(F("Transmitting packet...")); - char output[256]; - sprintf(output, "Let's create a really long packet to trigger lots of hop interrupts. A packet can be up to 256 bytes long. This packet is 222 bytes so using sf = 9, bw = 125, timeOnAir is 1488ms. 1488ms / (9*4.10ms) = 40 hops. Counter: %d", counter++); + String longOutput = "Let's create a really long packet to trigger lots of hop interrupts. A packet can be up to 256 bytes long. This packet is 222 bytes so using sf = 9, bw = 125, timeOnAir is 1488ms. 1488ms / (9*4.10ms) = 40 hops. Counter: "; - radio.startTransmit(output, strlen(output) - 1); + state = radio.startTransmit(longOutput + counter); + if (state != RADIOLIB_ERR_NONE) { + Serial.print(F("Error transmitting with code: ")); + Serial.println(state); + } } -void loop() -{ - if (xmitComplete == true) - { +void loop() { + if (xmitComplete == true) { xmitComplete = false; Serial.println(F("Transmit complete")); Serial.print(F("Radio after xmit is on channel: ")); Serial.println(radio.getFHSSChannel()); - //The FHSS channel is automatically reset to 0 upon end of transmission + // the FHSS channel is automatically reset to 0 upon end of transmission - radio.setFrequency(channels[radio.getFHSSChannel() % numberOfChannels]); //Return to home channel before next transaction + radio.setFrequency(channels[radio.getFHSSChannel() % numberOfChannels]); // Return to home channel before next transaction Serial.print(F("Hops completed: ")); Serial.println(hopsCompleted); @@ -97,11 +91,8 @@ void loop() radio.startReceive(); } - if (fhssChange == true) - { + if (fhssChange == true) { radio.setFrequency(channels[radio.getFHSSChannel() % numberOfChannels]); - //Serial.print(F("Radio on channel: ")); - //Serial.println(radio.getFHSSChannel()); hopsCompleted++; fhssChange = false; @@ -109,16 +100,14 @@ void loop() } } -//ISR when DIO0 goes low -//Called when transmission is complete or when RX is received -void dio0ISR(void) -{ +// ISR when DIO0 goes low +// called when transmission is complete or when RX is received +void dio0ISR(void) { xmitComplete = true; } -//ISR when DIO1 goes low -//Called when FhssChangeChannel interrupt occurs (at regular HoppingPeriods) -void dio1ISR(void) -{ +// ISR when DIO1 goes low +// called when FhssChangeChannel interrupt occurs (at regular HoppingPeriods) +void dio1ISR(void) { fhssChange = true; } From 06ef449b68fb698914d4becaff2fa18b099bb489 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 17 Jan 2022 11:47:49 -0700 Subject: [PATCH 4/4] Move helper functions from SX1276/7/8/9 to global SX127x. --- src/modules/SX127x/SX1276.cpp | 22 ---------------------- src/modules/SX127x/SX1276.h | 28 ---------------------------- src/modules/SX127x/SX1277.cpp | 20 -------------------- src/modules/SX127x/SX1277.h | 28 ---------------------------- src/modules/SX127x/SX1278.cpp | 21 --------------------- src/modules/SX127x/SX1278.h | 28 ---------------------------- src/modules/SX127x/SX1279.cpp | 21 --------------------- src/modules/SX127x/SX1279.h | 28 ---------------------------- src/modules/SX127x/SX127x.cpp | 21 +++++++++++++++++++++ src/modules/SX127x/SX127x.h | 28 ++++++++++++++++++++++++++++ 10 files changed, 49 insertions(+), 196 deletions(-) diff --git a/src/modules/SX127x/SX1276.cpp b/src/modules/SX127x/SX1276.cpp index fa1b46b8..c4c32f9c 100644 --- a/src/modules/SX127x/SX1276.cpp +++ b/src/modules/SX127x/SX1276.cpp @@ -70,26 +70,4 @@ int16_t SX1276::setFrequency(float freq) { return(state); } -int16_t SX1276::setFHSSHoppingPeriod(uint8_t freqHoppingPeriod) { - return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD, freqHoppingPeriod)); -} - -uint8_t SX1276::getFHSSHoppingPeriod(void) { - return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD)); -} - -uint8_t SX1276::getFHSSChannel(void) { - return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_CHANNEL, 5, 0)); -} - -void SX1276::clearFHSSInt(void) { - int16_t modem = getActiveModem(); - if(modem == RADIOLIB_SX127X_LORA) { - _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS, getIRQFlags() | RADIOLIB_SX127X_CLEAR_IRQ_FLAG_FHSS_CHANGE_CHANNEL); - } else if(modem == RADIOLIB_SX127X_FSK_OOK) { - return; //These are not the interrupts you are looking for - } -} - - #endif diff --git a/src/modules/SX127x/SX1276.h b/src/modules/SX127x/SX1276.h index 15006ce3..cdc4cac5 100644 --- a/src/modules/SX127x/SX1276.h +++ b/src/modules/SX127x/SX1276.h @@ -84,34 +84,6 @@ class SX1276: public SX1278 { */ int16_t setFrequency(float freq); - /*! - \brief Sets the hopping period and enables FHSS - - \param freqHoppingPeriod Integer multiple of symbol periods between hops - - \returns \ref status_codes - */ - int16_t setFHSSHoppingPeriod(uint8_t freqHoppingPeriod); - - /*! - \brief Gets FHSS hopping period - - \returns 8 bit period - */ - uint8_t getFHSSHoppingPeriod(void); - - /*! - \brief Gets the FHSS channel in use - - \returns 6 bit channel number - */ - uint8_t getFHSSChannel(void); - - /*! - \brief Clear the FHSS interrupt - */ - void clearFHSSInt(void); - #if !defined(RADIOLIB_GODMODE) private: #endif diff --git a/src/modules/SX127x/SX1277.cpp b/src/modules/SX127x/SX1277.cpp index 2bc2790a..59250e45 100644 --- a/src/modules/SX127x/SX1277.cpp +++ b/src/modules/SX127x/SX1277.cpp @@ -100,24 +100,4 @@ int16_t SX1277::setSpreadingFactor(uint8_t sf) { return(state); } -int16_t SX1277::setFHSSHoppingPeriod(uint8_t freqHoppingPeriod) { - return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD, freqHoppingPeriod)); -} - -uint8_t SX1277::getFHSSHoppingPeriod(void) { - return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD)); -} - -uint8_t SX1277::getFHSSChannel(void) { - return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_CHANNEL, 5, 0)); -} - -void SX1277::clearFHSSInt(void) { - int16_t modem = getActiveModem(); - if(modem == RADIOLIB_SX127X_LORA) { - _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS, getIRQFlags() | RADIOLIB_SX127X_CLEAR_IRQ_FLAG_FHSS_CHANGE_CHANNEL); - } else if(modem == RADIOLIB_SX127X_FSK_OOK) { - return; //These are not the interrupts you are looking for - } -} #endif diff --git a/src/modules/SX127x/SX1277.h b/src/modules/SX127x/SX1277.h index fed18de5..b9f7a5cf 100644 --- a/src/modules/SX127x/SX1277.h +++ b/src/modules/SX127x/SX1277.h @@ -93,34 +93,6 @@ class SX1277: public SX1278 { */ int16_t setSpreadingFactor(uint8_t sf); - /*! - \brief Sets the hopping period and enables FHSS - - \param freqHoppingPeriod Integer multiple of symbol periods between hops - - \returns \ref status_codes - */ - int16_t setFHSSHoppingPeriod(uint8_t freqHoppingPeriod); - - /*! - \brief Gets FHSS hopping period - - \returns 8 bit period - */ - uint8_t getFHSSHoppingPeriod(void); - - /*! - \brief Gets the FHSS channel in use - - \returns 6 bit channel number - */ - uint8_t getFHSSChannel(void); - - /*! - \brief Clear the FHSS interrupt - */ - void clearFHSSInt(void); - #if !defined(RADIOLIB_GODMODE) private: #endif diff --git a/src/modules/SX127x/SX1278.cpp b/src/modules/SX127x/SX1278.cpp index 71ba02e1..317c38ee 100644 --- a/src/modules/SX127x/SX1278.cpp +++ b/src/modules/SX127x/SX1278.cpp @@ -623,25 +623,4 @@ void SX1278::errataFix(bool rx) { _mod->SPIsetRegValue(0x30, fixedRegs[2]); } -int16_t SX1278::setFHSSHoppingPeriod(uint8_t freqHoppingPeriod) { - return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD, freqHoppingPeriod)); -} - -uint8_t SX1278::getFHSSHoppingPeriod(void) { - return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD)); -} - -uint8_t SX1278::getFHSSChannel(void) { - return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_CHANNEL, 5, 0)); -} - -void SX1278::clearFHSSInt(void) { - int16_t modem = getActiveModem(); - if(modem == RADIOLIB_SX127X_LORA) { - _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS, getIRQFlags() | RADIOLIB_SX127X_CLEAR_IRQ_FLAG_FHSS_CHANGE_CHANNEL); - } else if(modem == RADIOLIB_SX127X_FSK_OOK) { - return; //These are not the interrupts you are looking for - } -} - #endif diff --git a/src/modules/SX127x/SX1278.h b/src/modules/SX127x/SX1278.h index 533a0da9..150b97c3 100644 --- a/src/modules/SX127x/SX1278.h +++ b/src/modules/SX127x/SX1278.h @@ -302,34 +302,6 @@ class SX1278: public SX127x { */ int16_t explicitHeader(); - /*! - \brief Sets the hopping period and enables FHSS - - \param freqHoppingPeriod Integer multiple of symbol periods between hops - - \returns \ref status_codes - */ - int16_t setFHSSHoppingPeriod(uint8_t freqHoppingPeriod); - - /*! - \brief Gets FHSS hopping period - - \returns 8 bit period - */ - uint8_t getFHSSHoppingPeriod(void); - - /*! - \brief Gets the FHSS channel in use - - \returns 6 bit channel number - */ - uint8_t getFHSSChannel(void); - - /*! - \brief Clear the FHSS interrupt - */ - void clearFHSSInt(void); - #if !defined(RADIOLIB_GODMODE) protected: #endif diff --git a/src/modules/SX127x/SX1279.cpp b/src/modules/SX127x/SX1279.cpp index 286d0f47..1eac9dc9 100644 --- a/src/modules/SX127x/SX1279.cpp +++ b/src/modules/SX127x/SX1279.cpp @@ -70,25 +70,4 @@ int16_t SX1279::setFrequency(float freq) { return(state); } -int16_t SX1279::setFHSSHoppingPeriod(uint8_t freqHoppingPeriod) { - return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD, freqHoppingPeriod)); -} - -uint8_t SX1279::getFHSSHoppingPeriod(void) { - return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD)); -} - -uint8_t SX1279::getFHSSChannel(void) { - return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_CHANNEL, 5, 0)); -} - -void SX1279::clearFHSSInt(void) { - int16_t modem = getActiveModem(); - if(modem == RADIOLIB_SX127X_LORA) { - _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS, getIRQFlags() | RADIOLIB_SX127X_CLEAR_IRQ_FLAG_FHSS_CHANGE_CHANNEL); - } else if(modem == RADIOLIB_SX127X_FSK_OOK) { - return; //These are not the interrupts you are looking for - } -} - #endif diff --git a/src/modules/SX127x/SX1279.h b/src/modules/SX127x/SX1279.h index 5328213b..c9ff8ab0 100644 --- a/src/modules/SX127x/SX1279.h +++ b/src/modules/SX127x/SX1279.h @@ -84,34 +84,6 @@ class SX1279: public SX1278 { */ int16_t setFrequency(float freq); - /*! - \brief Sets the hopping period and enables FHSS - - \param freqHoppingPeriod Integer multiple of symbol periods between hops - - \returns \ref status_codes - */ - int16_t setFHSSHoppingPeriod(uint8_t freqHoppingPeriod); - - /*! - \brief Gets FHSS hopping period - - \returns 8 bit period - */ - uint8_t getFHSSHoppingPeriod(void); - - /*! - \brief Gets the FHSS channel in use - - \returns 6 bit channel number - */ - uint8_t getFHSSChannel(void); - - /*! - \brief Clear the FHSS interrupt - */ - void clearFHSSInt(void); - #if !defined(RADIOLIB_GODMODE) private: #endif diff --git a/src/modules/SX127x/SX127x.cpp b/src/modules/SX127x/SX127x.cpp index 15736a0a..1db50c20 100644 --- a/src/modules/SX127x/SX127x.cpp +++ b/src/modules/SX127x/SX127x.cpp @@ -1367,4 +1367,25 @@ void SX127x::readBit(RADIOLIB_PIN_TYPE pin) { updateDirectBuffer((uint8_t)digitalRead(pin)); } +int16_t SX127x::setFHSSHoppingPeriod(uint8_t freqHoppingPeriod) { + return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD, freqHoppingPeriod)); +} + +uint8_t SX127x::getFHSSHoppingPeriod(void) { + return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD)); +} + +uint8_t SX127x::getFHSSChannel(void) { + return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_CHANNEL, 5, 0)); +} + +void SX127x::clearFHSSInt(void) { + int16_t modem = getActiveModem(); + if(modem == RADIOLIB_SX127X_LORA) { + _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS, getIRQFlags() | RADIOLIB_SX127X_CLEAR_IRQ_FLAG_FHSS_CHANGE_CHANNEL); + } else if(modem == RADIOLIB_SX127X_FSK_OOK) { + return; //These are not the interrupts you are looking for + } +} + #endif diff --git a/src/modules/SX127x/SX127x.h b/src/modules/SX127x/SX127x.h index 66ab01c8..b0671bac 100644 --- a/src/modules/SX127x/SX127x.h +++ b/src/modules/SX127x/SX127x.h @@ -1073,6 +1073,34 @@ class SX127x: public PhysicalLayer { */ void readBit(RADIOLIB_PIN_TYPE pin); + /*! + \brief Sets the hopping period and enables FHSS + + \param freqHoppingPeriod Integer multiple of symbol periods between hops + + \returns \ref status_codes + */ + int16_t setFHSSHoppingPeriod(uint8_t freqHoppingPeriod); + + /*! + \brief Gets FHSS hopping period + + \returns 8 bit period + */ + uint8_t getFHSSHoppingPeriod(void); + + /*! + \brief Gets the FHSS channel in use + + \returns 6 bit channel number + */ + uint8_t getFHSSChannel(void); + + /*! + \brief Clear the FHSS interrupt + */ + void clearFHSSInt(void); + #if !defined(RADIOLIB_GODMODE) && !defined(RADIOLIB_LOW_LEVEL) protected: #endif