LP-CC1352P7: Advanced Packet Format

Part Number: LP-CC1352P7

Tool/software:

I am using the Advanced Packet Format for data transmission and reception, but the maximum data length I can send is only 255 bytes. According to the manual, there should be no limit on the data length. Could you tell me if there is an issue with my configuration? The configuration and usage are as follows:

rfc_CMD_PROP_TX_ADV_t RF_cmdPropTxAdv_LongRange_400bps =
{
    .commandNo = 0x3803,
    .status = 0x0000,
    .pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
    .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 = 0x0,
    .pktLen = 0xFF,
    .startConf.bExtTxTrig = 0x0,
    .startConf.inputMode = 0x0,
    .startConf.source = 0x0,
    .preTrigger.triggerType = 0x0,
    .preTrigger.bEnaCmd = 0x0,
    .preTrigger.triggerNo = 0x0,
    .preTrigger.pastTrig = 0x0,
    .preTime = 0x0,
    .syncWord = 0xFE6B2840,
    .pPkt = 0 // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
};

rfc_CMD_PROP_RX_ADV_t RF_cmdPropRxAdv_LongRange_400bps =
{
    .commandNo = 0x3804,
    .status = 0x0000,
    .pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
    .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 = 0x0,
    .pktConf.bRepeatNok = 0x0,
    .pktConf.bUseCrc = 0x1,
    .pktConf.bCrcIncSw = 0x0,
    .pktConf.bCrcIncHdr = 0x0,
    .pktConf.endType = 0x0,
    .pktConf.filterOp = 0x0,
    .rxConf.bAutoFlushIgnored = 0x0,
    .rxConf.bAutoFlushCrcErr = 0x0,
    .rxConf.bIncludeHdr = 0x1,
    .rxConf.bIncludeCrc = 0x0,
    .rxConf.bAppendRssi = 0x0,
    .rxConf.bAppendTimestamp = 0x0,
    .rxConf.bAppendStatus = 0x1,
    .syncWord0 = 0xFE6B2840,
    .syncWord1 = 0x0,
    .maxPktLen = 0xFF,
    .hdrConf.numHdrBits = 0x0,
    .hdrConf.lenPos = 0x0,
    .hdrConf.numLenBits = 0x0,
    .addrConf.addrType = 0x0,
    .addrConf.addrSize = 0x0,
    .addrConf.addrPos = 0x0,
    .addrConf.numAddr = 0x0,
    .lenOffset = 0,
    .endTrigger.triggerType = 0x1,
    .endTrigger.bEnaCmd = 0x0,
    .endTrigger.triggerNo = 0x0,
    .endTrigger.pastTrig = 0x0,
    .endTime = 0x00000000,
    .pAddr = 0,
    .pQueue = 0, // INSERT APPLICABLE POINTER: (dataQueue_t*)&xxx
    .pOutput = 0 // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
};
  • the  packet_tx code is follows:

            RF_cmdPropTxAdv.startTrigger.triggerType = TRIG_NOW;
            RF_cmdPropTxAdv.numHdrBits = 0;
            RF_cmdPropTxAdv.pktLen = ((uint8_t)(pktLen)) + 2;
            RF_cmdPropTxAdv.pPkt = txPacket;

           
    the packet_rx code is follows:

            RF_cmdPropRxAdv.pQueue = &dataQueue;
            RF_cmdPropRxAdv.rxConf.bAutoFlushIgnored = 1;
            RF_cmdPropRxAdv.rxConf.bAutoFlushCrcErr = 1;
            RF_cmdPropRxAdv.maxPktLen = RADIO_MAX_LENGTH;
            RF_cmdPropRxAdv.pktConf.bRepeatOk = 1;
            RF_cmdPropRxAdv.pktConf.bRepeatNok = 1;
            RF_cmdPropRxAdv.pOutput = (uint8_t*)&rxStatisticsProp;

         For reference
  • Not sure what PHY you are using (400bps???) as out SLR PHYs are 2.5 or 5 kbps (and they have a fixed sync word (not 0xFE6B2840)):

    https://www.ti.com/lit/swra642

    Assuming you are using one of our SLR PHYs, teh following code can be used to transmit packets where your length byte is 2 bytes instead of 1:

    TX:

    /***** Includes *****/
    /* Standard C Libraries */
    #include <stdlib.h>
    #include <unistd.h>
    
    /* TI Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/GPIO.h>
    
    /* Driverlib Header files */
    #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    
    /* Board Header files */
    #include "ti_drivers_config.h"
    #include <ti_radio_config.h>
    
    /***** Defines *****/
    
    // Packet TX Configuration
    #define SIZE_OF_LENGHT_FIELD    2
    #define PAYLOAD_LENGTH          400
    
    #define PACKET_INTERVAL         500000  // Set packet interval to 500000 us or 500 ms
    
    static RF_Object rfObject;
    static RF_Handle rfHandle;
    
    static uint8_t packet[SIZE_OF_LENGHT_FIELD + PAYLOAD_LENGTH];
    static uint16_t seqNumber;
    
    void *mainThread(void *arg0)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        GPIO_setConfig(CONFIG_GPIO_GLED, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        GPIO_write(CONFIG_GPIO_GLED, CONFIG_GPIO_LED_OFF);
    
        RF_cmdPropTxAdv.pktLen = PAYLOAD_LENGTH + SIZE_OF_LENGHT_FIELD;
        RF_cmdPropTxAdv.pPkt = packet;
        RF_cmdPropTxAdv.startTrigger.triggerType = TRIG_NOW;
        RF_cmdPropTxAdv.condition.rule = 1;
        RF_cmdPropTxAdv.pktConf.bUseCrc = 1;
    
        // Request access to the radio
        rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
    
        // Set the frequency
        RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
    
        while(1)
        {
            packet[0] = (uint8_t)(PAYLOAD_LENGTH);
            packet[1] = (uint8_t)(PAYLOAD_LENGTH >> 8);
    
            for (uint16_t i = 2; i < PAYLOAD_LENGTH + SIZE_OF_LENGHT_FIELD; i++)
            {
                packet[i] = i - 1;
            }
    
            // Send packet
            RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTxAdv, RF_PriorityNormal, NULL, 0);
    
            GPIO_toggle(CONFIG_GPIO_GLED);
    
            // Power down the radio
            RF_yield(rfHandle);
    
            // Sleep for PACKET_INTERVAL us
            usleep(PACKET_INTERVAL);
        }
    }

    RX:

    /***** Includes *****/
    /* Standard C Libraries */
    #include <stdlib.h>
    
    /* TI Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/GPIO.h>
    
    /* Driverlib Header files */
    #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    
    /* Board Header files */
    #include "ti_drivers_config.h"
    
    /* Application Header files */
    #include "RFQueue.h"
    #include <ti_radio_config.h>
    
    /***** Defines *****/
    
    #define DATA_ENTRY_HEADER_SIZE 8    // Constant header size of a Generic Data Entry
    #define NUM_DATA_ENTRIES       2    // NOTE: Only two data entries supported at the moment
    
    #define SIZE_OF_LENGHT_FIELD   2
    
    // Optional appended bytes at the end of the packet
    //  -------------------------------------------------------
    //  | CRC1 | CRC0 | RSSI | TS0 | TS1 | TS2 | TS3 | Status |
    //  -------------------------------------------------------
    
    #define CRC                     0   // 2 if .rxConf.bIncludeCrc = 0x1, 0 otherwise
    #define RSSI                    0   // 1 if .rxConf.bAppendRssi = 0x1, 0 otherwise
    #define TIMESTAMP               0   // 4 if .rxConf.bAppendTimestamp = 0x1, 0 otherwise
    #define STATUS                  0   // 1 if .rxConf.bAppendStatus = 0x1, 0 otherwise
    
    #define NUM_APPENDED_BYTES      SIZE_OF_LENGHT_FIELD + CRC + RSSI + TIMESTAMP + STATUS
    
    #define MAX_LENGTH              400 // Max length byte the radio will accept
    
    static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
    
    static RF_Object rfObject;
    static RF_Handle rfHandle;
    
    /* Buffer which contains all Data Entries for receiving data.
     * Pragmas are needed to make sure this buffer is 4 byte aligned (requirement from the RF Core) */
    static uint8_t rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                                     MAX_LENGTH,
                                                                     NUM_APPENDED_BYTES)]
                                                                     __attribute__((aligned(4)));
    // Receive dataQueue for RF Core to fill in data
    dataQueue_t dataQueue;
    rfc_dataEntryGeneral_t* currentDataEntry;
    uint16_t packetLength;
    uint8_t* packetDataPointer;
    rfc_propRxOutput_t rxStatistics;
    
    uint8_t packet[MAX_LENGTH + NUM_APPENDED_BYTES - SIZE_OF_LENGHT_FIELD]; // Length is stored separately
    
    void *mainThread(void *arg0)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        GPIO_setConfig(CONFIG_GPIO_RLED, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_write(CONFIG_GPIO_RLED, CONFIG_GPIO_LED_OFF);
    
        if( RFQueue_defineQueue(&dataQueue,
                                rxDataEntryBuffer,
                                sizeof(rxDataEntryBuffer),
                                NUM_DATA_ENTRIES,
                                MAX_LENGTH + NUM_APPENDED_BYTES))
        {
            // Failed to allocate space for all data entries
            while(1);
        }
    
        // Modify CMD_PROP_RX command for application needs
        // Set the Data Entity queue for received data
        RF_cmdPropRxAdv.pQueue = &dataQueue;
        // Discard ignored packets from Rx queue
        RF_cmdPropRxAdv.rxConf.bAutoFlushIgnored = 1;
        // Discard packets with CRC error from Rx queue
        RF_cmdPropRxAdv.rxConf.bAutoFlushCrcErr = 1;
        // Implement packet length filtering to avoid PROP_ERROR_RXBUF
        RF_cmdPropRxAdv.maxPktLen = MAX_LENGTH;
        RF_cmdPropRxAdv.pktConf.bRepeatOk = 1;
        RF_cmdPropRxAdv.pktConf.bRepeatNok = 1;
        RF_cmdPropRxAdv.pOutput = (uint8_t*)&rxStatistics;
        RF_cmdPropRxAdv.condition.rule = 1;
        RF_cmdPropRxAdv.pktConf.bUseCrc = 0x1;
        RF_cmdPropRxAdv.rxConf.bIncludeHdr = 0x1;
        RF_cmdPropRxAdv.endTrigger.triggerType = 0x1;
        RF_cmdPropRxAdv.pktConf.bCrcIncHdr = 0x1;
        RF_cmdPropRxAdv.hdrConf.numHdrBits = 16;
        RF_cmdPropRxAdv.hdrConf.numLenBits = 16;
    
        // Optional bytes to append:
        RF_cmdPropRxAdv.rxConf.bIncludeCrc = 0x0;
        RF_cmdPropRxAdv.rxConf.bAppendRssi = 0x0;
        RF_cmdPropRxAdv.rxConf.bAppendTimestamp = 0x0;
        RF_cmdPropRxAdv.rxConf.bAppendStatus = 0x0;
    
        // Request access to the radio
        rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
    
        // Set the frequency
        RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
    
        RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropRxAdv, RF_PriorityNormal, &callback, RF_EventRxEntryDone);
    
        while(1);
    }
    
    void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
    {
        if (e & RF_EventRxEntryDone)
        {
            // Toggle pin to indicate RX
            GPIO_toggle(CONFIG_GPIO_RLED);
    
            // Get current unhandled data entry
            currentDataEntry = RFQueue_getDataEntry();
    
            packetLength = ((uint16_t)((*(uint8_t*)(&currentDataEntry->data+1)) << 8) | (uint16_t)(*(uint8_t*)(&currentDataEntry->data)));
            packetDataPointer = (uint8_t*)(&currentDataEntry->data + SIZE_OF_LENGHT_FIELD);
    
            // Copy the payload and the status bytes to the packet variable
            memcpy(packet, packetDataPointer, (packetLength + NUM_APPENDED_BYTES - SIZE_OF_LENGHT_FIELD));
    
            RFQueue_nextEntry();
        }
    }
    

    The code is tested and works as expected.

    Siri

  • Thanks for your reply,Siri

  • Hi,Siri,

    We are currently using a custom physical layer and want to transmit 54528 bytes. How should we configure parameters such as the synchronization word?

    Best Regards.

  • First of all, it is not possible to change the sync word if you are using the SLR mode (see 

    CC13xx Long Range Modes)

    Second, even if you have 2 bytes available for the length, internal constraints in the modem limits this to 8191 bytes (including header and CRC).

    Sending very long packets is generally a bad idea, as the Packet Error Rate increase with packet length.

    Siri

  • Thanks a lot, Siri

  • Hi, Siri

    We use fecMode of '0000: Uncoded binary modulation', can the syncword be modified? and how to set 64bit syncword according "CC13xx Long Range Modes" Mode 1?

    Regards.

  • Hi, Siri

    How to send 8000 bytes? we tested it is 750 bytes.

    Best Regards.

  • You cannot change fecMode when using the Long Range Mode PHY.

    You cannot change the sync word either. Please read the documentation that I linked to:

    "Mode 1- Legacy Long Range Packet Format

    Mode 1 uses a standard preamble sequence (010101..) followed by a fixed 64-bit sync word. The 64-bit sync word used in Mode 1 is 0xFE6B_2840_0194_D7BF, LSB-first. This sync word is not user-programmable"

    Siri

  • The max length needs to be less than 4096 (not 8191 as I first wrote).

    This is including the CRC, so in TX you can set

    #define PAYLOAD_LENGTH          4093

    and in RX

    #define MAX_LENGTH              4093

    I have tested this with the 2.5 kbps SLR mode, and it works as expected.

    Siri