From a20f62da2fd300524d6c664bc1e9680d4924c217 Mon Sep 17 00:00:00 2001 From: BarryPSmith Date: Tue, 3 Dec 2019 22:43:10 -0800 Subject: [PATCH 1/7] Added sx126x receive duty cycle interface --- keywords.txt | 2 + src/TypeDef.h | 13 +++++ src/modules/SX126x/SX126x.cpp | 95 ++++++++++++++++++++++++++++++++--- src/modules/SX126x/SX126x.h | 36 ++++++++++++- 4 files changed, 136 insertions(+), 10 deletions(-) diff --git a/keywords.txt b/keywords.txt index 71a1a76a..93a463b5 100644 --- a/keywords.txt +++ b/keywords.txt @@ -115,6 +115,8 @@ setDio2AsRfSwitch KEYWORD2 getTimeOnAir KEYWORD2 setSyncBits KEYWORD2 setWhitening KEYWORD2 +startReceiveDutyCycle KEYWORD2 +startReceiveDutyCycleAuto KEYWORD2 # ESP8266 join KEYWORD2 diff --git a/src/TypeDef.h b/src/TypeDef.h index c9898a93..01697665 100644 --- a/src/TypeDef.h +++ b/src/TypeDef.h @@ -305,6 +305,19 @@ */ #define ERR_INVALID_ENCODING -23 +/*! + \brief The supplied sleep period is invalid. + + The specified sleep period is shorter than the time necessary to sleep and wake the hardware, + including TCXO delay +*/ +#define ERR_INVALID_SLEEP_PERIOD -24 + +/*! + \brief A specified value would cause an integer overflow +*/ +#define ERR_OVERFLOW -25 + // RF69-specific status codes /*! diff --git a/src/modules/SX126x/SX126x.cpp b/src/modules/SX126x/SX126x.cpp index e8db4995..44b9ee43 100644 --- a/src/modules/SX126x/SX126x.cpp +++ b/src/modules/SX126x/SX126x.cpp @@ -443,7 +443,91 @@ int16_t SX126x::startTransmit(uint8_t* data, size_t len, uint8_t addr) { } int16_t SX126x::startReceive(uint32_t timeout) { - // set DIO mapping + int16_t state = startReceiveCommon(); + if(state != ERR_NONE) { + return(state); + } + + // set mode to receive + state = setRx(timeout); + + return(state); +} + +int16_t SX126x::startReceiveDutyCycle(uint32_t rxPeriod_us, uint32_t sleepPeriod_us) +{ + // datasheet claims time to go to sleep is ~500us, same to wake up. + // compensate for that 1ms + tcxo delay: + uint32_t transitionTime = _tcxoDelay_us + 1000; + if (sleepPeriod_us < transitionTime + 16) { + return(ERR_INVALID_SLEEP_PERIOD); + } + sleepPeriod_us -= transitionTime; + + // divide by 15.625 + uint32_t rxPeriodRaw = (rxPeriod_us * 8) / 125; + uint32_t sleepPeriodRaw = (sleepPeriod_us * 8) / 125; + + // 24 bit limit: + if ((rxPeriodRaw & 0xFF000000) || (sleepPeriodRaw & 0xFF000000)) { + return(ERR_OVERFLOW); + } + + int16_t state = startReceiveCommon(); + if (state != ERR_NONE) { + return(state); + } + + byte data[6] = { + (rxPeriodRaw >> 16) & 0xFF, (rxPeriodRaw >> 8) & 0xFF, rxPeriodRaw & 0xFF, + (sleepPeriodRaw >> 16) & 0xFF, (sleepPeriodRaw >> 8) & 0xFF, sleepPeriodRaw & 0xFF + }; + return(SPIwriteCommand(SX126X_CMD_SET_RX_DUTY_CYCLE, data, 6)); +} + +int16_t SX126x::startReceiveDutyCycleAuto(uint16_t senderPreambleLength, uint16_t minSymbols) +{ + if (senderPreambleLength == 0) { + senderPreambleLength = _preambleLength; + } + + // worst case is that the sender starts transmiting when we're just less than minSymbols from going back to sleep. + // in this case, we don't catch minSymbols before going to sleep, + // so we must be awake for at least that long before the sender stops transmitting. + uint16_t sleepSymbols = senderPreambleLength - 2 * minSymbols; + + // if we're not to sleep at all, just use the standard startReceive. + if (2 * minSymbols > senderPreambleLength) { + return(startReceive()); + } + + uint32_t symbolLength_us = ((uint32_t)(10 * 1000) << _sf) / (10 * _bwKhz); + uint32_t sleepPeriod_us = symbolLength_us * sleepSymbols; + RADIOLIB_DEBUG_PRINT(F("Auto sleep period: ")); + RADIOLIB_DEBUG_PRINTLN(sleepPeriod_us); + // when the unit detects a preamble, it starts a timer that will timeout if it doesn't receive a header in time. + // the duration is sleepPeriod + 2 * wakePeriod. + // The sleepPeriod doesn't take into account shutdown and startup time for the unit (~1ms) + // We need to ensure that the timout is longer than senderPreambleLength. + // So we must satisfy: wakePeriod > (preamblePeriod - (sleepPeriod - 1000)) / 2. (A) + // we also need to ensure the unit is awake to see at least minSymbols. (B) + uint32_t wakePeriod_us = max( + (symbolLength_us * (senderPreambleLength + 1) - (sleepPeriod_us - 1000)) / 2, // (A) + symbolLength_us * (minSymbols + 1)); //(B) + RADIOLIB_DEBUG_PRINT(F("Auto wake period: ")); + RADIOLIB_DEBUG_PRINTLN(wakePeriod_us); + + //If our sleep period is shorter than our transition time, just use the standard startReceive + if (sleepPeriod_us < _tcxoDelay_us + 1016) { + return(startReceive()); + } + + return(startReceiveDutyCycle(wakePeriod_us, sleepPeriod_us)); +} + +int16_t SX126x::startReceiveCommon() +{ + // set DIO mapping int16_t state = setDioIrqParams(SX126X_IRQ_RX_DONE | SX126X_IRQ_TIMEOUT | SX126X_IRQ_CRC_ERR | SX126X_IRQ_HEADER_ERR, SX126X_IRQ_RX_DONE); if(state != ERR_NONE) { return(state); @@ -457,13 +541,6 @@ int16_t SX126x::startReceive(uint32_t timeout) { // clear interrupt flags state = clearIrqStatus(); - if(state != ERR_NONE) { - return(state); - } - - // set mode to receive - state = setRx(timeout); - return(state); } @@ -1041,6 +1118,8 @@ int16_t SX126x::setTCXO(float voltage, uint32_t delay) { data[2] = (uint8_t)((delayValue >> 8) & 0xFF); data[3] = (uint8_t)(delayValue & 0xFF); + _tcxoDelay_us = delay; + // enable TCXO control on DIO3 return(SPIwriteCommand(SX126X_CMD_SET_DIO3_AS_TCXO_CTRL, data, 4)); } diff --git a/src/modules/SX126x/SX126x.h b/src/modules/SX126x/SX126x.h index ff25687a..e36ab1b4 100644 --- a/src/modules/SX126x/SX126x.h +++ b/src/modules/SX126x/SX126x.h @@ -499,6 +499,36 @@ class SX126x: public PhysicalLayer { */ int16_t startReceive(uint32_t timeout = SX126X_RX_TIMEOUT_INF); + /*! + \brief Interrupt-driven receive method where the device mostly sleeps and periodically wakes to listen. + + \param rxPeriod_us The duration the receiver will be in Rx mode, in microseconds. + + \param sleepPeriod_us The duration the receiver will not be in Rx mode, in microseconds. + + \returns \ref status_codes + + Note that this function assumes the unit will take 500us to change state. See datasheet [SECTION]. + */ + int16_t startReceiveDutyCycle(uint32_t rxPeriod_us, uint32_t sleepPeriod_us); + + /*! + \brief Calls \ref startReceiveDutyCycle with rxPeriod and sleepPeriod set so the unit shouldn't miss any messages. + + \param senderPreambleLength Expected preamble length of the messages to receive. + If zero, uses the currently configured preamble length. Default zero. + + \param minSymbols Parameters will be chosen to ensure that the unit will catch at least this many symbols of any preamble of the specified length. + Default 3. + + Note that Semtech in the CAD application note state that 2 symbols are fine for CAD, + but in the RX duty cycle note specify that sleep duration should be 8 symbols less than preamble length (corresponding to minSymbols = 4). + Testing suggests that a value of 3 for minSymbols works at high SNR. + + \returns \ref status_codes + */ + int16_t startReceiveDutyCycleAuto(uint16_t senderPreambleLength = 0, uint16_t minSymbols = 3); + /*! \brief Reads data received after calling startReceive method. @@ -747,7 +777,6 @@ class SX126x: public PhysicalLayer { \returns Expected time-on-air in microseconds. */ uint32_t getTimeOnAir(size_t len); - #ifndef RADIOLIB_GODMODE protected: #endif @@ -776,7 +805,8 @@ class SX126x: public PhysicalLayer { uint32_t getPacketStatus(); uint16_t getDeviceErrors(); int16_t clearDeviceErrors(); - + + int16_t startReceiveCommon(); int16_t setFrequencyRaw(float freq); int16_t setOptimalHiPowerPaConfig(int8_t* inOutPower); int16_t setPacketMode(uint8_t mode, uint8_t len); @@ -803,6 +833,8 @@ class SX126x: public PhysicalLayer { float _dataRate; + uint32_t _tcxoDelay_us = 0; + int16_t config(uint8_t modem); // common low-level SPI interface From 825fa90e7f57147026eda68e86d383f932f1479b Mon Sep 17 00:00:00 2001 From: BarryPSmith Date: Wed, 4 Dec 2019 12:41:41 -0800 Subject: [PATCH 2/7] Minor startReceiveDutyCycle changes, as requested. --- src/TypeDef.h | 10 ++++++---- src/modules/SX126x/SX126x.cpp | 17 +++++++++-------- src/modules/SX126x/SX126x.h | 2 +- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/TypeDef.h b/src/TypeDef.h index 01697665..a6e3f245 100644 --- a/src/TypeDef.h +++ b/src/TypeDef.h @@ -308,15 +308,17 @@ /*! \brief The supplied sleep period is invalid. - The specified sleep period is shorter than the time necessary to sleep and wake the hardware, - including TCXO delay + The specified sleep period is shorter than the time necessary to sleep and wake the hardware + including TCXO delay, or longer than the maximum possible */ #define ERR_INVALID_SLEEP_PERIOD -24 /*! - \brief A specified value would cause an integer overflow + \brief The supplied Rx period is invalid. + + The specified Rx period is shorter or longer than the hardware can handle. */ -#define ERR_OVERFLOW -25 +#define ERR_INVALID_RX_PERIOD -25 // RF69-specific status codes diff --git a/src/modules/SX126x/SX126x.cpp b/src/modules/SX126x/SX126x.cpp index 44b9ee43..f57e0f75 100644 --- a/src/modules/SX126x/SX126x.cpp +++ b/src/modules/SX126x/SX126x.cpp @@ -457,20 +457,21 @@ int16_t SX126x::startReceive(uint32_t timeout) { int16_t SX126x::startReceiveDutyCycle(uint32_t rxPeriod_us, uint32_t sleepPeriod_us) { // datasheet claims time to go to sleep is ~500us, same to wake up. - // compensate for that 1ms + tcxo delay: + // compensate for that 1ms + tcxo delay. uint32_t transitionTime = _tcxoDelay_us + 1000; - if (sleepPeriod_us < transitionTime + 16) { - return(ERR_INVALID_SLEEP_PERIOD); - } sleepPeriod_us -= transitionTime; // divide by 15.625 uint32_t rxPeriodRaw = (rxPeriod_us * 8) / 125; uint32_t sleepPeriodRaw = (sleepPeriod_us * 8) / 125; - // 24 bit limit: - if ((rxPeriodRaw & 0xFF000000) || (sleepPeriodRaw & 0xFF000000)) { - return(ERR_OVERFLOW); + // 24 bit limit. Also give an error if the user passes zero values (likely unintentional) + if ((rxPeriodRaw & 0xFF000000) || (rxPeriodRaw == 0)) { + return(ERR_INVALID_RX_PERIOD); + } + // this check of the high byte also catches underflow when we subtracted transitionTime + if ((sleepPeriodRaw & 0xFF000000) || (sleepPeriodRaw == 0)) { + return(ERR_INVALID_SLEEP_PERIOD); } int16_t state = startReceiveCommon(); @@ -478,7 +479,7 @@ int16_t SX126x::startReceiveDutyCycle(uint32_t rxPeriod_us, uint32_t sleepPeriod return(state); } - byte data[6] = { + uint8_t data[6] = { (rxPeriodRaw >> 16) & 0xFF, (rxPeriodRaw >> 8) & 0xFF, rxPeriodRaw & 0xFF, (sleepPeriodRaw >> 16) & 0xFF, (sleepPeriodRaw >> 8) & 0xFF, sleepPeriodRaw & 0xFF }; diff --git a/src/modules/SX126x/SX126x.h b/src/modules/SX126x/SX126x.h index e36ab1b4..0eec2d96 100644 --- a/src/modules/SX126x/SX126x.h +++ b/src/modules/SX126x/SX126x.h @@ -508,7 +508,7 @@ class SX126x: public PhysicalLayer { \returns \ref status_codes - Note that this function assumes the unit will take 500us to change state. See datasheet [SECTION]. + Note that this function assumes the unit will take 500us + TCXO_delay to change state. See datasheet section 13.1.7, version 1.2. */ int16_t startReceiveDutyCycle(uint32_t rxPeriod_us, uint32_t sleepPeriod_us); From be9a4e0d618acec5e11f6388b0fadf05d3f8744c Mon Sep 17 00:00:00 2001 From: jgromes Date: Thu, 5 Dec 2019 14:37:47 +0100 Subject: [PATCH 3/7] Added missing keywords --- keywords.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/keywords.txt b/keywords.txt index 93a463b5..329fcc9d 100644 --- a/keywords.txt +++ b/keywords.txt @@ -248,3 +248,5 @@ ERR_INVALID_MODULATION_PARAMETERS LITERAL1 ERR_SPI_CMD_TIMEOUT LITERAL1 ERR_SPI_CMD_INVALID LITERAL1 ERR_SPI_CMD_FAILED LITERAL1 +ERR_INVALID_SLEEP_PERIOD LITERAL1 +ERR_INVALID_RX_PERIOD LITERAL1 From 8a4cae94113634b0f8197e1a99922c7d5b3f3787 Mon Sep 17 00:00:00 2001 From: jgromes Date: Thu, 5 Dec 2019 14:38:02 +0100 Subject: [PATCH 4/7] Moved new status codes to SX126x-specific errors --- src/TypeDef.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/TypeDef.h b/src/TypeDef.h index a6e3f245..c7ab81d7 100644 --- a/src/TypeDef.h +++ b/src/TypeDef.h @@ -305,21 +305,6 @@ */ #define ERR_INVALID_ENCODING -23 -/*! - \brief The supplied sleep period is invalid. - - The specified sleep period is shorter than the time necessary to sleep and wake the hardware - including TCXO delay, or longer than the maximum possible -*/ -#define ERR_INVALID_SLEEP_PERIOD -24 - -/*! - \brief The supplied Rx period is invalid. - - The specified Rx period is shorter or longer than the hardware can handle. -*/ -#define ERR_INVALID_RX_PERIOD -25 - // RF69-specific status codes /*! @@ -539,6 +524,21 @@ */ #define ERR_SPI_CMD_FAILED -707 +/*! + \brief The supplied sleep period is invalid. + + The specified sleep period is shorter than the time necessary to sleep and wake the hardware + including TCXO delay, or longer than the maximum possible +*/ +#define ERR_INVALID_SLEEP_PERIOD -708 + +/*! + \brief The supplied Rx period is invalid. + + The specified Rx period is shorter or longer than the hardware can handle. +*/ +#define ERR_INVALID_RX_PERIOD -709 + /*! \} */ From f543436647decf38ade3c86b556d55160e4f1a45 Mon Sep 17 00:00:00 2001 From: jgromes Date: Thu, 5 Dec 2019 14:38:44 +0100 Subject: [PATCH 5/7] Minor formatting changes --- src/modules/SX126x/SX126x.cpp | 63 +++++++++++++++++------------------ src/modules/SX126x/SX126x.h | 17 ++++------ 2 files changed, 37 insertions(+), 43 deletions(-) diff --git a/src/modules/SX126x/SX126x.cpp b/src/modules/SX126x/SX126x.cpp index f57e0f75..8f49c29d 100644 --- a/src/modules/SX126x/SX126x.cpp +++ b/src/modules/SX126x/SX126x.cpp @@ -454,41 +454,37 @@ int16_t SX126x::startReceive(uint32_t timeout) { return(state); } -int16_t SX126x::startReceiveDutyCycle(uint32_t rxPeriod_us, uint32_t sleepPeriod_us) -{ - // datasheet claims time to go to sleep is ~500us, same to wake up. - // compensate for that 1ms + tcxo delay. - uint32_t transitionTime = _tcxoDelay_us + 1000; - sleepPeriod_us -= transitionTime; +int16_t SX126x::startReceiveDutyCycle(uint32_t rxPeriod, uint32_t sleepPeriod) { + // datasheet claims time to go to sleep is ~500us, same to wake up, compensate for that with 1 ms + TCXO delay + uint32_t transitionTime = _tcxoDelay + 1000; + sleepPeriod -= transitionTime; // divide by 15.625 - uint32_t rxPeriodRaw = (rxPeriod_us * 8) / 125; - uint32_t sleepPeriodRaw = (sleepPeriod_us * 8) / 125; + uint32_t rxPeriodRaw = (rxPeriod * 8) / 125; + uint32_t sleepPeriodRaw = (sleepPeriod * 8) / 125; - // 24 bit limit. Also give an error if the user passes zero values (likely unintentional) - if ((rxPeriodRaw & 0xFF000000) || (rxPeriodRaw == 0)) { + // check 24 bit limit and zero value (likely not intended) + if((rxPeriodRaw & 0xFF000000) || (rxPeriodRaw == 0)) { return(ERR_INVALID_RX_PERIOD); } + // this check of the high byte also catches underflow when we subtracted transitionTime - if ((sleepPeriodRaw & 0xFF000000) || (sleepPeriodRaw == 0)) { + if((sleepPeriodRaw & 0xFF000000) || (sleepPeriodRaw == 0)) { return(ERR_INVALID_SLEEP_PERIOD); } int16_t state = startReceiveCommon(); - if (state != ERR_NONE) { + if(state != ERR_NONE) { return(state); } - uint8_t data[6] = { - (rxPeriodRaw >> 16) & 0xFF, (rxPeriodRaw >> 8) & 0xFF, rxPeriodRaw & 0xFF, - (sleepPeriodRaw >> 16) & 0xFF, (sleepPeriodRaw >> 8) & 0xFF, sleepPeriodRaw & 0xFF - }; + uint8_t data[6] = {(rxPeriodRaw >> 16) & 0xFF, (rxPeriodRaw >> 8) & 0xFF, rxPeriodRaw & 0xFF, + (sleepPeriodRaw >> 16) & 0xFF, (sleepPeriodRaw >> 8) & 0xFF, sleepPeriodRaw & 0xFF}; return(SPIwriteCommand(SX126X_CMD_SET_RX_DUTY_CYCLE, data, 6)); } -int16_t SX126x::startReceiveDutyCycleAuto(uint16_t senderPreambleLength, uint16_t minSymbols) -{ - if (senderPreambleLength == 0) { +int16_t SX126x::startReceiveDutyCycleAuto(uint16_t senderPreambleLength, uint16_t minSymbols) { + if(senderPreambleLength == 0) { senderPreambleLength = _preambleLength; } @@ -498,37 +494,37 @@ int16_t SX126x::startReceiveDutyCycleAuto(uint16_t senderPreambleLength, uint16_ uint16_t sleepSymbols = senderPreambleLength - 2 * minSymbols; // if we're not to sleep at all, just use the standard startReceive. - if (2 * minSymbols > senderPreambleLength) { + if(2 * minSymbols > senderPreambleLength) { return(startReceive()); } - uint32_t symbolLength_us = ((uint32_t)(10 * 1000) << _sf) / (10 * _bwKhz); - uint32_t sleepPeriod_us = symbolLength_us * sleepSymbols; + uint32_t symbolLength = ((uint32_t)(10 * 1000) << _sf) / (10 * _bwKhz); + uint32_t sleepPeriod = symbolLength * sleepSymbols; RADIOLIB_DEBUG_PRINT(F("Auto sleep period: ")); - RADIOLIB_DEBUG_PRINTLN(sleepPeriod_us); + RADIOLIB_DEBUG_PRINTLN(sleepPeriod); + // when the unit detects a preamble, it starts a timer that will timeout if it doesn't receive a header in time. // the duration is sleepPeriod + 2 * wakePeriod. // The sleepPeriod doesn't take into account shutdown and startup time for the unit (~1ms) // We need to ensure that the timout is longer than senderPreambleLength. // So we must satisfy: wakePeriod > (preamblePeriod - (sleepPeriod - 1000)) / 2. (A) // we also need to ensure the unit is awake to see at least minSymbols. (B) - uint32_t wakePeriod_us = max( - (symbolLength_us * (senderPreambleLength + 1) - (sleepPeriod_us - 1000)) / 2, // (A) - symbolLength_us * (minSymbols + 1)); //(B) + uint32_t wakePeriod = max( + (symbolLength * (senderPreambleLength + 1) - (sleepPeriod - 1000)) / 2, // (A) + symbolLength * (minSymbols + 1)); //(B) RADIOLIB_DEBUG_PRINT(F("Auto wake period: ")); - RADIOLIB_DEBUG_PRINTLN(wakePeriod_us); + RADIOLIB_DEBUG_PRINTLN(wakePeriod); //If our sleep period is shorter than our transition time, just use the standard startReceive - if (sleepPeriod_us < _tcxoDelay_us + 1016) { + if(sleepPeriod < _tcxoDelay + 1016) { return(startReceive()); } - return(startReceiveDutyCycle(wakePeriod_us, sleepPeriod_us)); + return(startReceiveDutyCycle(wakePeriod, sleepPeriod)); } -int16_t SX126x::startReceiveCommon() -{ - // set DIO mapping +int16_t SX126x::startReceiveCommon() { + // set DIO mapping int16_t state = setDioIrqParams(SX126X_IRQ_RX_DONE | SX126X_IRQ_TIMEOUT | SX126X_IRQ_CRC_ERR | SX126X_IRQ_HEADER_ERR, SX126X_IRQ_RX_DONE); if(state != ERR_NONE) { return(state); @@ -542,6 +538,7 @@ int16_t SX126x::startReceiveCommon() // clear interrupt flags state = clearIrqStatus(); + return(state); } @@ -1119,7 +1116,7 @@ int16_t SX126x::setTCXO(float voltage, uint32_t delay) { data[2] = (uint8_t)((delayValue >> 8) & 0xFF); data[3] = (uint8_t)(delayValue & 0xFF); - _tcxoDelay_us = delay; + _tcxoDelay = delay; // enable TCXO control on DIO3 return(SPIwriteCommand(SX126X_CMD_SET_DIO3_AS_TCXO_CTRL, data, 4)); diff --git a/src/modules/SX126x/SX126x.h b/src/modules/SX126x/SX126x.h index 0eec2d96..a643ebc7 100644 --- a/src/modules/SX126x/SX126x.h +++ b/src/modules/SX126x/SX126x.h @@ -501,26 +501,23 @@ class SX126x: public PhysicalLayer { /*! \brief Interrupt-driven receive method where the device mostly sleeps and periodically wakes to listen. + Note that this function assumes the unit will take 500us + TCXO_delay to change state. See datasheet section 13.1.7, version 1.2. - \param rxPeriod_us The duration the receiver will be in Rx mode, in microseconds. + \param rxPeriod The duration the receiver will be in Rx mode, in microseconds. - \param sleepPeriod_us The duration the receiver will not be in Rx mode, in microseconds. + \param sleepPeriod The duration the receiver will not be in Rx mode, in microseconds. \returns \ref status_codes - - Note that this function assumes the unit will take 500us + TCXO_delay to change state. See datasheet section 13.1.7, version 1.2. */ - int16_t startReceiveDutyCycle(uint32_t rxPeriod_us, uint32_t sleepPeriod_us); + int16_t startReceiveDutyCycle(uint32_t rxPeriod, uint32_t sleepPeriod); /*! \brief Calls \ref startReceiveDutyCycle with rxPeriod and sleepPeriod set so the unit shouldn't miss any messages. \param senderPreambleLength Expected preamble length of the messages to receive. - If zero, uses the currently configured preamble length. Default zero. - - \param minSymbols Parameters will be chosen to ensure that the unit will catch at least this many symbols of any preamble of the specified length. - Default 3. + If set to zero, the currently configured preamble length will be used. Defaults to zero. + \param minSymbols Parameters will be chosen to ensure that the unit will catch at least this many symbols of any preamble of the specified length. Defaults to 3. Note that Semtech in the CAD application note state that 2 symbols are fine for CAD, but in the RX duty cycle note specify that sleep duration should be 8 symbols less than preamble length (corresponding to minSymbols = 4). Testing suggests that a value of 3 for minSymbols works at high SNR. @@ -805,7 +802,7 @@ class SX126x: public PhysicalLayer { uint32_t getPacketStatus(); uint16_t getDeviceErrors(); int16_t clearDeviceErrors(); - + int16_t startReceiveCommon(); int16_t setFrequencyRaw(float freq); int16_t setOptimalHiPowerPaConfig(int8_t* inOutPower); From 7631353b4ac1ac38ae050d9d36a3fde2af99f542 Mon Sep 17 00:00:00 2001 From: jgromes Date: Thu, 5 Dec 2019 14:42:00 +0100 Subject: [PATCH 6/7] Fixed incorrect variable name --- src/modules/SX126x/SX126x.cpp | 1 + src/modules/SX126x/SX126x.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/SX126x/SX126x.cpp b/src/modules/SX126x/SX126x.cpp index 8f49c29d..05022b6a 100644 --- a/src/modules/SX126x/SX126x.cpp +++ b/src/modules/SX126x/SX126x.cpp @@ -18,6 +18,7 @@ int16_t SX126x::begin(float bw, uint8_t sf, uint8_t cr, uint16_t syncWord, float _ldro = 0x00; _crcType = SX126X_LORA_CRC_ON; _preambleLength = preambleLength; + _tcxoDelay = 0; // set mode to standby int16_t state = standby(); diff --git a/src/modules/SX126x/SX126x.h b/src/modules/SX126x/SX126x.h index a643ebc7..d132cab8 100644 --- a/src/modules/SX126x/SX126x.h +++ b/src/modules/SX126x/SX126x.h @@ -830,7 +830,7 @@ class SX126x: public PhysicalLayer { float _dataRate; - uint32_t _tcxoDelay_us = 0; + uint32_t _tcxoDelay; int16_t config(uint8_t modem); From df7e517ca50cc7fb43f7fb00bdd14e2c2cdac0fc Mon Sep 17 00:00:00 2001 From: jgromes Date: Thu, 5 Dec 2019 15:22:51 +0100 Subject: [PATCH 7/7] [SX126x] Changed default minSymbols value to 8 --- src/modules/SX126x/SX126x.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/modules/SX126x/SX126x.h b/src/modules/SX126x/SX126x.h index d132cab8..10e1184d 100644 --- a/src/modules/SX126x/SX126x.h +++ b/src/modules/SX126x/SX126x.h @@ -517,14 +517,12 @@ class SX126x: public PhysicalLayer { \param senderPreambleLength Expected preamble length of the messages to receive. If set to zero, the currently configured preamble length will be used. Defaults to zero. - \param minSymbols Parameters will be chosen to ensure that the unit will catch at least this many symbols of any preamble of the specified length. Defaults to 3. - Note that Semtech in the CAD application note state that 2 symbols are fine for CAD, - but in the RX duty cycle note specify that sleep duration should be 8 symbols less than preamble length (corresponding to minSymbols = 4). - Testing suggests that a value of 3 for minSymbols works at high SNR. + \param minSymbols Parameters will be chosen to ensure that the unit will catch at least this many symbols of any preamble of the specified length. Defaults to 8. + According to Semtech, receiver requires 8 symbols to reliably latch a preamble. This makes this method redundant when transmitter preamble length is less than 17 (2*minSymbols + 1). \returns \ref status_codes */ - int16_t startReceiveDutyCycleAuto(uint16_t senderPreambleLength = 0, uint16_t minSymbols = 3); + int16_t startReceiveDutyCycleAuto(uint16_t senderPreambleLength = 0, uint16_t minSymbols = 8); /*! \brief Reads data received after calling startReceive method.