[CC1101] FIFO Refills to transmit packets up to 255 bytes (#1404)

* Update CC1101.h

Add Max packet size for FIFO Refills

* Define FIFO Size, Max packet Length for FIFO refills

* FIFO REFILL

- Go through FSTXON State
- Check MARCSTATE to ensure ready to tx
- Initial FIFO fill
- Check FIFO bytes twice in accordance with errata
- Refill FIFO
- Check MARCSTATE is idle before returning

* Fix typos

* Fix another typo

* min -> std::min per build check

* Revert std::min back to min

* Use RADIOLIB_MIN Macro instead of min

* Move MARC State check for Idle to finishTransmit function

Change allows startTransmit to stop blocking once the last bytes are added to the FIFO

* Add timeouts for both MARC state checks

* Fix typo

* No interrupt for packets bigger than 64 bytes

* Initialize state as RADIOLIB_ERR_NONE if avoiding ISR

* Update example with packet size and discussion link

* Update example with new packet size and discussion link

* Update example, clarify blocking on greater than 64 bytes link discussion

* Update doxygen comments for 255 byte limit, limitations and discussion link
This commit is contained in:
Crsarmv7l 2025-02-13 17:20:56 +01:00 committed by GitHub
parent bcbf2a12e1
commit b9c214db95
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 79 additions and 17 deletions

View file

@ -82,10 +82,11 @@ void setup() {
void loop() { void loop() {
Serial.print(F("[CC1101] Transmitting packet ... ")); Serial.print(F("[CC1101] Transmitting packet ... "));
// you can transmit C-string or Arduino string up to 64 characters long // you can transmit C-string or Arduino string up to 255 characters long
int state = radio.transmit("Hello World!"); int state = radio.transmit("Hello World!");
// you can also transmit byte array up to 64 bytes long // you can also transmit byte array up to 255 bytes long
// With some limitations see here: https://github.com/jgromes/RadioLib/discussions/1138
/* /*
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
int state = radio.transmit(byteArr, 8); int state = radio.transmit(byteArr, 8);

View file

@ -2,7 +2,7 @@
RadioLib CC1101 Blocking Transmit Example RadioLib CC1101 Blocking Transmit Example
This example transmits packets using CC1101 FSK radio module. This example transmits packets using CC1101 FSK radio module.
Each packet contains up to 64 bytes of data, in the form of: Each packet contains up to 255 bytes of data with some limitations (https://github.com/jgromes/RadioLib/discussions/1138), in the form of:
- Arduino String - Arduino String
- null-terminated char array (C-string) - null-terminated char array (C-string)
- arbitrary binary data (byte array) - arbitrary binary data (byte array)
@ -57,11 +57,11 @@ int count = 0;
void loop() { void loop() {
Serial.print(F("[CC1101] Transmitting packet ... ")); Serial.print(F("[CC1101] Transmitting packet ... "));
// you can transmit C-string or Arduino string up to 64 characters long // you can transmit C-string or Arduino string up to 255 characters long
String str = "Hello World! #" + String(count++); String str = "Hello World! #" + String(count++);
int state = radio.transmit(str); int state = radio.transmit(str);
// you can also transmit byte array up to 64 bytes long // you can also transmit byte array up to 255 bytes long with some limitations; https://github.com/jgromes/RadioLib/discussions/1138
/* /*
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
int state = radio.transmit(byteArr, 8); int state = radio.transmit(byteArr, 8);
@ -72,7 +72,7 @@ void loop() {
Serial.println(F("success!")); Serial.println(F("success!"));
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) { } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
// the supplied packet was longer than 64 bytes // the supplied packet was longer than 255 bytes
Serial.println(F("too long!")); Serial.println(F("too long!"));
} else { } else {

View file

@ -3,7 +3,7 @@
This example transmits packets using CC1101 FSK radio module. This example transmits packets using CC1101 FSK radio module.
Once a packet is transmitted, an interrupt is triggered. Once a packet is transmitted, an interrupt is triggered.
Each packet contains up to 64 bytes of data, in the form of: Each packet contains up to 255 bytes of data with some limitations (https://github.com/jgromes/RadioLib/discussions/1138), in the form of:
- Arduino String - Arduino String
- null-terminated char array (C-string) - null-terminated char array (C-string)
- arbitrary binary data (byte array) - arbitrary binary data (byte array)
@ -73,10 +73,12 @@ void setup() {
Serial.print(F("[CC1101] Sending first packet ... ")); Serial.print(F("[CC1101] Sending first packet ... "));
// you can transmit C-string or Arduino string up to // you can transmit C-string or Arduino string up to
// 64 characters long // 255 characters long
transmissionState = radio.startTransmit("Hello World!"); transmissionState = radio.startTransmit("Hello World!");
// you can also transmit byte array up to 64 bytes long // you can also transmit byte array up to 255 bytes long
// When transmitting more than 64 bytes startTransmit blocks to refill the FIFO.
// Blocking ceases once the last bytes have been placed in the FIFO
/* /*
byte byteArr[] = {0x01, 0x23, 0x45, 0x56, byte byteArr[] = {0x01, 0x23, 0x45, 0x56,
0x78, 0xAB, 0xCD, 0xEF}; 0x78, 0xAB, 0xCD, 0xEF};
@ -119,11 +121,11 @@ void loop() {
Serial.print(F("[CC1101] Sending another packet ... ")); Serial.print(F("[CC1101] Sending another packet ... "));
// you can transmit C-string or Arduino string up to // you can transmit C-string or Arduino string up to
// 64 characters long // 255 characters long
String str = "Hello World! #" + String(count++); String str = "Hello World! #" + String(count++);
transmissionState = radio.startTransmit(str); transmissionState = radio.startTransmit(str);
// you can also transmit byte array up to 64 bytes long // you can also transmit byte array up to 255 bytes long with limitations https://github.com/jgromes/RadioLib/discussions/1138
/* /*
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
0x89, 0xAB, 0xCD, 0xEF}; 0x89, 0xAB, 0xCD, 0xEF};

View file

@ -236,23 +236,49 @@ int16_t CC1101::startTransmit(const uint8_t* data, size_t len, uint8_t addr) {
// flush Tx FIFO // flush Tx FIFO
SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_TX); SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_TX);
// set GDO0 mapping // Turn on freq oscilator
int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG2, RADIOLIB_CC1101_GDOX_SYNC_WORD_SENT_OR_PKT_RECEIVED, 5, 0); SPIsendCommand(RADIOLIB_CC1101_CMD_FSTXON);
// Check MARCSTATE and wait until ready to tx
// 724us is the longest time for calibrate per datasheet
RadioLibTime_t start = this->mod->hal->micros();
while(SPIgetRegValue(RADIOLIB_CC1101_REG_MARCSTATE, 4, 0) != 0x12) {
if(this->mod->hal->micros() - start > 724) {
standby();
return(RADIOLIB_ERR_TX_TIMEOUT);
}
}
// set GDO0 mapping only if we aren't refilling the FIFO
int16_t state = RADIOLIB_ERR_NONE;
if(len <= RADIOLIB_CC1101_FIFO_SIZE) {
state = SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG2, RADIOLIB_CC1101_GDOX_SYNC_WORD_SENT_OR_PKT_RECEIVED, 5, 0);
RADIOLIB_ASSERT(state); RADIOLIB_ASSERT(state);
}
// data put on FIFO
uint8_t dataSent = 0;
// optionally write packet length // optionally write packet length
if(this->packetLengthConfig == RADIOLIB_CC1101_LENGTH_CONFIG_VARIABLE) { if(this->packetLengthConfig == RADIOLIB_CC1101_LENGTH_CONFIG_VARIABLE) {
if (len > RADIOLIB_CC1101_MAX_PACKET_LENGTH - 1) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}
SPIwriteRegister(RADIOLIB_CC1101_REG_FIFO, len); SPIwriteRegister(RADIOLIB_CC1101_REG_FIFO, len);
dataSent+= 1;
} }
// check address filtering // check address filtering
uint8_t filter = SPIgetRegValue(RADIOLIB_CC1101_REG_PKTCTRL1, 1, 0); uint8_t filter = SPIgetRegValue(RADIOLIB_CC1101_REG_PKTCTRL1, 1, 0);
if(filter != RADIOLIB_CC1101_ADR_CHK_NONE) { if(filter != RADIOLIB_CC1101_ADR_CHK_NONE) {
SPIwriteRegister(RADIOLIB_CC1101_REG_FIFO, addr); SPIwriteRegister(RADIOLIB_CC1101_REG_FIFO, addr);
dataSent += 1;
} }
// fill the FIFO // fill the FIFO
SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_FIFO, const_cast<uint8_t*>(data), len); uint8_t initialWrite = RADIOLIB_MIN((uint8_t)len, (uint8_t)(RADIOLIB_CC1101_FIFO_SIZE - dataSent));
SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_FIFO, const_cast<uint8_t*>(data), initialWrite);
dataSent += initialWrite;
// set RF switch (if present) // set RF switch (if present)
this->mod->setRfSwitchState(Module::MODE_TX); this->mod->setRfSwitchState(Module::MODE_TX);
@ -260,11 +286,40 @@ int16_t CC1101::startTransmit(const uint8_t* data, size_t len, uint8_t addr) {
// set mode to transmit // set mode to transmit
SPIsendCommand(RADIOLIB_CC1101_CMD_TX); SPIsendCommand(RADIOLIB_CC1101_CMD_TX);
// Keep feeding the FIFO until the packet is done
while (dataSent < len) {
uint8_t fifoBytes = 0;
uint8_t prevFifobytes = 0;
// Check number of bytes on FIFO twice due to the CC1101 errata. Block until two reads are equal.
do{
fifoBytes = SPIgetRegValue(RADIOLIB_CC1101_REG_TXBYTES, 6, 0);
prevFifobytes = SPIgetRegValue(RADIOLIB_CC1101_REG_TXBYTES, 6, 0);
} while (fifoBytes != prevFifobytes);
//If there is room add more data to the FIFO
if (fifoBytes < RADIOLIB_CC1101_FIFO_SIZE) {
uint8_t bytesToWrite = RADIOLIB_MIN((uint8_t)(RADIOLIB_CC1101_FIFO_SIZE - fifoBytes), (uint8_t)(len - dataSent));
SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_FIFO, const_cast<uint8_t*>(&data[dataSent]), bytesToWrite);
dataSent += bytesToWrite;
}
}
return(state); return(state);
} }
int16_t CC1101::finishTransmit() { int16_t CC1101::finishTransmit() {
// set mode to standby to disable transmitter/RF switch // set mode to standby to disable transmitter/RF switch
// Check MARCSTATE for Idle to let anything in the FIFO empty
// Timeout is 2x FIFO transmit time
RadioLibTime_t timeout = (1.0f/(this->bitRate))*(RADIOLIB_CC1101_FIFO_SIZE*2.0f);
RadioLibTime_t start = this->mod->hal->millis();
while(SPIgetRegValue(RADIOLIB_CC1101_REG_MARCSTATE, 4, 0) != 0x01) {
if(this->mod->hal->millis() - start > timeout) {
return(RADIOLIB_ERR_TX_TIMEOUT);
}
}
int16_t state = standby(); int16_t state = standby();
RADIOLIB_ASSERT(state); RADIOLIB_ASSERT(state);

View file

@ -8,7 +8,8 @@
// CC1101 physical layer properties // CC1101 physical layer properties
#define RADIOLIB_CC1101_FREQUENCY_STEP_SIZE 396.7285156 #define RADIOLIB_CC1101_FREQUENCY_STEP_SIZE 396.7285156
#define RADIOLIB_CC1101_MAX_PACKET_LENGTH 64 #define RADIOLIB_CC1101_MAX_PACKET_LENGTH 255
#define RADIOLIB_CC1101_FIFO_SIZE 64
#define RADIOLIB_CC1101_CRYSTAL_FREQ 26.0f #define RADIOLIB_CC1101_CRYSTAL_FREQ 26.0f
#define RADIOLIB_CC1101_DIV_EXPONENT 16 #define RADIOLIB_CC1101_DIV_EXPONENT 16
@ -701,7 +702,10 @@ class CC1101: public PhysicalLayer {
void clearPacketSentAction() override; void clearPacketSentAction() override;
/*! /*!
\brief Interrupt-driven binary transmit method. \brief Interrupt-driven binary transmit method for packets less than 64 bytes.
Method blocks for packets longer than 64 bytes up to a 255 byte limit, until
the last bytes are placed in the FIFO. Some limitations and issues apply; see discussion:
https://github.com/jgromes/RadioLib/discussions/1138
Overloads for string-based transmissions are implemented in PhysicalLayer. Overloads for string-based transmissions are implemented in PhysicalLayer.
\param data Binary data to be sent. \param data Binary data to be sent.
\param len Number of bytes to send. \param len Number of bytes to send.