From 43ca08d8ee6fc0ce60943279e71f110e0f6de428 Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 21 Apr 2024 15:24:49 +0200 Subject: [PATCH] [LR11x0] Added LR1120/21 classes --- src/RadioLib.h | 2 + src/modules/LR11x0/LR1110.cpp | 43 ++------------- src/modules/LR11x0/LR1110.h | 16 ------ src/modules/LR11x0/LR1120.cpp | 59 +++++++++++++++++++++ src/modules/LR11x0/LR1120.h | 99 +++++++++++++++++++++++++++++++++++ src/modules/LR11x0/LR1121.cpp | 8 +++ src/modules/LR11x0/LR1121.h | 35 +++++++++++++ src/modules/LR11x0/LR11x0.cpp | 43 +++++++++++++-- src/modules/LR11x0/LR11x0.h | 25 +++++++-- 9 files changed, 268 insertions(+), 62 deletions(-) create mode 100644 src/modules/LR11x0/LR1120.cpp create mode 100644 src/modules/LR11x0/LR1120.h create mode 100644 src/modules/LR11x0/LR1121.cpp create mode 100644 src/modules/LR11x0/LR1121.h diff --git a/src/RadioLib.h b/src/RadioLib.h index 304dae6d..34b1d90e 100644 --- a/src/RadioLib.h +++ b/src/RadioLib.h @@ -69,6 +69,8 @@ #include "modules/CC1101/CC1101.h" #include "modules/LLCC68/LLCC68.h" #include "modules/LR11x0/LR1110.h" +#include "modules/LR11x0/LR1120.h" +#include "modules/LR11x0/LR1121.h" #include "modules/nRF24/nRF24.h" #include "modules/RF69/RF69.h" #include "modules/RFM2x/RFM22.h" diff --git a/src/modules/LR11x0/LR1110.cpp b/src/modules/LR11x0/LR1110.cpp index 729300af..39f00527 100644 --- a/src/modules/LR11x0/LR1110.cpp +++ b/src/modules/LR11x0/LR1110.cpp @@ -7,40 +7,31 @@ LR1110::LR1110(Module* mod) : LR11x0(mod) { int16_t LR1110::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, float tcxoVoltage) { // execute common part - int16_t state = LR11x0::begin(bw, sf, cr, syncWord, preambleLength, tcxoVoltage); + int16_t state = LR11x0::begin(bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage); RADIOLIB_ASSERT(state); // configure publicly accessible settings state = setFrequency(freq); - RADIOLIB_ASSERT(state); - - state = setOutputPower(power); return(state); } int16_t LR1110::beginGFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, float tcxoVoltage) { // execute common part - int16_t state = LR11x0::beginGFSK(br, freqDev, rxBw, preambleLength, tcxoVoltage); + int16_t state = LR11x0::beginGFSK(br, freqDev, rxBw, power, preambleLength, tcxoVoltage); RADIOLIB_ASSERT(state); // configure publicly accessible settings state = setFrequency(freq); - RADIOLIB_ASSERT(state); - - state = setOutputPower(power); return(state); } int16_t LR1110::beginLRFHSS(float freq, uint8_t bw, uint8_t cr, int8_t power, float tcxoVoltage) { // execute common part - int16_t state = LR11x0::beginLRFHSS(bw, cr, tcxoVoltage); + int16_t state = LR11x0::beginLRFHSS(bw, cr, power, tcxoVoltage); RADIOLIB_ASSERT(state); // configure publicly accessible settings state = setFrequency(freq); - RADIOLIB_ASSERT(state); - - state = setOutputPower(power); return(state); } @@ -61,32 +52,4 @@ int16_t LR1110::setFrequency(float freq, bool calibrate, float band) { return(LR11x0::setRfFrequency((uint32_t)(freq*1000000.0f))); } -int16_t LR1110::setOutputPower(int8_t power) { - return(this->setOutputPower(power, false)); -} - -int16_t LR1110::setOutputPower(int8_t power, bool forceHighPower) { - // determine whether to use HP or LP PA and check range accordingly - bool useHp = forceHighPower || (power > 14); - if(useHp) { - RADIOLIB_CHECK_RANGE(power, -9, 22, RADIOLIB_ERR_INVALID_OUTPUT_POWER); - useHp = true; - - } else { - RADIOLIB_CHECK_RANGE(power, -17, 14, RADIOLIB_ERR_INVALID_OUTPUT_POWER); - useHp = false; - - } - - // TODO how and when to configure OCP? - - // update PA config - always use VBAT for high-power PA - int16_t state = LR11x0::setPaConfig((uint8_t)useHp, (uint8_t)useHp, 0x04, 0x07); - RADIOLIB_ASSERT(state); - - // set output power - state = LR11x0::setTxParams(power, RADIOLIB_LR11X0_PA_RAMP_48U); - return(state); -} - #endif \ No newline at end of file diff --git a/src/modules/LR11x0/LR1110.h b/src/modules/LR11x0/LR1110.h index ffcd2e9d..daf54b6f 100644 --- a/src/modules/LR11x0/LR1110.h +++ b/src/modules/LR11x0/LR1110.h @@ -86,22 +86,6 @@ class LR1110: public LR11x0 { \returns \ref status_codes */ int16_t setFrequency(float freq, bool calibrate, float band = 4); - - /*! - \brief Sets output power. Allowed values are in range from -9 to 22 dBm (high-power PA) or -17 to 14 dBm (low-power PA). - \param power Output power to be set in dBm, output PA is determined automatically preferring the low-power PA. - \returns \ref status_codes - */ - int16_t setOutputPower(int8_t power); - - /*! - \brief Sets output power. Allowed values are in range from -9 to 22 dBm (high-power PA) or -17 to 14 dBm (low-power PA). - \param power Output power to be set in dBm. - \param forceHighPower Force using the high-power PA. If set to false, PA will be determined automatically - based on configured output power, preferring the low-power PA. If set to true, only high-power PA will be used. - \returns \ref status_codes - */ - int16_t setOutputPower(int8_t power, bool forceHighPower); #if !RADIOLIB_GODMODE private: diff --git a/src/modules/LR11x0/LR1120.cpp b/src/modules/LR11x0/LR1120.cpp new file mode 100644 index 00000000..b3c0c88e --- /dev/null +++ b/src/modules/LR11x0/LR1120.cpp @@ -0,0 +1,59 @@ +#include "LR1120.h" +#if !RADIOLIB_EXCLUDE_LR11X0 + +LR1120::LR1120(Module* mod) : LR11x0(mod) { + chipType = RADIOLIB_LR11X0_HW_LR1120; +} + +int16_t LR1120::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, float tcxoVoltage) { + // execute common part + int16_t state = LR11x0::begin(bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage); + RADIOLIB_ASSERT(state); + + // configure publicly accessible settings + state = setFrequency(freq); + return(state); +} + +int16_t LR1120::beginGFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, float tcxoVoltage) { + // execute common part + int16_t state = LR11x0::beginGFSK(br, freqDev, rxBw, power, preambleLength, tcxoVoltage); + RADIOLIB_ASSERT(state); + + // configure publicly accessible settings + state = setFrequency(freq); + return(state); +} + +int16_t LR1120::beginLRFHSS(float freq, uint8_t bw, uint8_t cr, int8_t power, float tcxoVoltage) { + // execute common part + int16_t state = LR11x0::beginLRFHSS(bw, cr, power, tcxoVoltage); + RADIOLIB_ASSERT(state); + + // configure publicly accessible settings + state = setFrequency(freq); + return(state); +} + +int16_t LR1120::setFrequency(float freq) { + return(this->setFrequency(freq, true)); +} + +int16_t LR1120::setFrequency(float freq, bool calibrate, float band) { + if(!(((freq >= 150.0) && (freq <= 960.0)) || + ((freq >= 1900.0) && (freq <= 2200.0)) || + ((freq >= 2400.0) && (freq <= 2500.0)))) { + return(RADIOLIB_ERR_INVALID_FREQUENCY); + } + + // calibrate image rejection + if(calibrate) { + int16_t state = LR11x0::calibImage(freq - band, freq + band); + RADIOLIB_ASSERT(state); + } + + // set frequency + return(LR11x0::setRfFrequency((uint32_t)(freq*1000000.0f))); +} + +#endif \ No newline at end of file diff --git a/src/modules/LR11x0/LR1120.h b/src/modules/LR11x0/LR1120.h new file mode 100644 index 00000000..c7360c7a --- /dev/null +++ b/src/modules/LR11x0/LR1120.h @@ -0,0 +1,99 @@ +#if !defined(_RADIOLIB_LR1120_H) +#define _RADIOLIB_LR1120_H + +#include "../../TypeDef.h" + +#if !RADIOLIB_EXCLUDE_LR11X0 + +#include "../../Module.h" +#include "LR11x0.h" + +/*! + \class LR1120 + \brief Derived class for %LR1120 modules. +*/ +class LR1120: public LR11x0 { + public: + /*! + \brief Default constructor. + \param mod Instance of Module that will be used to communicate with the radio. + */ + LR1120(Module* mod); + + // basic methods + + /*! + \brief Initialization method for LoRa modem. + \param freq Carrier frequency in MHz. Defaults to 434.0 MHz. + \param bw LoRa bandwidth in kHz. Defaults to 125.0 kHz. + \param sf LoRa spreading factor. Defaults to 9. + \param cr LoRa coding rate denominator. Defaults to 7 (coding rate 4/7). + \param syncWord 1-byte LoRa sync word. Defaults to RADIOLIB_LR11X0_LORA_SYNC_WORD_PRIVATE (0x12). + \param power Output power in dBm. Defaults to 10 dBm. + \param preambleLength LoRa preamble length in symbols. Defaults to 8 symbols. + \param tcxoVoltage TCXO reference voltage to be set. Defaults to 1.6 V. + If you are seeing -706/-707 error codes, it likely means you are using non-0 value for module with XTAL. + To use XTAL, either set this value to 0, or set LR11x0::XTAL to true. + \returns \ref status_codes + */ + int16_t begin(float freq = 434.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_LR11X0_LORA_SYNC_WORD_PRIVATE, int8_t power = 10, uint16_t preambleLength = 8, float tcxoVoltage = 1.6); + + /*! + \brief Initialization method for FSK modem. + \param freq Carrier frequency in MHz. Defaults to 434.0 MHz. + \param br FSK bit rate in kbps. Defaults to 4.8 kbps. + \param freqDev Frequency deviation from carrier frequency in kHz. Defaults to 5.0 kHz. + \param rxBw Receiver bandwidth in kHz. Defaults to 156.2 kHz. + \param power Output power in dBm. Defaults to 10 dBm. + \param preambleLength FSK preamble length in bits. Defaults to 16 bits. + \param tcxoVoltage TCXO reference voltage to be set. Defaults to 1.6 V. + If you are seeing -706/-707 error codes, it likely means you are using non-0 value for module with XTAL. + To use XTAL, either set this value to 0, or set LR11x0::XTAL to true. + \returns \ref status_codes + */ + int16_t beginGFSK(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 156.2, int8_t power = 10, uint16_t preambleLength = 16, float tcxoVoltage = 1.6); + + /*! + \brief Initialization method for LR-FHSS modem. + \param freq Carrier frequency in MHz. Defaults to 434.0 MHz. + \param bw LR-FHSS bandwidth, one of RADIOLIB_LR11X0_LR_FHSS_BW_* values. Defaults to 722.66 kHz. + \param cr LR-FHSS coding rate, one of RADIOLIB_LR11X0_LR_FHSS_CR_* values. Defaults to 2/3 coding rate. + \param power Output power in dBm. Defaults to 10 dBm. + \param tcxoVoltage TCXO reference voltage to be set. Defaults to 1.6 V. + If you are seeing -706/-707 error codes, it likely means you are using non-0 value for module with XTAL. + To use XTAL, either set this value to 0, or set LR11x0::XTAL to true. + \returns \ref status_codes + */ + int16_t beginLRFHSS(float freq = 434.0, uint8_t bw = RADIOLIB_LR11X0_LR_FHSS_BW_722_66, uint8_t cr = RADIOLIB_LR11X0_LR_FHSS_CR_2_3, int8_t power = 10, float tcxoVoltage = 1.6); + + // configuration methods + + /*! + \brief Sets carrier frequency. Allowed values are in range from 150.0 to 960.0 MHz, + 1900 - 2200 MHz and 2400 - 2500 MHz. Will also perform calibrations. + \param freq Carrier frequency to be set in MHz. + \returns \ref status_codes + */ + int16_t setFrequency(float freq); + + /*! + \brief Sets carrier frequency. Allowed values are in range from 150.0 to 960.0 MHz, + 1900 - 2200 MHz and 2400 - 2500 MHz. Will also perform calibrations. + \param freq Carrier frequency to be set in MHz. + \param calibrate Run image calibration. + \param band Half bandwidth for image calibration. For example, + if carrier is 434 MHz and band is set to 4 MHz, then the image will be calibrate + for band 430 - 438 MHz. Unused if calibrate is set to false, defaults to 4 MHz + \returns \ref status_codes + */ + int16_t setFrequency(float freq, bool calibrate, float band = 4); + +#if !RADIOLIB_GODMODE + private: +#endif + +}; + +#endif + +#endif diff --git a/src/modules/LR11x0/LR1121.cpp b/src/modules/LR11x0/LR1121.cpp new file mode 100644 index 00000000..14e72920 --- /dev/null +++ b/src/modules/LR11x0/LR1121.cpp @@ -0,0 +1,8 @@ +#include "LR1121.h" +#if !RADIOLIB_EXCLUDE_LR11X0 + +LR1121::LR1121(Module* mod) : LR1120(mod) { + chipType = RADIOLIB_LR11X0_HW_LR1121; +} + +#endif \ No newline at end of file diff --git a/src/modules/LR11x0/LR1121.h b/src/modules/LR11x0/LR1121.h new file mode 100644 index 00000000..183e023a --- /dev/null +++ b/src/modules/LR11x0/LR1121.h @@ -0,0 +1,35 @@ +#if !defined(_RADIOLIB_LR1121_H) +#define _RADIOLIB_LR1121_H + +#include "../../TypeDef.h" + +#if !RADIOLIB_EXCLUDE_LR11X0 + +#include "../../Module.h" +#include "LR11x0.h" +#include "LR1120.h" + +/*! + \class LR1121 + \brief Derived class for %LR1121 modules. +*/ +class LR1121: public LR1120 { + public: + /*! + \brief Default constructor. + \param mod Instance of Module that will be used to communicate with the radio. + */ + LR1121(Module* mod); + + // TODO this is where overrides to disable GNSS+WiFi scanning methods on LR1121 + // will be put once those are implemented + +#if !RADIOLIB_GODMODE + private: +#endif + +}; + +#endif + +#endif diff --git a/src/modules/LR11x0/LR11x0.cpp b/src/modules/LR11x0/LR11x0.cpp index 26d54aef..1ddcbf47 100644 --- a/src/modules/LR11x0/LR11x0.cpp +++ b/src/modules/LR11x0/LR11x0.cpp @@ -13,7 +13,7 @@ LR11x0::LR11x0(Module* mod) : PhysicalLayer(RADIOLIB_LR11X0_FREQUENCY_STEP_SIZE, this->XTAL = false; } -int16_t LR11x0::begin(float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16_t preambleLength, float tcxoVoltage) { +int16_t LR11x0::begin(float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, float tcxoVoltage) { // set module properties and perform initial setup int16_t state = this->modSetup(tcxoVoltage, RADIOLIB_LR11X0_PACKET_TYPE_LORA); RADIOLIB_ASSERT(state); @@ -30,6 +30,9 @@ int16_t LR11x0::begin(float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16 state = setSyncWord(syncWord); RADIOLIB_ASSERT(state); + + state = setOutputPower(power); + RADIOLIB_ASSERT(state); state = setPreambleLength(preambleLength); RADIOLIB_ASSERT(state); @@ -44,7 +47,7 @@ int16_t LR11x0::begin(float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16 return(RADIOLIB_ERR_NONE); } -int16_t LR11x0::beginGFSK(float br, float freqDev, float rxBw, uint16_t preambleLength, float tcxoVoltage) { +int16_t LR11x0::beginGFSK(float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, float tcxoVoltage) { // set module properties and perform initial setup int16_t state = this->modSetup(tcxoVoltage, RADIOLIB_LR11X0_PACKET_TYPE_GFSK); RADIOLIB_ASSERT(state); @@ -58,6 +61,9 @@ int16_t LR11x0::beginGFSK(float br, float freqDev, float rxBw, uint16_t preamble state = setRxBandwidth(rxBw); RADIOLIB_ASSERT(state); + + state = setOutputPower(power); + RADIOLIB_ASSERT(state); state = setPreambleLength(preambleLength); RADIOLIB_ASSERT(state); @@ -82,7 +88,7 @@ int16_t LR11x0::beginGFSK(float br, float freqDev, float rxBw, uint16_t preamble return(RADIOLIB_ERR_NONE); } -int16_t LR11x0::beginLRFHSS(uint8_t bw, uint8_t cr, float tcxoVoltage) { +int16_t LR11x0::beginLRFHSS(uint8_t bw, uint8_t cr, int8_t power, float tcxoVoltage) { // set module properties and perform initial setup int16_t state = this->modSetup(tcxoVoltage, RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS); RADIOLIB_ASSERT(state); @@ -91,6 +97,9 @@ int16_t LR11x0::beginLRFHSS(uint8_t bw, uint8_t cr, float tcxoVoltage) { state = setLrFhssConfig(bw, cr); RADIOLIB_ASSERT(state); + state = setOutputPower(power); + RADIOLIB_ASSERT(state); + state = setSyncWord(0x12AD101B); RADIOLIB_ASSERT(state); @@ -579,6 +588,34 @@ int16_t LR11x0::getChannelScanResult() { return(RADIOLIB_ERR_UNKNOWN); } +int16_t LR11x0::setOutputPower(int8_t power) { + return(this->setOutputPower(power, false)); +} + +int16_t LR11x0::setOutputPower(int8_t power, bool forceHighPower) { + // determine whether to use HP or LP PA and check range accordingly + bool useHp = forceHighPower || (power > 14); + if(useHp) { + RADIOLIB_CHECK_RANGE(power, -9, 22, RADIOLIB_ERR_INVALID_OUTPUT_POWER); + useHp = true; + + } else { + RADIOLIB_CHECK_RANGE(power, -17, 14, RADIOLIB_ERR_INVALID_OUTPUT_POWER); + useHp = false; + + } + + // TODO how and when to configure OCP? + + // update PA config - always use VBAT for high-power PA + int16_t state = setPaConfig((uint8_t)useHp, (uint8_t)useHp, 0x04, 0x07); + RADIOLIB_ASSERT(state); + + // set output power + state = setTxParams(power, RADIOLIB_LR11X0_PA_RAMP_48U); + return(state); +} + int16_t LR11x0::setBandwidth(float bw) { // check active modem uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE; diff --git a/src/modules/LR11x0/LR11x0.h b/src/modules/LR11x0/LR11x0.h index 63d70414..2a09a297 100644 --- a/src/modules/LR11x0/LR11x0.h +++ b/src/modules/LR11x0/LR11x0.h @@ -566,31 +566,34 @@ class LR11x0: public PhysicalLayer { \param sf LoRa spreading factor. \param cr LoRa coding rate denominator. \param syncWord 1-byte LoRa sync word. + \param power Output power in dBm. \param preambleLength LoRa preamble length in symbols \param tcxoVoltage TCXO reference voltage to be set. \returns \ref status_codes */ - int16_t begin(float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16_t preambleLength, float tcxoVoltage); + int16_t begin(float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, float tcxoVoltage); /*! \brief Initialization method for FSK modem. \param br FSK bit rate in kbps. \param freqDev Frequency deviation from carrier frequency in kHz. \param rxBw Receiver bandwidth in kHz. + \param power Output power in dBm. \param preambleLength FSK preamble length in bits. \param tcxoVoltage TCXO reference voltage to be set. \returns \ref status_codes */ - int16_t beginGFSK(float br, float freqDev, float rxBw, uint16_t preambleLength, float tcxoVoltage); + int16_t beginGFSK(float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, float tcxoVoltage); /*! \brief Initialization method for LR-FHSS modem. \param bw LR-FHSS bandwidth, one of RADIOLIB_LR11X0_LR_FHSS_BW_* values. \param cr LR-FHSS coding rate, one of RADIOLIB_LR11X0_LR_FHSS_CR_* values. + \param power Output power in dBm. \param tcxoVoltage TCXO reference voltage to be set. \returns \ref status_codes */ - int16_t beginLRFHSS(uint8_t bw, uint8_t cr, float tcxoVoltage); + int16_t beginLRFHSS(uint8_t bw, uint8_t cr, int8_t power, float tcxoVoltage); /*! \brief Reset method. Will reset the chip to the default state using RST pin. @@ -782,6 +785,22 @@ class LR11x0: public PhysicalLayer { int16_t getChannelScanResult() override; // configuration methods + + /*! + \brief Sets output power. Allowed values are in range from -9 to 22 dBm (high-power PA) or -17 to 14 dBm (low-power PA). + \param power Output power to be set in dBm, output PA is determined automatically preferring the low-power PA. + \returns \ref status_codes + */ + int16_t setOutputPower(int8_t power); + + /*! + \brief Sets output power. Allowed values are in range from -9 to 22 dBm (high-power PA) or -17 to 14 dBm (low-power PA). + \param power Output power to be set in dBm. + \param forceHighPower Force using the high-power PA. If set to false, PA will be determined automatically + based on configured output power, preferring the low-power PA. If set to true, only high-power PA will be used. + \returns \ref status_codes + */ + int16_t setOutputPower(int8_t power, bool forceHighPower); /*! \brief Sets LoRa bandwidth. Allowed values are 62.5, 125.0, 250.0 and 500.0 kHz.