[RF69][SX1231] Added Stream support (#201)
This commit is contained in:
parent
31da00649c
commit
60aa0098b3
4 changed files with 162 additions and 11 deletions
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
Modules that can be used for Stream are:
|
Modules that can be used for Stream are:
|
||||||
- SX127x/RFM9x (FSK mode only)
|
- SX127x/RFM9x (FSK mode only)
|
||||||
|
- RF69
|
||||||
|
- SX1231
|
||||||
|
|
||||||
For default module settings, see the wiki page
|
For default module settings, see the wiki page
|
||||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
|
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
Modules that can be used for Stream are:
|
Modules that can be used for Stream are:
|
||||||
- SX127x/RFM9x (FSK mode only)
|
- SX127x/RFM9x (FSK mode only)
|
||||||
|
- RF69
|
||||||
|
- SX1231
|
||||||
|
|
||||||
For default module settings, see the wiki page
|
For default module settings, see the wiki page
|
||||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
|
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
|
||||||
|
|
|
@ -297,23 +297,109 @@ void RF69::clearDio1Action() {
|
||||||
_mod->detachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getGpio()));
|
_mod->detachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getGpio()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t RF69::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
|
void RF69::setFifoEmptyAction(void (*func)(void)) {
|
||||||
// check packet length
|
// set DIO1 to the FIFO empty event (the register setting is done in startTransmit)
|
||||||
if(len > RADIOLIB_RF69_MAX_PACKET_LENGTH) {
|
if(_mod->getGpio() == RADIOLIB_NC) {
|
||||||
return(RADIOLIB_ERR_PACKET_TOO_LONG);
|
return;
|
||||||
|
}
|
||||||
|
_mod->pinMode(_mod->getGpio(), INPUT);
|
||||||
|
|
||||||
|
// we need to invert the logic here (as compared to setDio1Action), since we are using the "FIFO not empty interrupt"
|
||||||
|
_mod->attachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getGpio()), func, FALLING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RF69::clearFifoEmptyAction() {
|
||||||
|
clearDio1Action();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RF69::setFifoFullAction(void (*func)(void)) {
|
||||||
|
// set the interrupt
|
||||||
|
_mod->SPIsetRegValue(RADIOLIB_RF69_REG_FIFO_THRESH, RADIOLIB_RF69_FIFO_THRESH, 6, 0);
|
||||||
|
_mod->SPIsetRegValue(RADIOLIB_RF69_REG_DIO_MAPPING_1, RADIOLIB_RF69_DIO1_PACK_FIFO_LEVEL, 5, 4);
|
||||||
|
|
||||||
|
// set DIO1 to the FIFO full event
|
||||||
|
setDio1Action(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RF69::clearFifoFullAction() {
|
||||||
|
clearDio1Action();
|
||||||
|
_mod->SPIsetRegValue(RADIOLIB_RF69_REG_DIO_MAPPING_1, 0x00, 5, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RF69::fifoAdd(uint8_t* data, int totalLen, volatile int* remLen) {
|
||||||
|
// subtract first (this may be the first time we get to modify the remaining length)
|
||||||
|
*remLen -= RADIOLIB_RF69_FIFO_THRESH - 1;
|
||||||
|
|
||||||
|
// check if there is still something left to send
|
||||||
|
if(*remLen <= 0) {
|
||||||
|
// we're done
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the number of bytes we can copy
|
||||||
|
int len = *remLen;
|
||||||
|
if(len > RADIOLIB_RF69_FIFO_THRESH - 1) {
|
||||||
|
len = RADIOLIB_RF69_FIFO_THRESH - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear interrupt flags
|
||||||
|
clearIRQFlags();
|
||||||
|
|
||||||
|
// copy the bytes to the FIFO
|
||||||
|
_mod->SPIwriteRegisterBurst(RADIOLIB_RF69_REG_FIFO, &data[totalLen - *remLen], len);
|
||||||
|
|
||||||
|
// this is a hack, but it seems Rx FIFO level is getting triggered 1 byte before it should
|
||||||
|
// we just add a padding byte that we can drop without consequence
|
||||||
|
_mod->SPIwriteRegister(RADIOLIB_RF69_REG_FIFO, '/');
|
||||||
|
|
||||||
|
// we're not done yet
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RF69::fifoGet(volatile uint8_t* data, int totalLen, volatile int* rcvLen) {
|
||||||
|
// get pointer to the correct position in data buffer
|
||||||
|
uint8_t* dataPtr = (uint8_t*)&data[*rcvLen];
|
||||||
|
|
||||||
|
// check how much data are we still expecting
|
||||||
|
uint8_t len = RADIOLIB_RF69_FIFO_THRESH - 1;
|
||||||
|
if(totalLen - *rcvLen < len) {
|
||||||
|
// we're nearly at the end
|
||||||
|
len = totalLen - *rcvLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the data
|
||||||
|
_mod->SPIreadRegisterBurst(RADIOLIB_RF69_REG_FIFO, len, dataPtr);
|
||||||
|
(*rcvLen) += (len);
|
||||||
|
|
||||||
|
// dump the padding byte
|
||||||
|
_mod->SPIreadRegister(RADIOLIB_RF69_REG_FIFO);
|
||||||
|
|
||||||
|
// clear flags
|
||||||
|
clearIRQFlags();
|
||||||
|
|
||||||
|
// check if we're done
|
||||||
|
if(*rcvLen >= totalLen) {
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t RF69::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
|
||||||
// set mode to standby
|
// set mode to standby
|
||||||
int16_t state = setMode(RADIOLIB_RF69_STANDBY);
|
int16_t state = setMode(RADIOLIB_RF69_STANDBY);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// set DIO pin mapping
|
|
||||||
state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_DIO_MAPPING_1, RADIOLIB_RF69_DIO0_PACK_PACKET_SENT, 7, 6);
|
|
||||||
RADIOLIB_ASSERT(state);
|
|
||||||
|
|
||||||
// clear interrupt flags
|
// clear interrupt flags
|
||||||
clearIRQFlags();
|
clearIRQFlags();
|
||||||
|
|
||||||
|
// set DIO mapping
|
||||||
|
if(len > RADIOLIB_RF69_MAX_PACKET_LENGTH) {
|
||||||
|
state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_DIO_MAPPING_1, RADIOLIB_RF69_DIO1_PACK_FIFO_NOT_EMPTY, 5, 4);
|
||||||
|
} else {
|
||||||
|
state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_DIO_MAPPING_1, RADIOLIB_RF69_DIO0_PACK_PACKET_SENT, 7, 6);
|
||||||
|
}
|
||||||
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// optionally write packet length
|
// optionally write packet length
|
||||||
if (_packetLengthConfig == RADIOLIB_RF69_PACKET_FORMAT_VARIABLE) {
|
if (_packetLengthConfig == RADIOLIB_RF69_PACKET_FORMAT_VARIABLE) {
|
||||||
_mod->SPIwriteRegister(RADIOLIB_RF69_REG_FIFO, len);
|
_mod->SPIwriteRegister(RADIOLIB_RF69_REG_FIFO, len);
|
||||||
|
@ -326,7 +412,18 @@ int16_t RF69::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// write packet to FIFO
|
// write packet to FIFO
|
||||||
_mod->SPIwriteRegisterBurst(RADIOLIB_RF69_REG_FIFO, data, len);
|
size_t packetLen = len;
|
||||||
|
if(len > RADIOLIB_RF69_MAX_PACKET_LENGTH) {
|
||||||
|
packetLen = RADIOLIB_RF69_FIFO_THRESH - 1;
|
||||||
|
_mod->SPIsetRegValue(RADIOLIB_RF69_REG_FIFO_THRESH, RADIOLIB_RF69_TX_START_CONDITION_FIFO_NOT_EMPTY, 7, 7);
|
||||||
|
}
|
||||||
|
_mod->SPIwriteRegisterBurst(RADIOLIB_RF69_REG_FIFO, data, packetLen);
|
||||||
|
|
||||||
|
// this is a hack, but it seems than in Stream mode, Rx FIFO level is getting triggered 1 byte before it should
|
||||||
|
// just add a padding byte that can be dropped without consequence
|
||||||
|
if(len > RADIOLIB_RF69_MAX_PACKET_LENGTH) {
|
||||||
|
_mod->SPIwriteRegister(RADIOLIB_RF69_REG_FIFO, '/');
|
||||||
|
}
|
||||||
|
|
||||||
// enable +20 dBm operation
|
// enable +20 dBm operation
|
||||||
if(_power > 17) {
|
if(_power > 17) {
|
||||||
|
@ -852,7 +949,7 @@ int16_t RF69::config() {
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// set FIFO threshold
|
// set FIFO threshold
|
||||||
state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_FIFO_THRESH, RADIOLIB_RF69_TX_START_CONDITION_FIFO_NOT_EMPTY | RADIOLIB_RF69_FIFO_THRESHOLD, 7, 0);
|
state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_FIFO_THRESH, RADIOLIB_RF69_TX_START_CONDITION_FIFO_NOT_EMPTY | RADIOLIB_RF69_FIFO_THRESH, 7, 0);
|
||||||
RADIOLIB_ASSERT(state);
|
RADIOLIB_ASSERT(state);
|
||||||
|
|
||||||
// set Rx timeouts
|
// set Rx timeouts
|
||||||
|
|
|
@ -400,7 +400,7 @@
|
||||||
// RF69_REG_FIFO_THRESH
|
// RF69_REG_FIFO_THRESH
|
||||||
#define RADIOLIB_RF69_TX_START_CONDITION_FIFO_LEVEL 0b00000000 // 7 7 packet transmission start condition: FifoLevel
|
#define RADIOLIB_RF69_TX_START_CONDITION_FIFO_LEVEL 0b00000000 // 7 7 packet transmission start condition: FifoLevel
|
||||||
#define RADIOLIB_RF69_TX_START_CONDITION_FIFO_NOT_EMPTY 0b10000000 // 7 7 FifoNotEmpty (default)
|
#define RADIOLIB_RF69_TX_START_CONDITION_FIFO_NOT_EMPTY 0b10000000 // 7 7 FifoNotEmpty (default)
|
||||||
#define RADIOLIB_RF69_FIFO_THRESHOLD 0b00001111 // 6 0 default threshold to trigger FifoLevel interrupt
|
#define RADIOLIB_RF69_FIFO_THRESH 0x1F // 6 0 default threshold to trigger FifoLevel interrupt
|
||||||
|
|
||||||
// RF69_REG_PACKET_CONFIG_2
|
// RF69_REG_PACKET_CONFIG_2
|
||||||
#define RADIOLIB_RF69_INTER_PACKET_RX_DELAY 0b00000000 // 7 4 delay between FIFO empty and start of new RSSI phase
|
#define RADIOLIB_RF69_INTER_PACKET_RX_DELAY 0b00000000 // 7 4 delay between FIFO empty and start of new RSSI phase
|
||||||
|
@ -590,6 +590,56 @@ class RF69: public PhysicalLayer {
|
||||||
*/
|
*/
|
||||||
void clearDio1Action();
|
void clearDio1Action();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Set interrupt service routine function to call when FIFO is empty.
|
||||||
|
|
||||||
|
\param func Pointer to interrupt service routine.
|
||||||
|
*/
|
||||||
|
void setFifoEmptyAction(void (*func)(void));
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Clears interrupt service routine to call when FIFO is empty.
|
||||||
|
*/
|
||||||
|
void clearFifoEmptyAction();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Set interrupt service routine function to call when FIFO is full.
|
||||||
|
|
||||||
|
\param func Pointer to interrupt service routine.
|
||||||
|
*/
|
||||||
|
void setFifoFullAction(void (*func)(void));
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Clears interrupt service routine to call when FIFO is full.
|
||||||
|
*/
|
||||||
|
void clearFifoFullAction();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Set interrupt service routine function to call when FIFO is empty.
|
||||||
|
|
||||||
|
\param data Pointer to the transmission buffer.
|
||||||
|
|
||||||
|
\param totalLen Total number of bytes to transmit.
|
||||||
|
|
||||||
|
\param remLen Pointer to a counter holding the number of bytes that have been transmitted so far.
|
||||||
|
|
||||||
|
\returns True when a complete packet is sent, false if more data is needed.
|
||||||
|
*/
|
||||||
|
bool fifoAdd(uint8_t* data, int totalLen, volatile int* remLen);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Set interrupt service routine function to call when FIFO is sufficently full to read.
|
||||||
|
|
||||||
|
\param data Pointer to a buffer that stores the receive data.
|
||||||
|
|
||||||
|
\param totalLen Total number of bytes to receive.
|
||||||
|
|
||||||
|
\param rcvLen Pointer to a counter holding the number of bytes that have been received so far.
|
||||||
|
|
||||||
|
\returns True when a complete packet is received, false if more data is needed.
|
||||||
|
*/
|
||||||
|
bool fifoGet(volatile uint8_t* data, int totalLen, volatile int* rcvLen);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Interrupt-driven binary transmit method.
|
\brief Interrupt-driven binary transmit method.
|
||||||
Overloads for string-based transmissions are implemented in PhysicalLayer.
|
Overloads for string-based transmissions are implemented in PhysicalLayer.
|
||||||
|
|
Loading…
Add table
Reference in a new issue