[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();
|
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() {
|
int16_t SX128x::finishTransmit() {
|
||||||
// clear interrupt flags
|
// clear interrupt flags
|
||||||
clearIrqStatus();
|
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));
|
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) {
|
int16_t SX128x::readData(uint8_t* data, size_t len) {
|
||||||
// check active modem
|
// check active modem
|
||||||
if(getPacketType() == RADIOLIB_SX128X_PACKET_TYPE_RANGING) {
|
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));
|
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
|
#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
|
||||||
void SX128x::setDirectAction(void (*func)(void)) {
|
void SX128x::setDirectAction(void (*func)(void)) {
|
||||||
// SX128x is unable to perform direct mode reception
|
// SX128x is unable to perform direct mode reception
|
||||||
|
|
|
@ -354,6 +354,7 @@ class SX128x: public PhysicalLayer {
|
||||||
using PhysicalLayer::transmit;
|
using PhysicalLayer::transmit;
|
||||||
using PhysicalLayer::receive;
|
using PhysicalLayer::receive;
|
||||||
using PhysicalLayer::startTransmit;
|
using PhysicalLayer::startTransmit;
|
||||||
|
using PhysicalLayer::startReceive;
|
||||||
using PhysicalLayer::readData;
|
using PhysicalLayer::readData;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -530,16 +531,6 @@ class SX128x: public PhysicalLayer {
|
||||||
*/
|
*/
|
||||||
void clearPacketSentAction() override;
|
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.
|
\brief Clean up after transmission is done.
|
||||||
\returns \ref status_codes
|
\returns \ref status_codes
|
||||||
|
@ -554,20 +545,6 @@ class SX128x: public PhysicalLayer {
|
||||||
*/
|
*/
|
||||||
int16_t startReceive() override;
|
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.
|
\brief Reads the current IRQ status.
|
||||||
\returns IRQ status bits
|
\returns IRQ status bits
|
||||||
|
@ -863,6 +840,12 @@ class SX128x: public PhysicalLayer {
|
||||||
\returns \ref status_codes
|
\returns \ref status_codes
|
||||||
*/
|
*/
|
||||||
int16_t invertIQ(bool enable) override;
|
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
|
#if !RADIOLIB_EXCLUDE_DIRECT_RECEIVE
|
||||||
/*!
|
/*!
|
||||||
|
@ -920,6 +903,7 @@ class SX128x: public PhysicalLayer {
|
||||||
|
|
||||||
// common parameters
|
// common parameters
|
||||||
uint8_t power = 0;
|
uint8_t power = 0;
|
||||||
|
uint32_t rxTimeout = 0;
|
||||||
|
|
||||||
// cached LoRa parameters
|
// cached LoRa parameters
|
||||||
uint8_t invertIQEnabled = RADIOLIB_SX128X_LORA_IQ_STANDARD;
|
uint8_t invertIQEnabled = RADIOLIB_SX128X_LORA_IQ_STANDARD;
|
||||||
|
|
Loading…
Add table
Reference in a new issue