[LR11x0] Calibrate image based on frequency change

pull/1302/head
jgromes 2024-10-27 07:39:46 +00:00
rodzic 9f4c15333c
commit 28360f9b0f
6 zmienionych plików z 49 dodań i 23 usunięć

Wyświetl plik

@ -1,4 +1,6 @@
#include "LR1110.h"
#include <math.h>
#if !RADIOLIB_EXCLUDE_LR11X0
LR1110::LR1110(Module* mod) : LR11x0(mod) {
@ -45,20 +47,24 @@ int16_t LR1110::beginLRFHSS(float freq, uint8_t bw, uint8_t cr, bool narrowGrid,
}
int16_t LR1110::setFrequency(float freq) {
return(this->setFrequency(freq, true));
return(this->setFrequency(freq, false));
}
int16_t LR1110::setFrequency(float freq, bool calibrate, float band) {
int16_t LR1110::setFrequency(float freq, bool skipCalibration, float band) {
RADIOLIB_CHECK_RANGE(freq, 150.0, 960.0, RADIOLIB_ERR_INVALID_FREQUENCY);
// calibrate image rejection
if(calibrate) {
int16_t state = LR11x0::calibImage(freq - band, freq + band);
// check if we need to recalibrate image
int16_t state;
if(!skipCalibration && (fabsf(freq - this->freqMHz) >= RADIOLIB_LR11X0_CAL_IMG_FREQ_TRIG_MHZ)) {
state = LR11x0::calibrateImageRejection(freq - band, freq + band);
RADIOLIB_ASSERT(state);
}
// set frequency
return(LR11x0::setRfFrequency((uint32_t)(freq*1000000.0f)));
state = LR11x0::setRfFrequency((uint32_t)(freq*1000000.0f));
RADIOLIB_ASSERT(state);
this->freqMHz = freq;
return(state);
}
int16_t LR1110::setOutputPower(int8_t power) {

Wyświetl plik

@ -71,7 +71,8 @@ class LR1110: public LR11x0 {
/*!
\brief Sets carrier frequency. Allowed values are in range from 150.0 to 960.0 MHz.
Will also perform calibrations.
Will automatically perform image calibration if the frequency changes by
more than RADIOLIB_LR11X0_CAL_IMG_FREQ_TRIG MHz.
\param freq Carrier frequency to be set in MHz.
\returns \ref status_codes
*/
@ -79,14 +80,16 @@ class LR1110: public LR11x0 {
/*!
\brief Sets carrier frequency. Allowed values are in range from 150.0 to 960.0 MHz.
Will automatically perform image calibration if the frequency changes by
more than RADIOLIB_LR11X0_CAL_IMG_FREQ_TRIG MHz.
\param freq Carrier frequency to be set in MHz.
\param calibrate Run image calibration.
\param skipCalibration Skip automated 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 skipCalibration, 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).

Wyświetl plik

@ -1,4 +1,6 @@
#include "LR1120.h"
#include <math.h>
#if !RADIOLIB_EXCLUDE_LR11X0
LR1120::LR1120(Module* mod) : LR11x0(mod) {
@ -45,26 +47,27 @@ int16_t LR1120::beginLRFHSS(float freq, uint8_t bw, uint8_t cr, bool narrowGrid,
}
int16_t LR1120::setFrequency(float freq) {
return(this->setFrequency(freq, true));
return(this->setFrequency(freq, false));
}
int16_t LR1120::setFrequency(float freq, bool calibrate, float band) {
int16_t LR1120::setFrequency(float freq, bool skipCalibration, 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
// check if we need to recalibrate image
int16_t state;
if(calibrate) {
state = LR11x0::calibImage(freq - band, freq + band);
if(!skipCalibration && (fabsf(freq - this->freqMHz) >= RADIOLIB_LR11X0_CAL_IMG_FREQ_TRIG_MHZ)) {
state = LR11x0::calibrateImageRejection(freq - band, freq + band);
RADIOLIB_ASSERT(state);
}
// set frequency
state = LR11x0::setRfFrequency((uint32_t)(freq*1000000.0f));
RADIOLIB_ASSERT(state);
this->freqMHz = freq;
this->highFreq = (freq > 1000.0);
return(RADIOLIB_ERR_NONE);
}

Wyświetl plik

@ -71,7 +71,9 @@ class LR1120: public LR11x0 {
/*!
\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.
1900 - 2200 MHz and 2400 - 2500 MHz.
Will automatically perform image calibration if the frequency changes by
more than RADIOLIB_LR11X0_CAL_IMG_FREQ_TRIG MHz.
NOTE: When switching between sub-GHz and high-frequency bands, after changing the frequency,
setOutputPower() must be called in order to set the correct power amplifier!
\param freq Carrier frequency to be set in MHz.
@ -81,17 +83,19 @@ class LR1120: public LR11x0 {
/*!
\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.
1900 - 2200 MHz and 2400 - 2500 MHz.
Will automatically perform image calibration if the frequency changes by
more than RADIOLIB_LR11X0_CAL_IMG_FREQ_TRIG MHz.
NOTE: When switching between sub-GHz and high-frequency bands, after changing the frequency,
setOutputPower() must be called in order to set the correct power amplifier!
\param freq Carrier frequency to be set in MHz.
\param calibrate Run image calibration.
\param skipCalibration Skip automated 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 skipCalibration, 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).

Wyświetl plik

@ -2400,10 +2400,10 @@ int16_t LR11x0::setRegMode(uint8_t mode) {
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_REG_MODE, true, &mode, 1));
}
int16_t LR11x0::calibImage(float freq1, float freq2) {
int16_t LR11x0::calibrateImageRejection(float freqMin, float freqMax) {
uint8_t buff[2] = {
(uint8_t)floor((freq1 - 1.0f) / 4.0f),
(uint8_t)ceil((freq2 + 1.0f) / 4.0f)
(uint8_t)floor((freqMin - 1.0f) / 4.0f),
(uint8_t)ceil((freqMax + 1.0f) / 4.0f)
};
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_CALIB_IMAGE, true, buff, sizeof(buff)));
}

Wyświetl plik

@ -233,6 +233,7 @@
#define RADIOLIB_LR11X0_CALIBRATE_HF_RC (0x01UL << 1) // 1 1 high frequency RC
#define RADIOLIB_LR11X0_CALIBRATE_LF_RC (0x01UL << 0) // 0 0 low frequency RC
#define RADIOLIB_LR11X0_CALIBRATE_ALL (0x3FUL << 0) // 5 0 everything
#define RADIOLIB_LR11X0_CAL_IMG_FREQ_TRIG_MHZ (20.0)
// RADIOLIB_LR11X0_CMD_SET_REG_MODE
#define RADIOLIB_LR11X0_REG_MODE_LDO (0x00UL << 0) // 0 0 regulator mode: LDO in all modes
@ -1609,6 +1610,15 @@ class LR11x0: public PhysicalLayer {
\returns \ref status_codes
*/
int16_t getModem(ModemType_t* modem) override;
/*!
\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:
@ -1629,7 +1639,6 @@ class LR11x0: public PhysicalLayer {
int16_t clearErrors(void);
int16_t calibrate(uint8_t params);
int16_t setRegMode(uint8_t mode);
int16_t calibImage(float freq1, float freq2);
int16_t setDioAsRfSwitch(uint8_t en, uint8_t stbyCfg, uint8_t rxCfg, uint8_t txCfg, uint8_t txHpCfg, uint8_t txHfCfg, uint8_t gnssCfg, uint8_t wifiCfg);
int16_t setDioIrqParams(uint32_t irq1, uint32_t irq2);
int16_t setDioIrqParams(uint32_t irq);
@ -1790,6 +1799,7 @@ class LR11x0: public PhysicalLayer {
protected:
#endif
uint8_t chipType = 0;
float freqMHz = 0;
#if !RADIOLIB_GODMODE
private: