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.

CC1312R: Trouble extending 2 byte address filtering to 4 bytes using CMD_PROP_RX_ADV

Part Number: CC1312R
Other Parts Discussed in Thread: SYSCONFIG

I have a system that uses two radio to form a network. This system already has address filtering enabled on a two byte address in the payload (not the header). I'm trying to extend the address to 4 bytes by using the first two U16 values in the payload (uint16_t), I also have unit tests written in python to verify the status of the connection.

Both devices have a network ID set to 8888

With device_id set to 1 and 2 respectively

destination_address is the device_id of the receiver in the payload structure

My address list is currently set to the network ID and device ID, packet into a uint32_t like so

uint32_t s_address_list[] = 

{
0xB8 0x22 0x01 0x00

}

with 0xB822 = 8888 (network ID)

and 0x0100 = 01 (Device ID)

Packet Format

typedef struct ism_msg_t {
    uint8_t length;
    uint16_t network_id;
    uint16_t destination_address;
    uint16_t input_id;
    uint8_t message_type;
    uint8_t sequence_number;
    uint16_t source_address;
    uint8_t payload[FORT_ISM_PAYLOAD_LENGTH_MAX];
} ism_msg_t;
My beacon message is sent with a 4 byte payload
Address List
The packet is set to the start of network_id using the rfc_CMD_PROP_TX_t structure's pPkt pointer...
rf_prop_tx->pPkt  = (uint8_t*)&ps_radio->p_tx_beacon_msg->network_id;
CMD_PROP_RX_ADV_t is setup to receive using the following settings
static rfc_CMD_PROP_RX_ADV_t s_prop_rx_adv = {
    .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 = 0x1,
    .pktConf.bRepeatNok = 0x1,
    .pktConf.bUseCrc = 0x1,
    .pktConf.bCrcIncSw = 0x0,
    .pktConf.bCrcIncHdr = 1U,
    .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 = 0x0,
    .syncWord0 = 0x930B51DE,
    .syncWord1 = 0x00000000,
    .maxPktLen = 0x00FF,
    .hdrConf.numHdrBits = 8U,  // size of length and address, we only used length
    .hdrConf.lenPos = 0U,
    .hdrConf.numLenBits = 8U,
    .addrConf.addrType = 0x0,
    .addrConf.addrSize = sizeof(uint_16_t),
    .addrConf.addrPos = 0x0,
    .addrConf.numAddr = 0x1,
    .lenOffset = 0x00,
    .endTrigger.triggerType = 0x0,
    .endTrigger.bEnaCmd = 0x0,
    .endTrigger.triggerNo = 0x0,
    .endTrigger.pastTrig = 0x0,
    .endTime = 0x00000000,
    .pAddr = 0,   // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
    .pQueue = 0,  // INSERT APPLICABLE POINTER: (dataQueue_t*)&xxx
    .pOutput = 0  // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
};
Because the full 4 byte address is already in s_address_list, I would expect to only have to change .addrConf.addrSize = sizeof(uint_16_t) to .addrConf.addrSize = sizeof(uint_32_t) inside the rfc_CMD_PROP_RX_ADV_t structure. 
When I make that change, all my unit tests stop responding. I can no longer connect to my network. Changing the address size back to sizeof(uint16_t) fixes the issue.
I even tried reversing the byte order from 0xB8 0x22 0x01 0x00 to 0x00 0x01 0x22 0xB8. That did not work.
I event tried adding both address to the list (LSB & MSB first), and setting the addrConf.numAddr = 2. That did not work either.
Any suggestions, because I feel like this should work?
  • Attached is an example that transmit a packet with 4 address bytes.

    I have used rfPacketTX andrfPacketRX as a starting point and exported the advanced TX and RX commands from SysConfig:

    TX:

    //------------------------------------------------------------------------------------------------------------------
    //                          RF_cmdPropTxAdv.numHdrBits = 0x00
    //
    //                          <------------------------------  RF_cmdPropTxAdv.pktLen  ------------------------------>
    //------------------------------------------------------------------------------------------------------------------
    //|  Preamble  |    Sync    | Length (SIZE_OF_LENGHT_FIELD) | Address (SIZE_OF_ADDRESS) | Payload (PAYLOAD_LENGTH) |
    //------------------------------------------------------------------------------------------------------------------
    //| 0x55555555 | 0x930B51DE |             0x0E              |     A3A2A1A0              |  0x0102030405060708090A  |
    //------------------------------------------------------------------------------------------------------------------
    //
    // Sent on the air: 0x55555555 + 0x930B51DE + 0x12 + 0xA7A6A5A4A3A2A1A0 + 0x0102030405060708090A + CRC
    //------------------------------------------------------------------------------------------------------------------
    
    // Packet TX Configuration
    #define SIZE_OF_LENGHT_FIELD    1 // Can be 1 or 2 bytes
    #define SIZE_OF_ADDRESS         4 // Can be 1 - 8 bytes
    
    // The address length needs to correspond to SIZE_OF_ADDRESS
    #define ADDRESS                 0xA3A2A1A0
    
    #define PAYLOAD_LENGTH          10 // Max 255 if SIZE_OF_LENGHT_FIELD = 1
    
    #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 + SIZE_OF_ADDRESS + PAYLOAD_LENGTH];
    static uint16_t seqNumber;
    static uint64_t addr = (uint64_t)ADDRESS;
    static uint8_t addrSize = SIZE_OF_ADDRESS;
    
    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 = SIZE_OF_LENGHT_FIELD + SIZE_OF_ADDRESS + PAYLOAD_LENGTH; // For the advanced TX command, pktLen must cover length + address + payload
        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)
        {
            uint16_t j;
            uint8_t i = 0;
    
            // For the advanced TX command, the length must manually be written to the packet
            packet[i++] = (uint8_t)(SIZE_OF_ADDRESS + PAYLOAD_LENGTH);
    
            packet[i++] = (uint8_t)((addr & 0x00000000FF000000) >> 24); // A3
            packet[i++] = (uint8_t)((addr & 0x0000000000FF0000) >> 16); // A2
            packet[i++] = (uint8_t)((addr & 0x000000000000FF00) >> 8);  // A1
            packet[i++] = (uint8_t)((addr & 0x00000000000000FF) >> 0);  // A0
    
            for (j = i; j < (SIZE_OF_LENGHT_FIELD + SIZE_OF_ADDRESS + PAYLOAD_LENGTH); j++)
            {
                packet[j] = j - 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:

    #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
    
    // The following two parameters must be the same as in the rfPacketTX.c
    // Appended bytes in the start of the packet due to rxConf.bIncludeHdr = 0x1
    #define SIZE_OF_LENGHT_FIELD    1   // if 1: .hdrConf.numHdrBits = 8 and hdrConf.numLenBits = 8
                                        // if 2: .hdrConf.numHdrBits = 16 and hdrConf.numLenBits = 16
    #define PAYLOAD_LENGTH          10  // Must be set larger or equal to what is set in rfPacketTx.c
    #define SIZE_OF_ADDRESS         4
    #define NUMBER_OF_ADDRESSES     1
    
    // 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                  1   // 1 if .rxConf.bAppendStatus = 0x1, 0 otherwise
    
    #define NUM_APPENDED_BYTES      SIZE_OF_LENGHT_FIELD + CRC + RSSI + TIMESTAMP + STATUS
    
    #define MAX_LENGTH              SIZE_OF_ADDRESS + PAYLOAD_LENGTH
    
    
    // The address needs to be written in the opposite direction compared to what is done in rfPacketTx
    uint32_t AddressList[] = {0xA0A1A2A3};
    
    
    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) */
    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_ALIGN (rxDataEntryBuffer, 4);
    static uint8_t
    rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES)];
    #elif defined(__IAR_SYSTEMS_ICC__)
    #pragma data_alignment = 4
    static uint8_t
    rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES)];
    #elif defined(__GNUC__)
    static uint8_t
    rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES)]
                                                      __attribute__((aligned(4)));
    #else
    #error This compiler is not supported.
    #endif
    
    // 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 stores 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;             // Not set in sysConfig like for the RF_cmdPropRx
        RF_cmdPropRxAdv.pktConf.bUseCrc = 0x1;          // Not set in sysConfig like for the RF_cmdPropRx
        RF_cmdPropRxAdv.rxConf.bIncludeHdr = 0x1;       // Not set in sysConfig like for the RF_cmdPropRx
        RF_cmdPropRxAdv.endTrigger.triggerType = 0x1;   // Not set in sysConfig like for the RF_cmdPropRx
    
        RF_cmdPropRxAdv.pktConf.bCrcIncHdr = 0x1;       // Field specific for the advanced RX command
    
        RF_cmdPropRxAdv.hdrConf.numHdrBits = 8; // Field specific for the advanced RX command
        RF_cmdPropRxAdv.hdrConf.numLenBits = 8; // Field specific for the advanced RX command
    
        // Optional bytes to append:
        RF_cmdPropRxAdv.rxConf.bIncludeCrc = 0x0;
        RF_cmdPropRxAdv.rxConf.bAppendRssi = 0x0;
        RF_cmdPropRxAdv.rxConf.bAppendTimestamp = 0x0;
        RF_cmdPropRxAdv.rxConf.bAppendStatus = 0x1;             // This should be set to 1 to be able to read addressInd (which index in the AddressList the received address matches)
    
        RF_cmdPropRxAdv.addrConf.addrType = 0;                  // Address after header
        RF_cmdPropRxAdv.addrConf.addrSize = SIZE_OF_ADDRESS;    // size of address (in bytes)
        RF_cmdPropRxAdv.addrConf.numAddr = NUMBER_OF_ADDRESSES; // Number of addresses in address list
        RF_cmdPropRxAdv.pAddr = (uint8_t*)&AddressList;
    
        // 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();
    
            if (SIZE_OF_LENGHT_FIELD == 1)
            {
                packetLength      =  (uint16_t)(*(uint8_t*)(&currentDataEntry->data));
                packetDataPointer = (uint8_t*)(&currentDataEntry->data + SIZE_OF_LENGHT_FIELD);
    
                // Copy the payload + the status byte to the packet variable
                memcpy(packet, packetDataPointer, (packetLength + NUM_APPENDED_BYTES - SIZE_OF_LENGHT_FIELD));
            }
            else // SIZE_OF_LENGHT_FIELD = 2
            {
                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();
        }
    }

    Siri

  • Thank you. This example helped a lot. I believe my issue was that I was not packing the address in TX in reverse byte order.