diff --git a/src/modules/SX126x/SX1262.cpp b/src/modules/SX126x/SX1262.cpp index 0bbce30d..7400da47 100644 --- a/src/modules/SX126x/SX1262.cpp +++ b/src/modules/SX126x/SX1262.cpp @@ -51,13 +51,46 @@ int16_t SX1262::setFrequency(float freq) { return(setFrequency(freq, true)); } -int16_t SX1262::setFrequency(float freq, bool calibrate, float band) { +int16_t SX1262::setFrequency(float freq, bool calibrate) { RADIOLIB_CHECK_RANGE(freq, 150.0, 960.0, RADIOLIB_ERR_INVALID_FREQUENCY); // calibrate image rejection if(calibrate) { - int16_t state = SX126x::calibrateImage(freq - band, freq + band); + uint8_t data[2] = { 0, 0 }; + + // try to match the frequency ranges + int freqBand = (int)freq; + if((freq >= 902) && (freq <= 928)) { + data[0] = RADIOLIB_SX126X_CAL_IMG_902_MHZ_1; + data[1] = RADIOLIB_SX126X_CAL_IMG_902_MHZ_2; + } else if((freq >= 863) && (freq <= 870)) { + data[0] = RADIOLIB_SX126X_CAL_IMG_863_MHZ_1; + data[1] = RADIOLIB_SX126X_CAL_IMG_863_MHZ_2; + } else if((freq >= 779) && (freq <= 787)) { + data[0] = RADIOLIB_SX126X_CAL_IMG_779_MHZ_1; + data[1] = RADIOLIB_SX126X_CAL_IMG_779_MHZ_2; + } else if((freq >= 470) && (freq <= 510)) { + data[0] = RADIOLIB_SX126X_CAL_IMG_470_MHZ_1; + data[1] = RADIOLIB_SX126X_CAL_IMG_470_MHZ_2; + } else if((freq >= 430) && (freq <= 440)) { + data[0] = RADIOLIB_SX126X_CAL_IMG_430_MHZ_1; + data[1] = RADIOLIB_SX126X_CAL_IMG_430_MHZ_2; + } + + int16_t state; + if(data[0]) { + // matched with predefined ranges, do the calibration + state = SX126x::calibrateImage(data); + + } else { + // if nothing matched, try custom calibration - the may or may not work + RADIOLIB_DEBUG_BASIC_PRINTLN("Failed to match predefined frequency range, trying custom"); + state = SX126x::calibrateImageRejection(freq - 4.0f, freq + 4.0f); + + } + RADIOLIB_ASSERT(state); + } // set frequency diff --git a/src/modules/SX126x/SX1262.h b/src/modules/SX126x/SX1262.h index 61f8facc..f47b1a81 100644 --- a/src/modules/SX126x/SX1262.h +++ b/src/modules/SX126x/SX1262.h @@ -75,12 +75,9 @@ class SX1262: public SX126x { \brief Sets carrier frequency. Allowed values are in range from 150.0 to 960.0 MHz. \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); + int16_t setFrequency(float freq, bool calibrate); /*! \brief Sets output power. Allowed values are in range from -9 to 22 dBm. diff --git a/src/modules/SX126x/SX1268.cpp b/src/modules/SX126x/SX1268.cpp index 7f14e9fa..2b00d550 100644 --- a/src/modules/SX126x/SX1268.cpp +++ b/src/modules/SX126x/SX1268.cpp @@ -52,13 +52,40 @@ int16_t SX1268::setFrequency(float freq) { } /// \todo integers only (all modules - frequency, data rate, bandwidth etc.) -int16_t SX1268::setFrequency(float freq, bool calibrate, float band) { +int16_t SX1268::setFrequency(float freq, bool calibrate) { RADIOLIB_CHECK_RANGE(freq, 410.0, 810.0, RADIOLIB_ERR_INVALID_FREQUENCY); // calibrate image rejection if(calibrate) { - int16_t state = SX126x::calibrateImage(freq - band, freq + band); + uint8_t data[2] = { 0, 0 }; + + // try to match the frequency ranges + int freqBand = (int)freq; + if((freq >= 779) && (freq <= 787)) { + data[0] = RADIOLIB_SX126X_CAL_IMG_779_MHZ_1; + data[1] = RADIOLIB_SX126X_CAL_IMG_779_MHZ_2; + } else if((freq >= 470) && (freq <= 510)) { + data[0] = RADIOLIB_SX126X_CAL_IMG_470_MHZ_1; + data[1] = RADIOLIB_SX126X_CAL_IMG_470_MHZ_2; + } else if((freq >= 430) && (freq <= 440)) { + data[0] = RADIOLIB_SX126X_CAL_IMG_430_MHZ_1; + data[1] = RADIOLIB_SX126X_CAL_IMG_430_MHZ_2; + } + + int16_t state; + if(data[0]) { + // matched with predefined ranges, do the calibration + state = SX126x::calibrateImage(data); + + } else { + // if nothing matched, try custom calibration - the may or may not work + RADIOLIB_DEBUG_BASIC_PRINTLN("Failed to match predefined frequency range, trying custom"); + state = SX126x::calibrateImageRejection(freq - 4.0f, freq + 4.0f); + + } + RADIOLIB_ASSERT(state); + } // set frequency diff --git a/src/modules/SX126x/SX1268.h b/src/modules/SX126x/SX1268.h index f3f61dc8..04edba39 100644 --- a/src/modules/SX126x/SX1268.h +++ b/src/modules/SX126x/SX1268.h @@ -74,12 +74,9 @@ class SX1268: public SX126x { \brief Sets carrier frequency. Allowed values are in range from 150.0 to 960.0 MHz. \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); + int16_t setFrequency(float freq, bool calibrate); /*! \brief Sets output power. Allowed values are in range from -9 to 22 dBm. diff --git a/src/modules/SX126x/SX126x.h b/src/modules/SX126x/SX126x.h index d5cfd4c1..d2b9ecfe 100644 --- a/src/modules/SX126x/SX126x.h +++ b/src/modules/SX126x/SX126x.h @@ -188,6 +188,18 @@ #define RADIOLIB_SX126X_CALIBRATE_RC64K_ON 0b00000001 // 0 0 enabled #define RADIOLIB_SX126X_CALIBRATE_ALL 0b01111111 // 6 0 calibrate all blocks +//RADIOLIB_SX126X_CMD_CALIBRATE_IMAGE +#define RADIOLIB_SX126X_CAL_IMG_430_MHZ_1 0x6B +#define RADIOLIB_SX126X_CAL_IMG_430_MHZ_2 0x6F +#define RADIOLIB_SX126X_CAL_IMG_470_MHZ_1 0x75 +#define RADIOLIB_SX126X_CAL_IMG_470_MHZ_2 0x81 +#define RADIOLIB_SX126X_CAL_IMG_779_MHZ_1 0xC1 +#define RADIOLIB_SX126X_CAL_IMG_779_MHZ_2 0xC5 +#define RADIOLIB_SX126X_CAL_IMG_863_MHZ_1 0xD7 +#define RADIOLIB_SX126X_CAL_IMG_863_MHZ_2 0xDB +#define RADIOLIB_SX126X_CAL_IMG_902_MHZ_1 0xE1 +#define RADIOLIB_SX126X_CAL_IMG_902_MHZ_2 0xE9 + //RADIOLIB_SX126X_CMD_SET_PA_CONFIG #define RADIOLIB_SX126X_PA_CONFIG_HP_MAX 0x07 #define RADIOLIB_SX126X_PA_CONFIG_PA_LUT 0x01 @@ -1102,6 +1114,15 @@ class SX126x: public PhysicalLayer { */ int16_t setPaConfig(uint8_t paDutyCycle, uint8_t deviceSel, uint8_t hpMax = RADIOLIB_SX126X_PA_CONFIG_HP_MAX, uint8_t paLut = RADIOLIB_SX126X_PA_CONFIG_PA_LUT); + /*! + \brief Perform image rejection calibration for the specified frequency band. + WARNING: Use at your own risk! Setting incorrect values may lead to decreased performance + \param freqMin Frequency band lower bound. + \param freqMax Frequency band upper bound. + \returns \ref status_codes + */ + int16_t calibrateImageRejection(float freqMin, float freqMax); + #if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL protected: #endif @@ -1119,7 +1140,7 @@ class SX126x: public PhysicalLayer { int16_t setDioIrqParams(uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask = RADIOLIB_SX126X_IRQ_NONE, uint16_t dio3Mask = RADIOLIB_SX126X_IRQ_NONE); virtual int16_t clearIrqStatus(uint16_t clearIrqParams = RADIOLIB_SX126X_IRQ_ALL); int16_t setRfFrequency(uint32_t frf); - int16_t calibrateImage(float freqMin, float freqMax); + int16_t calibrateImage(uint8_t* data); uint8_t getPacketType(); int16_t setTxParams(uint8_t power, uint8_t rampTime = RADIOLIB_SX126X_PA_RAMP_200U); int16_t setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, uint8_t ldro);