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: reception of packet size more than 128 bytes

Part Number: CC1200
Other Parts Discussed in Thread: CC1120

Hi,

I am using cc1200 in sniff mode. so i am using the variable length packet mode.

We have a requirement where we have to receive a packet of  large size, about 240 bytes.

I am receiving packets on interrupt, RXFIFO_THR_PKT, where the FIFO threshold is configured for 127 bytes.

i am not receiving the whole packets but the first few bytes continuously

Could you please help me to resolve this issue.

  • First of all, I would recommend that that you get this working without using sniff mode, to verify that you are able to both transmit and receive packets larger than 128 bytes correctly.

    Start by using some of the typical settings in SmartRF Studio, and have your SW work with these settings before you start changing anything.

    Without knowing more about what you are doing it is not possible for me to tell you what is causing the problems you are seeing.

    I would recommend you to set a lower threshold, as there is no need for the RX FIFO to almost overflow before you start reading it.

    Remember that even if the packets you are expecting are 240 bytes long, the radio might receive false packets with a length byte that is much lower (lower than what you have set your FIFO threshold to). To then must make sure that your SW handle these cases as well. 

    In these cases the RXFIFO_THR signal will never be asserted, and you will need to use the PKT_SYNC_RXTX signal in addition, to figure out that a packet is received

    Siri

  • Hi,

    I have already tested in packet mode(without sniff mode) and in that scenario also i am not able to receive any packet and i am getting RX FIFO error. It only works fine with synchronous serial mode.

    I have also tried with FIFO threshold as half size for 64 bytes , i.e.  0x3F. In this scenario also I am observing the same issue. 

    My reception mechanism is as follows:

    Rx interrupt is configured for GPIO0 as 0x01( i.e RXFIFO_THR_PKT). On receiving the interrupt, my Reception function is triggered.

    // Read number of bytes in RX FIFO
    cc120xSpiReadReg(CC1200_NUM_RXBYTES, &rxBytes, 1);
    do
    {
      if(rxBytes != 0)
      {

        cc120xSpiReadRxFifo(&RFBuffer[rx_data_index], rxBytes);
        rx_data_index += rxBytes;
      }
      cc120xSpiReadReg(CC1200_NUM_RXBYTES, &rxBytes, 1);
    }
    while(rxBytes != 0);

    If suppose my packet is F0 01 02 03 04 05 .... F0.

    I am receiving first interrupt when 128 bytes are available in FIFO and there are no FIFO errors. I am reading the first 128 bytes and it is correctly read. but as you observe in my function, I keep on reading the FIFO till it is empty. So in next iteration, i am getting 30bytes available in FIFO and then again, the packet starts from F0 01 02 03.. up to 30bytes, and I keep getting some 1, 2 bytes in the RX FIFO till it is 0 and every time it starts from the starting of the packet and not the next bytes.

    Is there anything i am missing in reading the FIFO? Or do i need to read in some other mechanism in this particular scenario? 

  • I looked at the infinite packet length mode for the CC1120 and made some changes to be able to transmit and receive packets with length ranging from 1 to 255. My modified code is below:

    Please use this as a reference:

    TX:

    #define FIFO_SIZE                   128
    #define CRC_OK                      0x80
    #define AVAILABLE_BYTES_IN_TX_FIFO  122     // # of bytes one can write to the
                                                // TX_FIFO when a falling edge occur
                                                // on IOCFGx = 0x02 and
                                                // FIFO_THR = 120
    #define BYTES_IN_TX_FIFO            (FIFO_SIZE - AVAILABLE_BYTES_IN_TX_FIFO)
    #define INFINITE                    0
    #define FIXED                       1
    #define MAX_VARIABLE_LENGTH         255
    #define INFINITE_PACKET_LENGTH_MODE 0x40
    #define FIXED_PACKET_LENGTH_MODE    0x00
    
    #define GPIO3                       0x04
    #define GPIO2                       0x08
    #define GPIO0                       0x80
    
    
    /*******************************************************************************
    * LOCAL VARIABLES
    */
    static uint8 txBuffer[MAX_VARIABLE_LENGTH + 1];   // Buffer used to hold the packet
                                                      // to be sent
    static uint8 packetSent = FALSE;            // Flag set when packet is sent
    static uint16 packetCounter = 0;            // Counter keeping track of
                                                // packets sent
    static uint16 packetLength = 1;             // Length byte inserted in the first
                                                // byte of the TX FIFO
    static uint32 bytesLeft;                    // Keeping track of bytes left to
                                                // write to the TX FIFO
    static uint8 *pBufferIndex;                 // Pointer to current position in
                                                // the txBuffer
    static int8 iterations;                     // For packets greater than 128
                                                // bytes, this variable is used to
                                                // keep track of how many time the
                                                // TX FIFO should be re-filled to
                                                // its limit
    static uint8 writeRemainingDataFlag;        // When this flag is set, the
                                                // TX FIFO should not be filled
                                                // entirely
    
    
    /*******************************************************************************
    * STATIC FUNCTIONS
    */
    static void initMCU(void);
    static void registerConfig(void);
    static void updateLcd(void);
    static void packetSentISR(void);
    static void txFifoBelowThresholdISR(void);
    static void printWelcomeMessage(void);
    static void waitMs(uint16 msec);
    static void waitUs(uint16 msec);
    
    
    /*******************************************************************************
    *   @fn         main
    *
    *   @brief      Runs the main routine
    *
    *   @param      none
    *
    *   @return     none
    */
    void main(void)
    {
        uint8 writeByte;
    
        // Initialize MCU and peripherals
        initMCU();
    
        // Write radio registers (typical settings from SmartRF Studio)
        registerConfig();
    
        // Application specific registers
        // FIFO_THR = 120
        // GPIO0 = TXFIFO_THR
        // GPIO2 = PKT_SYNC_RXTX
        writeByte = 0x78; cc120xSpiWriteReg(CC120X_FIFO_CFG, &writeByte, 1);
        writeByte = 0x02; cc120xSpiWriteReg(CC120X_IOCFG0,   &writeByte, 1);
        writeByte = 0x06; cc120xSpiWriteReg(CC120X_IOCFG2,   &writeByte, 1);
    
        // Connect ISR function to GPIO0
        ioPinIntRegister(IO_PIN_PORT_1, GPIO0, &txFifoBelowThresholdISR);
    
        // Interrupt on falling edge
        ioPinIntTypeSet(IO_PIN_PORT_1, GPIO0, IO_PIN_FALLING_EDGE);
    
        // Clear interrupt
        ioPinIntClear(IO_PIN_PORT_1, GPIO0);
    
        // Connect ISR function to GPIO2
        ioPinIntRegister(IO_PIN_PORT_1, GPIO2, &packetSentISR);
    
        // Interrupt on falling edge
        ioPinIntTypeSet(IO_PIN_PORT_1, GPIO2, IO_PIN_FALLING_EDGE);
    
        // Clear interrupt
        ioPinIntClear(IO_PIN_PORT_1, GPIO2);
    
        // Enable interrupt
        ioPinIntEnable(IO_PIN_PORT_1, GPIO2);
    
        printWelcomeMessage();
    
        // Infinite loop
        while(TRUE)
        {
            // Wait for button push
            while(!bspKeyPushed(BSP_KEY_ALL));
    
            // Transmit 1000 packets
            for (uint16 i = 0; i < MAX_VARIABLE_LENGTH; i++)
            {
                // Create data packet
                txBuffer[0] = packetLength;
                for (uint16 i = 1; i < packetLength + 1; i++)
                {
                    txBuffer[i] = (uint8)i;
                }
        
                writeRemainingDataFlag = FALSE;
                
                ioPinIntClear(IO_PIN_PORT_1, GPIO0);
                ioPinIntEnable(IO_PIN_PORT_1, GPIO0);
                       
                if (packetLength < FIFO_SIZE)
                {
                    cc120xSpiWriteTxFifo(txBuffer, packetLength + 1);
                    ioPinIntDisable(IO_PIN_PORT_1, GPIO0);
                }
                else
                {
                    cc120xSpiWriteTxFifo(txBuffer, FIFO_SIZE);
                    pBufferIndex = txBuffer + FIFO_SIZE;
                    bytesLeft = packetLength + 1 - FIFO_SIZE;
                    iterations = (bytesLeft / AVAILABLE_BYTES_IN_TX_FIFO);
                
                    if(iterations < 1)
                    {
                        writeRemainingDataFlag = TRUE;
                    }
                }
                
                // Enter TX mode
                trxSpiCmdStrobe(CC120X_STX);
    
                // Wait for packet to be sent
                while (!packetSent);
                packetSent = FALSE;
    
                // Update LCD
                updateLcd();
    
                waitMs(300);
                
                packetLength++;
            }
        }
    }
    
    /*******************************************************************************
    * @fn          packetSentISR
    *
    * @brief       Function running every time a packet has been sent
    *
    * @param       none
    *
    * @return      none
    */
    static void packetSentISR(void) {
    
        packetSent = TRUE;
    
        // Clear ISR flag
        ioPinIntClear(IO_PIN_PORT_1, GPIO2);
        ioPinIntClear(IO_PIN_PORT_1, GPIO0);
    }
    
    
    /*******************************************************************************
    *   @fn         txFifoBelowThresholdISR
    *
    *   @brief      Function running every time the TX FIFO is drained below
    *               127 - FIFO_THR = 127 - 120 = 7
    *
    *   @param      none
    *
    *   @return     none
    */
    static void txFifoBelowThresholdISR(void) {
    
        uint8 writeByte;
    
        if (writeRemainingDataFlag)
        { 
            cc120xSpiWriteTxFifo(pBufferIndex, bytesLeft);  // Write remaining bytes
                                                            // to the TX FIFO
            // Disable interrupt on GPIO0
            ioPinIntDisable(IO_PIN_PORT_1, GPIO0);
    
        }
        else 
        { // Fill up the TX FIFO
            cc120xSpiWriteTxFifo(pBufferIndex, AVAILABLE_BYTES_IN_TX_FIFO);
    
            pBufferIndex += AVAILABLE_BYTES_IN_TX_FIFO;
            bytesLeft -= AVAILABLE_BYTES_IN_TX_FIFO;
    
            if (!(--iterations))
            {
                writeRemainingDataFlag = TRUE;
            }
        }
    
        // Clear ISR flag
        ioPinIntClear(IO_PIN_PORT_1, GPIO0);
    }
    

    RX:

    #define PACKET_LENGTH               255     // Max packet length excepted
    #define CRC_OK                      0x80
    #define BYTES_IN_RX_FIFO            121     // # of bytes one can read from the
                                                // RX_FIFO when a rising edge occur
                                                // on IOCFGx = 0x00 and
                                                // FIFO_THR = 120
    
    #define MAX_VARIABLE_LENGTH         255
    #define RX_START                    0
    #define RX_WAIT                     1
    
    #define GPIO3                       0x04
    #define GPIO2                       0x08
    #define GPIO0                       0x80
    
    
    /*******************************************************************************
    * LOCAL VARIABLES
    */
    static uint8 rxBuffer[PACKET_LENGTH + 3];   // Buffer used to hold the received
                                                // packet (1 length byte + 2 status bytes)
    static uint8 packetReceived = FALSE;        // Flag set when packet is received
    static uint16 packetCounter = 0;            // Counter keeping track of packets
                                                // with CRC OK
    static uint16 packetLength;                 // Two first bytes received after
                                                // the sync word
    static uint32 bytesLeft;                    // Keeping track of bytes left to
                                                // read from the RX FIFO
    static uint8 fixedPacketLength;
    static uint8 *pBufferIndex;                 // Pointer to current position in
                                                // the rxBuffer
    static uint8 state = RX_START;
    
    
    /*******************************************************************************
    * STATIC FUNCTIONS
    */
    static void initMCU(void);
    static void registerConfig(void);
    static void updateLcd(void);
    static void syncReceivedISR(void);
    static void packetReceivedISR(void);
    static void rxFifoAboveThresholdISR(void);
    static void printWelcomeMessage(void);
    
    
    /*******************************************************************************
    *   @fn         main
    *
    *   @brief      Runs the main routine
    *
    *   @param      none
    *
    *   @return     none
    */
    void main(void) {
    
        uint8 writeByte;
    
        // Initialize MCU and peripherals
        initMCU();
    
        // Write radio registers (preferred settings from SmartRF Studio)
        registerConfig();
    
        // Application specific registers
        // FIFO_THR = 120
        // GPIO0 = RXFIFO_THR
        // GPIO2 = PKT_SYNC_RXTX
        // GPIO3 = PKT_SYNC_RXTX
        writeByte = 0x78; cc120xSpiWriteReg(CC120X_FIFO_CFG, &writeByte, 1);
        writeByte = 0x00; cc120xSpiWriteReg(CC120X_IOCFG0,   &writeByte, 1);
        writeByte = 0x06; cc120xSpiWriteReg(CC120X_IOCFG2,   &writeByte, 1);
        writeByte = 0x06; cc120xSpiWriteReg(CC120X_IOCFG3,   &writeByte, 1);
    
        // Connect ISR function to GPIO0
        ioPinIntRegister(IO_PIN_PORT_1, GPIO0, &rxFifoAboveThresholdISR);
    
        // Interrupt on falling edge
        ioPinIntTypeSet(IO_PIN_PORT_1, GPIO0, IO_PIN_RISING_EDGE);
    
        // Clear interrupt
        ioPinIntClear(IO_PIN_PORT_1, GPIO0);
    
        // Enable interrupt
        ioPinIntEnable(IO_PIN_PORT_1, GPIO0);
    
        // Connect ISR function to GPIO2
        ioPinIntRegister(IO_PIN_PORT_1, GPIO2, &syncReceivedISR);
    
        // Interrupt on rising edge
        ioPinIntTypeSet(IO_PIN_PORT_1, GPIO2, IO_PIN_RISING_EDGE);
    
        // Clear interrupt
        ioPinIntClear(IO_PIN_PORT_1, GPIO2);
    
        // Enable interrupt
        ioPinIntEnable(IO_PIN_PORT_1, GPIO2);
    
        // Set up interrupt on GPIO3 (PKT_SYNC_RXTX)
        ioPinIntRegister(IO_PIN_PORT_1, GPIO3, &packetReceivedISR);
    
        // Interrupt on falling edge
        ioPinIntTypeSet(IO_PIN_PORT_1, GPIO3, IO_PIN_FALLING_EDGE);
    
        printWelcomeMessage();
    
        while (TRUE) {
            switch (state) {
    
                //------------------------------------------------------------------
                case RX_START:
                //------------------------------------------------------------------
                trxSpiCmdStrobe(CC120X_SRX);
                pBufferIndex = rxBuffer;
    
                // Disable interrupt on GPIO3
                ioPinIntDisable(IO_PIN_PORT_1, GPIO3);
                
                ioPinIntClear(IO_PIN_PORT_1, GPIO0);
                ioPinIntClear(IO_PIN_PORT_1, GPIO2);
    
                state = RX_WAIT;
    
                //------------------------------------------------------------------
                case RX_WAIT:
                //------------------------------------------------------------------
                if (packetReceived) {
                    packetReceived = FALSE;
    
                    // Check CRC and update LCD if CRC OK
                    if ((rxBuffer[packetLength + 2]) & CRC_OK)
                        updateLcd();
    
                    state = RX_START;
                }
                break;
    
                //------------------------------------------------------------------
                default:
                //------------------------------------------------------------------
    
                break;
            }
        }
    }
    
    /*******************************************************************************
    *   @fn         syncReceivedISR
    *
    *   @brief      Function running every time a sync word has been received
    *
    *   @param      none
    *
    *   @return     none
    */
    static void syncReceivedISR(void) {
    
        uint8 numRxBytes;
        uint8 writeByte;
    
        // After the sync word is received one needs to wait for the 
        // length byte to be put in the RX FIFO
        do {
            cc120xSpiReadReg(CC120X_NUM_RXBYTES, &numRxBytes, 1);
        } while (numRxBytes < 1);
    
        // Read the length byte and store it in the packetLength variable
        cc120xSpiReadRxFifo(rxBuffer, 1);
        pBufferIndex += 1;
        packetLength =  rxBuffer[0];
    
        bytesLeft = packetLength + 2;
    
        // Clear interrupt flag and enable GPIO3
        ioPinIntClear(IO_PIN_PORT_1, GPIO3);
        ioPinIntEnable(IO_PIN_PORT_1, GPIO3);
    
        // Clear ISR flag
        ioPinIntClear(IO_PIN_PORT_1, GPIO2);
    }
    
    
    /*******************************************************************************
    *   @fn         packetReceivedISR
    *
    *   @brief      Function running every time a packet has been received
    *
    *   @param      none
    *
    *   @return     none
    */
    static void packetReceivedISR(void) {
        cc120xSpiReadRxFifo(pBufferIndex, bytesLeft);
        bytesLeft = 0;
        packetReceived = TRUE;
    
        // Clear ISR flag
        ioPinIntClear(IO_PIN_PORT_1, GPIO3);
    }
    
    
    /*******************************************************************************
    *   @fn         rxFifoAboveThresholdISR
    *
    *   @brief      Function running every time the RX FIFO is filled above
    *               threshold (FIFO_THR = 120)
    *
    *   @param      none
    *
    *   @return     none
    */
    static void rxFifoAboveThresholdISR(void) {
    
        uint8 writeByte;
    
        if(!packetReceived)
        {
            cc120xSpiReadRxFifo(pBufferIndex, BYTES_IN_RX_FIFO);
            bytesLeft -= BYTES_IN_RX_FIFO;
            pBufferIndex += BYTES_IN_RX_FIFO;
    
            // Clear ISR flag
            ioPinIntClear(IO_PIN_PORT_1, GPIO0);
        }
    }
    

    siri

  • Hi siri,

    Thank you for your quick response.

    But i need to implement this along with RF sniff Mode (eWOR with PQT). It would be really helpful if you could suggest me a method for the same.

    Meanwhile i will try at my end with infinite packet mode, if that is compatible with sniff mode

  • I am afraid we do not have the bandwidth to make a complete code example for you. I have shown you how to receive packets of length greater than the FIFO size, and there are example code available showing how to use sniff mode with packets not longer than the FIFO size.

    You need to do the effort of combining these two examples together.

    Siri

  • Yes sure, i understand.

    Just one query: Is Infinite packet mode compatible with RF sniff mode?

  • You should not use infinite packet mode if your packet length is less than 255 bytes. In the example I provided I used variable packet length mode (I just used the infinite packet length mode example as a starting point and modified it).

    Siri

  • i could implement a similar logic in sniff mode for cc1200 eval board. same logic when i am porting for my custom cc1200 board i am seeing different behavior. 

    interrupt is configured as -> GPIO0 0x01 and GPIO2 0x29

    suppose the packet size is 240 and fifo threshold is 120, i am getting an interrupt for 121 bytes in fifo, but not for the end of packet.

    Could you help me with a probable reason for the same?

  • Unfortunately I am not in the office this week so I do not have CC1200 HW to test on to provide you any plots.

    The code I sent you are tested on the CC1200 EM (+ TRXEB) and works with all packet length.

    It is my understanding that you get the code running on the EMs but not on your HW. Is that correct?

    What I recommend you to do it to take my code that we know is working, and modify it to only send packets of length 240.

    Monitor the SPI line and the GPIOs with a logic analyzer to see how the GPIOs behave in this case.

    Then try the same thing on your HW, and compare the GPIO toggling.

    On your own HW, the first thing you should do is to verify that your interrupts are configured correctly and that you are able to get interrupt on the correct edge on all of the GPIOs. How to enable/disable/clear interrupts might be different on your MCU compared to the MSP430 I am using, so my demo code must be changes according to how your MCU is working.

    BR

    Siri