Initial work on full-length FSK messages based on ISR callbacks.
Untested, but it does compile.
This commit is contained in:
parent
e2d7f41347
commit
7dedc57b4c
4 changed files with 224 additions and 4 deletions
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
RadioLib SX127x FSK FIFO on-the-fly Refilling Example
|
||||
|
||||
This example shows how to use refill the FIFO buffer in SX127x chips, to allow for transmitting
|
||||
FSK/OOK packets longer than 256 bytes.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---fsk-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1276 has the following connections:
|
||||
// NSS pin: 8
|
||||
// DIO0 pin: 51
|
||||
// RESET pin: 22
|
||||
// DIO1 pin: 52
|
||||
SX1276 radio = new Module(8, 51, 22, 52);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//SX1278 fsk = RadioShield.ModuleA;
|
||||
|
||||
uint8_t syncWord[] = { 0x91, 0xD3, 0x91, 0xD3 };
|
||||
|
||||
char* msg = "This is just some message that extends well beyond the 64 bytes limit of the FIFO";
|
||||
size_t msg_length;
|
||||
size_t msg_counter;
|
||||
|
||||
// this interrupt is called whenever the FIFO buffer falls below a certain threshold
|
||||
void fifoRefill() {
|
||||
msg_counter += radio.fifoAppend(
|
||||
(uint8_t*)msg + msg_counter, // start of message, offset by # of bytes already sent
|
||||
msg_length - msg_counter // # of bytes left to send
|
||||
);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// RF switch for my board
|
||||
pinMode(47, OUTPUT);
|
||||
|
||||
// initialize SX1278 FSK modem with default settings
|
||||
Serial.print(F("[SX1276] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// Set config options
|
||||
radio.setDataShaping(RADIOLIB_SHAPING_NONE);
|
||||
radio.setSyncWord(syncWord, sizeof(syncWord));
|
||||
radio.setEncoding(RADIOLIB_ENCODING_WHITENING);
|
||||
radio.setCRC(true);
|
||||
|
||||
// Set up FIFO operations
|
||||
radio.setFifoThreshold(16);
|
||||
radio.setFifoThresholdAction(fifoRefill);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
radio.variablePacketLengthMode();
|
||||
|
||||
// set RF switch to TX mode
|
||||
digitalWrite(47, LOW);
|
||||
|
||||
// start transmission of message
|
||||
msg_length = strlen(msg);
|
||||
radio.startTransmit((uint8_t*)msg, msg_length, msg_counter);
|
||||
while (msg_counter != msg_length);
|
||||
|
||||
Serial.println("[SX1276] Done transmitting");
|
||||
}
|
|
@ -446,6 +446,19 @@ void SX127x::clearDio1Action() {
|
|||
}
|
||||
|
||||
int16_t SX127x::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
|
||||
|
||||
// if in FSK/OOK mode and trying to send a packet larger than can fit in the
|
||||
// FIFO, error out. For packets larger than FIFO, the startTransmit overload
|
||||
// with a counter outparam must be used.
|
||||
if (getActiveModem() == SX127X_FSK_OOK && len >= SX127X_FIFO_CAPACITY) {
|
||||
return ERR_PACKET_TOO_LONG;
|
||||
}
|
||||
|
||||
// call the "full" startTransmit overload
|
||||
return startTransmit(data, len, 0, addr);
|
||||
}
|
||||
|
||||
int16_t SX127x::startTransmit(uint8_t* data, size_t len, size_t&& counter, uint8_t addr) {
|
||||
// set mode to standby
|
||||
int16_t state = setMode(SX127X_STANDBY);
|
||||
|
||||
|
@ -472,12 +485,28 @@ int16_t SX127x::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
|
|||
state |= _mod->SPIsetRegValue(SX127X_REG_FIFO_TX_BASE_ADDR, SX127X_FIFO_TX_BASE_ADDR_MAX);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_FIFO_ADDR_PTR, SX127X_FIFO_TX_BASE_ADDR_MAX);
|
||||
|
||||
// set the counter to the length written to FIFO
|
||||
counter = len;
|
||||
|
||||
// write packet to FIFO
|
||||
_mod->SPIwriteRegisterBurst(SX127X_REG_FIFO, data, len);
|
||||
|
||||
} else if(modem == SX127X_FSK_OOK) {
|
||||
// check packet length
|
||||
if(len >= SX127X_MAX_PACKET_LENGTH_FSK) {
|
||||
return(ERR_PACKET_TOO_LONG);
|
||||
}
|
||||
|
||||
// if packet is too large to fit in the FIFO at once, attach the fifo-refill ISR to DIO1. If no
|
||||
// ISR has been defined by the user, error out.
|
||||
else if (len >= SX127X_FIFO_CAPACITY) {
|
||||
if (_fifoThresholdISR == NULL) {
|
||||
return ERR_PACKET_TOO_LONG;
|
||||
} else {
|
||||
Module::attachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getGpio()), _fifoThresholdISR, RISING);
|
||||
}
|
||||
}
|
||||
|
||||
// set DIO mapping
|
||||
_mod->SPIsetRegValue(SX127X_REG_DIO_MAPPING_1, SX127X_DIO0_PACK_PACKET_SENT, 7, 6);
|
||||
|
||||
|
@ -494,10 +523,13 @@ int16_t SX127x::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
|
|||
if((filter == SX127X_ADDRESS_FILTERING_NODE) || (filter == SX127X_ADDRESS_FILTERING_NODE_BROADCAST)) {
|
||||
_mod->SPIwriteRegister(SX127X_REG_FIFO, addr);
|
||||
}
|
||||
}
|
||||
|
||||
// write packet to FIFO
|
||||
_mod->SPIwriteRegisterBurst(SX127X_REG_FIFO, data, len);
|
||||
// set the byte counter to the length to be written to FIFO
|
||||
counter = min(len, SX127X_FIFO_CAPACITY - 1);
|
||||
|
||||
// write packet to FIFO
|
||||
_mod->SPIwriteRegisterBurst(SX127X_REG_FIFO, data, counter);
|
||||
}
|
||||
|
||||
// set RF switch (if present)
|
||||
_mod->setRfSwitchState(LOW, HIGH);
|
||||
|
@ -509,6 +541,41 @@ int16_t SX127x::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
|
|||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
void SX127x::setFifoThresholdAction(void (*func)(void)) {
|
||||
_fifoThresholdISR = func;
|
||||
}
|
||||
|
||||
int SX127x::fifoAppend(uint8_t* buff, size_t remaining) {
|
||||
// check modem
|
||||
if (getActiveModem() != SX127X_FSK_OOK) {
|
||||
return ERR_WRONG_MODEM;
|
||||
}
|
||||
|
||||
// figure out how much to write
|
||||
uint8_t fifoThresh = _mod->SPIreadRegister(SX127X_FIFO_THRESH) & 0x3F;
|
||||
uint8_t toWrite = min(remaining, SX127X_FIFO_CAPACITY - fifoThresh);
|
||||
|
||||
// write to the register
|
||||
_mod->SPIwriteRegisterBurst(SX127X_REG_FIFO, buff, toWrite);
|
||||
return toWrite;
|
||||
}
|
||||
|
||||
int SX127x::fifoGet(uint8_t* buff, size_t available) {
|
||||
// check modem
|
||||
if (getActiveModem() != SX127X_FSK_OOK) {
|
||||
return ERR_WRONG_MODEM;
|
||||
}
|
||||
|
||||
// figure out how many bytes to read in
|
||||
uint8_t fifoThresh = _mod->SPIreadRegister(SX127X_FIFO_THRESH) & 0x3F;
|
||||
uint8_t toRead = min(available, fifoThresh);
|
||||
|
||||
// write to the register
|
||||
_mod->SPIreadRegisterBurst(SX127X_REG_FIFO, toRead, buff);
|
||||
return toRead;
|
||||
|
||||
}
|
||||
|
||||
int16_t SX127x::readData(uint8_t* data, size_t len) {
|
||||
int16_t modem = getActiveModem();
|
||||
size_t length = len;
|
||||
|
@ -1003,6 +1070,18 @@ int16_t SX127x::variablePacketLengthMode(uint8_t maxLen) {
|
|||
return(SX127x::setPacketMode(SX127X_PACKET_VARIABLE, maxLen));
|
||||
}
|
||||
|
||||
int16_t SX127x::setFifoThreshold(uint8_t cap) {
|
||||
// check active modem
|
||||
if (getActiveModem() != SX127X_FSK_OOK) {
|
||||
return ERR_WRONG_MODEM;
|
||||
} else if (cap > 63) {
|
||||
return ERR_PACKET_TOO_LONG;
|
||||
}
|
||||
|
||||
// write the 6 LSbits to the register
|
||||
return _mod->SPIsetRegValue(SX127X_REG_FIFO_THRESH, cap & 0x3F);
|
||||
}
|
||||
|
||||
int16_t SX127x::setRSSIConfig(uint8_t smoothingSamples, int8_t offset) {
|
||||
// check active modem
|
||||
if(getActiveModem() != SX127X_FSK_OOK) {
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
// SX127x physical layer properties
|
||||
#define SX127X_FREQUENCY_STEP_SIZE 61.03515625
|
||||
#define SX127X_MAX_PACKET_LENGTH 255
|
||||
#define SX127X_MAX_PACKET_LENGTH_FSK 64
|
||||
#define SX127X_MAX_PACKET_LENGTH_FSK 255
|
||||
#define SX127X_FIFO_CAPACITY 64
|
||||
#define SX127X_CRYSTAL_FREQ 32.0
|
||||
#define SX127X_DIV_EXPONENT 19
|
||||
|
||||
|
@ -712,6 +713,16 @@ class SX127x: public PhysicalLayer {
|
|||
*/
|
||||
int16_t startTransmit(uint8_t* data, size_t len, uint8_t addr = 0) override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven binary transmit method. Will start transmitting arbitrary binary data up to 255 bytes long using %LoRa or up to 255 bytes using FSK modem.
|
||||
\param data Binary data that will be transmitted.
|
||||
\param len Length of binary data to transmit (in bytes).
|
||||
\param[out] counter Reference to a variable to track the number of sent bytes in
|
||||
\param addr Node address to transmit the packet to. Only used in FSK mode.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t startTransmit(uint8_t* data, size_t len, size_t&& counter, uint8_t addr = 0) override;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven receive method. DIO0 will be activated when full valid packet is received.
|
||||
|
||||
|
@ -947,6 +958,15 @@ class SX127x: public PhysicalLayer {
|
|||
*/
|
||||
int16_t variablePacketLengthMode(uint8_t maxLen = SX127X_MAX_PACKET_LENGTH_FSK);
|
||||
|
||||
/*!
|
||||
\brief Set the level at which the FIFO Threshold interrupt triggers
|
||||
\param cap A capacity 0-63 for the FIFO buffer.
|
||||
*/
|
||||
int16_t setFifoThreshold(uint8_t cap = 16);
|
||||
void setFifoThresholdAction(void (*func)(void)) override;
|
||||
int fifoAppend(uint8_t* buff, size_t remaining) override;
|
||||
int fifoGet(uint8_t* buff, size_t remaining) override;
|
||||
|
||||
/*!
|
||||
\brief Sets RSSI measurement configuration in FSK mode.
|
||||
|
||||
|
@ -1071,6 +1091,7 @@ class SX127x: public PhysicalLayer {
|
|||
float _dataRate = 0;
|
||||
bool _packetLengthQueried = false; // FSK packet length is the first byte in FIFO, length can only be queried once
|
||||
uint8_t _packetLengthConfig = SX127X_PACKET_VARIABLE;
|
||||
void (*_fifoThresholdISR)(void) = NULL;
|
||||
|
||||
bool findChip(uint8_t ver);
|
||||
int16_t setMode(uint8_t mode);
|
||||
|
|
|
@ -139,6 +139,43 @@ class PhysicalLayer {
|
|||
*/
|
||||
virtual int16_t startTransmit(uint8_t* data, size_t len, uint8_t addr = 0) = 0;
|
||||
|
||||
/*!
|
||||
\brief Interrupt-driven binary transmit method.
|
||||
\param data Binary data that will be transmitted.
|
||||
\param len Length of binary data to transmit (in bytes).
|
||||
\param[out] counter Reference to a variable to track the number of bytes sent in.
|
||||
\param addr Node address to transmit the packet to. Only used in FSK mode.
|
||||
*/
|
||||
virtual int16_t startTransmit(uint8_t* data, size_t len, size_t&& counter, uint8_t add = 0) = 0;
|
||||
|
||||
/*!
|
||||
\brief Set the ISR routine to execute when the FIFO falls below the threshold.
|
||||
|
||||
This interrupt will only be called when transmitting a message larger than the FIFO capacity.
|
||||
|
||||
\param func Pointer to an Interrupt Service Routine. `NULL` will clear action.
|
||||
*/
|
||||
virtual void setFifoThresholdAction(void (*func)(void)) = 0;
|
||||
|
||||
/*!
|
||||
\brief Append more data into the FIFO Buffer
|
||||
|
||||
This is used for stream-based transmissions.
|
||||
|
||||
\param buff A pointer to the start of the data to append
|
||||
\param remaining A pointer to a counter variable
|
||||
\return Number of bytes consumed from `buff`, or error code.
|
||||
*/
|
||||
virtual int16_t fifoAppend(uint8_t* buff, size_t remaining) = 0;
|
||||
|
||||
/*!
|
||||
\brief Read data from the FIFO buffer.
|
||||
\param buff the buffer to read data into
|
||||
\param available the maximum number of bytes available in `buff`
|
||||
\return Number of bytes read in from FIFO, or error code.
|
||||
*/
|
||||
virtual int16_t fifoGet(uint8_t* buff, size_t available) = 0;
|
||||
|
||||
/*!
|
||||
\brief Reads data that was received after calling startReceive method.
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue