[SX126x] Implement staged modes

This commit is contained in:
jgromes 2025-02-03 20:33:43 +01:00
parent d7c00bfa0a
commit a8bbdc6eaa
2 changed files with 18 additions and 77 deletions

View file

@ -518,21 +518,6 @@ void SX126x::clearChannelScanAction() {
this->clearDio1Action();
}
int16_t SX126x::startTransmit(const uint8_t* data, size_t len, uint8_t addr) {
RadioModeConfig_t cfg = {
.transmit = {
.data = const_cast<uint8_t*>(data),
.len = len,
.addr = addr,
}
};
int16_t state = this->stageMode(RADIOLIB_RADIO_MODE_TX, cfg);
RADIOLIB_ASSERT(state);
return(this->launchMode());
}
int16_t SX126x::finishTransmit() {
// clear interrupt flags
int16_t state = clearIrqStatus();
@ -546,21 +531,6 @@ int16_t SX126x::startReceive() {
return(this->startReceive(RADIOLIB_SX126X_RX_TIMEOUT_INF, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, 0));
}
int16_t SX126x::startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask, size_t len) {
RadioModeConfig_t cfg = {
.receive = {
.timeout = timeout,
.irqFlags = irqFlags,
.irqMask = irqMask,
.len = len,
}
};
int16_t state = this->stageMode(RADIOLIB_RADIO_MODE_RX, cfg);
RADIOLIB_ASSERT(state);
return(this->launchMode());
}
int16_t SX126x::startReceiveDutyCycle(uint32_t rxPeriod, uint32_t sleepPeriod, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask) {
// datasheet claims time to go to sleep is ~500us, same to wake up, compensate for that with 1 ms + TCXO delay
uint32_t transitionTime = this->tcxoDelay + 1000;
@ -1568,44 +1538,43 @@ int16_t SX126x::getModem(ModemType_t* modem) {
return(RADIOLIB_ERR_WRONG_MODEM);
}
int16_t SX126x::stageMode(RadioModeType_t mode, RadioModeConfig_t cfg) {
int16_t SX126x::stageMode(RadioModeType_t mode, RadioModeConfig_t* cfg) {
int16_t state;
switch(mode) {
case(RADIOLIB_RADIO_MODE_RX): {
// in implicit header mode, use the provided length if it is nonzero
// otherwise we trust the user has previously set the payload length manually
if((this->headerType == RADIOLIB_SX126X_LORA_HEADER_IMPLICIT) && (cfg.receive.len != 0)) {
this->implicitLen = cfg.receive.len;
if((this->headerType == RADIOLIB_SX126X_LORA_HEADER_IMPLICIT) && (cfg->receive.len != 0)) {
this->implicitLen = cfg->receive.len;
}
state = startReceiveCommon(cfg.receive.timeout, cfg.receive.irqFlags, cfg.receive.irqMask);
state = startReceiveCommon(cfg->receive.timeout, cfg->receive.irqFlags, cfg->receive.irqMask);
RADIOLIB_ASSERT(state);
// set RF switch (if present)
this->mod->setRfSwitchState(Module::MODE_RX);
this->rxTimeout = cfg->receive.timeout;
} break;
case(RADIOLIB_RADIO_MODE_TX): {
// check packet length
if(cfg.transmit.len > RADIOLIB_SX126X_MAX_PACKET_LENGTH) {
if(cfg->transmit.len > RADIOLIB_SX126X_MAX_PACKET_LENGTH) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}
// maximum packet length is decreased by 1 when address filtering is active
if((RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF != RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF) &&
(cfg.transmit.len > RADIOLIB_SX126X_MAX_PACKET_LENGTH - 1)) {
(cfg->transmit.len > RADIOLIB_SX126X_MAX_PACKET_LENGTH - 1)) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}
// set packet Length
int16_t state = RADIOLIB_ERR_NONE;
state = RADIOLIB_ERR_NONE;
uint8_t modem = getPacketType();
if(modem == RADIOLIB_SX126X_PACKET_TYPE_LORA) {
state = setPacketParams(this->preambleLengthLoRa, this->crcTypeLoRa, cfg.transmit.len, this->headerType, this->invertIQEnabled);
state = setPacketParams(this->preambleLengthLoRa, this->crcTypeLoRa, cfg->transmit.len, this->headerType, this->invertIQEnabled);
} else if(modem == RADIOLIB_SX126X_PACKET_TYPE_GFSK) {
state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening, this->packetType, cfg.transmit.len);
state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening, this->packetType, cfg->transmit.len);
} else if(modem != RADIOLIB_SX126X_PACKET_TYPE_LR_FHSS) {
return(RADIOLIB_ERR_UNKNOWN);
@ -1627,7 +1596,7 @@ int16_t SX126x::stageMode(RadioModeType_t mode, RadioModeConfig_t cfg) {
// write packet to buffer
if(modem != RADIOLIB_SX126X_PACKET_TYPE_LR_FHSS) {
state = writeBuffer(const_cast<uint8_t*>(cfg.transmit.data), cfg.transmit.len);
state = writeBuffer(cfg->transmit.data, cfg->transmit.len);
} else {
// first, reset the LR-FHSS state machine
@ -1645,7 +1614,7 @@ int16_t SX126x::stageMode(RadioModeType_t mode, RadioModeConfig_t cfg) {
this->lrFhssFrameBitsRem = 0;
this->lrFhssFrameHopsRem = 0;
this->lrFhssHopNum = 0;
state = buildLRFHSSPacket(const_cast<uint8_t*>(cfg.transmit.data), cfg.transmit.len, frame, &frameLen, &this->lrFhssFrameBitsRem, &this->lrFhssFrameHopsRem);
state = buildLRFHSSPacket(cfg->transmit.data, cfg->transmit.len, frame, &frameLen, &this->lrFhssFrameBitsRem, &this->lrFhssFrameHopsRem);
RADIOLIB_ASSERT(state);
// FIXME check max len for FHSS
@ -1678,9 +1647,6 @@ int16_t SX126x::stageMode(RadioModeType_t mode, RadioModeConfig_t cfg) {
// fix sensitivity
state = fixSensitivity();
RADIOLIB_ASSERT(state);
// set RF switch (if present)
this->mod->setRfSwitchState(this->txMode);
} break;
default:
@ -1688,8 +1654,6 @@ int16_t SX126x::stageMode(RadioModeType_t mode, RadioModeConfig_t cfg) {
}
this->stagedMode = mode;
this->stagedConfig = cfg;
return(state);
}
@ -1697,10 +1661,12 @@ int16_t SX126x::launchMode() {
int16_t state;
switch(this->stagedMode) {
case(RADIOLIB_RADIO_MODE_RX): {
state = setRx(this->stagedConfig.receive.timeout);
this->mod->setRfSwitchState(Module::MODE_RX);
state = setRx(this->rxTimeout);
} break;
case(RADIOLIB_RADIO_MODE_TX): {
this->mod->setRfSwitchState(this->txMode);
state = setTx(RADIOLIB_SX126X_TX_TIMEOUT_NONE);
RADIOLIB_ASSERT(state);

View file

@ -478,6 +478,7 @@ class SX126x: public PhysicalLayer {
using PhysicalLayer::transmit;
using PhysicalLayer::receive;
using PhysicalLayer::startTransmit;
using PhysicalLayer::startReceive;
using PhysicalLayer::readData;
/*!
@ -681,16 +682,6 @@ class SX126x: public PhysicalLayer {
*/
void clearChannelScanAction() override;
/*!
\brief Interrupt-driven binary transmit 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 addr Address to send the data to. Will only be added if address filtering was enabled.
\returns \ref status_codes
*/
int16_t startTransmit(const uint8_t* data, size_t len, uint8_t addr = 0) override;
/*!
\brief Clean up after transmission is done.
\returns \ref status_codes
@ -705,23 +696,6 @@ class SX126x: public PhysicalLayer {
*/
int16_t startReceive() override;
/*!
\brief Interrupt-driven receive method. DIO1 will be activated when full packet is received.
\param timeout Receive mode type and/or raw timeout value, expressed as multiples of 15.625 us.
When set to RADIOLIB_SX126X_RX_TIMEOUT_INF, the timeout will be infinite and the device will remain
in Rx mode until explicitly commanded to stop (Rx continuous mode).
When set to RADIOLIB_SX126X_RX_TIMEOUT_NONE, there will be no timeout and the device will return
to standby when a packet is received (Rx single mode).
For any other value, timeout will be applied and signal will be generated on DIO1 for conditions
defined by irqFlags and irqMask.
\param irqFlags Sets the IRQ flags, defaults to RX done, RX timeout, CRC error and header error.
\param irqMask Sets the mask of IRQ flags that will trigger DIO1, defaults to RX done.
\param len Only for PhysicalLayer compatibility, not used.
\returns \ref status_codes
*/
int16_t startReceive(uint32_t timeout, RadioLibIrqFlags_t irqFlags = RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RadioLibIrqFlags_t irqMask = RADIOLIB_IRQ_RX_DEFAULT_MASK, size_t len = 0);
/*!
\brief Interrupt-driven receive method where the device mostly sleeps and periodically wakes to listen.
Note that this function assumes the unit will take 500us + TCXO_delay to change state.
@ -1147,7 +1121,7 @@ class SX126x: public PhysicalLayer {
int16_t getModem(ModemType_t* modem) override;
/*! \copydoc PhysicalLayer::stageMode */
int16_t stageMode(RadioModeType_t mode, RadioModeConfig_t cfg) override;
int16_t stageMode(RadioModeType_t mode, RadioModeConfig_t* cfg) override;
/*! \copydoc PhysicalLayer::launchMode */
int16_t launchMode() override;
@ -1310,6 +1284,7 @@ class SX126x: public PhysicalLayer {
size_t implicitLen = 0;
uint8_t invertIQEnabled = RADIOLIB_SX126X_LORA_IQ_STANDARD;
uint32_t rxTimeout = 0;
// LR-FHSS stuff - there's a lot of it because all the encoding happens in software
uint8_t lrFhssCr = RADIOLIB_SX126X_LR_FHSS_CR_2_3;