From 9d3807168f0cfed6b2e7e18644b13ee8c549be38 Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 17 Oct 2021 11:10:52 +0200 Subject: [PATCH] [SX127x] Fixed low-power output on RFO pin (#385) --- src/modules/SX127x/SX1272.cpp | 40 +++++++++++++++----------- src/modules/SX127x/SX1272.h | 6 ++-- src/modules/SX127x/SX1278.cpp | 53 ++++++++++++++++++++++++----------- src/modules/SX127x/SX1278.h | 7 +++-- 4 files changed, 69 insertions(+), 37 deletions(-) diff --git a/src/modules/SX127x/SX1272.cpp b/src/modules/SX127x/SX1272.cpp index cab42675..4dfc6479 100644 --- a/src/modules/SX127x/SX1272.cpp +++ b/src/modules/SX127x/SX1272.cpp @@ -208,32 +208,40 @@ int16_t SX1272::setCodingRate(uint8_t cr) { return(state); } -int16_t SX1272::setOutputPower(int8_t power) { +int16_t SX1272::setOutputPower(int8_t power, bool useRfo = false) { // check allowed power range - if(!(((power >= -1) && (power <= 17)) || (power == 20))) { - return(ERR_INVALID_OUTPUT_POWER); + if(useRfo) { + RADIOLIB_CHECK_RANGE(power, -1, 14, ERR_INVALID_OUTPUT_POWER); + } else { + RADIOLIB_CHECK_RANGE(power, 2, 20, ERR_INVALID_OUTPUT_POWER); } // set mode to standby int16_t state = SX127x::standby(); - // set output power - if(power < 2) { - // power is less than 2 dBm, enable PA0 on RFIO + if(useRfo) { + // RFO output 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 <= 17) { - // power is 2 - 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 == 20) { - // power is 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); + + } else { + if(power <= 17) { + // power is 2 - 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 { + // 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); + + } + } + return(state); } diff --git a/src/modules/SX127x/SX1272.h b/src/modules/SX127x/SX1272.h index 8f333e35..3851960e 100644 --- a/src/modules/SX127x/SX1272.h +++ b/src/modules/SX127x/SX1272.h @@ -198,13 +198,15 @@ class SX1272: public SX127x { int16_t setCodingRate(uint8_t cr); /*! - \brief Sets transmission output power. Allowed values range from 2 to 17 dBm. + \brief Sets transmission output power. Allowed values range from -1 to 14 dBm (RFO pin) or +2 to +20 dBm (PA_BOOST pin). \param power Transmission output power in dBm. + \param useRfo Whether to use the RFO (true) or the PA_BOOST (false) pin for the RF output. Defaults to PA_BOOST. + \returns \ref status_codes */ - int16_t setOutputPower(int8_t power); + int16_t setOutputPower(int8_t power, bool useRfo = false); /*! \brief Sets gain of receiver LNA (low-noise amplifier). Can be set to any integer in range 1 to 6 where 1 is the highest gain. diff --git a/src/modules/SX127x/SX1278.cpp b/src/modules/SX127x/SX1278.cpp index 903855d8..78cfa332 100644 --- a/src/modules/SX127x/SX1278.cpp +++ b/src/modules/SX127x/SX1278.cpp @@ -222,32 +222,51 @@ int16_t SX1278::setCodingRate(uint8_t cr) { return(state); } -int16_t SX1278::setOutputPower(int8_t power) { +int16_t SX1278::setOutputPower(int8_t power, bool useRfo = false) { // check allowed power range - if(!(((power >= -3) && (power <= 17)) || (power == 20))) { - return(ERR_INVALID_OUTPUT_POWER); + if(useRfo) { + // RFO output + RADIOLIB_CHECK_RANGE(power, -3, 15, ERR_INVALID_OUTPUT_POWER); + } else { + // PA_BOOST output, check high-power operation + if(power != 20) { + RADIOLIB_CHECK_RANGE(power, 2, 17, ERR_INVALID_OUTPUT_POWER); + } } // set mode to standby int16_t state = SX127x::standby(); - // set output power - if(power < 2) { - // power is less than 2 dBm, enable PA on RFO + if(useRfo) { + uint8_t paCfg = 0; + if(power < 0) { + // low power mode RFO output + paCfg = SX1278_LOW_POWER | (power + 3); + } else { + // high power mode RFO output + paCfg = SX1278_MAX_POWER | power; + } + 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(SX127X_REG_PA_CONFIG, paCfg, 6, 0); state |= _mod->SPIsetRegValue(SX1278_REG_PA_DAC, SX127X_PA_BOOST_OFF, 2, 0); - } else if(power <= 17) { - // power is 2 - 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 == 20) { - // power is 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 - 5), 6, 0); - state |= _mod->SPIsetRegValue(SX1278_REG_PA_DAC, SX127X_PA_BOOST_ON, 2, 0); + + } else { + if(power != 20) { + // power is 2 - 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 { + // power is 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, SX1278_MAX_POWER | 0x0F, 6, 0); + state |= _mod->SPIsetRegValue(SX1278_REG_PA_DAC, SX127X_PA_BOOST_ON, 2, 0); + + } } + return(state); } diff --git a/src/modules/SX127x/SX1278.h b/src/modules/SX127x/SX1278.h index d22145cf..7e69a398 100644 --- a/src/modules/SX127x/SX1278.h +++ b/src/modules/SX127x/SX1278.h @@ -206,13 +206,16 @@ class SX1278: public SX127x { int16_t setCodingRate(uint8_t cr); /*! - \brief Sets transmission output power. Allowed values range from 2 to 17 dBm. + \brief Sets transmission output power. Allowed values range from -3 to 15 dBm (RFO pin) or +2 to +17 dBm (PA_BOOST pin). + High power +20 dBm operation is also supported, on the PA_BOOST pin. \param power Transmission output power in dBm. + \param useRfo Whether to use the RFO (true) or the PA_BOOST (false) pin for the RF output. Defaults to PA_BOOST. + \returns \ref status_codes */ - int16_t setOutputPower(int8_t power); + int16_t setOutputPower(int8_t power, bool useRfo = false); /*! \brief Sets gain of receiver LNA (low-noise amplifier). Can be set to any integer in range 1 to 6 where 1 is the highest gain.