SDAA260 April 2026 CC1310 , CC1311P3 , CC1312PSIP , CC1312R , CC1312R7 , CC1314R10 , CC1350 , CC1352P , CC1352P7 , CC1352R , CC1354P10 , CC1354R10
Below is code that can be used to receive a packet using the advanced packet format. This code can only be used for PHY settings that export/import the advanced commands by default.
1: //--------------------------------------------------------------------------------------------
2: // Receive Advanced Packet Format with CMD_PROP_RX_ADV
3: //--------------------------------------------------------------------------------------------
4:
5: // Defines
6: #define DATA_ENTRY_HEADER_SIZE 8 // Constant header size of a Generic Data Entry
7: #define NUM_DATA_ENTRIES 2 // NOTE: Only two data entries supported
8: #define CRC 4 // 4/2 (based on FCS) if .rxConf.bIncludeCrc = 0x1, else 0
9: #define RSSI 1 // 1 if .rxConf.bAppendRssi = 0x1, 0 otherwise
10: #define TIMESTAMP 4 // 4 if .rxConf.bAppendTimestamp = 0x1, 0 otherwise
11: #define STATUS 1 // 1 if .rxConf.bAppendStatus = 0x1, 0 otherwise
12: #define HEADER_FIELD 2 // RF_cmdPropRx.rxConf.bIncludeHdr = 0x1
13: #define MAX_LENGTH 2047 // Max length the radio will accept (incl. CRC bytes)
14: #define NUM_APPENDED_BYTES HEADER_FIELD + RSSI + TIMESTAMP + STATUS
15:
16: uint8_t packet[MAX_LENGTH + NUM_APPENDED_BYTES - HEADER_FIELD]; // Header/Length stored in
17: uint16_t packetLength; // packetLength variable
18:
19: static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
20:
21: static RF_Object rfObject;
22: static RF_Handle rfHandle;
23:
24: static uint8_t rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
25: MAX_LENGTH, NUM_APPENDED_BYTES)]__attribute__((aligned(4)));
26: static dataQueue_t dataQueue;
27: static rfc_dataEntryGeneral_t* currentDataEntry;
28: static uint8_t* packetDataPointer;
29: rfc_propRxOutput_t rxStatistics;
30: uint16_t crc16;
31: uint32_t crc32;
32: int8_t rssi;
33: uint32_t timestamp;
34: uint8_t status;
35:
36: void *mainThread(void *arg0)
37: {
38: RF_Params rfParams;
39: RF_Params_init(&rfParams);
40:
41: if(RFQueue_defineQueue(&dataQueue, rxDataEntryBuffer, sizeof(rxDataEntryBuffer),
42: NUM_DATA_ENTRIES, MAX_LENGTH + NUM_APPENDED_BYTES))
43: {
44: while(1);
45: }
46:
47: RF_cmdPropRxAdv.pktConf.bRepeatOk = 0x1; // Application specific settings
48: RF_cmdPropRxAdv.pktConf.bRepeatNok = 0x1;
49: RF_cmdPropRxAdv.rxConf.bAutoFlushCrcErr = 0x1;
50: RF_cmdPropRxAdv.maxPktLen = MAX_LENGTH;
51: RF_cmdPropRxAdv.pQueue = &dataQueue;
52:
53: RF_cmdPropRxAdv.pOutput = (uint8_t*)&rxStatistics; // Optional (for debug)
54:
55: rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup,
56: &rfParams);
57: RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
58: RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropRxAdv, RF_PriorityNormal,
59: &callback, RF_EventRxEntryDone);
60: while(1);
61: }
62:63: //--------------------------------------------------------------------------------------------
64: // Callback for Receiving Advanced Packet Format with CMD_PROP_RX_ADV
65: //--------------------------------------------------------------------------------------------
66:
67: void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
68: {
69: if(e & RF_EventRxEntryDone)
70: {
71: currentDataEntry = RFQueue_getDataEntry();
72:
73: uint16_t header = ((uint16_t)(*(uint8_t*)(¤tDataEntry->data + 1) << 8) |
74: (uint16_t)(*(uint8_t*)(¤tDataEntry->data + 0) << 0));
75:
76: bool fcs = (bool)(0x1000 & header);
77:
78: packetLength = 0x07FF & header;
79:
80: packetDataPointer = (uint8_t*)(¤tDataEntry->data + HEADER_FIELD);
81:
82: memcpy(packet, packetDataPointer,
83: (packetLength + NUM_APPENDED_BYTES - HEADER_FIELD));
84:
85: // The FCS field in the header tell us if the CRC is 2 or 4 bytes long
86: if(fcs) // FCS = 1 -> 2 bytes CRC
87: {
88: crc16 = ((uint16_t)(packet[packetLength - 2] << 8) +
89: (uint16_t)(packet[packetLength - 1] << 0));
90: }
91: else // FCS = 0 -> 4 bytes CRC
92: {
93: crc32 = ((uint32_t)(packet[packetLength - 4] << 24) +
94: (uint32_t)(packet[packetLength - 3] << 16) +
95: (uint32_t)(packet[packetLength - 2] << 8) +
96: (uint32_t)(packet[packetLength - 1] << 0));
97: }
98:
99: rssi = packet[packetLength + 0];
100:
101: timestamp = ((uint32_t)(packet[packetLength + 1] << 0 ) +
102: (uint32_t)(packet[packetLength + 2] << 8 ) +
103: (uint32_t)(packet[packetLength + 3] << 16) +
104: (uint32_t)(packet[packetLength + 4] << 24));
105:
106: status = packet[packetLength + 5];
107:
108: RFQueue_nextEntry();
109: }
110: }The maximum packet length supported for this format is 2047 bytes (this includes CRC (2 or 4 bytes)).
Please note that IEEE 802.15.4g does not specify the format of the payload (PSDU data). The PSDU is only described as a stream of bits, and whatever is inside is decided by the higher-level MAC specification.
In the code examples in Section 3.1.1 and Section 3.1.2, the payload is transmitted MSB first. To be compliant with SmartRF Studio (transmitting the payload LSB first by default), the code below can be used (on both RX and TX).
1: //---------------------------------------------------------------------------------------------
2: // Code for Converting Payload from MSB First to LSB First
3: //---------------------------------------------------------------------------------------------
4:
5: uint8_t lsbFirst(uint8_t b)
6: {
7: b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
8: b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
9: b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
10: return b;
11: }