diff --git a/src/modules/CC1101/CC1101.cpp b/src/modules/CC1101/CC1101.cpp index 235ef13d..5e2fc776 100644 --- a/src/modules/CC1101/CC1101.cpp +++ b/src/modules/CC1101/CC1101.cpp @@ -85,7 +85,7 @@ int16_t CC1101::begin(float freq, float br, float freqDev, float rxBw, int8_t pw RADIOLIB_ASSERT(state); // flush FIFOs - SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_RX | RADIOLIB_CC1101_CMD_READ); + SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_RX); SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_TX); return(state); @@ -163,6 +163,16 @@ int16_t CC1101::standby() { // set idle mode SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE); + // wait until idle is reached + uint32_t start = this->mod->hal->millis(); + while(SPIgetRegValue(RADIOLIB_CC1101_REG_MARCSTATE, 4, 0) != RADIOLIB_CC1101_MARC_STATE_IDLE) { + mod->hal->yield(); + if(this->mod->hal->millis() - start > 100) { + // timeout, this should really not happen + return(RADIOLIB_ERR_UNKNOWN); + } + }; + // set RF switch (if present) this->mod->setRfSwitchState(Module::MODE_IDLE); return(RADIOLIB_ERR_NONE); @@ -272,9 +282,9 @@ void CC1101::clearGdo2Action() { int16_t CC1101::startTransmit(uint8_t* data, size_t len, uint8_t addr) { // check packet length - /*if(len > RADIOLIB_CC1101_MAX_PACKET_LENGTH) { + if(len > RADIOLIB_CC1101_MAX_PACKET_LENGTH) { return(RADIOLIB_ERR_PACKET_TOO_LONG); - }*/ + } // set mode to standby standby(); @@ -285,46 +295,20 @@ int16_t CC1101::startTransmit(uint8_t* data, size_t len, uint8_t addr) { // 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); - /*int16_t state = RADIOLIB_ERR_NONE; - if(len > RADIOLIB_CC1101_MAX_PACKET_LENGTH) { - state = SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG2, RADIOLIB_CC1101_GDOX_TX_FIFO_ABOVE_THR); - } else { - state = SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG0, RADIOLIB_CC1101_GDOX_SYNC_WORD_SENT_OR_PKT_RECEIVED); - }*/ - - // data put on FIFO - uint8_t dataSent = 0; // optionally write packet length - if (this->packetLengthConfig == RADIOLIB_CC1101_LENGTH_CONFIG_VARIABLE) { - - // enforce variable len limit - if (len > RADIOLIB_CC1101_MAX_PACKET_LENGTH - 1) { - return (RADIOLIB_ERR_PACKET_TOO_LONG); - } - + if(this->packetLengthConfig == RADIOLIB_CC1101_LENGTH_CONFIG_VARIABLE) { 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 - /*if(len > RADIOLIB_CC1101_MAX_PACKET_LENGTH) { - SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_FIFO, data, RADIOLIB_CC1101_FIFO_THRESH_TX); - } else { - uint8_t initialWrite = RADIOLIB_MIN((uint8_t)len, (uint8_t)(RADIOLIB_CC1101_FIFO_SIZE - dataSent)); - SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_FIFO, data, initialWrite); - dataSent += initialWrite; - }*/ - uint8_t initialWrite = RADIOLIB_MIN((uint8_t)len, (uint8_t)(RADIOLIB_CC1101_FIFO_SIZE - dataSent)); - SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_FIFO, data, initialWrite); - dataSent += initialWrite; + SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_FIFO, data, len); // set RF switch (if present) this->mod->setRfSwitchState(Module::MODE_TX); @@ -332,33 +316,7 @@ int16_t CC1101::startTransmit(uint8_t* data, size_t len, uint8_t addr) { // set mode to transmit SPIsendCommand(RADIOLIB_CC1101_CMD_TX); - if(len > RADIOLIB_CC1101_MAX_PACKET_LENGTH) { - return(state); - } - - // keep feeding the FIFO until the packet is over - while (dataSent < len) { - // get number of bytes in FIFO - uint8_t bytesInFIFO = SPIgetRegValue(RADIOLIB_CC1101_REG_TXBYTES, 6, 0); - - // if there's room then put other data - if (bytesInFIFO < RADIOLIB_CC1101_FIFO_SIZE) { - uint8_t bytesToWrite = RADIOLIB_MIN((uint8_t)(RADIOLIB_CC1101_FIFO_SIZE - bytesInFIFO), (uint8_t)(len - dataSent)); - SPIwriteRegisterBurst(RADIOLIB_CC1101_REG_FIFO, &data[dataSent], bytesToWrite); - dataSent += bytesToWrite; - } else { - // wait for radio to send some data - /* - * Does this work for all rates? If 1 ms is longer than the 1ms delay - * then the entire FIFO will be transmitted during that delay. - * - * TODO: test this on real hardware - */ - this->mod->hal->delayMicroseconds(250); - } - } - - return (state); + return(state); } int16_t CC1101::finishTransmit() { @@ -378,12 +336,11 @@ int16_t CC1101::startReceive() { RADIOLIB_ASSERT(state); // flush Rx FIFO - SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_RX | RADIOLIB_CC1101_CMD_READ); + SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_RX); - // set GDO0 mapping: Asserted when RX FIFO > 4 bytes. - state = SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG0, RADIOLIB_CC1101_GDOX_RX_FIFO_FULL_OR_PKT_END); - //state = SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG0, RADIOLIB_CC1101_GDOX_SYNC_WORD_SENT_OR_PKT_RECEIVED); - state |= SPIsetRegValue(RADIOLIB_CC1101_REG_FIFOTHR, RADIOLIB_CC1101_FIFO_THR_TX_61_RX_4, 3, 0); + // set GDO0 mapping + // GDO0 is de-asserted at packet end, hence it is inverted here + state = SPIsetRegValue(RADIOLIB_CC1101_REG_IOCFG0, RADIOLIB_CC1101_GDO0_INV | RADIOLIB_CC1101_GDOX_SYNC_WORD_SENT_OR_PKT_RECEIVED, 6, 0); RADIOLIB_ASSERT(state); // set RF switch (if present) @@ -406,19 +363,10 @@ int16_t CC1101::startReceive(uint32_t timeout, uint16_t irqFlags, uint16_t irqMa int16_t CC1101::readData(uint8_t* data, size_t len) { // get packet length size_t length = getPacketLength(); - /*RADIOLIB_DEBUG_PRINTLN("length = %d", length); - if(length == 0) { - this->packetLengthQueried = false; - standby(); - SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_RX); - return(RADIOLIB_ERR_RX_TIMEOUT); - }*/ if((len != 0) && (len < length)) { // user requested less data than we got, only return what was requested length = len; } - //SPIsendCommand(RADIOLIB_CC1101_CMD_IDLE | RADIOLIB_CC1101_CMD_READ); - SPIreadRegister(RADIOLIB_CC1101_REG_RXBYTES); // check address filtering uint8_t filter = SPIgetRegValue(RADIOLIB_CC1101_REG_PKTCTRL1, 1, 0); @@ -426,41 +374,14 @@ int16_t CC1101::readData(uint8_t* data, size_t len) { SPIreadRegister(RADIOLIB_CC1101_REG_FIFO); } - uint8_t bytesInFIFO = SPIgetRegValue(RADIOLIB_CC1101_REG_RXBYTES, 6, 0); - size_t readBytes = 0; - uint32_t lastPop = this->mod->hal->millis(); - - // keep reading from FIFO until we get all the packet. - while (readBytes < length) { - if (bytesInFIFO == 0) { - if (this->mod->hal->millis() - lastPop > 5) { - // readData was required to read a packet longer than the one received. - RADIOLIB_DEBUG_PRINTLN("No data for more than 5mS. Stop here."); - break; - } else { - this->mod->hal->delay(1); - bytesInFIFO = SPIgetRegValue(RADIOLIB_CC1101_REG_RXBYTES, 6, 0); - continue; - } - } - - // read the minimum between "remaining length" and bytesInFifo - uint8_t bytesToRead = RADIOLIB_MIN((uint8_t)(length - readBytes), bytesInFIFO); - SPIreadRegisterBurst(RADIOLIB_CC1101_REG_FIFO, bytesToRead, &(data[readBytes])); - readBytes += bytesToRead; - lastPop = this->mod->hal->millis(); - - // Get how many bytes are left in FIFO. - bytesInFIFO = SPIgetRegValue(RADIOLIB_CC1101_REG_RXBYTES, 6, 0); - } + // read packet data + SPIreadRegisterBurst(RADIOLIB_CC1101_REG_FIFO, length, data); // check if status bytes are enabled (default: RADIOLIB_CC1101_APPEND_STATUS_ON) bool isAppendStatus = SPIgetRegValue(RADIOLIB_CC1101_REG_PKTCTRL1, 2, 2) == RADIOLIB_CC1101_APPEND_STATUS_ON; - // for some reason, we need this delay here to get the correct status bytes - this->mod->hal->delay(3); - // If status byte is enabled at least 2 bytes (2 status bytes + any following packet) will remain in FIFO. + int16_t state = RADIOLIB_ERR_NONE; if (isAppendStatus) { // read RSSI byte this->rawRSSI = SPIgetRegValue(RADIOLIB_CC1101_REG_FIFO); @@ -470,9 +391,9 @@ int16_t CC1101::readData(uint8_t* data, size_t len) { this->rawLQI = val & 0x7F; // check CRC - if (this->crcOn && (val & RADIOLIB_CC1101_CRC_OK) == RADIOLIB_CC1101_CRC_ERROR) { + if(this->crcOn && (val & RADIOLIB_CC1101_CRC_OK) == RADIOLIB_CC1101_CRC_ERROR) { this->packetLengthQueried = false; - return (RADIOLIB_ERR_CRC_MISMATCH); + state = RADIOLIB_ERR_CRC_MISMATCH; } } @@ -480,16 +401,16 @@ int16_t CC1101::readData(uint8_t* data, size_t len) { this->packetLengthQueried = false; // Flush then standby according to RXOFF_MODE (default: RADIOLIB_CC1101_RXOFF_IDLE) - if (SPIgetRegValue(RADIOLIB_CC1101_REG_MCSM1, 3, 2) == RADIOLIB_CC1101_RXOFF_IDLE) { + if(SPIgetRegValue(RADIOLIB_CC1101_REG_MCSM1, 3, 2) == RADIOLIB_CC1101_RXOFF_IDLE) { // set mode to standby standby(); // flush Rx FIFO - SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_RX | RADIOLIB_CC1101_CMD_READ); + SPIsendCommand(RADIOLIB_CC1101_CMD_FLUSH_RX); } - return(RADIOLIB_ERR_NONE); + return(state); } int16_t CC1101::setFrequency(float freq) { @@ -835,23 +756,15 @@ uint8_t CC1101::getLQI() const { } size_t CC1101::getPacketLength(bool update) { - RADIOLIB_DEBUG_PRINTLN("this->packetLengthQueried=%d", this->packetLengthQueried); - RADIOLIB_DEBUG_PRINTLN("update=%d", update); - RADIOLIB_DEBUG_PRINTLN("this->packetLengthConfig=%d", this->packetLengthConfig); if(!this->packetLengthQueried && update) { - if (this->packetLengthConfig == RADIOLIB_CC1101_LENGTH_CONFIG_VARIABLE) { - this->packetLength = 0; - while(this->packetLength == 0) { - this->packetLength = SPIreadRegister(RADIOLIB_CC1101_REG_FIFO); - } - + if(this->packetLengthConfig == RADIOLIB_CC1101_LENGTH_CONFIG_VARIABLE) { + this->packetLength = SPIreadRegister(RADIOLIB_CC1101_REG_FIFO); } else { this->packetLength = SPIreadRegister(RADIOLIB_CC1101_REG_PKTLEN); } this->packetLengthQueried = true; } - RADIOLIB_DEBUG_PRINTLN("this->packetLength=%d", this->packetLength); return(this->packetLength); } @@ -1131,7 +1044,7 @@ int16_t CC1101::setPacketMode(uint8_t mode, uint16_t len) { int16_t CC1101::SPIgetRegValue(uint8_t reg, uint8_t msb, uint8_t lsb) { // status registers require special command - if(reg > RADIOLIB_CC1101_REG_TEST0) { + if((reg > RADIOLIB_CC1101_REG_TEST0) && (reg < RADIOLIB_CC1101_REG_PATABLE)) { reg |= RADIOLIB_CC1101_CMD_ACCESS_STATUS_REG; } @@ -1140,7 +1053,7 @@ int16_t CC1101::SPIgetRegValue(uint8_t reg, uint8_t msb, uint8_t lsb) { int16_t CC1101::SPIsetRegValue(uint8_t reg, uint8_t value, uint8_t msb, uint8_t lsb, uint8_t checkInterval) { // status registers require special command - if(reg > RADIOLIB_CC1101_REG_TEST0) { + if((reg > RADIOLIB_CC1101_REG_TEST0) && (reg < RADIOLIB_CC1101_REG_PATABLE)) { reg |= RADIOLIB_CC1101_CMD_ACCESS_STATUS_REG; } @@ -1153,7 +1066,7 @@ void CC1101::SPIreadRegisterBurst(uint8_t reg, uint8_t numBytes, uint8_t* inByte uint8_t CC1101::SPIreadRegister(uint8_t reg) { // status registers require special command - if(reg > RADIOLIB_CC1101_REG_TEST0) { + if((reg > RADIOLIB_CC1101_REG_TEST0) && (reg < RADIOLIB_CC1101_REG_PATABLE)) { reg |= RADIOLIB_CC1101_CMD_ACCESS_STATUS_REG; } @@ -1162,7 +1075,7 @@ uint8_t CC1101::SPIreadRegister(uint8_t reg) { void CC1101::SPIwriteRegister(uint8_t reg, uint8_t data) { // status registers require special command - if(reg > RADIOLIB_CC1101_REG_TEST0) { + if((reg > RADIOLIB_CC1101_REG_TEST0) && (reg < RADIOLIB_CC1101_REG_PATABLE)) { reg |= RADIOLIB_CC1101_CMD_ACCESS_STATUS_REG; } diff --git a/src/modules/CC1101/CC1101.h b/src/modules/CC1101/CC1101.h index 012b7bda..a13327e9 100644 --- a/src/modules/CC1101/CC1101.h +++ b/src/modules/CC1101/CC1101.h @@ -8,10 +8,9 @@ // CC1101 physical layer properties #define RADIOLIB_CC1101_FREQUENCY_STEP_SIZE 396.7285156 -#define RADIOLIB_CC1101_MAX_PACKET_LENGTH 255 +#define RADIOLIB_CC1101_MAX_PACKET_LENGTH 63 #define RADIOLIB_CC1101_CRYSTAL_FREQ 26.0 #define RADIOLIB_CC1101_DIV_EXPONENT 16 -#define RADIOLIB_CC1101_FIFO_SIZE 64 // CC1101 SPI commands #define RADIOLIB_CC1101_CMD_READ 0b10000000 @@ -116,8 +115,8 @@ #define RADIOLIB_CC1101_GDO2_INV 0b01000000 // 6 6 active low // RADIOLIB_CC1101_REG_IOCFG1 -#define RADIOLIB_CC1101_GDO1_DS_LOW 0b00000000 // 7 7 GDO1 output drive strength: low (default) -#define RADIOLIB_CC1101_GDO1_DS_HIGH 0b10000000 // 7 7 high +#define RADIOLIB_CC1101_GDO_DS_LOW 0b00000000 // 7 7 GDOx output drive strength: low (default) +#define RADIOLIB_CC1101_GDO_DS_HIGH 0b10000000 // 7 7 high #define RADIOLIB_CC1101_GDO1_NORM 0b00000000 // 6 6 GDO1 output: active high (default) #define RADIOLIB_CC1101_GDO1_INV 0b01000000 // 6 6 active low