[Si443x] Fix CRC error IRQ (#1430)
This commit is contained in:
parent
d526ac3091
commit
416f52d92a
2 changed files with 64 additions and 33 deletions
|
@ -28,7 +28,7 @@ int16_t Si443x::begin(float br, float freqDev, float rxBw, uint8_t preambleLen)
|
|||
this->mod->SPIwriteRegister(RADIOLIB_SI443X_REG_OP_FUNC_CONTROL_1, RADIOLIB_SI443X_SOFTWARE_RESET);
|
||||
|
||||
// clear POR interrupt
|
||||
clearIRQFlags();
|
||||
clearIrqStatus();
|
||||
|
||||
// configure settings not accessible by API
|
||||
int16_t state = config();
|
||||
|
@ -107,7 +107,7 @@ int16_t Si443x::receive(uint8_t* data, size_t len) {
|
|||
while(this->mod->hal->digitalRead(this->mod->getIrq())) {
|
||||
if(this->mod->hal->millis() - start > timeout) {
|
||||
standby();
|
||||
clearIRQFlags();
|
||||
clearIrqStatus();
|
||||
return(RADIOLIB_ERR_RX_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
@ -243,7 +243,7 @@ int16_t Si443x::startTransmit(const uint8_t* data, size_t len, uint8_t addr) {
|
|||
this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_OP_FUNC_CONTROL_2, RADIOLIB_SI443X_TX_FIFO_CLEAR, 0, 0);
|
||||
|
||||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
clearIrqStatus();
|
||||
|
||||
// set packet length
|
||||
if (this->packetLengthConfig == RADIOLIB_SI443X_FIXED_PACKET_LENGTH_OFF) {
|
||||
|
@ -271,7 +271,7 @@ int16_t Si443x::startTransmit(const uint8_t* data, size_t len, uint8_t addr) {
|
|||
|
||||
int16_t Si443x::finishTransmit() {
|
||||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
clearIrqStatus();
|
||||
|
||||
// set mode to standby to disable transmitter/RF switch
|
||||
return(standby());
|
||||
|
@ -287,7 +287,7 @@ int16_t Si443x::startReceive() {
|
|||
this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_OP_FUNC_CONTROL_2, RADIOLIB_SI443X_RX_FIFO_CLEAR, 1, 1);
|
||||
|
||||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
clearIrqStatus();
|
||||
|
||||
// set RF switch (if present)
|
||||
this->mod->setRfSwitchState(Module::MODE_RX);
|
||||
|
@ -311,8 +311,15 @@ int16_t Si443x::startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMa
|
|||
}
|
||||
|
||||
int16_t Si443x::readData(uint8_t* data, size_t len) {
|
||||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
// read interrupt flags
|
||||
uint32_t irq = getIrqFlags();
|
||||
|
||||
// check integrity CRC
|
||||
// Si443x does not have the option to keep the data after CRC failed
|
||||
// reading the FIFO will just repeat the first byte (see https://github.com/jgromes/RadioLib/issues/1430)
|
||||
if(irq & RADIOLIB_SI443X_CRC_ERROR_INTERRUPT) {
|
||||
return(RADIOLIB_ERR_CRC_MISMATCH);
|
||||
}
|
||||
|
||||
// get packet length
|
||||
size_t length = getPacketLength();
|
||||
|
@ -339,7 +346,7 @@ int16_t Si443x::readData(uint8_t* data, size_t len) {
|
|||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
clearIrqStatus();
|
||||
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
@ -635,6 +642,18 @@ int16_t Si443x::variablePacketLengthMode(uint8_t maxLen) {
|
|||
return(Si443x::setPacketMode(RADIOLIB_SI443X_FIXED_PACKET_LENGTH_OFF, maxLen));
|
||||
}
|
||||
|
||||
uint32_t Si443x::getIrqFlags() {
|
||||
uint8_t data[] = { 0x00, 0x00 };
|
||||
this->mod->SPIreadRegisterBurst(RADIOLIB_SI443X_REG_INTERRUPT_STATUS_1, 2, data);
|
||||
return(((uint32_t)(data[0]) << 8) | data[1]);
|
||||
}
|
||||
|
||||
int16_t Si443x::clearIrqFlags(uint32_t irq) {
|
||||
(void)irq;
|
||||
(void)getIrqFlags();
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
||||
Module* Si443x::getMod() {
|
||||
return(this->mod);
|
||||
}
|
||||
|
@ -707,9 +726,8 @@ bool Si443x::findChip() {
|
|||
return(flagFound);
|
||||
}
|
||||
|
||||
void Si443x::clearIRQFlags() {
|
||||
uint8_t buff[2];
|
||||
this->mod->SPIreadRegisterBurst(RADIOLIB_SI443X_REG_INTERRUPT_STATUS_1, 2, buff);
|
||||
void Si443x::clearIrqStatus() {
|
||||
(void)getIrqFlags();
|
||||
}
|
||||
|
||||
void Si443x::clearFIFO(size_t count) {
|
||||
|
|
|
@ -128,19 +128,19 @@
|
|||
#define RADIOLIB_SI443X_IDLE 0b00000000 // 1 0 idle
|
||||
|
||||
// RADIOLIB_SI443X_REG_INTERRUPT_STATUS_1
|
||||
#define RADIOLIB_SI443X_FIFO_LEVEL_ERROR_INTERRUPT 0b10000000 // 7 7 Tx/Rx FIFO overflow or underflow
|
||||
#define RADIOLIB_SI443X_TX_FIFO_ALMOST_FULL_INTERRUPT 0b01000000 // 6 6 Tx FIFO almost full
|
||||
#define RADIOLIB_SI443X_TX_FIFO_ALMOST_EMPTY_INTERRUPT 0b00100000 // 5 5 Tx FIFO almost empty
|
||||
#define RADIOLIB_SI443X_RX_FIFO_ALMOST_FULL_INTERRUPT 0b00010000 // 4 4 Rx FIFO almost full
|
||||
#define RADIOLIB_SI443X_EXTERNAL_INTERRUPT 0b00001000 // 3 3 external interrupt occurred on GPIOx
|
||||
#define RADIOLIB_SI443X_PACKET_SENT_INTERRUPT 0b00000100 // 2 2 packet transmission done
|
||||
#define RADIOLIB_SI443X_VALID_PACKET_RECEIVED_INTERRUPT 0b00000010 // 1 1 valid packet has been received
|
||||
#define RADIOLIB_SI443X_CRC_ERROR_INTERRUPT 0b00000001 // 0 0 CRC failed
|
||||
#define RADIOLIB_SI443X_FIFO_LEVEL_ERROR_INTERRUPT 0b10000000 << 8 // 7 7 Tx/Rx FIFO overflow or underflow
|
||||
#define RADIOLIB_SI443X_TX_FIFO_ALMOST_FULL_INTERRUPT 0b01000000 << 8 // 6 6 Tx FIFO almost full
|
||||
#define RADIOLIB_SI443X_TX_FIFO_ALMOST_EMPTY_INTERRUPT 0b00100000 << 8 // 5 5 Tx FIFO almost empty
|
||||
#define RADIOLIB_SI443X_RX_FIFO_ALMOST_FULL_INTERRUPT 0b00010000 << 8 // 4 4 Rx FIFO almost full
|
||||
#define RADIOLIB_SI443X_EXTERNAL_INTERRUPT 0b00001000 << 8 // 3 3 external interrupt occurred on GPIOx
|
||||
#define RADIOLIB_SI443X_PACKET_SENT_INTERRUPT 0b00000100 << 8 // 2 2 packet transmission done
|
||||
#define RADIOLIB_SI443X_VALID_PACKET_RECEIVED_INTERRUPT 0b00000010 << 8 // 1 1 valid packet has been received
|
||||
#define RADIOLIB_SI443X_CRC_ERROR_INTERRUPT 0b00000001 << 8 // 0 0 CRC failed
|
||||
|
||||
// RADIOLIB_SI443X_REG_INTERRUPT_STATUS_2
|
||||
#define RADIOLIB_SI443X_SYNC_WORD_DETECTED_INTERRUPT 0b10000000 // 7 7 sync word has been detected
|
||||
#define RADIOLIB_SI443X_VALID_RADIOLIB_PREAMBLE_DETECTED_INTERRUPT 0b01000000 // 6 6 valid preamble has been detected
|
||||
#define RADIOLIB_SI443X_INVALID_RADIOLIB_PREAMBLE_DETECTED_INTERRUPT 0b00100000 // 5 5 invalid preamble has been detected
|
||||
#define RADIOLIB_SI443X_VALID_PREAMBLE_DETECTED_INTERRUPT 0b01000000 // 6 6 valid preamble has been detected
|
||||
#define RADIOLIB_SI443X_INVALID_PREAMBLE_DETECTED_INTERRUPT 0b00100000 // 5 5 invalid preamble has been detected
|
||||
#define RADIOLIB_SI443X_RSSI_INTERRUPT 0b00010000 // 4 4 RSSI exceeded programmed threshold
|
||||
#define RADIOLIB_SI443X_WAKEUP_TIMER_INTERRUPT 0b00001000 // 3 3 wake-up timer expired
|
||||
#define RADIOLIB_SI443X_LOW_BATTERY_INTERRUPT 0b00000100 // 2 2 low battery detected
|
||||
|
@ -159,8 +159,8 @@
|
|||
|
||||
// RADIOLIB_SI443X_REG_INTERRUPT_ENABLE_2
|
||||
#define RADIOLIB_SI443X_SYNC_WORD_DETECTED_ENABLED 0b10000000 // 7 7 sync word interrupt enabled
|
||||
#define RADIOLIB_SI443X_VALID_RADIOLIB_PREAMBLE_DETECTED_ENABLED 0b01000000 // 6 6 valid preamble interrupt enabled
|
||||
#define RADIOLIB_SI443X_INVALID_RADIOLIB_PREAMBLE_DETECTED_ENABLED 0b00100000 // 5 5 invalid preamble interrupt enabled
|
||||
#define RADIOLIB_SI443X_VALID_PREAMBLE_DETECTED_ENABLED 0b01000000 // 6 6 valid preamble interrupt enabled
|
||||
#define RADIOLIB_SI443X_INVALID_PREAMBLE_DETECTED_ENABLED 0b00100000 // 5 5 invalid preamble interrupt enabled
|
||||
#define RADIOLIB_SI443X_RSSI_ENABLED 0b00010000 // 4 4 RSSI exceeded programmed threshold interrupt enabled
|
||||
#define RADIOLIB_SI443X_WAKEUP_TIMER_ENABLED 0b00001000 // 3 3 wake-up timer interrupt enabled
|
||||
#define RADIOLIB_SI443X_LOW_BATTERY_ENABLED 0b00000100 // 2 2 low battery interrupt enabled
|
||||
|
@ -810,18 +810,31 @@ class Si443x: public PhysicalLayer {
|
|||
#endif
|
||||
|
||||
/*!
|
||||
\brief Set modem in fixed packet length mode.
|
||||
\param len Packet length.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t fixedPacketLengthMode(uint8_t len = RADIOLIB_SI443X_MAX_PACKET_LENGTH);
|
||||
\brief Set modem in fixed packet length mode.
|
||||
\param len Packet length.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t fixedPacketLengthMode(uint8_t len = RADIOLIB_SI443X_MAX_PACKET_LENGTH);
|
||||
|
||||
/*!
|
||||
\brief Set modem in variable packet length mode.
|
||||
\param maxLen Maximum packet length.
|
||||
\brief Set modem in variable packet length mode.
|
||||
\param maxLen Maximum packet length.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t variablePacketLengthMode(uint8_t maxLen = RADIOLIB_SI443X_MAX_PACKET_LENGTH);
|
||||
*/
|
||||
int16_t variablePacketLengthMode(uint8_t maxLen = RADIOLIB_SI443X_MAX_PACKET_LENGTH);
|
||||
|
||||
/*!
|
||||
\brief Read currently active IRQ flags.
|
||||
\returns IRQ flags.
|
||||
*/
|
||||
uint32_t getIrqFlags() override;
|
||||
|
||||
/*!
|
||||
\brief Clear interrupt on a specific IRQ bit (e.g. RxTimeout, CadDone).
|
||||
\param irq Module-specific IRQ flags.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t clearIrqFlags(uint32_t irq) override;
|
||||
|
||||
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
|
||||
protected:
|
||||
|
@ -847,7 +860,7 @@ class Si443x: public PhysicalLayer {
|
|||
uint8_t packetLengthConfig = RADIOLIB_SI443X_FIXED_PACKET_LENGTH_ON;
|
||||
|
||||
bool findChip();
|
||||
void clearIRQFlags();
|
||||
void clearIrqStatus();
|
||||
void clearFIFO(size_t count);
|
||||
int16_t config();
|
||||
int16_t updateClockRecovery();
|
||||
|
|
Loading…
Add table
Reference in a new issue