Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LR11x0] Implement automatic and forced LDRO #1237

Merged
merged 1 commit into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 40 additions & 1 deletion src/modules/LR11x0/LR11x0.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1414,6 +1414,33 @@ void LR11x0::setRfSwitchTable(const uint32_t (&pins)[Module::RFSWITCH_MAX_PINS],
this->setDioAsRfSwitch(enable, modes[0], modes[1], modes[2], modes[3], modes[4], modes[5], modes[6]);
}

int16_t LR11x0::forceLDRO(bool enable) {
// check packet type
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
int16_t state = getPacketType(&type);
RADIOLIB_ASSERT(state);
if(type != RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
return(RADIOLIB_ERR_WRONG_MODEM);
}

// update modulation parameters
this->ldroAuto = false;
this->ldrOptimize = (uint8_t)enable;
return(setModulationParamsLoRa(this->spreadingFactor, this->bandwidth, this->codingRate, this->ldrOptimize));
}

int16_t LR11x0::autoLDRO() {
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
int16_t state = getPacketType(&type);
RADIOLIB_ASSERT(state);
if(type != RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
return(RADIOLIB_ERR_WRONG_MODEM);
}

this->ldroAuto = true;
return(RADIOLIB_ERR_NONE);
}

int16_t LR11x0::setLrFhssConfig(uint8_t bw, uint8_t cr, uint8_t hdrCount, uint16_t hopSeed) {
// check active modem
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
Expand Down Expand Up @@ -2388,7 +2415,19 @@ int16_t LR11x0::setPacketType(uint8_t type) {
}

int16_t LR11x0::setModulationParamsLoRa(uint8_t sf, uint8_t bw, uint8_t cr, uint8_t ldro) {
uint8_t buff[4] = { sf, bw, cr, ldro };
// calculate symbol length and enable low data rate optimization, if auto-configuration is enabled
if(this->ldroAuto) {
float symbolLength = (float)(uint32_t(1) << this->spreadingFactor) / (float)this->bandwidthKhz;
if(symbolLength >= 16.0) {
this->ldrOptimize = RADIOLIB_LR11X0_LORA_LDRO_ENABLED;
} else {
this->ldrOptimize = RADIOLIB_LR11X0_LORA_LDRO_DISABLED;
}
} else {
this->ldrOptimize = ldro;
}

uint8_t buff[4] = { sf, bw, cr, this->ldrOptimize };
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_MODULATION_PARAMS, true, buff, sizeof(buff)));
}

Expand Down
15 changes: 15 additions & 0 deletions src/modules/LR11x0/LR11x0.h
Original file line number Diff line number Diff line change
Expand Up @@ -1283,6 +1283,21 @@ class LR11x0: public PhysicalLayer {
/*! \copydoc Module::setRfSwitchTable */
void setRfSwitchTable(const uint32_t (&pins)[Module::RFSWITCH_MAX_PINS], const Module::RfSwitchMode_t table[]);

/*!
\brief Forces LoRa low data rate optimization. Only available in LoRa mode. After calling this method, LDRO will always be set to
the provided value, regardless of symbol length. To re-enable automatic LDRO configuration, call LR11x0::autoLDRO()
\param enable Force LDRO to be always enabled (true) or disabled (false).
\returns \ref status_codes
*/
int16_t forceLDRO(bool enable);

/*!
\brief Re-enables automatic LDRO configuration. Only available in LoRa mode. After calling this method, LDRO will be enabled automatically
when symbol length exceeds 16 ms.
\returns \ref status_codes
*/
int16_t autoLDRO();

/*!
\brief Sets LR-FHSS configuration.
\param bw LR-FHSS bandwidth, one of RADIOLIB_LR11X0_LR_FHSS_BW_* values.
Expand Down
Loading