2019-05-10 13:47:10 +00:00
|
|
|
#include "SX1262.h"
|
|
|
|
|
|
|
|
SX1262::SX1262(Module* mod) : SX126x(mod) {
|
2019-05-12 17:24:07 +00:00
|
|
|
|
2019-05-10 13:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int16_t SX1262::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint16_t syncWord, int8_t power, float currentLimit, uint16_t preambleLength) {
|
|
|
|
// execute common part
|
2019-06-22 14:37:57 +00:00
|
|
|
int16_t state = SX126x::begin(bw, sf, cr, syncWord, currentLimit, preambleLength);
|
2019-05-10 13:47:10 +00:00
|
|
|
if(state != ERR_NONE) {
|
|
|
|
return(state);
|
|
|
|
}
|
2019-05-12 17:24:07 +00:00
|
|
|
|
2019-05-10 13:47:10 +00:00
|
|
|
// configure publicly accessible settings
|
2019-05-15 15:20:20 +00:00
|
|
|
state = setFrequency(freq);
|
|
|
|
if(state != ERR_NONE) {
|
|
|
|
return(state);
|
|
|
|
}
|
|
|
|
|
|
|
|
state = setOutputPower(power);
|
|
|
|
if(state != ERR_NONE) {
|
|
|
|
return(state);
|
|
|
|
}
|
|
|
|
|
|
|
|
return(state);
|
|
|
|
}
|
|
|
|
|
|
|
|
int16_t SX1262::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, float currentLimit, uint16_t preambleLength, float dataShaping) {
|
|
|
|
// execute common part
|
2019-06-22 14:37:57 +00:00
|
|
|
int16_t state = SX126x::beginFSK(br, freqDev, rxBw, currentLimit, preambleLength, dataShaping);
|
2019-05-15 15:20:20 +00:00
|
|
|
if(state != ERR_NONE) {
|
|
|
|
return(state);
|
|
|
|
}
|
|
|
|
|
|
|
|
// configure publicly accessible settings
|
2019-05-10 13:47:10 +00:00
|
|
|
state = setFrequency(freq);
|
|
|
|
if(state != ERR_NONE) {
|
|
|
|
return(state);
|
|
|
|
}
|
2019-05-12 17:24:07 +00:00
|
|
|
|
2019-05-10 13:47:10 +00:00
|
|
|
state = setOutputPower(power);
|
|
|
|
if(state != ERR_NONE) {
|
|
|
|
return(state);
|
|
|
|
}
|
2019-05-12 17:24:07 +00:00
|
|
|
|
2019-05-10 13:47:10 +00:00
|
|
|
return(state);
|
|
|
|
}
|
|
|
|
|
2019-06-03 08:41:39 +00:00
|
|
|
int16_t SX1262::setFrequency(float freq, bool calibrate) {
|
2019-05-10 13:47:10 +00:00
|
|
|
// check frequency range
|
|
|
|
if((freq < 150.0) || (freq > 960.0)) {
|
|
|
|
return(ERR_INVALID_FREQUENCY);
|
|
|
|
}
|
2019-05-12 17:24:07 +00:00
|
|
|
|
2019-06-03 08:41:39 +00:00
|
|
|
int16_t state = ERR_NONE;
|
|
|
|
|
|
|
|
// calibrate image
|
|
|
|
if(calibrate) {
|
|
|
|
uint8_t data[2];
|
|
|
|
if(freq > 900.0) {
|
|
|
|
data[0] = SX126X_CAL_IMG_902_MHZ_1;
|
|
|
|
data[1] = SX126X_CAL_IMG_902_MHZ_2;
|
|
|
|
} else if(freq > 850.0) {
|
|
|
|
data[0] = SX126X_CAL_IMG_863_MHZ_1;
|
|
|
|
data[1] = SX126X_CAL_IMG_863_MHZ_2;
|
|
|
|
} else if(freq > 770.0) {
|
|
|
|
data[0] = SX126X_CAL_IMG_779_MHZ_1;
|
|
|
|
data[1] = SX126X_CAL_IMG_779_MHZ_2;
|
|
|
|
} else if(freq > 460.0) {
|
|
|
|
data[0] = SX126X_CAL_IMG_470_MHZ_1;
|
|
|
|
data[1] = SX126X_CAL_IMG_470_MHZ_2;
|
|
|
|
} else {
|
|
|
|
data[0] = SX126X_CAL_IMG_430_MHZ_1;
|
|
|
|
data[1] = SX126X_CAL_IMG_430_MHZ_2;
|
|
|
|
}
|
|
|
|
state = SX126x::calibrateImage(data);
|
|
|
|
if(state != ERR_NONE) {
|
|
|
|
return(state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-10 13:47:10 +00:00
|
|
|
// set frequency
|
|
|
|
return(SX126x::setFrequencyRaw(freq));
|
|
|
|
}
|
|
|
|
|
|
|
|
int16_t SX1262::setOutputPower(int8_t power) {
|
|
|
|
// check allowed power range
|
2019-11-11 19:26:41 +00:00
|
|
|
if (!((power >= -17) && (power <= 22))) {
|
2019-05-10 13:47:10 +00:00
|
|
|
return(ERR_INVALID_OUTPUT_POWER);
|
|
|
|
}
|
2019-05-12 17:24:07 +00:00
|
|
|
|
2019-06-22 14:37:57 +00:00
|
|
|
// get current OCP configuration
|
|
|
|
uint8_t ocp = 0;
|
|
|
|
int16_t state = readRegister(SX126X_REG_OCP_CONFIGURATION, &ocp, 1);
|
2019-11-11 19:26:41 +00:00
|
|
|
if (state != ERR_NONE) {
|
2019-06-22 14:37:57 +00:00
|
|
|
return(state);
|
|
|
|
}
|
|
|
|
|
2019-11-11 19:26:41 +00:00
|
|
|
int8_t scaledPower;
|
2019-11-08 16:20:52 +00:00
|
|
|
// set PA config for optimal consumption as described in section 13-21 of the datasheet:
|
2019-11-11 19:26:41 +00:00
|
|
|
// the final column of Table 13-21 suggests that the value passed in SetTxParams
|
|
|
|
// is actually scaled depending on the parameters of setPaConfig.
|
|
|
|
// Testing confirms this is approximately right
|
2019-11-08 16:20:52 +00:00
|
|
|
if (power >= 21) {
|
|
|
|
state = SX126x::setPaConfig(0x04, SX126X_PA_CONFIG_SX1262, SX126X_PA_CONFIG_HP_MAX/*0x07*/);
|
2019-11-11 19:26:41 +00:00
|
|
|
scaledPower = power;
|
|
|
|
}
|
|
|
|
else if (power >= 18) {
|
2019-11-08 16:20:52 +00:00
|
|
|
state = SX126x::setPaConfig(0x03, SX126X_PA_CONFIG_SX1262, 0x05);
|
2019-11-11 19:26:41 +00:00
|
|
|
scaledPower = power + 2;
|
|
|
|
}
|
|
|
|
else if (power >= 15) {
|
2019-11-08 16:20:52 +00:00
|
|
|
state = SX126x::setPaConfig(0x02, SX126X_PA_CONFIG_SX1262, 0x03);
|
2019-11-11 19:26:41 +00:00
|
|
|
scaledPower = power + 5;
|
|
|
|
}
|
|
|
|
else {
|
2019-11-08 16:20:52 +00:00
|
|
|
state = SX126x::setPaConfig(0x02, SX126X_PA_CONFIG_SX1262, 0x02);
|
2019-11-11 19:26:41 +00:00
|
|
|
scaledPower = power + 8;
|
2019-05-10 13:47:10 +00:00
|
|
|
}
|
2019-11-08 16:20:52 +00:00
|
|
|
if (state != ERR_NONE) {
|
|
|
|
return(state);
|
|
|
|
}
|
|
|
|
// TODO investigate if better power efficiency can be achieved using undocumented even lower settings
|
|
|
|
|
|
|
|
// note that we set SX126X_PA_CONFIG_SX1262 for all power levels - setting SX126X_PA_CONFIG_SX1261 causes no output (on the nameless module I have).
|
2019-05-12 17:24:07 +00:00
|
|
|
|
2019-05-10 13:47:10 +00:00
|
|
|
// set output power
|
|
|
|
// TODO power ramp time configuration
|
2019-11-11 19:26:41 +00:00
|
|
|
state = SX126x::setTxParams(scaledPower);
|
2019-11-08 16:20:52 +00:00
|
|
|
if (state != ERR_NONE) {
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
2019-06-22 14:37:57 +00:00
|
|
|
|
|
|
|
// restore OCP configuration
|
|
|
|
return(writeRegister(SX126X_REG_OCP_CONFIGURATION, &ocp, 1));
|
2019-05-10 13:47:10 +00:00
|
|
|
}
|