[CC1101] Fixed garbage data (#733)

This commit is contained in:
jgromes 2023-08-02 22:08:52 +02:00
parent 72b95e5c82
commit 6247cb7e85
2 changed files with 37 additions and 125 deletions

View file

@ -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;
}

View file

@ -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