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.

CC1310: How to receive a packet with unknow length or unlimited?

Other Parts Discussed in Thread: CC1310

I modifed the rfEasyLinkNp_CC1310DK_7XD_TI_CC1310F128 example and just use it to test receice and transimit. But  I found that  the packet length was limited  less than 255. (I have changed EASYLINK_MAX_DATA_LENGTH as 512). 

Since in that example, it used command rfc_CMD_PROP_RX_ADV_s(0x3804), due to the pdf and register details,  it can received a packet with unlimited length or unknow length if we set  the maxPktLen as 0:

uint16_t maxPktLen; //!< \brief Packet length for fixed length, maximum packet length for variable length<br>
//!< 0: Unlimited or unknown length

Actually when I set EasyLink_cmdPropRxAdv.maxPktLen = 0,  I found cc1310 can receive nothing, so I had to recover its value as 

EasyLink_cmdPropRxAdv.maxPktLen = EASYLINK_MAX_DATA_LENGTH +
EASYLINK_MAX_ADDR_SIZE;

 then I can receive a packet whose length is less than 255.

Is anyone can tell me how to do to receive a packet with more over than 255bytes or unlimited length???

I will appreciate for your reply.

  • Hi

    I am not too familiar with the EasyLink API, so it might be that there are limitations there that will not allow you to set the packet length to more than 255.
    What you can do is to use the rfPacketRX examples instead.
    The easiest way to support packets that are longer than 255 bytes is to use the CMD_PROP_RX_ADV command. You can there configure how long your header should be (up to 4 bytes), how many bits your length is (up to 16 bits) and you can configure where the length information in the header is.
    If your length info is placed somewhere else in the packets (and not within the first 4 bytes after the sync word) you can use infinite packet length (you can then use the CMD_PROP_RX). You need to use partial read entries and set the packet length to infinite. Then you set up when you want an interrupt (after every n bytes have been put in the data entry).
    When you have received enough bytes to get hold of the length information, you use the CMD_PROP_SET_LEN to set the desired length. This length can be two bytes long.

    Siri
  • Hi Siri:
    Thank you for your reply.I want to explain:
    Actually I have used CMD_PROP_RX_ADV,my test project was modified according to the registers/data structure explained by the documents and driver lib,which I downloaded from the official website, but it didn't work.I was confused about where I made a mistake or the device's bug. Is there a project shows how to receive a packet that more than 255bytes and unknow its length at the same time?
  • Hi,

    As Siri has explained, if the payload is longer than 255 bytes, cmd_prop_rx_adv command can be used. It is possible to receive variable length packets with this command but the length information for each packet should be inserted as part of the header for this mode to work. It is also possible to receive packets of unknown length by programming the maxpktlen to 0. Please refer to section 23.7.5.4 in TRM for details on how to stop packet reception in this case.
    Currently we do not have any examples with this scheme implemented.

    Regards,
  • Hi,
    try with the following structures for PROP_ADV_TX and PROP_ADV_RX. This is specific for IEEE802.15.4g packets which are 2047bytes.
    /* CMD_PROP_RX_ADV */
    rfc_CMD_PROP_RX_ADV_t RF_cmdPropRxAdv =
    {
    .commandNo = CMD_PROP_RX_ADV,
    .status = 0x0000,
    .pNextOp = 0x00000000,
    .startTime = 0x00000000,
    .startTrigger.triggerType = 0x0,
    .startTrigger.bEnaCmd = 0x0,
    .startTrigger.triggerNo = 0x0,
    .startTrigger.pastTrig = 0x0,
    .condition.rule = 0x1,
    .condition.nSkip = 0x0,
    .pktConf.bFsOff = 0x0,
    .pktConf.bRepeatOk = 0x1,
    .pktConf.bRepeatNok = 0x1,
    .pktConf.bUseCrc = 0x1,
    .pktConf.bCrcIncSw = 0x0,
    .pktConf.bCrcIncHdr = 0x0,
    .pktConf.endType = 0x0,
    .pktConf.filterOp = 0x1,
    .rxConf.bAutoFlushIgnored = 0x0,
    .rxConf.bAutoFlushCrcErr = 0x0,
    .rxConf.bIncludeHdr = 0x1,
    .rxConf.bIncludeCrc = 0x1,
    .rxConf.bAppendRssi = 0x1,
    .rxConf.bAppendTimestamp = 0x0,
    .rxConf.bAppendStatus = 0x1,
    .syncWord0 = 0x904E,
    .syncWord1 = 0,
    .maxPktLen = 2047,
    .hdrConf.numHdrBits = 16,
    .hdrConf.lenPos = 0,
    .hdrConf.numLenBits = 11,
    .addrConf.addrType = 0,
    .addrConf.addrSize = 0,
    .addrConf.addrPos = 0,
    .addrConf.numAddr = 0,
    .lenOffset = -4,
    .endTrigger.triggerType = 0x1,
    .endTrigger.bEnaCmd = 0x0,
    .endTrigger.triggerNo = 0x0,
    .endTrigger.pastTrig = 0x0,
    .endTime = 0x00000000,
    .pAddr = 0x00000000,
    .pQueue = 0x00000000,
    .pOutput = 0x00000000,
    };

    /* CMD_PROP_TX_ADV */
    rfc_CMD_PROP_TX_ADV_t RF_cmdPropTxAdv =
    {
    .commandNo = CMD_PROP_TX_ADV,
    .status = 0x0000,
    .pNextOp = 0x00000000,
    .startTime = 0x00000000,
    .startTrigger.triggerType = 0x0,
    .startTrigger.bEnaCmd = 0x0,
    .startTrigger.triggerNo = 0x0,
    .startTrigger.pastTrig = 0x0,
    .condition.rule = 0x1,
    .condition.nSkip = 0x0,
    .pktConf.bFsOff = 0x0,
    .pktConf.bUseCrc = 0x1,
    .pktConf.bCrcIncSw = 0x0,
    .pktConf.bCrcIncHdr = 0x0,
    .numHdrBits = 16,
    .pktLen = 0x00,
    .startConf = 0x0,
    .preTrigger.triggerType = TRIG_REL_START, /* Setting needed for 15.4g due to bug. Will do the same as TRIG_NOW */
    .preTrigger.bEnaCmd = 0,
    .preTrigger.triggerNo = 0,
    .preTrigger.pastTrig = 1, /* Setting needed for 15.4g due to bug */
    .preTime = 0x0, /* Setting needed for 15.4g due to bug */
    .syncWord = 0x904E,
    .pPkt = 0x00000000,
    };
  • Hi FI:
    Thank you for your reply, actually in my test project what I process the receive/tramsmit operation is nearly the same as you said, and I still can just receive less than 255bytes and I cannot transmit  success if I use 0x3803 command. Here is my receive operation:
    //Rx command
    static rfc_CMD_PROP_RX_ADV_t EasyLink_cmdPropRxAdv = {
    .commandNo = 0x3804,
    .status = 0x0000,
    .pNextOp = 0,
    .startTime = 0x00000000,
    .startTrigger.triggerType = TRIG_NOW,
    .startTrigger.bEnaCmd = 0x0,
    .startTrigger.triggerNo = 0x0,
    .startTrigger.pastTrig = 0x0,
    .condition.rule = 0x1,
    .condition.nSkip = 0x0,
    .pktConf.bFsOff = 0x0,
    .pktConf.bRepeatOk = 0x0,
    .pktConf.bRepeatNok = 0x0,
    .pktConf.bUseCrc = 0x0,//0x1,
    .pktConf.bCrcIncSw = 0x0,
    .pktConf.bCrcIncHdr = 0x0,//0x1,
    .pktConf.endType = 0x0,
    .pktConf.filterOp = 0x0,//0x1,
    .rxConf.bAutoFlushIgnored = 0x0,
    .rxConf.bAutoFlushCrcErr = 0x0,
    .rxConf.bIncludeHdr = 0x00,//0x1,
    .rxConf.bIncludeCrc = 0x0,
    .rxConf.bAppendRssi = 0x0,
    .rxConf.bAppendTimestamp = 0x0,
    .rxConf.bAppendStatus = 0x0,
    .syncWord0 = 0x930b51de,
    .syncWord1 = 0,
    .maxPktLen = 1024,//0,
    .hdrConf.numHdrBits = 16,//8,
    .hdrConf.lenPos = 0,
    .hdrConf.numLenBits = 8,
    .addrConf.addrType = 0,
    .addrConf.addrSize = 0,
    .addrConf.addrPos = 0,
    .addrConf.numAddr = 1,
    .lenOffset = 0,
    .endTrigger.triggerType = TRIG_NEVER,
    .endTrigger.bEnaCmd = 0x0,
    .endTrigger.triggerNo = 0x0,
    .endTrigger.pastTrig = 0x0,
    .endTime = 0x00000000,
    .pAddr = 0,
    .pQueue = 0,
    .pOutput = 0,
    };


    EasyLink_Status EasyLink_receiveAsync(EasyLink_ReceiveCb cb, uint32_t absTime)
    {
    EasyLink_Status status = EasyLink_Status_Rx_Error;
    rfc_dataEntryGeneral_t *pDataEntry;

    //Check if not configure of already an Async command being performed
    if(!configured)
    {
    return EasyLink_Status_Config_Error;
    }
    //Check and take the busyMutex
    if( (Semaphore_pend(busyMutex, 0) == FALSE) || (asyncCmdHndl > 0) )//(asyncCmdHndl != NULL) )
    {
    return EasyLink_Status_Busy_Error;
    }

    rxCb = cb;
    memset(rxBuffer, 0, sizeof(rxBuffer));
    pDataEntry = (rfc_dataEntryGeneral_t*) rxBuffer;
    //data entry rx buffer includes hdr (len-1Byte), addr (max 8Bytes) and data
    pDataEntry->length = 1024;
    pDataEntry->status = 0;
    dataQueue.pCurrEntry = (uint8_t*) pDataEntry;
    dataQueue.pLastEntry = NULL;
    EasyLink_cmdPropRxAdv.pQueue = &dataQueue; /* Set the Data Entity queue for received data */
    EasyLink_cmdPropRxAdv.pOutput = (uint8_t*)&rxStatistics;

    if(absTime != 0)
    {
    EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_ABSTIME;
    EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1;
    EasyLink_cmdPropRxAdv.startTime = absTime;
    }
    else
    {
    EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_NOW;
    EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1;
    EasyLink_cmdPropRxAdv.startTime = 0;
    }

    //no timeout for Async Rx
    EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_NEVER;
    EasyLink_cmdPropRxAdv.endTime = 0;

    //Clear the Rx statistics structure
    memset(&rxStatistics, 0, sizeof(rfc_propRxOutput_t));

    asyncCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRxAdv,
    RF_PriorityNormal, rxDoneCallback, EASYLINK_RF_EVENT_MASK);

    if(asyncCmdHndl >= 0)
    {
    status = EasyLink_Status_Success;
    }

    //busyMutex will be released in callback

    return status;
    }


    //Callback for Async Rx complete
    static void rxDoneCallback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
    {
    EasyLink_Status status = EasyLink_Status_Rx_Error;
    //create rxPacket as a static so that the large payload buffer it is not
    //allocated from the stack
    // static EasyLink_RxPacket rxPacket;
    rfc_dataEntryGeneral_t *pDataEntry;
    pDataEntry = (rfc_dataEntryGeneral_t*) rxBuffer;

    //Release now so user callback can call EasyLink API's
    Semaphore_post(busyMutex);
    asyncCmdHndl = -1;//asyncCmdHndl = NULL;

    if (e & RF_EventLastCmdDone)
    {
    while(pDataEntry->status != DATA_ENTRY_FINISHED);

    if( (rxStatistics.nRxOk == 1) ||
    //or filer disabled and ignore due to addr mistmatch
    ((EasyLink_cmdPropRxAdv.pktConf.filterOp == 1) &&
    (rxStatistics.nRxIgnored == 1)) )
    {
    memcpy(s_DataDecodeBuf, (&pDataEntry->data + 1), 1023);
    s_DataProcessLength = 1023;

    status = EasyLink_Status_Success;
    }
    else if( rxStatistics.nRxBufFull == 1)
    {
    status = EasyLink_Status_Rx_Buffer_Error;
    }
    else if( rxStatistics.nRxStopped == 1)
    {
    status = EasyLink_Status_Aborted;
    }
    else
    {
    status = EasyLink_Status_Rx_Error;
    }
    }
    else if( (e == RF_EventCmdAborted) || e == RF_EventCmdStopped )
    {
    status = EasyLink_Status_Aborted;
    }

    if(rxCb != NULL)
    {
    rxCb(status);//rxCb(&rxPacket, status);
    }
    }



    I don't know where the mistake is. Can you give me some advice?

  • Hi FI,

    I used the Tx_Adv command settings as you provided for my project. But the issue is using the Tx_Adv command I am not receiving any packets and the operation ends with CRC error status.
    Please see below the structure for Rx_Adv and Tx_Adv that I am using for my project.
    We don't know what is the number of packets that will be sent in one go so I have to use the Tx_Adv and Rx_Adv concept. But definitely the packets count will be more than 255.

    //AdvTx command
    static rfc_CMD_PROP_TX_ADV_t RF_cmdPropTxAdv = {
    .commandNo = CMD_PROP_TX_ADV,
    .status = 0x0000,
    .pNextOp = 0x00000000,
    .startTime = 0x00000000,
    .startTrigger.triggerType = 0x0,
    .startTrigger.bEnaCmd = 0x0,
    .startTrigger.triggerNo = 0x0,
    .startTrigger.pastTrig = 0x0,
    .condition.rule = 0x1,
    .condition.nSkip = 0x0,
    .pktConf.bFsOff = 0x0,
    .pktConf.bUseCrc = 0x1,
    .pktConf.bCrcIncSw = 0x0,
    .pktConf.bCrcIncHdr = 0x1,
    .numHdrBits = 8,
    .pktLen = 0x00,
    .startConf = 0x0,
    .preTrigger.triggerType = TRIG_NOW,
    .preTrigger.bEnaCmd = 0,
    .preTrigger.triggerNo = 0,
    .preTrigger.pastTrig = 1,
    .preTime = 0x0,
    .syncWord = 0x930b51de,
    .pPkt = 0x00000000
    };


    //AdvRx command
    static rfc_CMD_PROP_RX_ADV_t RF_cmdPropRxAdv = {
    .commandNo = 0x3804,
    .status = 0x0000,
    .pNextOp = 0,
    .startTime = 0x00000000,
    .startTrigger.triggerType = TRIG_NOW,
    .startTrigger.bEnaCmd = 0x0,
    .startTrigger.triggerNo = 0x0,
    .startTrigger.pastTrig = 0x0,
    .condition.rule = 0x1,
    .condition.nSkip = 0x0,
    .pktConf.bFsOff = 0x0,
    .pktConf.bRepeatOk = 0x0,
    .pktConf.bRepeatNok = 0x0,
    .pktConf.bUseCrc = 0x1,
    .pktConf.bCrcIncSw = 0x0,
    .pktConf.bCrcIncHdr = 0x1,
    .pktConf.endType = 0x0,
    .pktConf.filterOp = 0x1,
    .rxConf.bAutoFlushIgnored = 0x0,
    .rxConf.bAutoFlushCrcErr = 0x0,
    .rxConf.bIncludeHdr = 0x1,
    .rxConf.bIncludeCrc = 0x0,
    .rxConf.bAppendRssi = 0x0,
    .rxConf.bAppendTimestamp = 0x0,
    .rxConf.bAppendStatus = 0x0,
    .syncWord0 = 0x930b51de,
    .syncWord1 = 0,
    .maxPktLen = 0,
    .hdrConf.numHdrBits = 8,
    .hdrConf.lenPos = 0,
    .hdrConf.numLenBits = 9,//8,
    .addrConf.addrType = 0,
    .addrConf.addrSize = 0,
    .addrConf.addrPos = 0,
    .addrConf.numAddr = 1,
    .lenOffset = 0,
    .endTrigger.triggerType = TRIG_NEVER,
    .endTrigger.bEnaCmd = 0x0,
    .endTrigger.triggerNo = 0x0,
    .endTrigger.pastTrig = 0x0,
    .endTime = 0x00000000,
    .pAddr = 0,
    .pQueue = 0,
    .pOutput = 0,
    };

    Also if I have to use the partial data entry concept I am finding it difficult to understand on how to use it. Please explain.
    Kindly provide your feedback on how can I resolve the issue.

    Thank you
    Vikram
  • Hi Vikram: 

    Try to change hdrConf in  RF_cmdPropRxAdv  all to zero and then test, like this:

    .hdrConf.numHdrBits =0,
    .hdrConf.lenPos = 0,
    .hdrConf.numLenBits = 0,

    may be you can receive a packet more than 255 bytes success.