[SX126x] Added option to specify custom CAD parameters

This commit is contained in:
jgromes 2022-11-18 13:39:51 +01:00
parent e02b3f2ce0
commit f942ccaec7
2 changed files with 56 additions and 49 deletions

View file

@ -321,9 +321,9 @@ int16_t SX126x::receiveDirect() {
return(RADIOLIB_ERR_UNKNOWN);
}
int16_t SX126x::scanChannel() {
int16_t SX126x::scanChannel(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) {
// set mode to CAD
int state = startChannelScan();
int state = startChannelScan(symbolNum, detPeak, detMin);
RADIOLIB_ASSERT(state);
// wait for channel activity detected or timeout
@ -589,7 +589,7 @@ int16_t SX126x::readData(uint8_t* data, size_t len) {
return(state);
}
int16_t SX126x::startChannelScan() {
int16_t SX126x::startChannelScan(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) {
// check active modem
if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_LORA) {
return(RADIOLIB_ERR_WRONG_MODEM);
@ -611,7 +611,7 @@ int16_t SX126x::startChannelScan() {
RADIOLIB_ASSERT(state);
// set mode to CAD
state = setCad();
state = setCad(symbolNum, detPeak, detMin);
return(state);
}
@ -1327,52 +1327,45 @@ int16_t SX126x::setRx(uint32_t timeout) {
return(SPIwriteCommand(RADIOLIB_SX126X_CMD_SET_RX, data, 3, true, false));
}
int16_t SX126x::setCad() {
// Configure CAD parameters for assigned SF as per Semtech AN1200.48, Rev 2.1, Page 50, November 2019.
// Parameters are configured in RADIOLIB_SX126X_CMD_SET_CAD_PARAMS register.
int16_t SX126x::setCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) {
// default CAD parameters for assigned SF as per Semtech AN1200.48, Rev 2.1, Page 50
uint8_t detPeakValues[8] = { 22, 22, 22, 22, 23, 24, 25, 28};
uint8_t symbolNumValues[8] = { RADIOLIB_SX126X_CAD_ON_2_SYMB,
RADIOLIB_SX126X_CAD_ON_2_SYMB,
RADIOLIB_SX126X_CAD_ON_2_SYMB,
RADIOLIB_SX126X_CAD_ON_2_SYMB,
RADIOLIB_SX126X_CAD_ON_4_SYMB,
RADIOLIB_SX126X_CAD_ON_4_SYMB,
RADIOLIB_SX126X_CAD_ON_4_SYMB,
RADIOLIB_SX126X_CAD_ON_4_SYMB };
// build the packet
uint8_t data[7];
switch(_sf)
{
case 7:
data[0] = RADIOLIB_SX126X_CAD_ON_2_SYMB;
data[1] = 21;
break;
case 8:
data[0] = RADIOLIB_SX126X_CAD_ON_2_SYMB;
data[1] = 22;
break;
case 9:
data[0] = RADIOLIB_SX126X_CAD_ON_4_SYMB;
data[1] = 22;
break;
case 10:
data[0] = RADIOLIB_SX126X_CAD_ON_4_SYMB;
data[1] = 24;
break;
case 11:
data[0] = RADIOLIB_SX126X_CAD_ON_4_SYMB;
data[1] = 25;
break;
default:
data[0] = RADIOLIB_SX126X_CAD_ON_4_SYMB;
data[1] = 28;
break;
}
data[2] = 10;
data[0] = symbolNumValues[_sf - 5];
data[1] = detPeakValues[_sf - 5];
data[2] = RADIOLIB_SX126X_CAD_PARAM_DET_MIN;
data[3] = RADIOLIB_SX126X_CAD_GOTO_STDBY;
data[4] = 0x00;
data[5] = 0x00;
data[6] = 0x00;
SPIwriteCommand(RADIOLIB_SX126X_CMD_SET_CAD_PARAMS, data, 7);
// set user-provided values
if(symbolNum != RADIOLIB_SX126X_CAD_PARAM_DEFAULT) {
data[0] = symbolNum;
}
if(detPeak != RADIOLIB_SX126X_CAD_PARAM_DEFAULT) {
data[1] = detPeak;
}
if(detMin != RADIOLIB_SX126X_CAD_PARAM_DEFAULT) {
data[2] = detMin;
}
// configure paramaters
int16_t state = SPIwriteCommand(RADIOLIB_SX126X_CMD_SET_CAD_PARAMS, data, 7);
RADIOLIB_ASSERT(state);
// start CAD
return(SPIwriteCommand(RADIOLIB_SX126X_CMD_SET_CAD, NULL, 0));
}
@ -1652,10 +1645,10 @@ int16_t SX126x::config(uint8_t modem) {
state = SPIwriteCommand(RADIOLIB_SX126X_CMD_SET_RX_TX_FALLBACK_MODE, data, 1);
RADIOLIB_ASSERT(state);
// set CAD parameters
// set some CAD parameters - will be overwritten whel calling CAD anyway
data[0] = RADIOLIB_SX126X_CAD_ON_8_SYMB;
data[1] = _sf + 13;
data[2] = 10;
data[2] = RADIOLIB_SX126X_CAD_PARAM_DET_MIN;
data[3] = RADIOLIB_SX126X_CAD_GOTO_STDBY;
data[4] = 0x00;
data[5] = 0x00;

View file

@ -308,6 +308,8 @@
#define RADIOLIB_SX126X_CAD_ON_16_SYMB 0x04 // 7 0 16
#define RADIOLIB_SX126X_CAD_GOTO_STDBY 0x00 // 7 0 after CAD is done, always go to STDBY_RC mode
#define RADIOLIB_SX126X_CAD_GOTO_RX 0x01 // 7 0 after CAD is done, go to Rx mode if activity is detected
#define RADIOLIB_SX126X_CAD_PARAM_DEFAULT 0xFF // 7 0 used by the CAD methods to specify default parameter value
#define RADIOLIB_SX126X_CAD_PARAM_DET_MIN 10 // 7 0 default detMin CAD parameter
//RADIOLIB_SX126X_CMD_GET_STATUS
#define RADIOLIB_SX126X_STATUS_MODE_STDBY_RC 0b00100000 // 6 4 current chip mode: STDBY_RC
@ -470,9 +472,15 @@ class SX126x: public PhysicalLayer {
/*!
\brief Performs scan for LoRa transmission in the current channel. Detects both preamble and payload.
\param symbolNum Number of symbols for CAD detection. Defaults to the value recommended by AN1200.48.
\param detPeak Peak value for CAD detection. Defaults to the value recommended by AN1200.48.
\param detMin Minimum value for CAD detection. Defaults to the value recommended by AN1200.48.
\returns \ref status_codes
*/
int16_t scanChannel();
int16_t scanChannel(uint8_t symbolNum = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, uint8_t detPeak = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, uint8_t detMin = RADIOLIB_SX126X_CAD_PARAM_DEFAULT);
/*!
\brief Sets the module to sleep mode.
@ -591,9 +599,15 @@ class SX126x: public PhysicalLayer {
/*!
\brief Interrupt-driven channel activity detection method. DIO0 will be activated when LoRa preamble is detected, or upon timeout.
\param symbolNum Number of symbols for CAD detection. Defaults to the value recommended by AN1200.48.
\param detPeak Peak value for CAD detection. Defaults to the value recommended by AN1200.48.
\param detMin Minimum value for CAD detection. Defaults to the value recommended by AN1200.48.
\returns \ref status_codes
*/
int16_t startChannelScan();
int16_t startChannelScan(uint8_t symbolNum = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, uint8_t detPeak = RADIOLIB_SX126X_CAD_PARAM_DEFAULT, uint8_t detMin = RADIOLIB_SX126X_CAD_PARAM_DEFAULT);
/*!
\brief Read the channel scan result
@ -965,7 +979,7 @@ class SX126x: public PhysicalLayer {
// SX126x SPI command implementations
int16_t setTx(uint32_t timeout = 0);
int16_t setRx(uint32_t timeout);
int16_t setCad();
int16_t setCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin);
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);
int16_t writeRegister(uint16_t addr, uint8_t* data, uint8_t numBytes);
int16_t readRegister(uint16_t addr, uint8_t* data, uint8_t numBytes);