[LR11x0] Implement blocking receive timeout

pull/1592/head
jgromes 2025-09-06 18:17:58 +01:00
rodzic c5ce2f43b3
commit 4b916d39b6
2 zmienionych plików z 36 dodań i 32 usunięć

Wyświetl plik

@ -223,44 +223,46 @@ int16_t LR11x0::transmit(const uint8_t* data, size_t len, uint8_t addr) {
return(finishTransmit());
}
int16_t LR11x0::receive(uint8_t* data, size_t len) {
int16_t LR11x0::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;
// calcualte timeout based on the configured modem
RadioLibTime_t timeoutInternal = timeout;
if(!timeoutInternal) {
// get currently active modem
uint8_t modem = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
state = getPacketType(&modem);
RADIOLIB_ASSERT(state);
if(modem == RADIOLIB_LR11X0_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_LR11X0_PACKET_TYPE_GFSK) {
// calculate timeout (500 % of expected time-one-air)
size_t maxLen = len;
if(len == 0) {
maxLen = 0xFF;
}
float brBps = ((float)(RADIOLIB_LR11X0_CRYSTAL_FREQ) * 1000000.0f * 32.0f) / (float)this->bitRate;
timeoutInternal = (RadioLibTime_t)(((maxLen * 8.0f) / brBps) * 1000.0f * 5.0f);
} else if(modem == RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
// this modem cannot receive
return(RADIOLIB_ERR_WRONG_MODEM);
// get currently active modem
uint8_t modem = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
state = getPacketType(&modem);
RADIOLIB_ASSERT(state);
if(modem == RADIOLIB_LR11X0_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_LR11X0_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 = ((float)(RADIOLIB_LR11X0_CRYSTAL_FREQ) * 1000000.0f * 32.0f) / (float)this->bitRate;
timeout = (RadioLibTime_t)(((maxLen * 8.0f) / brBps) * 1000.0f * 5.0f);
} else if(modem == RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
// this modem cannot receive
return(RADIOLIB_ERR_WRONG_MODEM);
} 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) / 30.52f);
uint32_t timeoutValue = (uint32_t)(((float)timeoutInternal * 1000.0f) / 30.52f);
state = startReceive(timeoutValue);
RADIOLIB_ASSERT(state);
@ -270,7 +272,7 @@ int16_t LR11x0::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;
}

Wyświetl plik

@ -991,11 +991,13 @@ class LR11x0: 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.