diff --git a/src/modules/SX127x/SX1272.cpp b/src/modules/SX127x/SX1272.cpp index e6219fc2..cc3e8133 100644 --- a/src/modules/SX127x/SX1272.cpp +++ b/src/modules/SX127x/SX1272.cpp @@ -106,15 +106,17 @@ int16_t SX1272::setBandwidth(float bw) { if(state == ERR_NONE) { SX127x::_bw = bw; - // calculate symbol length and set low data rate optimization, if needed - float symbolLength = (float)(uint32_t(1) << SX127x::_sf) / (float)SX127x::_bw; - RADIOLIB_DEBUG_PRINT("Symbol length: "); - RADIOLIB_DEBUG_PRINT(symbolLength); - RADIOLIB_DEBUG_PRINTLN(" ms"); - if(symbolLength >= 16.0) { - state = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_ON, 0, 0); - } else { - state = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_OFF, 0, 0); + // calculate symbol length and set low data rate optimization, if auto-configuration is enabled + if(_ldroAuto) { + float symbolLength = (float)(uint32_t(1) << SX127x::_sf) / (float)SX127x::_bw; + RADIOLIB_DEBUG_PRINT("Symbol length: "); + RADIOLIB_DEBUG_PRINT(symbolLength); + RADIOLIB_DEBUG_PRINTLN(" ms"); + if(symbolLength >= 16.0) { + state = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_ON, 0, 0); + } else { + state = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_OFF, 0, 0); + } } } return(state); @@ -160,15 +162,17 @@ int16_t SX1272::setSpreadingFactor(uint8_t sf) { if(state == ERR_NONE) { SX127x::_sf = sf; - // calculate symbol length and set low data rate optimization, if needed + // calculate symbol length and set low data rate optimization, if auto-configuration is enabled + if(_ldroAuto) { float symbolLength = (float)(uint32_t(1) << SX127x::_sf) / (float)SX127x::_bw; - RADIOLIB_DEBUG_PRINT("Symbol length: "); - RADIOLIB_DEBUG_PRINT(symbolLength); - RADIOLIB_DEBUG_PRINTLN(" ms"); - if(symbolLength >= 16.0) { - state = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_ON, 0, 0); - } else { - state = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_OFF, 0, 0); + RADIOLIB_DEBUG_PRINT("Symbol length: "); + RADIOLIB_DEBUG_PRINT(symbolLength); + RADIOLIB_DEBUG_PRINTLN(" ms"); + if(symbolLength >= 16.0) { + state = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_ON, 0, 0); + } else { + state = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_OFF, 0, 0); + } } } return(state); @@ -372,6 +376,29 @@ int16_t SX1272::setCRC(bool enableCRC) { } } +int16_t SX1272::forceLDRO(bool enable) { + if(getActiveModem() != SX127X_LORA) { + return(ERR_WRONG_MODEM); + } + + _ldroAuto = false; + if(enable) { + return(_mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_ON, 0, 0)); + } else { + return(_mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_OFF, 0, 0)); + } +} + +int16_t SX1272::autoLDRO() { + if(getActiveModem() != SX127X_LORA) { + return(ERR_WRONG_MODEM); + } + + _ldroAuto = true; + return(ERR_NONE); +} + + int16_t SX1272::setBandwidthRaw(uint8_t newBandwidth) { // set mode to standby int16_t state = SX127x::standby(); diff --git a/src/modules/SX127x/SX1272.h b/src/modules/SX127x/SX1272.h index 26a5b84a..78e009d3 100644 --- a/src/modules/SX127x/SX1272.h +++ b/src/modules/SX127x/SX1272.h @@ -253,6 +253,24 @@ class SX1272: public SX127x { */ int16_t setCRC(bool enableCRC); + /*! + \brief Forces LoRa low data rate optimization. Only available in LoRa mode. After calling this method, LDRO will always be set to + the provided value, regardless of symbol length. To re-enable automatic LDRO configuration, call SX1278::autoLDRO() + + \param enable Force LDRO to be always enabled (true) or disabled (false). + + \returns \ref status_codes + */ + int16_t forceLDRO(bool enable); + + /*! + \brief Re-enables automatic LDRO configuration. Only available in LoRa mode. After calling this method, LDRO will be enabled automatically + when symbol length exceeds 16 ms. + + \returns \ref status_codes + */ + int16_t autoLDRO(); + #ifndef RADIOLIB_GODMODE protected: #endif @@ -265,6 +283,8 @@ class SX1272: public SX127x { #ifndef RADIOLIB_GODMODE private: #endif + bool _ldroAuto = true; + bool _ldroEnabled = false; }; diff --git a/src/modules/SX127x/SX1278.cpp b/src/modules/SX127x/SX1278.cpp index 2e0566a0..c4f6ff40 100644 --- a/src/modules/SX127x/SX1278.cpp +++ b/src/modules/SX127x/SX1278.cpp @@ -178,15 +178,17 @@ int16_t SX1278::setBandwidth(float bw) { if(state == ERR_NONE) { SX127x::_bw = bw; - // calculate symbol length and set low data rate optimization, if needed - float symbolLength = (float)(uint32_t(1) << SX127x::_sf) / (float)SX127x::_bw; - RADIOLIB_DEBUG_PRINT("Symbol length: "); - RADIOLIB_DEBUG_PRINT(symbolLength); - RADIOLIB_DEBUG_PRINTLN(" ms"); - if(symbolLength >= 16.0) { - state = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_ON, 3, 3); - } else { - state = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_OFF, 3, 3); + // calculate symbol length and set low data rate optimization, if auto-configuration is enabled + if(_ldroAuto) { + float symbolLength = (float)(uint32_t(1) << SX127x::_sf) / (float)SX127x::_bw; + RADIOLIB_DEBUG_PRINT("Symbol length: "); + RADIOLIB_DEBUG_PRINT(symbolLength); + RADIOLIB_DEBUG_PRINTLN(" ms"); + if(symbolLength >= 16.0) { + state = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_ON, 3, 3); + } else { + state = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_OFF, 3, 3); + } } } return(state); @@ -232,15 +234,17 @@ int16_t SX1278::setSpreadingFactor(uint8_t sf) { if(state == ERR_NONE) { SX127x::_sf = sf; - // calculate symbol length and set low data rate optimization, if needed - float symbolLength = (float)(uint32_t(1) << SX127x::_sf) / (float)SX127x::_bw; - RADIOLIB_DEBUG_PRINT("Symbol length: "); - RADIOLIB_DEBUG_PRINT(symbolLength); - RADIOLIB_DEBUG_PRINTLN(" ms"); - if(symbolLength >= 16.0) { - state = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_ON, 3, 3); - } else { - state = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_OFF, 3, 3); + // calculate symbol length and set low data rate optimization, if auto-configuration is enabled + if(_ldroAuto) { + float symbolLength = (float)(uint32_t(1) << SX127x::_sf) / (float)SX127x::_bw; + RADIOLIB_DEBUG_PRINT("Symbol length: "); + RADIOLIB_DEBUG_PRINT(symbolLength); + RADIOLIB_DEBUG_PRINTLN(" ms"); + if(symbolLength >= 16.0) { + state = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_ON, 3, 3); + } else { + state = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_OFF, 3, 3); + } } } return(state); @@ -450,6 +454,28 @@ int16_t SX1278::setCRC(bool enableCRC) { } } +int16_t SX1278::forceLDRO(bool enable) { + if(getActiveModem() != SX127X_LORA) { + return(ERR_WRONG_MODEM); + } + + _ldroAuto = false; + if(enable) { + return(_mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_ON, 3, 3)); + } else { + return(_mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_OFF, 3, 3)); + } +} + +int16_t SX1278::autoLDRO() { + if(getActiveModem() != SX127X_LORA) { + return(ERR_WRONG_MODEM); + } + + _ldroAuto = true; + return(ERR_NONE); +} + int16_t SX1278::setBandwidthRaw(uint8_t newBandwidth) { // set mode to standby int16_t state = SX127x::standby(); diff --git a/src/modules/SX127x/SX1278.h b/src/modules/SX127x/SX1278.h index b25d7be8..cba8c635 100644 --- a/src/modules/SX127x/SX1278.h +++ b/src/modules/SX127x/SX1278.h @@ -261,6 +261,24 @@ class SX1278: public SX127x { */ int16_t setCRC(bool enableCRC); + /*! + \brief Forces LoRa low data rate optimization. Only available in LoRa mode. After calling this method, LDRO will always be set to + the provided value, regardless of symbol length. To re-enable automatic LDRO configuration, call SX1278::autoLDRO() + + \param enable Force LDRO to be always enabled (true) or disabled (false). + + \returns \ref status_codes + */ + int16_t forceLDRO(bool enable); + + /*! + \brief Re-enables automatic LDRO configuration. Only available in LoRa mode. After calling this method, LDRO will be enabled automatically + when symbol length exceeds 16 ms. + + \returns \ref status_codes + */ + int16_t autoLDRO(); + #ifndef RADIOLIB_GODMODE protected: #endif @@ -273,6 +291,8 @@ class SX1278: public SX127x { #ifndef RADIOLIB_GODMODE private: #endif + bool _ldroAuto = true; + bool _ldroEnabled = false; };