SDAA260 April   2026 CC1310 , CC1311P3 , CC1312PSIP , CC1312R , CC1312R7 , CC1314R10 , CC1350 , CC1352P , CC1352P7 , CC1352R , CC1354P10 , CC1354R10

 

  1.   1
  2.   Abstract
  3.   Trademarks
  4. 1Introduction
  5. 2PHY Settings Exported with the Standard Commands
    1. 2.1 Standard Packet Format (1 Length Byte)
      1. 2.1.1 TX using CMD_PROP_TX and Standard Packet Format (1 Length Byte)
      2. 2.1.2 RX using CMD_PROP_RX and Standard Packet Format (1 Length Byte)
      3. 2.1.3 TX using CMD_PROP_TX_ADV and Standard Packet Format (1 Length Byte)
      4. 2.1.4 RX using CMD_PROP_RX_ADV and Standard Packet Format (1 Length Byte)
    2. 2.2 Standard Packet Format (2 Length Bytes)
      1. 2.2.1 TX using CMD_PROP_TX_ADV and Standard Packet Format (2 Length Bytes)
      2. 2.2.2 RX Using CMD_PROP_RX_ADV and Standard Packet Format (2 Length Bytes)
  6. 3TX and RX Settings Exported with the Advanced Commands
    1. 3.1 Advanced Packet Format
      1. 3.1.1 TX using CMD_PROP_TX_ADV and Advanced Packet Format
      2. 3.1.2 RX using CMD_PROP_RX_ADV and Advanced Packet Format
    2. 3.2 Standard Packet Format (1 Length Byte)
      1. 3.2.1 TX using CMD_PROP_TX_ADV and Standard Packet Format (1 Length Byte)
      2. 3.2.2 RX using CMD_PROP_RX_ADV and Standard Packet Format (1 Length Byte)
    3. 3.3 Standard Packet Format (2 Length Bytes)
      1. 3.3.1 TX using CMD_PROP_TX_ADV and Standard Packet Format (2 Length Bytes)
      2. 3.3.2 RX using CMD_PROP_RX_ADV and Standard Packet Format (2 Length Bytes)
  7. 4References

RX using CMD_PROP_RX_ADV and Advanced Packet Format

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*)(&currentDataEntry->data + 1) << 8) |
74:                             (uint16_t)(*(uint8_t*)(&currentDataEntry->data + 0) << 0));
75:
76:          bool fcs = (bool)(0x1000 & header);
77:
78:          packetLength = 0x07FF & header;
79:
80:          packetDataPointer = (uint8_t*)(&currentDataEntry->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: }