[RF69][SX1231] Added Stream support (#201)

pull/554/head
jgromes 2022-07-10 20:41:11 +02:00
rodzic 31da00649c
commit 60aa0098b3
4 zmienionych plików z 162 dodań i 11 usunięć

Wyświetl plik

@ -11,6 +11,8 @@
Modules that can be used for Stream are:
- SX127x/RFM9x (FSK mode only)
- RF69
- SX1231
For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem

Wyświetl plik

@ -11,6 +11,8 @@
Modules that can be used for Stream are:
- SX127x/RFM9x (FSK mode only)
- RF69
- SX1231
For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem

Wyświetl plik

@ -297,23 +297,109 @@ void RF69::clearDio1Action() {
_mod->detachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getGpio()));
}
int16_t RF69::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
// check packet length
if(len > RADIOLIB_RF69_MAX_PACKET_LENGTH) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
void RF69::setFifoEmptyAction(void (*func)(void)) {
// set DIO1 to the FIFO empty event (the register setting is done in startTransmit)
if(_mod->getGpio() == RADIOLIB_NC) {
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
int16_t state = setMode(RADIOLIB_RF69_STANDBY);
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
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
if (_packetLengthConfig == RADIOLIB_RF69_PACKET_FORMAT_VARIABLE) {
_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
_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
if(_power > 17) {
@ -852,7 +949,7 @@ int16_t RF69::config() {
RADIOLIB_ASSERT(state);
// 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);
// set Rx timeouts

Wyświetl plik

@ -400,7 +400,7 @@
// 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_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
#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();
/*!
\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.
Overloads for string-based transmissions are implemented in PhysicalLayer.