Hello,
I have problems where CC1101 receives oversize packets thus I have implemented a code where this should be
taken care of. A display panel (user interface) communicates with control unit using CC1101 at both ends.
Display panel uses RTOS where polling of GDO0 is done regularly in own task. When SW detects that a new RF packet
is received (RTOS_checkNewPacket function) it commands the chip to IDLE, then handles it (CC_DataReady function) by checking first the length of the packet. If the packet is larger than 60 bytes (oversize packet), the bytes in fifo
are still read in local ram array, radio is set to idle, both rx and tx fifos are flushed and power (Vdd) to radio chip is cycled. After power cycling
the radio is initialized and calibrated and set to RX. When a correct size packet is received, a packet is read from FIFO to local ram array.
After the data is read the radio is checked to be in IDLE state and then RX FIFO is flushed. After flushing the fifo size is checked to be zero.
If not, the chip is set to IDLE and FIFO is flushed again. At the end of the receive function the chip is set to RX. Question is that is my code properly implemented?
Especially the RX FIFO flushing? Is there any delays needed between the commands like in my implementation? Is there any reports that flushing of RX fifo has been failing?
When multiple parallel display/control units are communication within same RF range, I will get occasionally over 60 bytes packets in FIFO and I have to give a power cycle to radio.
With less parallel systems I will get fewer oversize packets.
I have read that when the CRC is ok, reading the FIFO is sufficient and FIFO FLUSH is not mandatory. Am I correct? Display unit has also USB stick which is run in idle task by RTOS.
The SW polls the USB stick regularly to see if it is connected or not. And sometimes even inserting the USB stick to HW generates oversize packet in RX FIFO but not always.
Thanks for your help!
Best Regards,
Mikko
Here is my code:
Polling of new packet:
static void RTOS_checkNewPacket(void)
{
if (GET_GD0())
{
CC_ENTER_IDLE(); //Set CC1101 to idle before reading the RX fifo and to reject new packets
CC_WriteStrobe(CC_SNOP); //Write NOP to get correct CC1101 state
CC_DataReady(); //Read the packet from RX fifo
}
}
/////////////////////////////////////////////////////////////////
Handling of new packet:
void CC_DataReady(void)
{
taskENTER_CRITICAL();
uint8_t FifoSize = CC_ReadRegister(CC_RXBYTES); //!Read the packet length
if (FifoSize > 60)
{
CC_ReadRX(&CC.RX_PktArray[0], FifoSize); //! ...read all data
taskEXIT_CRITICAL();
RFNw_PowercycleRadio();
return;
}
else if (FifoSize > 0)
{ //!If data is received...
CC_ReadRX(&CC.RX_PktArray[0], FifoSize); //! ...read all data
CC.RSSI = CC_ConvRSSI(CC.RX_PktArray[FifoSize - 2]); //! Get the RSSI value for this reception
CC.RX_len = FifoSize; //!Store data length for future use
irqFixTaskSched.CC_RX = true; //! New Packet got, handle it later;
}
else {
CC.RX_len = 0;
}
CC_GET_STATE(); //Get Radio state
while (CC.State != CC_STB_IDLE) //Make sure that CC1101 is in idle before flushing RX fifo
CC_FLUSH_RX_FIFO(); //Flush RX fifo
CC_WriteStrobe(CC_SNOP); //Write NOP before entering RX state (just to make some delay)
FifoSize = CC_ReadRegister(CC_RXBYTES); //!Read the packet length
if (FifoSize) {
CC_ENTER_IDLE();
CC_WriteStrobe(CC_SNOP); //Keep short delay to get correct state from CC1101
CC_GET_STATE(); //Get Radio state
while (CC.State != CC_STB_IDLE) //Make sure that CC1101 is in idle before flushing RX fifo
CC_FLUSH_RX_FIFO(); //Flush RX fifo
}
CC_ENTER_RX(); //!Re-enter RX
taskEXIT_CRITICAL();
}