[SX126x] Implement blocking receive timeout

pull/1592/head
jgromes 2025-09-06 16:27:45 +01:00
rodzic 4c498e288e
commit 3d5adf8779
2 zmienionych plików z 34 dodań i 37 usunięć

Wyświetl plik

@ -249,38 +249,37 @@ int16_t SX126x::transmit(const uint8_t* data, size_t len, uint8_t addr) {
return(finishTransmit());
}
int16_t SX126x::receive(uint8_t* data, size_t len) {
int16_t SX126x::receive(uint8_t* data, size_t len, RadioLibTime_t timeout) {
// set mode to standby
int16_t state = standby();
RADIOLIB_ASSERT(state);
RadioLibTime_t timeout = 0;
RadioLibTime_t timeoutInternal = timeout;
if(!timeoutInternal) {
// get currently active modem
uint8_t modem = getPacketType();
if(modem == RADIOLIB_SX126X_PACKET_TYPE_LORA) {
// calculate timeout (100 LoRa symbols, the default for SX127x series)
float symbolLength = (float)(uint32_t(1) << this->spreadingFactor) / (float)this->bandwidthKhz;
timeoutInternal = (RadioLibTime_t)(symbolLength * 100.0f);
} else if(modem == RADIOLIB_SX126X_PACKET_TYPE_GFSK) {
// calculate timeout (500 % of expected time-one-air)
size_t maxLen = len;
if(len == 0) { maxLen = 0xFF; }
float brBps = (RADIOLIB_SX126X_CRYSTAL_FREQ * 1000000.0f * 32.0f) / (float)this->bitRate;
timeoutInternal = (RadioLibTime_t)(((maxLen * 8.0f) / brBps) * 1000.0f * 5.0f);
// get currently active modem
uint8_t modem = getPacketType();
if(modem == RADIOLIB_SX126X_PACKET_TYPE_LORA) {
// calculate timeout (100 LoRa symbols, the default for SX127x series)
float symbolLength = (float)(uint32_t(1) << this->spreadingFactor) / (float)this->bandwidthKhz;
timeout = (RadioLibTime_t)(symbolLength * 100.0f);
} else if(modem == RADIOLIB_SX126X_PACKET_TYPE_GFSK) {
// calculate timeout (500 % of expected time-one-air)
size_t maxLen = len;
if(len == 0) {
maxLen = 0xFF;
} else {
return(RADIOLIB_ERR_UNKNOWN);
}
float brBps = (RADIOLIB_SX126X_CRYSTAL_FREQ * 1000000.0f * 32.0f) / (float)this->bitRate;
timeout = (RadioLibTime_t)(((maxLen * 8.0f) / brBps) * 1000.0f * 5.0f);
} else {
return(RADIOLIB_ERR_UNKNOWN);
}
RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu ms", timeout);
RADIOLIB_DEBUG_BASIC_PRINTLN("Timeout in %lu ms", timeoutInternal);
// start reception
uint32_t timeoutValue = (uint32_t)(((float)timeout * 1000.0f) / 15.625f);
uint32_t timeoutValue = (uint32_t)(((float)timeoutInternal * 1000.0f) / 15.625f);
state = startReceive(timeoutValue);
RADIOLIB_ASSERT(state);
@ -290,7 +289,7 @@ int16_t SX126x::receive(uint8_t* data, size_t len) {
while(!this->mod->hal->digitalRead(this->mod->getIrq())) {
this->mod->hal->yield();
// safety check, the timeout should be done by the radio
if(this->mod->hal->millis() - start > timeout) {
if(this->mod->hal->millis() - start > timeoutInternal) {
softTimeout = true;
break;
}
@ -302,18 +301,14 @@ int16_t SX126x::receive(uint8_t* data, size_t len) {
return(state);
}
// check whether this was a timeout or not
if((getIrqFlags() & RADIOLIB_SX126X_IRQ_TIMEOUT) || softTimeout) {
standby();
fixImplicitTimeout();
clearIrqStatus();
return(RADIOLIB_ERR_RX_TIMEOUT);
}
// cache the IRQ flags and clean up after reception
uint32_t irqFlags = getIrqFlags();
state = finishReceive();
RADIOLIB_ASSERT(state);
// fix timeout in implicit LoRa mode
if(((this->headerType == RADIOLIB_SX126X_LORA_HEADER_IMPLICIT) && (getPacketType() == RADIOLIB_SX126X_PACKET_TYPE_LORA))) {
state = fixImplicitTimeout();
RADIOLIB_ASSERT(state);
// check whether this was a timeout or not
if((irqFlags & RADIOLIB_SX126X_IRQ_TIMEOUT) || softTimeout) {
return(RADIOLIB_ERR_RX_TIMEOUT);
}
// read the received data

Wyświetl plik

@ -567,11 +567,13 @@ class SX126x: public PhysicalLayer {
/*!
\brief Blocking binary receive method.
Overloads for string-based transmissions are implemented in PhysicalLayer.
\param data Binary data to be sent.
\param len Number of bytes to send.
\param data Pointer to array to save the received binary data.
\param len Number of bytes that will be received. Must be known in advance for binary transmissions.
\param timeout Reception timeout in milliseconds. If set to 0,
timeout period will be calculated automatically based on the radio configuration.
\returns \ref status_codes
*/
int16_t receive(uint8_t* data, size_t len) override;
int16_t receive(uint8_t* data, size_t len, RadioLibTime_t timeout = 0) override;
/*!
\brief Starts direct mode transmission.