Because of the holidays, TI E2E™ design support forum responses will be delayed from Dec. 25 through Jan. 2. Thank you for your patience.

This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2500: CC2500 receiver hangs intermittently

Part Number: CC2500
Other Parts Discussed in Thread: TEST2

Hi, 

   I have a design with one transmitter and two receiver . I have a strange problem that if the transmitter is operated while moving away from the receiver, at some distance both the receiver hangs and only the power cycling the receiver will make it work again. If i work within  3 or 4 mts range there won't be any problem and if the transmitter goes beyond certain range then the problem arises. Does it have anything to do with flushing out the Garbage data from FIFO ?

    The testing environment is 40 x 50 feet open hall. The transmitter is hand held battery device operated with a 3.7V and receiver is connected with clean UPS power and no other electrical / RF interference.

     The packet size I send  is 3 bytes to both receivers.

Below are my RF settings.

 The packet size I send  is 3 bytes to both receivers.

/* Chipcon */
/* Product = CC2500 */
/* Chip version = E */
/* Crystal accuracy = 10 ppm */
/* X-tal frequency = 26 MHz */
/* RF output power = 0 dBm */
/* RX filterbandwidth = 541.666667 kHz */
/* Phase = 1 */
/* Datarate = 249.938965 kbps */
/* Modulation = (7) MSK */
/* Manchester enable = (0) Manchester disabled */
/* RF Frequency = 2432.999908 MHz */
/* Channel spacing = 199.951172 kHz */
/* Channel number = 0 */
/* Optimization = Sensitivity */
/* Sync mode = (3) 30/32 sync word bits detected */
/* Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX */
/* CRC operation = (1) CRC calculation in TX and CRC check in RX enabled */
/* Forward Error Correction = (0) FEC disabled */
/* Length configuration = (1) Variable length packets, packet length configured by the first received byte after sync word. */
/* Packetlength = 255 */
/* Preamble count = (2) 4 bytes */
/* Append status = 1 */
/* Address check = YES*/
/* FIFO autoflush = 0 */
/* Device address = 2 */
/* GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at the end of the packet */
/* GDO2 signal selection = (11) Serial Clock */
const unsigned char RF_rfSettings[42] =
{
// CC2500 registers data
0x07, // FIFOTHR
0x07, // MCSM2
0x30, // MCSM1
0x87, // WOREVT1
0x6B, // WOREVT0
0xF8, // WORCTRL
0x7F, // PTEST
0x3F, // AGCTEST
0x09, // FSCTRL1 Frequency synthesizer control.
0x00, // FSCTRL0 Frequency synthesizer control.
0x5D, // FREQ2 Frequency control word, high byte.
0x93, // FREQ1 Frequency control word, middle byte.
0xB1, // FREQ0 Frequency control word, low byte.
0x2D, // MDMCFG4 Modem configuration.
0x3B, // MDMCFG3 Modem configuration.
0x73, // MDMCFG2 Modem configuration.
0x22, // MDMCFG1 Modem configuration.
0xF8, // MDMCFG0 Modem configuration.
0x00, // CHANNR Channel number.
0x01, // DEVIATN Modem deviation setting (when FSK modulation is enabled).
0xB6, // FREND1 Front end RX configuration.
0x10, // FREND0 Front end RX configuration.
0x18, // MCSM0 Main Radio Control State Machine configuration.
0x1D, // FOCCFG Frequency Offset Compensation Configuration.
0x1C, // BSCFG Bit synchronization Configuration.
0xC7, // AGCCTRL2 AGC control.
0x00, // AGCCTRL1 AGC control.
0xB2, // AGCCTRL0 AGC control.
0xEA, // FSCAL3 Frequency synthesizer calibration.
0x0A, // FSCAL2 Frequency synthesizer calibration.
0x00, // FSCAL1 Frequency synthesizer calibration.
0x11, // FSCAL0 Frequency synthesizer calibration.
0x59, // FSTEST Frequency synthesizer calibration.
0x88, // TEST2 Various test settings.
0x31, // TEST1 Various test settings.
0x0B, // TEST0 Various test settings.
0x0B, // IOCFG2 GDO2 output pin configuration.
0x06, // IOCFG0D GDO0 output pin configuration. Refer to SmartRF® Studio User Manual for detailed pseudo register explanation.
0x05, // PKTCTRL1 Packet automation control.
0x05, // PKTCTRL0 Packet automation control.
0x70, // ADDR Device address.
0xFF // PKTLEN Packet length.
};

void RF_TxData (unsigned char fifo_length, unsigned char device_address)

{
unsigned char loop_e;
unsigned char tx_length, tx_address;

RF_WriteCommand (RF_SIDLE);
tx_length = fifo_length;
tx_address= device_address;
clr (PORTC, RF_CSN);
SPI0Buffer = RF_TXFIFO+0x40;
while (bit_is_set(PINB, RF_SO));
RF_WriteByte ();
SPI0Buffer = tx_length;
RF_WriteByte ();
SPI0Buffer = tx_address;
RF_WriteByte ();
tx_length--;
for (loop_e=0;loop_e<fifo_length;loop_e++)
{
SPI0Buffer = Tx_Data[loop_e];
RF_WriteByte ();
}
setb (PORTC, RF_CSN);
RF_ReadStatus (RF_TXBYTES);
RF_WriteCommand (RF_STX);
while (bit_is_clear(PINC, RF_GDO0));
while (bit_is_set(PINC, RF_GDO0));
RF_WriteCommand (RF_SIDLE);
RF_WriteCommand (RF_SFTX);
}

RECEIVER CODE :

void RF_RxData (void)
{
unsigned char loop_f;
RF_WriteCommand (RF_SRX); // receive mode
while (bit_is_clear(PINC, RF_GDO0)); // wait for data

if(bit_is_set(PINC, RF_GDO0)) // Check whether have data
{
while (bit_is_set(PINC, RF_GDO0)); // wait for receive complete
RF_ReadStatus (RF_RXBYTES);
if(s_data!=0)
{
clr (PORTC, RF_CSN);
SPI0Buffer = RF_RXFIFO+0xC0;
while(bit_is_set(PINB, RF_SO));
RF_WriteByte ();
RF_ReadByte ();
r_length = SPI0Buffer; // read first byte be fifo length
RF_ReadByte ();
r_address = SPI0Buffer; // read second byte be address
r_length--; // data length = fifo length -1
for(loop_f=0;loop_f<r_length;loop_f++)
{
RF_ReadByte ();
RF_Data[loop_f] = SPI0Buffer;
}
RF_ReadByte (); // Read RSSI data
RSSI = SPI0Buffer;
RF_ReadByte ();
CRC = SPI0Buffer;
setb (PORTC, RF_CSN);
if(CRC & 0x80)
{
if ((RF_Data[0] == 0xCC) && (RF_Data[2] == 0x55))
{
if (RF_Data[1] == 0x10)
{
TCCR1B = 0x00;
TMR_CNT = 0x00;
BED_UP ();
MOT_FLAG = 0x01;
}
else if (RF_Data[1] == 0x11)
{
TCCR1B = 0x00;
TMR_CNT = 0x00;
BED_DOWN ();
MOT_FLAG = 0x01;
}
else if ((RF_Data[1] == 0xFF) && (MOT_FLAG == 0x01))
{
BED_STOP ();
MOT_FLAG = 0x00;
}
}
}
}
}
RF_WriteCommand (RF_SIDLE);
RF_WriteCommand (RF_SFRX);
}

  • I agree with you, it has something to do with the error handling functions. In the code example below, which implements the read data that I use the most, it checks for both "no data" and "too much" data and in both cases flushes the fifo. 

    Regards
    /TA

    /******************************************************************************
     * @fn         radio_read
     *
     * @brief      Read a received packet into a buffer
     *
     *
     * input parameters
     *
     * @param       unsigned char *buf
     *              unsigned short buf_len
     *
     * output parameters
     *
     * @return      void
     *
     *
     */
    
    int radio_read(unsigned char *buf, unsigned short *buf_len) {
    	unsigned char status;
    	unsigned char pktLen;
    
    	/* Read number of bytes in RX FIFO */
    	trx8BitRegAccess(RADIO_READ_ACCESS|RADIO_BURST_ACCESS, RXBYTES, &pktLen, 1);
    	pktLen = pktLen  & NUM_RXBYTES;
    
    	/* make sure the packet size is appropriate, that is 1 -> buffer_size */
    	if ((pktLen > 0) && (pktLen <= *buf_len)) {
    
    		/* retrieve the FIFO content */
    		trx8BitRegAccess(RADIO_READ_ACCESS|RADIO_BURST_ACCESS, RXFIFO, buf, pktLen);
    
    		/* return the actual length of the FIFO */
    		*buf_len = pktLen;
    
    		/* retrieve the CRC status information */
    		trx8BitRegAccess(RADIO_READ_ACCESS+RADIO_BURST_ACCESS, PKTSTATUS, &status, 1);
    
    	} else {
    
    		/* if the length returned by the transceiver does not make sense, flush it */
    		*buf_len = 0;                                // 0
    		status = 0;
    		trxSpiCmdStrobe(RF_SFRX);	                 // Flush RXFIFO
    	}
    
    	/* return status information, CRC OK or NOT OK */
    	return (status & CRC_OK);
    }

    int radio_read(unsigned char *buf, unsigned short *buf_len) { unsigned char status; unsigned char pktLen;
    /* Read number of bytes in RX FIFO */ trx8BitRegAccess(RADIO_READ_ACCESS|RADIO_BURST_ACCESS, RXBYTES, &pktLen, 1); pktLen = pktLen  & NUM_RXBYTES;
    /* make sure the packet size is appropriate, that is 1 -> buffer_size */ if ((pktLen > 0) && (pktLen <= *buf_len)) {
    /* retrieve the FIFO content */ trx8BitRegAccess(RADIO_READ_ACCESS|RADIO_BURST_ACCESS, RXFIFO, buf, pktLen);
    /* return the actual length of the FIFO */ *buf_len = pktLen;
    /* retrieve the CRC status information */ trx8BitRegAccess(RADIO_READ_ACCESS+RADIO_BURST_ACCESS, PKTSTATUS, &status, 1);
    } else {
    /* if the length returned by the transceiver does not make sense, flush it */ *buf_len = 0;                                // 0 status = 0; trxSpiCmdStrobe(RF_SFRX);                 // Flush RXFIFO }
    /* return status information, CRC OK or NOT OK */ return (status & CRC_OK);}

  • Thanks for your suggestion and implemented the same in my coding.

    I could figure out while debugging that the GDO0 pin does not de-assert after receiving the packet and it stays high all the time when the program hangs. Since it hangs at this point I cannot go beyond to check the packet integrity.

    This hanging problem happens only when there is a bad reception but if I stay at close proximity ( around 5-6 mtrs ) it never hangs.

    void RF_RxData (void)  

    {  

       unsigned char loop_f;  

    RF_WriteCommand (RF_SRX); // receive mode  

                                                           while (bit_is_clear(PINC, RF_GDO0))       // wait for data

                                                           while (bit_is_set(PINC, RF_GDO0));               // wait for receive complete  ( Program hangs at this point )

    RF_ReadStatus (RF_RXBYTES);    

    if(s_data!=0)            

           {  

               clr  (PORTC, RF_CSN);  

               SPI0Buffer = RF_RXFIFO+0xC0;  

               while(bit_is_set(PINB, RF_SO));  

               RF_WriteByte ();  

               RF_ReadByte ();  

               r_length = SPI0Buffer;      // read first byte be fifo length    

               RF_ReadByte ();  

               r_address = SPI0Buffer;     // read second byte be address    

               r_length--;                 // data length = fifo length -1

    if ((r_length > 0) && ( r_length <=3))

    {          

               for(loop_f=0;loop_f<r_length;loop_f++)  

               {  

    RF_ReadByte ();  

                   RF_Data[loop_f] = SPI0Buffer;

               }  

  • Sorry for the long silence due to bad health issues.

    Back to the problem, I have modified the packet length reg to 0x3D as per ( errata ver.E ) and now the program does not hang while waiting for GDO0 activity which was the original issue.

    Now on bad reception the program hangs at waiting for MISO to go low.  The problem arises always whenever the transmitter goes beyond 10 meters are so. 

    Is it necessary to have pull-up enabled for MISO and GDO0 pins ?