diff --git a/src/modules/SX1272.cpp b/src/modules/SX1272.cpp index 1b9d727e..5bd205ee 100644 --- a/src/modules/SX1272.cpp +++ b/src/modules/SX1272.cpp @@ -6,7 +6,7 @@ SX1272::SX1272(Module* mod) : SX127x(mod) { uint8_t SX1272::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t addrEeprom) { // execute common part - uint8_t state = SX127x::begin(syncWord, power, addrEeprom); + uint8_t state = SX127x::begin(syncWord, addrEeprom); if(state != ERR_NONE) { return(state); } @@ -38,6 +38,11 @@ uint8_t SX1272::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync return(state); } + state = setOutputPower(power); + if(state != ERR_NONE) { + return(state); + } + return(ERR_NONE); } @@ -143,6 +148,38 @@ uint8_t SX1272::setCodingRate(uint8_t cr) { return(state); } +uint8_t SX1272::setOutputPower(int8_t power) { + if((power < -1) || (power > 20)) { + return(ERR_INVALID_OUTPUT_POWER); + } + + SX127x::standby(); + + uint8_t state; + if(power < 15) { + // power is less than 15 dBm, enable PA0 on RFIO + state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_RFO, 7, 7); + state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, power + 1, 3, 0); + state |= _mod->SPIsetRegValue(SX1272_REG_PA_DAC, SX127X_PA_BOOST_OFF, 2, 0); + } else if((power >= 15) && (power < 18)) { + // power is 15 - 17 dBm, enable PA1 + PA2 on PA_BOOST + state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_BOOST, 7, 7); + state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, power - 2, 3, 0); + state |= _mod->SPIsetRegValue(SX1272_REG_PA_DAC, SX127X_PA_BOOST_OFF, 2, 0); + } else if(power >= 18) { + // power is 18 - 20 dBm, enable PA1 + PA2 on PA_BOOST and enable high power control + state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_BOOST, 7, 7); + state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, power - 5, 3, 0); + state |= _mod->SPIsetRegValue(SX1272_REG_PA_DAC, SX127X_PA_BOOST_ON, 2, 0); + } + + if(state == ERR_NONE) { + _power = power; + } + + return(state); +} + uint8_t SX1272::setBandwidthRaw(uint8_t newBandwidth) { // set mode to standby SX127x::standby(); @@ -187,12 +224,6 @@ uint8_t SX1272::config() { return(state); } - // output power configuration - state = _mod->SPIsetRegValue(SX1272_REG_PA_DAC, SX127X_PA_BOOST_ON, 2, 0); - if(state != ERR_NONE) { - return(state); - } - // enable LNA gain setting by register state = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX1272_AGC_AUTO_OFF, 2, 2); if(state != ERR_NONE) { diff --git a/src/modules/SX1272.h b/src/modules/SX1272.h index fc10ec85..e8ac2984 100644 --- a/src/modules/SX1272.h +++ b/src/modules/SX1272.h @@ -53,6 +53,7 @@ class SX1272: public SX127x { uint8_t setBandwidth(float bw); uint8_t setSpreadingFactor(uint8_t sf); uint8_t setCodingRate(uint8_t cr); + uint8_t setOutputPower(int8_t power); protected: uint8_t setBandwidthRaw(uint8_t newBandwidth); diff --git a/src/modules/SX1278.cpp b/src/modules/SX1278.cpp index 64d7a7f0..659b5930 100644 --- a/src/modules/SX1278.cpp +++ b/src/modules/SX1278.cpp @@ -6,7 +6,7 @@ SX1278::SX1278(Module* mod) : SX127x(mod) { uint8_t SX1278::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t addrEeprom) { // execute common part - uint8_t state = SX127x::begin(syncWord, power, addrEeprom); + uint8_t state = SX127x::begin(syncWord, addrEeprom); if(state != ERR_NONE) { return(state); } @@ -38,6 +38,11 @@ uint8_t SX1278::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync return(state); } + state = setOutputPower(power); + if(state != ERR_NONE) { + return(state); + } + return(ERR_NONE); } @@ -155,6 +160,38 @@ uint8_t SX1278::setCodingRate(uint8_t cr) { return(state); } +uint8_t SX1278::setOutputPower(int8_t power) { + if((power < -3) || (power > 20)) { + return(ERR_INVALID_OUTPUT_POWER); + } + + SX127x::standby(); + + uint8_t state; + if(power < 13) { + // power is less than 12 dBm, enable PA on RFO + state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_RFO, 7, 7); + state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX1278_LOW_POWER | (power + 3), 6, 0); + state |= _mod->SPIsetRegValue(SX1278_REG_PA_DAC, SX127X_PA_BOOST_OFF, 2, 0); + } else if((power >= 13) && (power < 18)) { + // power is 13 - 17 dBm, enable PA1 + PA2 on PA_BOOST + state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_BOOST, 7, 7); + state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX1278_MAX_POWER | (power + 2), 6, 0); + state |= _mod->SPIsetRegValue(SX1278_REG_PA_DAC, SX127X_PA_BOOST_OFF, 2, 0); + } else if(power >= 18) { + // power is 18 - 20 dBm, enable PA1 + PA2 on PA_BOOST and enable high power mode + state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_BOOST, 7, 7); + state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX1278_MAX_POWER | (power + 2), 6, 0); + state |= _mod->SPIsetRegValue(SX1278_REG_PA_DAC, SX127X_PA_BOOST_ON, 2, 0); + } + + if(state == ERR_NONE) { + _power = power; + } + + return(state); +} + uint8_t SX1278::setBandwidthRaw(uint8_t newBandwidth) { // set mode to standby SX127x::standby(); @@ -199,13 +236,6 @@ uint8_t SX1278::config() { return(state); } - // output power configuration - state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX1278_MAX_POWER, 6, 4); - state |= _mod->SPIsetRegValue(SX1278_REG_PA_DAC, SX127X_PA_BOOST_ON, 2, 0); - if(state != ERR_NONE) { - return(state); - } - // enable LNA gain setting by register state = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_AGC_AUTO_OFF, 2, 2); if(state != ERR_NONE) { diff --git a/src/modules/SX1278.h b/src/modules/SX1278.h index 3a358a0b..f20de073 100644 --- a/src/modules/SX1278.h +++ b/src/modules/SX1278.h @@ -28,6 +28,7 @@ //SX1278_REG_PA_CONFIG #define SX1278_MAX_POWER 0b01110000 // 6 4 max power: P_max = 10.8 + 0.6*MAX_POWER [dBm]; P_max(MAX_POWER = 0b111) = 15 dBm +#define SX1278_LOW_POWER 0b00100000 // 6 4 //SX1278_REG_LNA #define SX1278_LNA_BOOST_LF_OFF 0b00000000 // 4 3 default LNA current @@ -70,6 +71,7 @@ class SX1278: public SX127x { uint8_t setBandwidth(float bw); uint8_t setSpreadingFactor(uint8_t sf); uint8_t setCodingRate(uint8_t cr); + uint8_t setOutputPower(int8_t power); protected: uint8_t setBandwidthRaw(uint8_t newBandwidth); diff --git a/src/modules/SX127x.cpp b/src/modules/SX127x.cpp index c66d1fa5..6612ddb1 100644 --- a/src/modules/SX127x.cpp +++ b/src/modules/SX127x.cpp @@ -4,7 +4,7 @@ SX127x::SX127x(Module* mod) { _mod = mod; } -uint8_t SX127x::begin(uint8_t syncWord, int8_t power, uint16_t addrEeprom) { +uint8_t SX127x::begin(uint8_t syncWord, uint16_t addrEeprom) { // ESP32-only: initialize EEPROM #ifdef ESP32 if(!EEPROM.begin(9)) { @@ -84,13 +84,6 @@ uint8_t SX127x::begin(uint8_t syncWord, int8_t power, uint16_t addrEeprom) { return(state); } - // set output power - state = SX127x::setOutputPower(power); - if(state != ERR_NONE) { - return(state); - } - - return(ERR_NONE); } @@ -110,7 +103,7 @@ uint8_t SX127x::transmit(Packet& pack) { float ih = (float)_mod->SPIgetRegValue(SX127X_REG_MODEM_CONFIG_1, 0, 0); float crc = (float)(_mod->SPIgetRegValue(SX127X_REG_MODEM_CONFIG_2, 2, 2) >> 2); float n_pre = (float)_mod->SPIgetRegValue(SX127X_REG_PREAMBLE_LSB); - float n_pay = 8.0 + max(ceil((8.0 * (float)pack.length - 4.0 * (float)_sf + 28.0 + 16.0 * crc - 20.0 * ih)/(4.0 * (float)_sf - 8.0 * de)) * (float)_cr, 0); + float n_pay = 8.0 + max(ceil((8.0 * (float)pack.length - 4.0 * (float)_sf + 28.0 + 16.0 * crc - 20.0 * ih)/(4.0 * (float)_sf - 8.0 * de)) * (float)_cr, 0.0); uint32_t timeout = ceil(symbolLength * (n_pre + n_pay + 4.25) * 1000.0); // set mode to standby @@ -249,21 +242,6 @@ uint8_t SX127x::setSyncWord(uint8_t syncWord) { return(state); } -uint8_t SX127x::setOutputPower(int8_t power) { - setMode(SX127X_STANDBY); - - if((power < 2) || (power > 17)) { - return(ERR_INVALID_OUTPUT_POWER); - } - - uint8_t state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, power - 2, 3, 0); - if(state == ERR_NONE) { - _power = power; - } - - return(state); -} - uint8_t SX127x::setFrequencyRaw(float newFreq) { // set mode to standby setMode(SX127X_STANDBY); @@ -293,9 +271,8 @@ uint8_t SX127x::config() { return(state); } - // output power configuration - state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_BOOST | SX127X_OUTPUT_POWER); - state |= _mod->SPIsetRegValue(SX127X_REG_OCP, SX127X_OCP_ON | SX127X_OCP_TRIM, 5, 0); + // set overcurrent protection and LNA gain + state = _mod->SPIsetRegValue(SX127X_REG_OCP, SX127X_OCP_ON | SX127X_OCP_TRIM, 5, 0); state |= _mod->SPIsetRegValue(SX127X_REG_LNA, SX127X_LNA_GAIN_1 | SX127X_LNA_BOOST_ON); if(state != ERR_NONE) { return(state); diff --git a/src/modules/SX127x.h b/src/modules/SX127x.h index 5120215c..7bbcf758 100644 --- a/src/modules/SX127x.h +++ b/src/modules/SX127x.h @@ -173,7 +173,7 @@ class SX127x { int8_t lastPacketRSSI; float lastPacketSNR; - uint8_t begin(uint8_t syncWord, int8_t power, uint16_t addrEeprom); + uint8_t begin(uint8_t syncWord, uint16_t addrEeprom); uint8_t transmit(Packet& pack); uint8_t receive(Packet& pack); uint8_t scanChannel(); @@ -182,7 +182,6 @@ class SX127x { uint8_t standby(); uint8_t setSyncWord(uint8_t syncWord); - uint8_t setOutputPower(int8_t power); protected: Module* _mod;