[SX128x] Implement staged modes
This commit is contained in:
parent
a8bbdc6eaa
commit
c0bcc219a9
2 changed files with 130 additions and 131 deletions
|
@ -513,70 +513,6 @@ void SX128x::clearPacketSentAction() {
|
|||
this->clearDio1Action();
|
||||
}
|
||||
|
||||
int16_t SX128x::startTransmit(const uint8_t* data, size_t len, uint8_t addr) {
|
||||
// suppress unused variable warning
|
||||
(void)addr;
|
||||
|
||||
// check packet length
|
||||
if(len > RADIOLIB_SX128X_MAX_PACKET_LENGTH) {
|
||||
return(RADIOLIB_ERR_PACKET_TOO_LONG);
|
||||
}
|
||||
|
||||
// set packet Length
|
||||
int16_t state = RADIOLIB_ERR_NONE;
|
||||
uint8_t modem = getPacketType();
|
||||
if(modem == RADIOLIB_SX128X_PACKET_TYPE_LORA) {
|
||||
state = setPacketParamsLoRa(this->preambleLengthLoRa, this->headerType, len, this->crcLoRa, this->invertIQEnabled);
|
||||
} else if((modem == RADIOLIB_SX128X_PACKET_TYPE_GFSK) || (modem == RADIOLIB_SX128X_PACKET_TYPE_FLRC)) {
|
||||
state = setPacketParamsGFSK(this->preambleLengthGFSK, this->syncWordLen, this->syncWordMatch, this->crcGFSK, this->whitening, len);
|
||||
} else if(modem == RADIOLIB_SX128X_PACKET_TYPE_BLE) {
|
||||
state = setPacketParamsBLE(this->connectionState, this->crcBLE, this->bleTestPayload, this->whitening);
|
||||
} else {
|
||||
return(RADIOLIB_ERR_WRONG_MODEM);
|
||||
}
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// update output power
|
||||
state = setTxParams(this->power);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set buffer pointers
|
||||
state = setBufferBaseAddress();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// write packet to buffer
|
||||
if(modem == RADIOLIB_SX128X_PACKET_TYPE_BLE) {
|
||||
// first 2 bytes of BLE payload are PDU header
|
||||
state = writeBuffer(const_cast<uint8_t*>(data), len, 2);
|
||||
RADIOLIB_ASSERT(state);
|
||||
} else {
|
||||
state = writeBuffer(const_cast<uint8_t*>(data), len);
|
||||
RADIOLIB_ASSERT(state);
|
||||
}
|
||||
|
||||
// set DIO mapping
|
||||
state = setDioIrqParams(RADIOLIB_SX128X_IRQ_TX_DONE | RADIOLIB_SX128X_IRQ_RX_TX_TIMEOUT, RADIOLIB_SX128X_IRQ_TX_DONE);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// clear interrupt flags
|
||||
state = clearIrqStatus();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set RF switch (if present)
|
||||
this->mod->setRfSwitchState(Module::MODE_TX);
|
||||
|
||||
// start transmission
|
||||
state = setTx(RADIOLIB_SX128X_TX_TIMEOUT_NONE);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// wait for BUSY to go low (= PA ramp up done)
|
||||
while(this->mod->hal->digitalRead(this->mod->getGpio())) {
|
||||
this->mod->hal->yield();
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX128x::finishTransmit() {
|
||||
// clear interrupt flags
|
||||
clearIrqStatus();
|
||||
|
@ -589,49 +525,6 @@ int16_t SX128x::startReceive() {
|
|||
return(this->startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, 0));
|
||||
}
|
||||
|
||||
int16_t SX128x::startReceive(uint16_t timeout, RadioLibIrqFlags_t irqFlags, RadioLibIrqFlags_t irqMask, size_t len) {
|
||||
// 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_SX128X_LORA_HEADER_IMPLICIT) && (len != 0)) {
|
||||
this->payloadLen = len;
|
||||
}
|
||||
|
||||
// check active modem
|
||||
if(getPacketType() == RADIOLIB_SX128X_PACKET_TYPE_RANGING) {
|
||||
return(RADIOLIB_ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// set DIO mapping
|
||||
if(timeout != RADIOLIB_SX128X_RX_TIMEOUT_INF) {
|
||||
irqMask |= (1UL << RADIOLIB_IRQ_TIMEOUT);
|
||||
}
|
||||
|
||||
int16_t state = setDioIrqParams(getIrqMapped(irqFlags), getIrqMapped(irqMask));
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set buffer pointers
|
||||
state = setBufferBaseAddress();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// clear interrupt flags
|
||||
state = clearIrqStatus();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set implicit mode and expected len if applicable
|
||||
if((this->headerType == RADIOLIB_SX128X_LORA_HEADER_IMPLICIT) && (getPacketType() == RADIOLIB_SX128X_PACKET_TYPE_LORA)) {
|
||||
state = setPacketParamsLoRa(this->preambleLengthLoRa, this->headerType, this->payloadLen, this->crcLoRa, this->invertIQEnabled);
|
||||
RADIOLIB_ASSERT(state);
|
||||
}
|
||||
|
||||
// set RF switch (if present)
|
||||
this->mod->setRfSwitchState(Module::MODE_RX);
|
||||
|
||||
// set mode to receive
|
||||
state = setRx(timeout);
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX128x::readData(uint8_t* data, size_t len) {
|
||||
// check active modem
|
||||
if(getPacketType() == RADIOLIB_SX128X_PACKET_TYPE_RANGING) {
|
||||
|
@ -1493,6 +1386,128 @@ int16_t SX128x::invertIQ(bool enable) {
|
|||
return(setPacketParamsLoRa(this->preambleLengthLoRa, this->headerType, this->payloadLen, this->crcLoRa, this->invertIQEnabled));
|
||||
}
|
||||
|
||||
int16_t SX128x::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_SX128X_LORA_HEADER_IMPLICIT) && (cfg->receive.len != 0)) {
|
||||
this->payloadLen = cfg->receive.len;
|
||||
}
|
||||
|
||||
// check active modem
|
||||
if(getPacketType() == RADIOLIB_SX128X_PACKET_TYPE_RANGING) {
|
||||
return(RADIOLIB_ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// set DIO mapping
|
||||
if(cfg->receive.timeout != RADIOLIB_SX128X_RX_TIMEOUT_INF) {
|
||||
cfg->receive.irqMask |= (1UL << RADIOLIB_IRQ_TIMEOUT);
|
||||
}
|
||||
|
||||
state = setDioIrqParams(getIrqMapped(cfg->receive.irqFlags), getIrqMapped(cfg->receive.irqMask));
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set buffer pointers
|
||||
state = setBufferBaseAddress();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// clear interrupt flags
|
||||
state = clearIrqStatus();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set implicit mode and expected len if applicable
|
||||
if((this->headerType == RADIOLIB_SX128X_LORA_HEADER_IMPLICIT) && (getPacketType() == RADIOLIB_SX128X_PACKET_TYPE_LORA)) {
|
||||
state = setPacketParamsLoRa(this->preambleLengthLoRa, this->headerType, this->payloadLen, this->crcLoRa, this->invertIQEnabled);
|
||||
RADIOLIB_ASSERT(state);
|
||||
}
|
||||
this->rxTimeout = cfg->receive.timeout;
|
||||
} break;
|
||||
|
||||
case(RADIOLIB_RADIO_MODE_TX): {
|
||||
// check packet length
|
||||
if(cfg->transmit.len > RADIOLIB_SX128X_MAX_PACKET_LENGTH) {
|
||||
return(RADIOLIB_ERR_PACKET_TOO_LONG);
|
||||
}
|
||||
|
||||
// set packet Length
|
||||
uint8_t modem = getPacketType();
|
||||
if(modem == RADIOLIB_SX128X_PACKET_TYPE_LORA) {
|
||||
state = setPacketParamsLoRa(this->preambleLengthLoRa, this->headerType, cfg->transmit.len, this->crcLoRa, this->invertIQEnabled);
|
||||
} else if((modem == RADIOLIB_SX128X_PACKET_TYPE_GFSK) || (modem == RADIOLIB_SX128X_PACKET_TYPE_FLRC)) {
|
||||
state = setPacketParamsGFSK(this->preambleLengthGFSK, this->syncWordLen, this->syncWordMatch, this->crcGFSK, this->whitening, cfg->transmit.len);
|
||||
} else if(modem == RADIOLIB_SX128X_PACKET_TYPE_BLE) {
|
||||
state = setPacketParamsBLE(this->connectionState, this->crcBLE, this->bleTestPayload, this->whitening);
|
||||
} else {
|
||||
return(RADIOLIB_ERR_WRONG_MODEM);
|
||||
}
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// update output power
|
||||
state = setTxParams(this->power);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// set buffer pointers
|
||||
state = setBufferBaseAddress();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// write packet to buffer
|
||||
if(modem == RADIOLIB_SX128X_PACKET_TYPE_BLE) {
|
||||
// first 2 bytes of BLE payload are PDU header
|
||||
state = writeBuffer(cfg->transmit.data, cfg->transmit.len, 2);
|
||||
RADIOLIB_ASSERT(state);
|
||||
} else {
|
||||
state = writeBuffer(cfg->transmit.data, cfg->transmit.len);
|
||||
RADIOLIB_ASSERT(state);
|
||||
}
|
||||
|
||||
// set DIO mapping
|
||||
state = setDioIrqParams(RADIOLIB_SX128X_IRQ_TX_DONE | RADIOLIB_SX128X_IRQ_RX_TX_TIMEOUT, RADIOLIB_SX128X_IRQ_TX_DONE);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// clear interrupt flags
|
||||
state = clearIrqStatus();
|
||||
RADIOLIB_ASSERT(state);
|
||||
} break;
|
||||
|
||||
default:
|
||||
return(RADIOLIB_ERR_UNSUPPORTED);
|
||||
}
|
||||
|
||||
this->stagedMode = mode;
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX128x::launchMode() {
|
||||
int16_t state;
|
||||
switch(this->stagedMode) {
|
||||
case(RADIOLIB_RADIO_MODE_RX): {
|
||||
this->mod->setRfSwitchState(Module::MODE_RX);
|
||||
state = setRx(this->rxTimeout);
|
||||
RADIOLIB_ASSERT(state);
|
||||
} break;
|
||||
|
||||
case(RADIOLIB_RADIO_MODE_TX): {
|
||||
this->mod->setRfSwitchState(Module::MODE_TX);
|
||||
state = setTx(RADIOLIB_SX128X_TX_TIMEOUT_NONE);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// wait for BUSY to go low (= PA ramp up done)
|
||||
while(this->mod->hal->digitalRead(this->mod->getGpio())) {
|
||||
this->mod->hal->yield();
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
return(RADIOLIB_ERR_UNSUPPORTED);
|
||||
}
|
||||
|
||||
this->stagedMode = RADIOLIB_RADIO_MODE_NONE;
|
||||
return(state);
|
||||
}
|
||||
|
||||
#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
|
||||
void SX128x::setDirectAction(void (*func)(void)) {
|
||||
// SX128x is unable to perform direct mode reception
|
||||
|
|
|
@ -354,6 +354,7 @@ class SX128x: public PhysicalLayer {
|
|||
using PhysicalLayer::transmit;
|
||||
using PhysicalLayer::receive;
|
||||
using PhysicalLayer::startTransmit;
|
||||
using PhysicalLayer::startReceive;
|
||||
using PhysicalLayer::readData;
|
||||
|
||||
/*!
|
||||
|
@ -530,16 +531,6 @@ class SX128x: public PhysicalLayer {
|
|||
*/
|
||||
void clearPacketSentAction() 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. Unsupported, compatibility only.
|
||||
\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
|
||||
|
@ -554,20 +545,6 @@ class SX128x: public PhysicalLayer {
|
|||
*/
|
||||
int16_t startReceive() override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven receive method. DIO1 will be activated when full packet is received.
|
||||
\param timeout Raw timeout value, expressed as multiples of 15.625 us. Defaults to
|
||||
RADIOLIB_SX128X_RX_TIMEOUT_INF for infinite timeout (Rx continuous mode),
|
||||
set to RADIOLIB_SX128X_RX_TIMEOUT_NONE for no timeout (Rx single mode).
|
||||
If timeout other than infinite is set, signal will be generated on DIO1.
|
||||
|
||||
\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(uint16_t timeout, RadioLibIrqFlags_t irqFlags = RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RadioLibIrqFlags_t irqMask = RADIOLIB_IRQ_RX_DEFAULT_MASK, size_t len = 0);
|
||||
|
||||
/*!
|
||||
\brief Reads the current IRQ status.
|
||||
\returns IRQ status bits
|
||||
|
@ -863,6 +840,12 @@ class SX128x: public PhysicalLayer {
|
|||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t invertIQ(bool enable) override;
|
||||
|
||||
/*! \copydoc PhysicalLayer::stageMode */
|
||||
int16_t stageMode(RadioModeType_t mode, RadioModeConfig_t* cfg) override;
|
||||
|
||||
/*! \copydoc PhysicalLayer::launchMode */
|
||||
int16_t launchMode() override;
|
||||
|
||||
#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
|
||||
/*!
|
||||
|
@ -920,6 +903,7 @@ class SX128x: public PhysicalLayer {
|
|||
|
||||
// common parameters
|
||||
uint8_t power = 0;
|
||||
uint32_t rxTimeout = 0;
|
||||
|
||||
// cached LoRa parameters
|
||||
uint8_t invertIQEnabled = RADIOLIB_SX128X_LORA_IQ_STANDARD;
|
||||
|
|
Loading…
Add table
Reference in a new issue