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.

CC1200 RX FIFO read problem

Other Parts Discussed in Thread: CC1200

When using Standard FIFO Access to read the CC1200's RX FIFO, there appears to be some kind of glitch that occurs sometimes when the RX packet ends during the FIFO read operation.  This glitch does not occur all the time:  Only ~2% of the time in my application, so the time jitter on my read operation is randomly hitting the critical window for the chip's internal race condition.  On looking at the received data when this occurs, the received bytes appear to be shifted by 1 bit position, as if one extra spurious SPI clock had occurred.  Because of this error, after reading the NUM_RXBYTES register to determine the number of bytes in the RX FIFO and then trying to read those bytes from the RX FIFO, an RX FIFO Underflow errors occurs.  This is a serious issue in a time-critical application such as mine, since clearing the FIFO error requires going back to IDLE mode, and trying to avoid the error requires suppressing FIFO read operations in proximity to the anticipated end of packet.  Is this a known problem or a new problem?  While it is always possible that this is a firmware issue, I have looked and not seen any SPI clock glitches on my signals that could be causing this problem.

  • Hi Dan

    Are you able to share some code snippets of your application together with your register settings? Especially the part when you read from the RXFIFO. 

  • My SPI clock is running at 6 MHz.  I am using a SAM4L Atmel processor that is running at 48 MHz.  The CC1200's data rate at 362 kbps.  The attached code is used to read the RX FIFO.

    My register settings are most easily conveyed via the attached window snapshots:

       https://docs.google.com/file/d/0ByaB4SBbLywGNFZzMVh0VlNYZlU/edit?usp=sharing

       https://docs.google.com/file/d/0ByaB4SBbLywGcUxuUmdsWkF4ck0/edit?usp=sharing

    As an example of the symptoms, see the following data.  The data pattern is an incrementing pattern:  0x33, 0x34, 0x35, 0x36...   When the glitch happens, some part of one byte will be shifted left, and all subsequent bytes will also be shifted left.  For instance, in the first line below, 0x41 and 0x42 were expected, but 0x42 and 0x84 were received, so the LSB nibble of the first byte was shifted left, and the entire next byte was shifted left.  In the next glitched RX packet, 0x3d and 0x3e were expected, but we got 0x3A and 0x7C, so the same thing happened.


    13:33:15.775: 0D: L=1D S=95 EXP: 41 ACT: 42 84
    13:33:16.878: 17: L=1D S=95 EXP: 3D ACT: 3A 7C
    13:33:17.837: 14: L=1D S=95 EXP: 3E ACT: 3C 7E
    13:33:18.189: 05: L=1D S=95 EXP: 45 ACT: 8A 8C
    13:33:20.954: 1F: L=1D S=95 EXP: 3A ACT: 34 76
    13:33:24.009: 25: L=1D S=95 EXP: 38 ACT: 00 72
    13:33:28.211: 06: L=1D S=95 EXP: 44 ACT: 48 8A


    /******************************************************************************
     *
     * Function Name:  rdoSendByteToSpi()
     *
     * Description: Wait for room in the TX holding register, then write the
     * specified command or data byte to the SPI.
     *
     *****************************************************************************/

    void rdoSendByteToSpi( uint8 dataByte )
    {
        // Wait for the previous byte to be moved into the shift register
        while ( ( CC1200_USART->US_CSR & US_CSR_TXRDY ) == 0 );

        // Write the new byte to the TX holding register
        CC1200_USART->US_THR = dataByte;
    }

    /******************************************************************************
     *
     * Function Name:  rdoTerminateTransaction
     *
     * Description: Delay briefly then pull both NSS lines high to terminate a
     * SPI transaction.
     *
     *****************************************************************************/

    void rdoTerminateTransaction( void )
    {
        // Ensure that we delay a minimum of 200 nsecs before pulling NSS high
        NOP;  // 20 nsecs
        NOP;  // 20 nsecs
        NOP;  // 20 nsecs
        NOP;  // 20 nsecs
        NOP;  // 20 nsecs
        NOP;  // 20 nsecs
        NOP;  // 20 nsecs
        NOP;  // 20 nsecs

        // Pull both NSS lines high
        gpioSetHigh( CC1200A_NSS_PIN );
    }

    /******************************************************************************
     *
     * Function Name:  rdoReadFifo
     *
     * Description: Read data from the radio's FIFO
     *
     *****************************************************************************/

    void rdoReadFifo( uint8 rficSelect, uint8 *pDest, uint8 count )
    {
        // Pull the nSS line low
        gpioSetLow( CC1200A_NSS_PIN );

        // Send the command to read the FIFO in burst mode
        rdoSendByteToSpi( READ_FIFO );

        // Wait for TX to complete
        while ( ( CC1200_USART->US_CSR & US_CSR_TXEMPTY ) == 0 );

        // Retrieve and record the chip status byte from the RX FIFO
        rdoChipStatus = CC1200_USART->US_RHR;

        // Read consecutive bytes from the CC1200's RX FIFO
        while ( count-- > 0 )
        {
            // Send a null byte to read the next byte from the FIFO
            rdoSendByteToSpi( 0 );

            // Wait for TX to complete
            while ( ( CC1200_USART->US_CSR & US_CSR_TXEMPTY ) == 0 );

            // Retrieve and record the byte from the RX FIFO
            *pDest++ = CC1200_USART->US_RHR;
        }

        // We need a 200 nsec minimum delay before pulling NSS high
        rdoTerminateTransaction();
    }

  • Hi

    Your code looks ok at first glance. Are you sure that the actual SPI transmission between the MCU and the CC1200 is as expected? Are you able to produce a plot of the SPI while you read from the RXFIFO in the same manner as shown below?

  • I might be able to produce a plot that shows SPI transactions.  I'll look into it.  However, I've done additional testing that demonstrates that so long as the FIFO read operation and chip select are not overlapping the falling edge of PKT_SYNC_RXTX, that this glitch does not occur.  Overlapping the falling edge of this signal seems to be required, but not sufficient, to induce this error.  (It occurs only a small percentage of the time.)  For this reason, I don't believe the problem is related to my SPI timing.  If that were the case, then it should be appearing at other times, too.

    I'm seeing another error too.  By avoiding the falling edge of PKT_SYNC_RXTX, I eliminate this problem, but still occasionally get other packets that are always the same (random looking) pattern and start with a packet length byte of 0x55.  This is a more manageable problem, however, since it is less frequent and the CC1200 actually allows reading of the bytes without generating an underflow error....

  • I have shortened the wires from my processor development board to the CC1200 dev board, and the problem seems to have disappeared.  Ground loops and crosstalk may have been my problem.  If this is a fix, then I apologize for the difficulties I have caused you.  I will keep you apprised of any further developments.  Thank you.

  • Hi Dan

    No problem. The important thing is that the issue is resolved and you can continue forward with your project. Please do not hesitate to post again if there any more issues.

    Good luck continuing forward!