kopia lustrzana https://github.com/jgromes/RadioLib
[SX126x] Implement blocking receive timeout
rodzic
4c498e288e
commit
3d5adf8779
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
Ładowanie…
Reference in New Issue