diff --git a/src/modules/CC1101/CC1101.cpp b/src/modules/CC1101/CC1101.cpp index 380658bd..3f02dbeb 100644 --- a/src/modules/CC1101/CC1101.cpp +++ b/src/modules/CC1101/CC1101.cpp @@ -218,24 +218,54 @@ int16_t CC1101::startTransmit(uint8_t* data, size_t len, uint8_t addr) { int16_t state = SPIsetRegValue(CC1101_REG_IOCFG0, CC1101_GDOX_SYNC_WORD_SENT_OR_RECEIVED); RADIOLIB_ASSERT(state); + // data put on FIFO. + uint8_t dataSent = 0; + // optionally write packet length if (_packetLengthConfig == CC1101_LENGTH_CONFIG_VARIABLE) { + + // enforce variable len limit. + if (len > 254) { + return (ERR_PACKET_TOO_LONG); + } + SPIwriteRegister(CC1101_REG_FIFO, len); + dataSent += 1; } // check address filtering uint8_t filter = SPIgetRegValue(CC1101_REG_PKTCTRL1, 1, 0); if(filter != CC1101_ADR_CHK_NONE) { SPIwriteRegister(CC1101_REG_FIFO, addr); + dataSent += 1; } - // write packet to FIFO - SPIwriteRegisterBurst(CC1101_REG_FIFO, data, len); + // fill the FIFO. + uint8_t initialWrite = min(len, (CC1101_FIFO_SIZE - dataSent)); + SPIwriteRegisterBurst(CC1101_REG_FIFO, data, initialWrite); + dataSent += initialWrite; // set mode to transmit SPIsendCommand(CC1101_CMD_TX); - return(state); + // keep feeding the FIFO until the packet is over. + uint8_t bytesInFIFO; + while (dataSent < len) { + // get number of bytes in FIFO. + bytesInFIFO = SPIgetRegValue(CC1101_REG_TXBYTES, 6, 0); + + // if there's room then put other data. + if (bytesInFIFO < CC1101_FIFO_SIZE) { + uint8_t bytesToWrite = min(CC1101_FIFO_SIZE - bytesInFIFO, len - dataSent); + SPIwriteRegisterBurst(CC1101_REG_FIFO, &data[dataSent], bytesToWrite); + dataSent += bytesToWrite; + } else { + // wait for radio to send some data. + delay(1); + } + } + + return (state); } int16_t CC1101::startReceive() { @@ -851,3 +881,8 @@ void CC1101::SPIsendCommand(uint8_t cmd) { SPI.endTransaction(); Module::digitalWrite(_mod->getCs(), HIGH); } + +uint8_t CC1101::min(uint8_t a, uint8_t b) { + if (a < b) return a; + return b; +} \ No newline at end of file diff --git a/src/modules/CC1101/CC1101.h b/src/modules/CC1101/CC1101.h index 2486647f..5d27c420 100644 --- a/src/modules/CC1101/CC1101.h +++ b/src/modules/CC1101/CC1101.h @@ -8,9 +8,10 @@ // CC1101 physical layer properties #define CC1101_FREQUENCY_STEP_SIZE 396.7285156 -#define CC1101_MAX_PACKET_LENGTH 63 +#define CC1101_MAX_PACKET_LENGTH 255 #define CC1101_CRYSTAL_FREQ 26.0 #define CC1101_DIV_EXPONENT 16 +#define CC1101_FIFO_SIZE 64 // CC1101 SPI commands #define CC1101_CMD_READ 0b10000000 @@ -168,7 +169,7 @@ #define CC1101_RX_ATTEN_6_DB 0b00010000 // 5 4 6 dB #define CC1101_RX_ATTEN_12_DB 0b00100000 // 5 4 12 dB #define CC1101_RX_ATTEN_18_DB 0b00110000 // 5 4 18 dB -#define CC1101_FIFO_THR 0b00000111 // 5 4 Rx FIFO threshold [bytes] = CC1101_FIFO_THR * 4; Tx FIFO threshold [bytes] = 65 - (CC1101_FIFO_THR * 4) +#define CC1101_FIFO_THR_TX_61_RX_4 0b00000000 // 3 0 TX fifo threshold: 61, RX fifo threshold: 4 // CC1101_REG_SYNC1 #define CC1101_SYNC_WORD_MSB 0xD3 // 7 0 sync word MSB @@ -884,6 +885,8 @@ class CC1101: public PhysicalLayer { uint8_t _syncWordLength; int8_t _power; + uint8_t min(uint8_t a, uint8_t b); + int16_t config(); int16_t directMode(); void getExpMant(float target, uint16_t mantOffset, uint8_t divExp, uint8_t expMax, uint8_t& exp, uint8_t& mant);