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.

RTOS/CC1310: How to use RF to send or receive indefinite length data?

Part Number: CC1310

Tool/software: TI-RTOS

Hi,Team

I want to implement sending or receiving variable length data, how to achieve it? Please explain the method, it is best to have a code example. Also, now I haven't learned how to use the TX queue, how to populate the data into the queue and send them out?

Hopefully for your answer!

  • You do not say anything about how long packets you want to send, but there are different ways to support different formats.

    If your packets are less than 255 bytes you can use CMD_PROP_RX and CMD_PROP_TX.

    You can then have a length byte as the first byte after sync and it can have a max value of 255.

    If you need longer packets, you can use the advanced TX and RX commands (CMD_PROP_RX_ADV and CMD_PROP_TX_ADV).

    You then have 2 bytes available for the length. Even if 16 bits give you a possible max length of 65536, internal constraints in the modem limits this to 8191 bytes (including header and CRC), see https://e2e.ti.com/support/wireless-connectivity/f/156/p/730832/2697539#2697539

    It is also possible to choose unlimited length.

    There are two reasons for selecting infinite packet length.

    1) Your length information is somewhere else in the packet than in the max 4 bytes long header. An example of this is explained in the following post:

    https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz/f/156/t/689154?CC1310-Require-Partial-Mode-Example-of-CC1310

    Please note that the max packet length is limited to 8191 bytes.

    2) If you do not need the radio to exit RX automatically after receiving a certain number of bytes or CRC to be calculated, you can use infinite packet length mode, and the radio can be left in RX until you have received all the bytes you need. When you have received what you want, you need to cancel the RX command manually. With this approach you can receive more than 8191 bytes.

    Regarding the use of TX queues, please take a look at this post:

    https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz/f/156/t/594277

    BR

    Siri

     

  • Hi Siri, I'm sorry for the way I asked questions. I am using the WOR example, the purpose is to receive instructions of different lengths through the UART and then send them out by RF, they are not too long. But your answer is very professional and perfect, this should be the standard answer to a similar question.
  • I tried it the way you did, but it didn't work and the program seemed to be stuck. I don't know why you created a full packet format in txSyncPacket[] buffer. Are the preamble and sync words not sent automatically? Below is my code, please take a look.

    /* TX task function. Executed in Task context by TI-RTOS when the scheduler starts. */
    static void txTaskFunction(UArg arg0, UArg arg1)
    {
        /* Initialize the display and try to open both UART and LCD types of display. */
        Display_Params params;
        Display_Params_init(&params);
        params.lineClearMode = DISPLAY_CLEAR_BOTH;
        Display_Handle uartDisplayHandle = Display_open(Display_Type_UART, &params);
        Display_Handle lcdDisplayHandle = Display_open(Display_Type_LCD, &params);
    
        /* Print initial display content on both UART and any LCD present */
        Display_printf(uartDisplayHandle, 0, 0, "Wake-on-Radio TX");
        Display_printf(uartDisplayHandle, 0, 0, "Pkts sent: %u", seqNumber);
        Display_printf(lcdDisplayHandle, 0, 0, "Wake-on-Radio TX");
        Display_printf(lcdDisplayHandle, 1, 0, "Pkts sent: %u", seqNumber);
    
        /* Setup callback for button pins */
        PIN_Status status = PIN_registerIntCb(buttonPinHandle, &buttonCallbackFunction);
        Assert_isTrue((status == PIN_SUCCESS), NULL);
        
        /* Configure TX Entry */
        txEntry.pNextEntry = (uint8_t*)&txEntry;
        txEntry.status = DATA_ENTRY_PENDING;
        txEntry.config.type = DATA_ENTRY_TYPE_PTR;
        txEntry.pData = (uint8_t*)txSyncPacket;
        txEntry.length = sizeof(txSyncPacket);
        
        /* Initialize the radio */
        RF_Params rfParams;
        RF_Params_init(&rfParams);
        
        /* Initialize TX_ADV command from TX command */
        initializeTxAdvCmdFromTxCmd(&RF_cmdPropTxAdv, &RF_cmdPropTx);
    
        /* Set application specific fields */
        RF_cmdPropTxAdv.pktLen = 0; /* +1 for length byte */
        RF_cmdPropTxAdv.pPkt = (uint8_t*)&txQueue;
        RF_cmdPropTxAdv.preTrigger.triggerType = TRIG_REL_START;
        RF_cmdPropTxAdv.preTime = WOR_PREAMBLE_TIME_RAT_TICKS(WOR_WAKEUPS_PER_SECOND);
        
        txQueue.pCurrEntry = (uint8_t*)&txEntry;
        txQueue.pLastEntry = NULL;
        
        /* Request access to the radio */
        rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
    
        /* Set the frequency */
        RF_runCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
        
        /* Enter main TX loop */
        while(1)
        {
            /* Wait for a button press */
            //Semaphore_pend(txSemaphoreHandle, BIOS_WAIT_FOREVER);
    
            /* Create packet with incrementing sequence number and random payload */
    //        Task_sleep(100000);
    //        packet[0] = PAYLOAD_LENGTH ;
    //        packet[1] = (uint8_t)(seqNumber >> 8);
    //        packet[2] = (uint8_t)(seqNumber++);
    //        uint8_t i;
    //        for (i = 3; i < PAYLOAD_LENGTH + 1; i++)
    //        {
    //            packet[i] = rand();
    //        }
          
            txQueue.pCurrEntry = (uint8_t*)&txEntry;
            /* Send packet */
            RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTxAdv, RF_PriorityNormal, NULL, 0);
    
            /* Update display */
            Display_printf(uartDisplayHandle, 0, 0, "Pkts sent: %u", seqNumber);
            Display_printf(lcdDisplayHandle, 1, 0, "Pkts sent: %u", seqNumber);
            
            /* Toggle LED */
            PIN_setOutputValue(ledPinHandle, IOID_22, !PIN_getOutputValue(IOID_22));
            
        }
    }

  • It would be easier for me to help you if I knew exactly exactly how long packets you want to send/receive.
    Why do you want/need to use a txQueue? Are you going to send packets greater than 8192 bytes?

    Please give me info about what data rate you are using, how long your packets are going to be and how often you want/can wake up on the RX side, and I can give you some pointers on how to do it.

    The example I referred to was simply to show how tx queues could be used. Normally, the radio will send preamble and sync word "automatically", but in this case the customer could not have any delay between each packet, and the only way to achieve this was to use infinite mode and write the preamble and sync as part of the infinite data payload.

    BR
    Siri
  • My data rate is 50Kbps, the packet length is about a dozen bytes, and the receiver wake-up interval is 1s. I am only interested in how to use the send queue, but after testing I found that I can't grasp it, so for convenience I now use the RF_cmdPropTxAdv.pktLen method.
  • OK. I think that is the solution you should go for. The queues is intended for the cases where you are sending very long packets and cannot afford to have one buffer that is going to hold the complete packet. In that case you will use a queue of several data entries, which holds different part of the packet. You then have to update/re-fill the data entries in the queue during transmission.

    Siri
  • Yes,I am very grateful for your help.