diff --git a/examples/CC1101/CC1101_Transmit_Address/CC1101_Transmit_Address.ino b/examples/CC1101/CC1101_Transmit_Address/CC1101_Transmit_Address.ino index 89fef51c0..704201562 100644 --- a/examples/CC1101/CC1101_Transmit_Address/CC1101_Transmit_Address.ino +++ b/examples/CC1101/CC1101_Transmit_Address/CC1101_Transmit_Address.ino @@ -82,10 +82,11 @@ void setup() { void loop() { 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!"); - // 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}; int state = radio.transmit(byteArr, 8); diff --git a/examples/CC1101/CC1101_Transmit_Blocking/CC1101_Transmit_Blocking.ino b/examples/CC1101/CC1101_Transmit_Blocking/CC1101_Transmit_Blocking.ino index 3f45061d9..809cfa60b 100644 --- a/examples/CC1101/CC1101_Transmit_Blocking/CC1101_Transmit_Blocking.ino +++ b/examples/CC1101/CC1101_Transmit_Blocking/CC1101_Transmit_Blocking.ino @@ -2,7 +2,7 @@ RadioLib CC1101 Blocking Transmit Example 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 - null-terminated char array (C-string) - arbitrary binary data (byte array) @@ -57,11 +57,11 @@ int count = 0; void loop() { 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++); 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}; int state = radio.transmit(byteArr, 8); @@ -72,7 +72,7 @@ void loop() { Serial.println(F("success!")); } 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!")); } else { diff --git a/examples/CC1101/CC1101_Transmit_Interrupt/CC1101_Transmit_Interrupt.ino b/examples/CC1101/CC1101_Transmit_Interrupt/CC1101_Transmit_Interrupt.ino index e1d88624e..e99e1910c 100644 --- a/examples/CC1101/CC1101_Transmit_Interrupt/CC1101_Transmit_Interrupt.ino +++ b/examples/CC1101/CC1101_Transmit_Interrupt/CC1101_Transmit_Interrupt.ino @@ -3,7 +3,7 @@ This example transmits packets using CC1101 FSK radio module. 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 - null-terminated char array (C-string) - arbitrary binary data (byte array) @@ -73,10 +73,12 @@ void setup() { Serial.print(F("[CC1101] Sending first packet ... ")); // you can transmit C-string or Arduino string up to - // 64 characters long + // 255 characters long 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, 0x78, 0xAB, 0xCD, 0xEF}; @@ -119,11 +121,11 @@ void loop() { Serial.print(F("[CC1101] Sending another packet ... ")); // you can transmit C-string or Arduino string up to - // 64 characters long + // 255 characters long String str = "Hello World! #" + String(count++); 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, 0x89, 0xAB, 0xCD, 0xEF}; diff --git a/src/modules/CC1101/CC1101.cpp b/src/modules/CC1101/CC1101.cpp index 1c0222c16..288be6333 100644 --- a/src/modules/CC1101/CC1101.cpp +++ b/src/modules/CC1101/CC1101.cpp @@ -236,23 +236,49 @@ int16_t CC1101::startTransmit(const uint8_t* data, size_t len, uint8_t addr) { // flush Tx FIFO SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_TX); - // set GDO0 mapping - int16_t state = SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG2, RADIOLIB_CC1101_GDOX_SYNC_WORD_SENT_OR_PKT_RECEIVED, 5, 0); - RADIOLIB_ASSERT(state); + // Turn on freq oscilator + 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); + } + + // data put on FIFO + uint8_t dataSent = 0; // optionally write packet length 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); + dataSent+= 1; } // check address filtering uint8_t filter = SPIgetRegValue(RADIOLIB_CC1101_REG_PKTCTRL1, 1, 0); if(filter != RADIOLIB_CC1101_ADR_CHK_NONE) { SPIwriteRegister(RADIOLIB_CC1101_REG_FIFO, addr); + dataSent += 1; } // fill the FIFO - SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_FIFO, const_cast(data), len); + uint8_t initialWrite = RADIOLIB_MIN((uint8_t)len, (uint8_t)(RADIOLIB_CC1101_FIFO_SIZE - dataSent)); + SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_FIFO, const_cast(data), initialWrite); + dataSent += initialWrite; // set RF switch (if present) 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 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(&data[dataSent]), bytesToWrite); + dataSent += bytesToWrite; + } + } return(state); } int16_t CC1101::finishTransmit() { // 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(); RADIOLIB_ASSERT(state); diff --git a/src/modules/CC1101/CC1101.h b/src/modules/CC1101/CC1101.h index 576f8d739..d85179d2c 100644 --- a/src/modules/CC1101/CC1101.h +++ b/src/modules/CC1101/CC1101.h @@ -8,7 +8,8 @@ // CC1101 physical layer properties #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_DIV_EXPONENT 16 @@ -701,7 +702,10 @@ class CC1101: public PhysicalLayer { 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. \param data Binary data to be sent. \param len Number of bytes to send.