rflib to RCL Migration Guide

As CC23xx devices do not have a separate CM0 core for RF, a Radio Control Layer (RCL) which is entirely different from the existing CC26x2 device rflib must be used.

The following sections discuss the major changes to radio commands from the main application file between CC26x2 devices and the CC23xx devices, using rfPacketTx.c as an example.

Warning

This is not a fully comprehensive list and the API documentation should be consulted when attempting to convert radio commands. File comparison software is highly recommended to compare the difference between application files’ radio commands.

Includes

The rflib directory was included for CC26x2 devices

/***** Includes *****/
//...

/* TI Drivers */
#include <ti/drivers/rf/RF.h>

/* Driverlib Header files */
#include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)

/* Board Header files */
#include <ti_radio_config.h>

CC23xx devices will use RCL instead

/***** Includes *****/
//...

/* TI Drivers */
#include <ti/drivers/rcl/RCL.h>
#include <ti/drivers/rcl/RCL_Scheduler.h>
#include <ti/drivers/rcl/commands/generic.h>

#if defined(USE_250KBPS_MSK) || defined(USE_500KBPS_MSK)
#include <setup/generic_fsk_prop_setup.h>
#else
#include <setup/generic_1m_prop_setup.h>
#endif

Defines

CC23xx devices are bound to rely on different definitions since the commands are not similar

/***** Defines *****/
/* Packet TX Configuration */
#define MAX_LENGTH              (30U) // Max packet length
#define NUM_DATA_ENTRIES        (2U)  // Number of data entries
#define NUM_PAD_BYTES           (3U)  // Number of pad bytes

/* Header length */
#if defined(USE_500KBPS_MSK) || defined(FIXED_LENGTH_SETUP) // 500KBPS is always set up for fixed length packets
#define HDR_LEN                 (0U)
#else
#if defined(USE_250KBPS_MSK) // 250KBPS with variable length enabled
#define HDR_LEN                 (1U)
#else // 1 Mbps with variable length enabled
#define HDR_LEN                 (2U)
#endif
#endif

#define PACKET_INTERVAL     500000  /* Set packet interval to 500000us or 500ms */

/* Indicates if FS is off */
#define FS_OFF                  (1U)  // 0: On, 1: Off

#if defined(USE_250KBPS_MSK) || defined(USE_500KBPS_MSK)
#define FREQUENCY               (2433000000U)
#else
#define FREQUENCY               (2440000000U)
#endif

Variables and initialization

RF_* had been initialized for CC26x2 devices

static RF_Object rfObject;
static RF_Handle rfHandle;

// ...

void *mainThread(void *arg0)
{
   RF_Params rfParams;
   RF_Params_init(&rfParams);

   /* Request access to the radio */
#if defined(DeviceFamily_CC26X0R2)
   rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioSetup, &rfParams);
#else
   rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
#endif// DeviceFamily_CC26X0R2

   /* Set the frequency */
   RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);

Which CC23xx devices replace with RCL_* variants

/* RCL Commands */
RCL_CmdGenericTx   txCmd;               // TX command

/* RCL Client used to open RCL */
static RCL_Client  rclClient;

// ...

void *mainThread(void *arg0)
{
   /* Initialize and open RCL */
   RCL_init();

#if defined(USE_250KBPS_MSK)
   RCL_Handle rclHandle = RCL_open(&rclClient, &rclRadioConfigGenericMsk250k);
#elif defined(USE_500KBPS_MSK)
   RCL_Handle rclHandle = RCL_open(&rclClient, &rclRadioConfigGenericMsk500k);
#else
   RCL_Handle rclHandle = RCL_open(&rclClient, &rclRadioConfigGenericBle);
#endif

   /* Setup generic transmit command */
   txCmd = RCL_CmdGenericTx_DefaultRuntime();

   /* Set RF frequency */
   txCmd.rfFrequency = FREQUENCY;
#if !(defined(USE_250KBPS_MSK) || defined(USE_500KBPS_MSK))
   txCmd.common.phyFeatures = RCL_GENERIC_PHY_FEATURE_PHY_1MBPS;
#endif

RF commands

Different command parameters should be expected. Below is an example for CC26x2 devices

RF_cmdPropTx.pktLen = PAYLOAD_LENGTH;
RF_cmdPropTx.pPkt = packet;
RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;

// ...

while(1)
{
    /* Create packet with incrementing sequence number and random payload */
    packet[0] = (uint8_t)(seqNumber >> 8);
    packet[1] = (uint8_t)(seqNumber++);
    uint8_t i;
    for (i = 2; i < PAYLOAD_LENGTH; i++)
    {
        packet[i] = rand();
    }

    /* Send packet */
    RF_EventMask terminationReason = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx,
                                                RF_PriorityNormal, NULL, 0);

Compared to CC23xx devices

   /* Start command as soon as possible */
   txCmd.common.scheduling = RCL_Schedule_Now;
   txCmd.common.status = RCL_CommandStatus_Idle;

   txCmd.config.fsOff = FS_OFF; // Turn off FS

   /* Callback triggers on last command done */
   txCmd.common.runtime.callback = defaultCallback;
   txCmd.common.runtime.rclCallbackMask.value = RCL_EventLastCmdDone.value;

   /* Set RCL TX buffer packet to be packet buffer */
   RCL_Buffer_TxBuffer *txPacket = (RCL_Buffer_TxBuffer *)&packet;

   while(1)
   {
      /* Create packet with random payload */
      uint8_t *txData;
      txData = RCL_TxBuffer_init(txPacket, NUM_PAD_BYTES, HDR_LEN, MAX_LENGTH);
#if !(defined(USE_500KBPS_MSK) || defined(FIXED_LENGTH_SETUP))
#if defined(USE_250KBPS_MSK)
      txData[0] = MAX_LENGTH;
#else
      txData[0] = 0;
      txData[1] = MAX_LENGTH;
#endif
#endif
      for (int i = HDR_LEN; i < MAX_LENGTH; i++)
      {
            txData[i] = rand();
      }

      /* Set packet to transmit */
      RCL_TxBuffer_put(&txCmd.txBuffers, txPacket);

      txCmd.common.status = RCL_CommandStatus_Idle;

      /* Submit command */
      RCL_Command_submit(rclHandle, &txCmd);

      /* Pend on command completion */
      RCL_Command_pend(&txCmd);

Note

If changing the txCmd->txPower parameter it is important to note that two additional sub-parameters, dbm and fraction, will each need to be initialized. For example, txCmd->txPower = (RCL_Command_TxPower){.dBm = txPower_dBm, .fraction = 0};

RF API comparison

Below is a table summarizing the different API functions, however it is once again advised that the rflib and Radio Control Layer (RCL) APIs be further referenced for a full understanding of differences.

Function

rflib API

RCL API

Initialize the radio driver

RF_Params_init

RCL_init

Open the radio instance

RF_open

RCL_open

Close the radio instance

RF_close

RCL_close

Submit a radio command

RF_postCmd

RCL_Command_submit

Wait for the radio command to complete

RF_pendCmd

RCL_Command_pend

Submit a radio command and wait for it to complete

RF_runCmd

RCL_Command_submit & RCL_Command_pend

Stop a radio command

RF_cancelCmd

RCL_Command_stop

Get RSSI

RF_getRssi

RCL_readRssi