149 lines
No EOL
4.2 KiB
C++
149 lines
No EOL
4.2 KiB
C++
#include "LR1120.h"
|
|
#include <math.h>
|
|
|
|
#if !RADIOLIB_EXCLUDE_LR11X0
|
|
|
|
LR1120::LR1120(Module* mod) : LR11x0(mod) {
|
|
chipType = RADIOLIB_LR11X0_DEVICE_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, preambleLength, tcxoVoltage, freq > 1000.0);
|
|
RADIOLIB_ASSERT(state);
|
|
|
|
// configure publicly accessible settings
|
|
state = setFrequency(freq);
|
|
RADIOLIB_ASSERT(state);
|
|
|
|
state = setOutputPower(power);
|
|
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, preambleLength, tcxoVoltage);
|
|
RADIOLIB_ASSERT(state);
|
|
|
|
// configure publicly accessible settings
|
|
state = setFrequency(freq);
|
|
RADIOLIB_ASSERT(state);
|
|
|
|
state = setOutputPower(power);
|
|
return(state);
|
|
}
|
|
|
|
int16_t LR1120::beginLRFHSS(float freq, uint8_t bw, uint8_t cr, bool narrowGrid, int8_t power, float tcxoVoltage) {
|
|
// execute common part
|
|
int16_t state = LR11x0::beginLRFHSS(bw, cr, narrowGrid, tcxoVoltage);
|
|
RADIOLIB_ASSERT(state);
|
|
|
|
// configure publicly accessible settings
|
|
state = setFrequency(freq);
|
|
RADIOLIB_ASSERT(state);
|
|
|
|
state = setOutputPower(power);
|
|
return(state);
|
|
}
|
|
|
|
int16_t LR1120::setFrequency(float freq) {
|
|
return(this->setFrequency(freq, false));
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
// 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
|
|
state = LR11x0::setRfFrequency((uint32_t)(freq*1000000.0f));
|
|
RADIOLIB_ASSERT(state);
|
|
this->freqMHz = freq;
|
|
this->highFreq = (freq > 1000.0);
|
|
return(RADIOLIB_ERR_NONE);
|
|
}
|
|
|
|
int16_t LR1120::setOutputPower(int8_t power) {
|
|
return(this->setOutputPower(power, false));
|
|
}
|
|
|
|
int16_t LR1120::setOutputPower(int8_t power, bool forceHighPower) {
|
|
// check if power value is configurable
|
|
int16_t state = this->checkOutputPower(power, NULL, forceHighPower);
|
|
RADIOLIB_ASSERT(state);
|
|
|
|
// determine whether to use HP or LP PA and check range accordingly
|
|
uint8_t paSel = 0;
|
|
uint8_t paSupply = 0;
|
|
if(this->highFreq) {
|
|
paSel = 2;
|
|
} else if(forceHighPower || (power > 14)) {
|
|
paSel = 1;
|
|
paSupply = 1;
|
|
}
|
|
|
|
// TODO how and when to configure OCP?
|
|
|
|
// update PA config - always use VBAT for high-power PA
|
|
state = setPaConfig(paSel, paSupply, 0x04, 0x07);
|
|
RADIOLIB_ASSERT(state);
|
|
|
|
// set output power
|
|
state = setTxParams(power, RADIOLIB_LR11X0_PA_RAMP_48U);
|
|
return(state);
|
|
}
|
|
|
|
int16_t LR1120::checkOutputPower(int8_t power, int8_t* clipped) {
|
|
return(checkOutputPower(power, clipped, false));
|
|
}
|
|
|
|
int16_t LR1120::checkOutputPower(int8_t power, int8_t* clipped, bool forceHighPower) {
|
|
if(this->highFreq) {
|
|
if(clipped) {
|
|
*clipped = RADIOLIB_MAX(-18, RADIOLIB_MIN(13, power));
|
|
}
|
|
RADIOLIB_CHECK_RANGE(power, -18, 13, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
|
return(RADIOLIB_ERR_NONE);
|
|
}
|
|
|
|
if(forceHighPower || (power > 14)) {
|
|
if(clipped) {
|
|
*clipped = RADIOLIB_MAX(-9, RADIOLIB_MIN(22, power));
|
|
}
|
|
RADIOLIB_CHECK_RANGE(power, -9, 22, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
|
|
|
} else {
|
|
if(clipped) {
|
|
*clipped = RADIOLIB_MAX(-17, RADIOLIB_MIN(14, power));
|
|
}
|
|
RADIOLIB_CHECK_RANGE(power, -17, 14, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
|
|
|
|
}
|
|
return(RADIOLIB_ERR_NONE);
|
|
}
|
|
|
|
int16_t LR1120::setModem(ModemType_t modem) {
|
|
switch(modem) {
|
|
case(ModemType_t::LoRa): {
|
|
return(this->begin());
|
|
} break;
|
|
case(ModemType_t::FSK): {
|
|
return(this->beginGFSK());
|
|
} break;
|
|
case(ModemType_t::LRFHSS): {
|
|
return(this->beginLRFHSS());
|
|
} break;
|
|
}
|
|
return(RADIOLIB_ERR_WRONG_MODEM);
|
|
}
|
|
|
|
#endif |