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.

CC1352P7: RX Only Header and no Payload w/ Advanced Proprietary RF Commands

Part Number: CC1352P7
Other Parts Discussed in Thread: SYSCONFIG

Tool/software:

Design Goal:

I'm trying to create a 915MHz based PHY and LL which uses 16-bit address filtering and CRC checking that could potentially support large payload.

Setup:

Frequency: 915MHz
Symbol rate: 100kbps
Deviation: 50kHz
RX Filter BW: 195.9kHz
Whitening: Dynamically IEEE 801.15.4g compatible whitener and 16/32-bit CRC
Sync word: 16 bit: 0x55AC
Preamble: 1 byte, Send different first preamble bit in preamble and sync word

See code below.

Problem:

1. When transmitting my packet with RF_cmdPropTxAdv and listen with RF_cmdPropRxAdv  I only receive the header information on the other side: `0F D6 BE` and nothing that comes after.
What I expect to see in the RFQueue is `0F D6 BE AB CD EF 01 23 45 AA BB CC DD EE FF`

When I play with the header configuration settings, like changing length and address positioning, then the packet gets filtered out for not matching the address.

I'm certain that the TX device is transmitting more than just 3 bytes based on my energy trace profile.

2. I expect my RF_cmdPropRxAdv to continue receiving packets after the first one is received given the configuration, but it only receives one and stops giving callbacks.

/***** Includes *****/
/* Standard C Libraries */
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>

/* TI Drivers */
#include <ti/drivers/rf/RF.h>
#include "RFQueue.h"
#include <ti/drivers/GPIO.h>
#include <ti/display/Display.h>
// #include <ti/drivers/pin/PINCC26XX.h>

/* Driverlib Header files */
// clang-format off
#include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
#include DeviceFamily_constructPath(driverlib/rf_prop_cmd.h)
#include DeviceFamily_constructPath(driverlib/rf_mailbox.h)
// clang-format on

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

/* Power Header files */
#include <ti/drivers/power/PowerCC26XX.h>
#include <ti/drivers/Power.h>

#include <assert.h>

#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/BIOS.h>

/***** Defines *****/

/* Do power measurement */
#define POWER_MEASUREMENT

/* Packet TX Configuration */
#define PACKET_SECONDS 2
#ifdef POWER_MEASUREMENT
#define PACKET_INTERVAL \
    PACKET_SECONDS /* For power measurement set packet interval to 5s */
#else
#define PACKET_INTERVAL \
    (PACKET_SECONDS *   \
     1e6) /* Set packet interval to x,000,000us or x seconds */
#endif

/***** Prototypes *****/
int radio_init(void);
int advertise(void);
int scan(void);

void init_tx_settings(void);
void init_rx_settings(void);
void init_adv_command(void);
void init_scan_command(void);
static void ADV_CALLBACK(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
static void SCAN_CALLBACK(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
Void rxPrintTaskFxn(UArg a0, UArg a1);
/***** Variable declarations *****/
static RF_Object rfObject;
static RF_Handle rfHandle;
static RF_Params rfParams;

Display_Handle display;

static Semaphore_Struct rxSemStruct;
static Semaphore_Handle rxSemHandle;
static Task_Struct rxPrintTaskStruct;
static uint8_t rxPrintTaskStack[1024];

/***** Function definitions *****/

void *mainThread(void *arg0) {
    Display_init();
    /* Open the display for output */
    display = Display_open(Display_Type_UART, NULL);
    if (display == NULL) {
        /* Failed to open display driver */
        while (1) {
        }
    }

    GPIO_setConfig(CONFIG_GPIO_GLED, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    GPIO_setConfig(CONFIG_GPIO_RLED, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    GPIO_write(CONFIG_GPIO_GLED, CONFIG_GPIO_LED_OFF);
    GPIO_write(CONFIG_GPIO_RLED, CONFIG_GPIO_LED_OFF);

    int ret = 0;
    ret = radio_init();
    assert(ret == 0);

    // Initialize semaphore
    Semaphore_Params semParams;
    Semaphore_Params_init(&semParams);
    Semaphore_construct(&rxSemStruct, 0, &semParams);
    rxSemHandle = Semaphore_handle(&rxSemStruct);

    // Create the print task
    Task_Params taskParams;
    Task_Params_init(&taskParams);
    taskParams.stack = rxPrintTaskStack;
    taskParams.stackSize = sizeof(rxPrintTaskStack);
    taskParams.priority = 1;
    Task_construct(&rxPrintTaskStruct, rxPrintTaskFxn, &taskParams, NULL);

#ifdef BUILD_CENTRAL
    Display_printf(display, 0, 0, "Starting as central\n");
    while (1) {
        GPIO_toggle(CONFIG_GPIO_GLED);
        ret = advertise();
        assert(ret == 0);
        /* Power down the radio */
        RF_yield(rfHandle);

#ifdef POWER_MEASUREMENT
        /* Sleep for PACKET_INTERVAL s */
        sleep(PACKET_INTERVAL);
#else
        /* Sleep for PACKET_INTERVAL us */
        usleep(PACKET_INTERVAL);
#endif
    }
#endif  // BUILD_CENTRAL

#ifdef BUILD_PERIPHERAL
    GPIO_write(CONFIG_GPIO_RLED, CONFIG_GPIO_LED_ON);
    Display_printf(display, 0, 0, "Starting as peripheral\n");
    ret = scan();
    assert(ret == 0);
    while (1) {
        Task_yield();
    }
    return 0;
#endif  // BUILD_PERIPHERAL
}

#define MAX_TX_RX_PAIRS 10
#define ADV_ADDRESS (uint16_t)(0x8E89BED6 & 0xffff)
#define PAYLOAD_LENGTH 30
#define LL_QUEUE_ITEM_COUNT 10
#define LL_QUEUE_ITEM_MAX_SIZE 200
#define LL_QUEUE_PADDING_SIZE 4

// Addresses are really only 2 bytes, but we need to store them as uint32_ts
uint16_t address_list[] = {ADV_ADDRESS, 0xAAAA, 0xBBBB, 0xAABB, 0xBBAA};

static uint8_t packet[LL_QUEUE_ITEM_MAX_SIZE] = {0};

rfc_CMD_PROP_RX_ADV_t scan_cfg = {0};
rfc_CMD_PROP_TX_ADV_t advtx_cfg = {0};
rfc_CMD_PROP_RX_ADV_t advrx_cfg = {0};

/**
 * @brief Fill packet with length, address, sequence number, and payload
 *
 * @param packet
 * @return int
 */
int prepare_packet(uint8_t *packet, uint8_t *payload, uint8_t payload_length,
                   uint8_t *total_length) {
    uint8_t tmp[PAYLOAD_LENGTH] = {0};
    uint16_t address = address_list[0];
    // Items in packet must be in little endian format!
    // uint16_t address = address_list[0] | 0xFFFF;
    tmp[0] = payload_length + 3;
    tmp[1] = (uint8_t)(address & 0xFF);
    tmp[2] = (uint8_t)(address >> 8);

    // Remaining is payload
    memcpy(&tmp[3], payload, payload_length);
    
    *total_length = payload_length + 3;
    memcpy(packet, tmp, *total_length);
    return 0;
}

int advertise(void) {
    uint8_t total_length = 0;
    uint8_t payload[] = {0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
    prepare_packet(packet, (uint8_t *)&payload, sizeof(payload)/sizeof(payload[0]), &total_length);

    advtx_cfg.pktLen = total_length;
    advtx_cfg.pPkt = packet;
    advtx_cfg.startTrigger.triggerType = TRIG_NOW;

    RF_EventMask subscribedEvents = (RF_EventCmdDone | RF_EventLastCmdDone | RF_EventTxDone | RF_EventTXAck | RF_EventTxCtrl | RF_EventTxCtrlAckAck | RF_EventInternalError | RF_EventError);
    RF_CmdHandle commandHandle =
        RF_postCmd(rfHandle, (RF_Op *)&advtx_cfg, RF_PriorityNormal,
                  ADV_CALLBACK, subscribedEvents);
    assert(commandHandle != RF_ALLOC_ERROR);
    Display_printf(display, 0, 0, "TX cmd started\n");
    return 0;
}

int scan(void) {

    // Start scanning now and never end
    scan_cfg.startTrigger.triggerType = TRIG_NOW;
    scan_cfg.endTrigger.triggerType = TRIG_NEVER;

    RF_EventMask subscribedEvents = (RF_EventRxEntryDone | RF_EventRxOk | RF_EventRxNOk | RF_EventRxIgnored);
    RF_CmdHandle commandHandle =
        RF_postCmd(rfHandle, (RF_Op *)&scan_cfg, RF_PriorityNormal,
                   SCAN_CALLBACK, subscribedEvents);
    assert(commandHandle != RF_ALLOC_ERROR);
    return 0;
}

int schedule_connection_central(void) { return 0; }

int schedule_connection_peripheral(void) { return 0; }

int radio_init(void) {
    int ret = 0;
    RF_Params_init(&rfParams);
    rfHandle = RF_open(&rfObject, &RF_prop,
                       (RF_RadioSetup *)&RF_cmdPropRadioDivSetup, &rfParams);
    if (rfHandle == NULL) {
        return -1;
    }
    RF_CmdHandle commandHandle =
        RF_runCmd(rfHandle, (RF_Op *)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
    assert(commandHandle != RF_ALLOC_ERROR);

    Power_setPolicy(PowerCC26XX_standbyPolicy);
    Power_enablePolicy();
    RF_yield(rfHandle);

    init_tx_settings();
    init_rx_settings();

    init_adv_command();
    init_scan_command();
    return 0;
}

void init_tx_settings(void) {
    RF_cmdPropTxAdv.pktConf.bFsOff = 0;
    RF_cmdPropTxAdv.pktConf.bUseCrc = 1;
    RF_cmdPropTxAdv.pktConf.bCrcIncSw = 0;
    RF_cmdPropTxAdv.pktConf.bCrcIncHdr = 1;

    RF_cmdPropTxAdv.numHdrBits = 24;
}
static dataQueue_t dataQueue;
static uint8_t ll_rx_buffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(
    LL_QUEUE_ITEM_COUNT, LL_QUEUE_ITEM_MAX_SIZE, LL_QUEUE_PADDING_SIZE)];
rfc_propRxOutput_t rx_statistics = {0};

void init_rx_settings(void) {
    int ret = 0;
    ret = RFQueue_defineQueue(&dataQueue, ll_rx_buffer, sizeof(ll_rx_buffer),
                              LL_QUEUE_ITEM_COUNT,
                              (LL_QUEUE_ITEM_MAX_SIZE + LL_QUEUE_PADDING_SIZE));
    assert(ret == 0);

    RF_cmdPropRxAdv.pktConf.bFsOff = 0;
    RF_cmdPropRxAdv.pktConf.bRepeatOk = 0;
    RF_cmdPropRxAdv.pktConf.bRepeatNok = 0;
    RF_cmdPropRxAdv.pktConf.bUseCrc = 1;
    RF_cmdPropRxAdv.pktConf.bCrcIncSw = 0;
    RF_cmdPropRxAdv.pktConf.bCrcIncHdr = 1;
    RF_cmdPropRxAdv.pktConf.endType = 0;
    RF_cmdPropRxAdv.pktConf.filterOp = 0;

    RF_cmdPropRxAdv.rxConf.bAutoFlushIgnored = 1;
    RF_cmdPropRxAdv.rxConf.bAutoFlushCrcErr = 1;
    RF_cmdPropRxAdv.rxConf.bIncludeHdr = 1;
    RF_cmdPropRxAdv.rxConf.bIncludeCrc = 0;
    RF_cmdPropRxAdv.rxConf.bAppendRssi = 0;
    RF_cmdPropRxAdv.rxConf.bAppendTimestamp = 0;
    RF_cmdPropRxAdv.rxConf.bAppendStatus = 0;

    RF_cmdPropRxAdv.maxPktLen = LL_QUEUE_ITEM_MAX_SIZE;

    RF_cmdPropRxAdv.hdrConf.numHdrBits = 24;
    RF_cmdPropRxAdv.hdrConf.numLenBits = 8;
    RF_cmdPropRxAdv.hdrConf.lenPos = 0;
    RF_cmdPropRxAdv.lenOffset = -2;

    RF_cmdPropRxAdv.addrConf.addrType = 1;
    RF_cmdPropRxAdv.addrConf.addrSize = 16;
    RF_cmdPropRxAdv.addrConf.addrPos = 8;
    RF_cmdPropRxAdv.addrConf.numAddr = sizeof(address_list) / sizeof(address_list[0]);

    RF_cmdPropRxAdv.pAddr = (uint8_t *)&address_list;
    RF_cmdPropRxAdv.pQueue = &dataQueue;
    RF_cmdPropRxAdv.pOutput = (uint8_t *)&rx_statistics;
}

void init_adv_command(void) {
    // TX portion config
    advtx_cfg = RF_cmdPropTxAdv;

    advtx_cfg.pNextOp = (RF_Op *)&advrx_cfg;
    advtx_cfg.pktConf.bFsOff = 0;
    advtx_cfg.condition.rule = COND_ALWAYS;

    advtx_cfg.startTrigger.triggerType = TRIG_NOW;
    advtx_cfg.startTrigger.pastTrig = 1;


    // RX portion config
    advrx_cfg = RF_cmdPropRxAdv;

    advrx_cfg.pktConf.bFsOff = 1; // Turn off frequency synth after command
    advrx_cfg.startTrigger.triggerType = TRIG_REL_PREVEND;
    advrx_cfg.startTrigger.bEnaCmd = 0;
    advrx_cfg.startTime = 150 * 4; // 150µs after previous command in RAT ticks (4 RAT ticks per µs)

    advrx_cfg.endTrigger.triggerType = TRIG_REL_START;
    advrx_cfg.endTrigger.bEnaCmd = 0;
    advrx_cfg.endTrigger.pastTrig = 1;
    advrx_cfg.endTime = 3000 * 4; // 3000µs after previous command in RAT ticks (4 RAT ticks per µs)
    
    advrx_cfg.pNextOp = NULL;
}

void init_scan_command(void) { 
    scan_cfg = RF_cmdPropRxAdv;
    scan_cfg.pktConf.bRepeatOk = 1; // Repeat on correct reception
    scan_cfg.pktConf.bRepeatNok = 1; // Repeat on incorrect reception
    // scan_cfg.rxConf.bAutoFlushIgnored = 0;  // Don't discard ignored packets
    // scan_cfg.rxConf.bAutoFlushCrcErr = 0;   // Don't discard CRC error packets
}


void ADV_CALLBACK(RF_Handle h, RF_CmdHandle ch, RF_EventMask e) {
    // Display_printf(display, 0, 0, "Scan op callback\n");
    if (e & (RF_EventTxDone | RF_EventTXAck | RF_EventTxCtrl | RF_EventTxCtrlAckAck)) {
        // Display_printf(display, 0, 0, "TX done: e=%d\n", e);
    }
    if (e & RF_EventCmdDone) {
        // Display_printf(display, 0, 0, "CMD done: e=%d\n", e);
    }
    if (e & RF_EventLastCmdDone) {
        // Display_printf(display, 0, 0, "Last cmd done\n");
    }
    if (e & (RF_EventInternalError | RF_EventError)) {
        // Display_printf(display, 0, 0, "Error: e=%d\n", e);
    }
}

volatile struct {
    uint8_t len;
    uint16_t address;
    uint8_t data[LL_QUEUE_ITEM_MAX_SIZE];
    rfc_propRxOutput_t packet_stats;
}rx_data;

void SCAN_CALLBACK(RF_Handle h, RF_CmdHandle ch, RF_EventMask e) {
    if (e & (RF_EventRxEntryDone | RF_EventRxIgnored)) {
        GPIO_toggle(CONFIG_GPIO_RLED);
        // Process all available entries in the queue
        rfc_dataEntryGeneral_t *entry = RFQueue_getDataEntry();
        if (entry == NULL) {
            return;
        }
        uint8_t *packetDataPointer = (uint8_t *)(&entry->data);
        rx_data.len = packetDataPointer[0];
        rx_data.address = (uint16_t)packetDataPointer[1] << 8 | (uint16_t)packetDataPointer[2];
        memcpy(rx_data.data, packetDataPointer + 3, rx_data.len);

        rx_data.packet_stats = rx_statistics;

        // Signal rxPrintThread to print the data
        Semaphore_post(rxSemHandle);

        RFQueue_nextEntry();
    }

    if (e & RF_EventLastCmdDone) {
        // Display_printf(display, 0, 0, "Last cmd done\n");
    }
    if (e & RF_EventCmdDone) {
        // Display_printf(display, 0, 0, "CMD done\n");
    }
}

Void rxPrintTaskFxn(UArg a0, UArg a1) {
    while (1) {
        Semaphore_pend(rxSemHandle, BIOS_WAIT_FOREVER);
        Display_printf(display, 0, 0, "nRxOk: %d, nRxNok: %d, nRxIgnored: %d, nRxStopped: %d, nRxBufFull: %d", rx_data.packet_stats.nRxOk, rx_data.packet_stats.nRxNok, rx_data.packet_stats.nRxIgnored, rx_data.packet_stats.nRxStopped, rx_data.packet_stats.nRxBufFull);
        Display_printf(display, 0, 0, "RSSI: %d", rx_data.packet_stats.lastRssi);
        Display_printf(display, 0, 0, "rx_data: len=%d, address=0x%04x", rx_data.len, rx_data.address);
        Display_printf(display, 0, 0, "data: ");
        for (int i = 0; i < rx_data.len; i++) {
            Display_printf(display, 0, 0, "%02x ", rx_data.data[i]);
        }
        uint32_t cmdStatus = ((volatile RF_Op*)&scan_cfg)->status;
        Display_printf(display, 0, 0, "CMD status: %d", cmdStatus);
        Display_printf(display, 0, 0, "\n");
    }
}

static void print_status(RF_Op * op) {
       switch (op->status) {
       case PROP_DONE_OK:
           // RX op completed successfully
           Display_printf(display, 0, 0, "RX op completed successfully\n");
           break;
       case PROP_DONE_RXTIMEOUT:
           // RX op timed out
           Display_printf(display, 0, 0, "RX op timed out\n");
           break;
       case PROP_DONE_BREAK:
           // received CMD_BREAK while transmitting packet and finished
           // transmitting packet
           Display_printf(display, 0, 0, "RX op received CMD_BREAK\n");
           break;
       case PROP_DONE_STOPPED:
           // received CMD_STOP while transmitting packet and finished
           // transmitting packet
           Display_printf(display, 0, 0, "RX op received CMD_STOP\n");
           break;
       case PROP_DONE_RXERR:
           // RX op received an error
           Display_printf(display, 0, 0, "RX op received an error\n");
           break;
       case PROP_DONE_ABORT:
           // Received CMD_ABORT while transmitting packet
           Display_printf(display, 0, 0, "RX op received CMD_ABORT\n");
           break;
       case PROP_DONE_IDLE:
           // received CMD_IDLE while transmitting packet and finished
           // transmitting packet
           Display_printf(display, 0, 0, "RX op received CMD_IDLE\n");
           break;
       case PROP_DONE_BUSY:
           // received CMD_BUSY while transmitting packet and finished
           // transmitting packet
           Display_printf(display, 0, 0, "RX op received CMD_BUSY\n");
           break;
       case PROP_DONE_IDLETIMEOUT:
           // received CMD_IDLE while transmitting packet and finished
           // transmitting packet
           Display_printf(display, 0, 0, "RX op received CMD_IDLETIMEOUT\n");
           break;
       case PROP_DONE_BUSYTIMEOUT:
           // received CMD_BUSY while transmitting packet and finished
           // transmitting packet
           Display_printf(display, 0, 0, "RX op received CMD_BUSYTIMEOUT\n");
           break;
       case PROP_ERROR_RXBUF:
           // received CMD_RXERR while transmitting packet and finished
           // transmitting packet
           Display_printf(display, 0, 0, "RX op received CMD_RXERR\n");
           break;
       case PROP_ERROR_RXFULL:
           // received CMD_RXFULL while transmitting packet and finished
           // transmitting packet
           Display_printf(display, 0, 0, "RX op received CMD_RXFULL\n");
           break;
       case PROP_ERROR_RXOVF:
           // received CMD_RXOVF while transmitting packet and finished
           // transmitting packet
           Display_printf(display, 0, 0, "RX op received CMD_RXOVF\n");
           break;
       case PROP_ERROR_PAR:
           // Observed illegal parameter
           Display_printf(display, 0, 0, "RX op received CMD_PAR\n");
           break;
       case PROP_ERROR_NO_SETUP:
           // Command sent without setting up the radio in a supported
           // mode using CMD_PROP_RADIO_SETUP or CMD_RADIO_SETUP
           Display_printf(display, 0, 0, "RX op received CMD_NO_SETUP\n");
           break;
       case PROP_ERROR_NO_FS:
           // Command sent without the synthesizer being programmed
           Display_printf(display, 0, 0, "RX op received CMD_NO_FS\n");
           break;
       case PROP_ERROR_TXUNF:
           // TX underflow observed during operation
           Display_printf(display, 0, 0, "RX op received CMD_TXUNF\n");
           break;
       default:
           // Uncaught error event - these could come from the
           // pool of states defined in rf_mailbox.h
           Display_printf(display, 0, 0, "Uncaught error event %d\n", op->status);
   }
}
/**
 * These arguments were used when this file was generated. They will be automatically applied on subsequent loads
 * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
 * @cliArgs --board "/ti/boards/LP_CC1352P7_1" --rtos "tirtos7" --product "simplelink_cc13xx_cc26xx_sdk@7.41.00.17"
 * @versions {"tool":"1.18.1+3343"}
 */

/**
 * Import the modules used in this configuration.
 */
const CCFG        = scripting.addModule("/ti/devices/CCFG");
const custom      = scripting.addModule("/ti/devices/radioconfig/custom");
const rfdesign    = scripting.addModule("/ti/devices/radioconfig/rfdesign");
const Display     = scripting.addModule("/ti/display/Display", {}, false);
const Display1    = Display.addInstance();
const GPIO        = scripting.addModule("/ti/drivers/GPIO");
const GPIO1       = GPIO.addInstance();
const GPIO2       = GPIO.addInstance();
const RF          = scripting.addModule("/ti/drivers/RF");
const Settings    = scripting.addModule("/ti/posix/tirtos/Settings");
const BIOS        = scripting.addModule("/ti/sysbios/BIOS");
const Event       = scripting.addModule("/ti/sysbios/knl/Event");
const Idle        = scripting.addModule("/ti/sysbios/knl/Idle", {}, false);
const Idle2       = Idle.addInstance();
const Mailbox     = scripting.addModule("/ti/sysbios/knl/Mailbox");
const Error       = scripting.addModule("/ti/sysbios/runtime/Error");
const SysCallback = scripting.addModule("/ti/sysbios/runtime/SysCallback");
const Timestamp   = scripting.addModule("/ti/sysbios/runtime/Timestamp");

/**
 * Write custom configuration values to the imported modules.
 */
CCFG.xoscCapArray            = true;
CCFG.xoscCapArrayDelta       = 0xC1;
CCFG.enableBootloader        = true;
CCFG.dioBootloaderBackdoor   = 15;
CCFG.levelBootloaderBackdoor = "Active low";
CCFG.ccfgTemplate.$name      = "ti_devices_CCFG_CCFGCC26XXTemplate0";

custom.prop8                                              = ["custom868"];
custom.radioConfigcustom868.$name                         = "RF_Custom_Setting";
custom.radioConfigcustom868.txPower                       = "0";
custom.radioConfigcustom868.preambleMode                  = "Send different first preamble bit in preamble and sync word";
custom.radioConfigcustom868.symbolRate                    = 100.000;
custom.radioConfigcustom868.deviation                     = 50.0;
custom.radioConfigcustom868.rxFilterBw                    = "195.9";
custom.radioConfigcustom868.syncWord                      = 0x000055AC;
custom.radioConfigcustom868.preambleCount                 = "1 Byte";
custom.radioConfigcustom868.syncWordLength                = "16 Bits";
custom.radioConfigcustom868.whitening                     = "Dynamically IEEE 802.15.4g compatible whitener and 16/32-bit CRC";
custom.radioConfigcustom868.codeExportConfig.$name        = "ti_devices_radioconfig_code_export_param0";
custom.radioConfigcustom868.codeExportConfig.paExport     = "combined";
custom.radioConfigcustom868.codeExportConfig.symGenMethod = "Legacy";
custom.radioConfigcustom868.codeExportConfig.cmdList_prop = ["cmdFs","cmdPropRadioDivSetupPa","cmdPropRx","cmdPropRxAdv","cmdPropTx","cmdPropTxAdv"];

rfdesign.pa20 = "none";

Display1.$name      = "CONFIG_Display_0";
Display1.$hardware  = system.deviceData.board.components.XDS110UART;
Display1.uart.$name = "CONFIG_UART2_0";

GPIO1.$hardware = system.deviceData.board.components.LED_GREEN;
GPIO1.$name     = "CONFIG_GPIO_GLED";

GPIO2.$hardware = system.deviceData.board.components.LED_RED;
GPIO2.$name     = "CONFIG_GPIO_RLED";

RF.$hardware = system.deviceData.board.components["SKY13317-373LF"];

BIOS.assertsEnabled = false;
BIOS.heapBaseAddr   = "__primary_heap_start__";
BIOS.heapEndAddr    = "__primary_heap_end__";

const Clock      = scripting.addModule("/ti/sysbios/knl/Clock", {}, false);
Clock.tickPeriod = 10;

const Timer = scripting.addModule("/ti/sysbios/family/arm/cc26xx/Timer", {}, false);

Idle2.$name   = "powerIdle";
Idle2.idleFxn = "Power_idleFunc";

const Semaphore            = scripting.addModule("/ti/sysbios/knl/Semaphore", {}, false);
Semaphore.supportsPriority = false;

const Swi         = scripting.addModule("/ti/sysbios/knl/Swi", {}, false);
Swi.numPriorities = 6;

const Task             = scripting.addModule("/ti/sysbios/knl/Task", {}, false);
Task.checkStackFlag    = false;
Task.defaultStackSize  = 512;
Task.idleTaskStackSize = 512;
Task.numPriorities     = 6;

Error.policy       = "Error_SPIN";
Error.printDetails = false;

const System           = scripting.addModule("/ti/sysbios/runtime/System", {}, false);
System.abortFxn        = "System_abortSpin";
System.exitFxn         = "System_exitSpin";
System.extendedFormats = "%f";
System.supportModule   = "SysCallback";

/**
 * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future
 * version of the tool will not impact the pinmux you originally saw.  These lines can be completely deleted in order to
 * re-solve from scratch.
 */
Display1.uart.uart.$suggestSolution       = "UART0";
Display1.uart.uart.txPin.$suggestSolution = "boosterpack.4";
Display1.uart.uart.rxPin.$suggestSolution = "boosterpack.3";
GPIO1.gpioPin.$suggestSolution            = "boosterpack.40";
GPIO2.gpioPin.$suggestSolution            = "boosterpack.39";
RF.rfAntennaPin0.$suggestSolution         = "DIO_28";
RF.rfAntennaPin1.$suggestSolution         = "DIO_29";
RF.rfAntennaPin2.$suggestSolution         = "DIO_30";
Timer.rtc.$suggestSolution                = "RTC0";

  • Hi Marciano,

    Have you tested your CMD_PROP_RX_ADV/CMD_PROP_TX_ADV configuration in SmartRF Studio 7 prior to the code implementation? What do you observe there?

    The TX side seems to be correct as the screenshot shows, but it would be interesting to see what you receive..

    Regards,

    Arthur

  • Hi Arthur,

    I attempted to test the CMD_PROP_RX_ADV/CMD_PROP_TX_ADV configuration in SmartRF Studio 7 version 2.32.0 as you suggested.

    However, I'm encountering a persistent issue where SmartRF Studio 7 repeatedly prompts for installation of the "Radio Test library" for SimpleLink Wireless MCUs, even after successful installation and system reboot. The SmartRF Test Environment fails to launch properly on my Windows 10 PC. Attaching the screenshot for your reference. What could be the problem?, Note that I've also included the Radio Test Library folder path to the system enviroment just in case. 


    And Could you please provide guidance on the specific event pattern I'm consistently observing:

    First callback: RF_EventRxOk | RF_EventCmdDone (0x810000)

    Second callback: RF_EventLastCmdDone | RF_EventCmdError (0x400002)

    The first packet header is received and parsed correctly (length=12, address=0xBED6), but the CMD_PROP_RX_ADV terminates after a single packet despite bRepeatOk=1 and bRepeatNok=1 configuration.

    Is this the expected behavior for advanced RX commands, or does it indicate a configuration issue?

    Regards,
    Sharan

  • Hi Sharan,

    This is quite strange, as the screenshot seems to indicate that the devices are detected as expected. Does it happens as well if you launch it as administrator?

    On the event pattern, it would be interesting to know what is the CMD_PROP_RX_ADV status upon the RF_EventCmdError :


     Proprietary Radio Operation Status Codes

    Regards,

    Arthur

  • First of all, it is not possible to use SmartRF Studio to test this (changing the complete packet format from default will also require that the firmware itself changes)

    Below is some test code that transmit the packet you have given, and there is also code to show how this packet can be correctly received.

    I have changed the first byte in the packet from 0x0F to 0x0E, as the length byte should tell how many bytes come AFTER the length (should not include itself)

    I used the rfPacketRX and rfPacketTX examples as a starting point, and changed the necessary parameters (data rate, deviation, sync word, preamble and whitening in sysconfig), and the rest of the parameters was modified in the code itself:

    TX:

    #define SIZE_OF_LENGHT_FIELD    1
    #define PAYLOAD_LENGTH          14
    
    #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] = {0x0E, 0xD6, 0xBE, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
    
    void *mainThread(void *arg0)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        RF_cmdPropTxAdv.pktLen = PAYLOAD_LENGTH + 1; // For the advanced TX command, pktLen must cover length + payload
        RF_cmdPropTxAdv.pPkt = packet;
        RF_cmdPropTxAdv.startTrigger.triggerType = TRIG_NOW;
        RF_cmdPropTxAdv.condition.rule = 1;
        RF_cmdPropTxAdv.pktConf.bUseCrc = 1;
        RF_cmdPropTxAdv.numHdrBits = 24;
        RF_cmdPropTxAdv.pktConf.bCrcIncHdr = 0x1;
    
        // 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)
        {
            // Send packet
            RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTxAdv, RF_PriorityNormal, NULL, 0);
    
            // 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
    
    #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      1 + CRC + RSSI + TIMESTAMP + STATUS // The length is 1 byte
    
    #define MAX_LENGTH              0x0E // Max length byte the radio will accept
                                         // Must be less than 256 if SIZE_OF_LENGHT_FIELD = 1
    
    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 - 1]; // Length is stored separately
    
    uint16_t AddressList[] = {0xBED6, 0xAAAA, 0xBBBB, 0xAABB, 0xBBAA};
    
    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 = 24;
        RF_cmdPropRxAdv.hdrConf.numLenBits = 8;
        RF_cmdPropRxAdv.hdrConf.lenPos = 0;
        RF_cmdPropRxAdv.lenOffset = -2;
    
        RF_cmdPropRxAdv.rxConf.bIncludeCrc = 0x0;
        RF_cmdPropRxAdv.rxConf.bAppendRssi = 0x0;
        RF_cmdPropRxAdv.rxConf.bAppendTimestamp = 0x0;
        RF_cmdPropRxAdv.rxConf.bAppendStatus = 0x0;
    
        RF_cmdPropRxAdv.addrConf.addrType = 1;  // Address in header
        RF_cmdPropRxAdv.addrConf.addrSize = 16; // size of address (in bits)
        RF_cmdPropRxAdv.addrConf.addrPos = 8;
        RF_cmdPropRxAdv.addrConf.numAddr = 5;   // 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();
    
            packetLength      = (uint16_t)(*(uint8_t*)(&currentDataEntry->data));
            packetDataPointer = (uint8_t*)(&currentDataEntry->data + 1);
    
            // Copy the payload + the status byte to the packet variable
            memcpy(packet, packetDataPointer, (packetLength + NUM_APPENDED_BYTES - 1));
    
            RFQueue_nextEntry();
        }
    }

    Siri

  • Hi Siri,

    Thank you for the valuable inputs and test code. We were able to successfully recreate the setup as suggested by you using the rfPacketRX and rfPacketTX examples as the starting point. RX callback is now triggered every 500ms based on TX timer (continuous reception working!)

    However, I still see the payload data showing as all zeros in the received packet.

    I've attached both TX and RX projects for your reference. Note that I've added UART debug (Display_printf) for debugging - hope that shouldn't be a problem.

    My setup:
    SDK: simplelink_cc13xx_cc26xx_sdk_7_41_00_17
    CCS: Version: 12.8.1.00005 



    RX:

    /*
     * Copyright (c) 2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /***** Includes *****/
    /* Standard C Libraries */
    #include <stdlib.h>
    
    /* TI Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/GPIO.h>
    #include <ti/display/Display.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>
    
    #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    #include DeviceFamily_constructPath(driverlib/rf_prop_cmd.h)
    #include DeviceFamily_constructPath(driverlib/rf_mailbox.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 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      1 + CRC + RSSI + TIMESTAMP + STATUS // The length is 1 byte
    
    #define MAX_LENGTH              0x0E // Max length byte the radio will accept
                                         // Must be less than 256 if SIZE_OF_LENGHT_FIELD = 1
    
    static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
    
    static RF_Object rfObject;
    static RF_Handle rfHandle;
    Display_Handle display;
    
    /* 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 - 1]; // Length is stored separately
    
    uint16_t AddressList[] = {0xBED6, 0xAAAA, 0xBBBB, 0xAABB, 0xBBAA};
    
    /***** Function definitions *****/
    
    void *mainThread(void *arg0)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        /* Open the display for output */
        display = Display_open(Display_Type_UART, NULL);
        if (display == NULL) {
            /* Failed to open display driver */
            while (1) {
            }
        }
    
        Display_printf(display, 0, 0, "Starting as RX\n");
    
        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 = 24;
        RF_cmdPropRxAdv.hdrConf.numLenBits = 8;
        RF_cmdPropRxAdv.hdrConf.lenPos = 0;
        RF_cmdPropRxAdv.lenOffset = -2;
    
        RF_cmdPropRxAdv.rxConf.bIncludeCrc = 0x0;
        RF_cmdPropRxAdv.rxConf.bAppendRssi = 0x0;
        RF_cmdPropRxAdv.rxConf.bAppendTimestamp = 0x0;
        RF_cmdPropRxAdv.rxConf.bAppendStatus = 0x0;
    
        RF_cmdPropRxAdv.addrConf.addrType = 1;  // Address in header
        RF_cmdPropRxAdv.addrConf.addrSize = 16; // size of address (in bits)
        RF_cmdPropRxAdv.addrConf.addrPos = 8;
        RF_cmdPropRxAdv.addrConf.numAddr = 5;   // 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();
    
            packetLength      = (uint16_t)(*(uint8_t*)(&currentDataEntry->data));
            packetDataPointer = (uint8_t*)(&currentDataEntry->data + 1);
    
            // Copy the payload + the status byte to the packet variable
            memcpy(packet, packetDataPointer, (packetLength + NUM_APPENDED_BYTES - 1));
    
            RFQueue_nextEntry();
        }
    }
    



    /**
     * These arguments were used when this file was generated. They will be automatically applied on subsequent loads
     * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
     * @cliArgs --board "/ti/boards/LP_CC1352P7_1" --rtos "tirtos7" --product "simplelink_cc13xx_cc26xx_sdk@7.41.00.17"
     * @versions {"tool":"1.18.1+3343"}
     */
    
    /**
     * Import the modules used in this configuration.
     */
    const CCFG        = scripting.addModule("/ti/devices/CCFG");
    const custom      = scripting.addModule("/ti/devices/radioconfig/custom");
    const rfdesign    = scripting.addModule("/ti/devices/radioconfig/rfdesign");
    const Display     = scripting.addModule("/ti/display/Display", {}, false);
    const Display1    = Display.addInstance();
    const GPIO        = scripting.addModule("/ti/drivers/GPIO");
    const GPIO4       = GPIO.addInstance();
    const RF          = scripting.addModule("/ti/drivers/RF");
    const Settings    = scripting.addModule("/ti/posix/tirtos/Settings");
    const BIOS        = scripting.addModule("/ti/sysbios/BIOS");
    const Event       = scripting.addModule("/ti/sysbios/knl/Event");
    const Idle        = scripting.addModule("/ti/sysbios/knl/Idle", {}, false);
    const Idle2       = Idle.addInstance();
    const Mailbox     = scripting.addModule("/ti/sysbios/knl/Mailbox");
    const Error       = scripting.addModule("/ti/sysbios/runtime/Error");
    const SysCallback = scripting.addModule("/ti/sysbios/runtime/SysCallback");
    const Timestamp   = scripting.addModule("/ti/sysbios/runtime/Timestamp");
    
    /**
     * Write custom configuration values to the imported modules.
     */
    CCFG.xoscCapArray            = true;
    CCFG.xoscCapArrayDelta       = 0xC1;
    CCFG.enableBootloader        = true;
    CCFG.dioBootloaderBackdoor   = 15;
    CCFG.levelBootloaderBackdoor = "Active low";
    CCFG.ccfgTemplate.$name      = "ti_devices_CCFG_CCFGCC26XXTemplate0";
    
    custom.prop8                                              = ["custom868"];
    custom.radioConfigcustom868.phyType868                    = "2gfsk50kbps";
    custom.radioConfigcustom868.highPA                        = true;
    custom.radioConfigcustom868.$name                         = "RF_Custom_Setting";
    custom.radioConfigcustom868.symbolRate                    = 100.000;
    custom.radioConfigcustom868.deviation                     = 50.0;
    custom.radioConfigcustom868.rxFilterBw                    = "195.9";
    custom.radioConfigcustom868.whitening                     = "Dynamically IEEE 802.15.4g compatible whitener and 16/32-bit CRC";
    custom.radioConfigcustom868.preambleCount                 = "1 Byte";
    custom.radioConfigcustom868.preambleMode                  = "Send different first preamble bit in preamble and sync word";
    custom.radioConfigcustom868.syncWordLength                = "16 Bits";
    custom.radioConfigcustom868.syncWord                      = 0x000055AC;
    custom.radioConfigcustom868.codeExportConfig.$name        = "ti_devices_radioconfig_code_export_param0";
    custom.radioConfigcustom868.codeExportConfig.paExport     = "combined";
    custom.radioConfigcustom868.codeExportConfig.symGenMethod = "Legacy";
    custom.radioConfigcustom868.codeExportConfig.cmdList_prop = ["cmdFs","cmdPropRadioDivSetupPa","cmdPropRx","cmdPropRxAdv","cmdPropTx","cmdPropTxAdv"];
    
    Display1.$name                   = "CONFIG_Display_0";
    Display1.$hardware               = system.deviceData.board.components.XDS110UART;
    Display1.uart.$name              = "CONFIG_UART2_0";
    Display1.uart.uart.txPin.$assign = "boosterpack.4";
    Display1.uart.uart.rxPin.$assign = "boosterpack.3";
    
    GPIO4.$hardware = system.deviceData.board.components.LED_RED;
    GPIO4.$name     = "CONFIG_GPIO_RLED";
    
    RF.$hardware = system.deviceData.board.components["SKY13317-373LF"];
    
    BIOS.assertsEnabled = false;
    BIOS.heapBaseAddr   = "__primary_heap_start__";
    BIOS.heapEndAddr    = "__primary_heap_end__";
    
    const Clock      = scripting.addModule("/ti/sysbios/knl/Clock", {}, false);
    Clock.tickPeriod = 10;
    
    const Timer = scripting.addModule("/ti/sysbios/family/arm/cc26xx/Timer", {}, false);
    
    Idle2.$name   = "powerIdle";
    Idle2.idleFxn = "Power_idleFunc";
    
    const Semaphore            = scripting.addModule("/ti/sysbios/knl/Semaphore", {}, false);
    Semaphore.supportsPriority = false;
    
    const Swi         = scripting.addModule("/ti/sysbios/knl/Swi", {}, false);
    Swi.numPriorities = 6;
    
    const Task             = scripting.addModule("/ti/sysbios/knl/Task", {}, false);
    Task.checkStackFlag    = false;
    Task.defaultStackSize  = 512;
    Task.idleTaskStackSize = 512;
    Task.numPriorities     = 6;
    
    Error.policy       = "Error_SPIN";
    Error.printDetails = false;
    
    const System           = scripting.addModule("/ti/sysbios/runtime/System", {}, false);
    System.abortFxn        = "System_abortSpin";
    System.exitFxn         = "System_exitSpin";
    System.extendedFormats = "%f";
    System.supportModule   = "SysCallback";
    
    /**
     * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future
     * version of the tool will not impact the pinmux you originally saw.  These lines can be completely deleted in order to
     * re-solve from scratch.
     */
    Display1.uart.uart.$suggestSolution = "UART0";
    GPIO4.gpioPin.$suggestSolution      = "boosterpack.39";
    RF.rfAntennaPin0.$suggestSolution   = "DIO_28";
    RF.rfAntennaPin1.$suggestSolution   = "DIO_29";
    RF.rfAntennaPin2.$suggestSolution   = "DIO_30";
    Timer.rtc.$suggestSolution          = "RTC0";
    



    TX:

    /*
     * Copyright (c) 2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /***** Includes *****/
    /* Standard C Libraries */
    #include <stdlib.h>
    #include <unistd.h>
    
    /* TI Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/GPIO.h>
    //#include <ti/drivers/pin/PINCC26XX.h>
    #include <ti/display/Display.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>
    
    
    #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    #include DeviceFamily_constructPath(driverlib/rf_prop_cmd.h)
    #include DeviceFamily_constructPath(driverlib/rf_mailbox.h)
    
    
    /***** Function definitions *****/
    
    #define SIZE_OF_LENGHT_FIELD    1
    #define PAYLOAD_LENGTH          14
    
    #define PACKET_INTERVAL         500000  // Set packet interval to 500000 us or 500 ms
    
    static RF_Object rfObject;
    static RF_Handle rfHandle;
    Display_Handle display;
    
    static uint8_t packet[SIZE_OF_LENGHT_FIELD + PAYLOAD_LENGTH] = {0x0E, 0xD6, 0xBE, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
    
    void *mainThread(void *arg0)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        /* Open the display for output */
        display = Display_open(Display_Type_UART, NULL);
        if (display == NULL) {
            /* Failed to open display driver */
            while (1) {
            }
        }
    
        Display_printf(display, 0, 0, "Starting as TX\n");
    
        RF_cmdPropTxAdv.pktLen = PAYLOAD_LENGTH + 1; // For the advanced TX command, pktLen must cover length + payload
        RF_cmdPropTxAdv.pPkt = packet;
        RF_cmdPropTxAdv.startTrigger.triggerType = TRIG_NOW;
        RF_cmdPropTxAdv.condition.rule = 1;
        RF_cmdPropTxAdv.pktConf.bUseCrc = 1;
        RF_cmdPropTxAdv.numHdrBits = 24;
        RF_cmdPropTxAdv.pktConf.bCrcIncHdr = 0x1;
    
        // 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)
        {
            Display_printf(display, 0, 0, "Sending ..\n");
            // Send packet
            RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTxAdv, RF_PriorityNormal, NULL, 0);
            //RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropTxAdv, RF_PriorityNormal, NULL, 0);
    
            // Power down the radio
            RF_yield(rfHandle);
    
            // Sleep for PACKET_INTERVAL us
            usleep(PACKET_INTERVAL);
        }
    }
    
    


    /**
     * These arguments were used when this file was generated. They will be automatically applied on subsequent loads
     * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
     * @cliArgs --board "/ti/boards/LP_CC1352P7_1" --rtos "tirtos7" --product "simplelink_cc13xx_cc26xx_sdk@7.41.00.17"
     * @versions {"tool":"1.18.1+3343"}
     */
    
    /**
     * Import the modules used in this configuration.
     */
    const CCFG        = scripting.addModule("/ti/devices/CCFG");
    const custom      = scripting.addModule("/ti/devices/radioconfig/custom");
    const rfdesign    = scripting.addModule("/ti/devices/radioconfig/rfdesign");
    const Display     = scripting.addModule("/ti/display/Display", {}, false);
    const Display1    = Display.addInstance();
    const GPIO        = scripting.addModule("/ti/drivers/GPIO");
    const GPIO4       = GPIO.addInstance();
    const RF          = scripting.addModule("/ti/drivers/RF");
    const Settings    = scripting.addModule("/ti/posix/tirtos/Settings");
    const BIOS        = scripting.addModule("/ti/sysbios/BIOS");
    const Event       = scripting.addModule("/ti/sysbios/knl/Event");
    const Idle        = scripting.addModule("/ti/sysbios/knl/Idle", {}, false);
    const Idle2       = Idle.addInstance();
    const Mailbox     = scripting.addModule("/ti/sysbios/knl/Mailbox");
    const Error       = scripting.addModule("/ti/sysbios/runtime/Error");
    const SysCallback = scripting.addModule("/ti/sysbios/runtime/SysCallback");
    const Timestamp   = scripting.addModule("/ti/sysbios/runtime/Timestamp");
    
    /**
     * Write custom configuration values to the imported modules.
     */
    CCFG.xoscCapArray            = true;
    CCFG.xoscCapArrayDelta       = 0xC1;
    CCFG.enableBootloader        = true;
    CCFG.dioBootloaderBackdoor   = 15;
    CCFG.levelBootloaderBackdoor = "Active low";
    CCFG.ccfgTemplate.$name      = "ti_devices_CCFG_CCFGCC26XXTemplate0";
    
    custom.prop8                                              = ["custom868"];
    custom.radioConfigcustom868.phyType868                    = "2gfsk50kbps";
    custom.radioConfigcustom868.$name                         = "RF_Custom_Setting";
    custom.radioConfigcustom868.symbolRate                    = 100.000;
    custom.radioConfigcustom868.deviation                     = 50.0;
    custom.radioConfigcustom868.rxFilterBw                    = "195.9";
    custom.radioConfigcustom868.whitening                     = "Dynamically IEEE 802.15.4g compatible whitener and 16/32-bit CRC";
    custom.radioConfigcustom868.syncWordLength                = "16 Bits";
    custom.radioConfigcustom868.syncWord                      = 0x000055AC;
    custom.radioConfigcustom868.preambleCount                 = "1 Byte";
    custom.radioConfigcustom868.preambleMode                  = "Send different first preamble bit in preamble and sync word";
    custom.radioConfigcustom868.highPA                        = true;
    custom.radioConfigcustom868.codeExportConfig.$name        = "ti_devices_radioconfig_code_export_param0";
    custom.radioConfigcustom868.codeExportConfig.paExport     = "combined";
    custom.radioConfigcustom868.codeExportConfig.symGenMethod = "Legacy";
    custom.radioConfigcustom868.codeExportConfig.cmdList_prop = ["cmdFs","cmdPropRadioDivSetupPa","cmdPropRx","cmdPropRxAdv","cmdPropTx","cmdPropTxAdv"];
    
    Display1.$name      = "CONFIG_Display_0";
    Display1.$hardware  = system.deviceData.board.components.XDS110UART;
    Display1.uart.$name = "CONFIG_UART2_0";
    
    GPIO4.$hardware = system.deviceData.board.components.LED_GREEN;
    GPIO4.$name     = "CONFIG_GPIO_GLED";
    
    RF.$hardware = system.deviceData.board.components["SKY13317-373LF"];
    
    BIOS.assertsEnabled = false;
    BIOS.heapBaseAddr   = "__primary_heap_start__";
    BIOS.heapEndAddr    = "__primary_heap_end__";
    
    const Clock      = scripting.addModule("/ti/sysbios/knl/Clock", {}, false);
    Clock.tickPeriod = 10;
    
    const Timer = scripting.addModule("/ti/sysbios/family/arm/cc26xx/Timer", {}, false);
    
    Idle2.$name   = "powerIdle";
    Idle2.idleFxn = "Power_idleFunc";
    
    const Semaphore            = scripting.addModule("/ti/sysbios/knl/Semaphore", {}, false);
    Semaphore.supportsPriority = false;
    
    const Swi         = scripting.addModule("/ti/sysbios/knl/Swi", {}, false);
    Swi.numPriorities = 6;
    
    const Task             = scripting.addModule("/ti/sysbios/knl/Task", {}, false);
    Task.checkStackFlag    = false;
    Task.defaultStackSize  = 512;
    Task.idleTaskStackSize = 512;
    Task.numPriorities     = 6;
    
    Error.policy       = "Error_SPIN";
    Error.printDetails = false;
    
    const System           = scripting.addModule("/ti/sysbios/runtime/System", {}, false);
    System.abortFxn        = "System_abortSpin";
    System.exitFxn         = "System_exitSpin";
    System.extendedFormats = "%f";
    System.supportModule   = "SysCallback";
    
    /**
     * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future
     * version of the tool will not impact the pinmux you originally saw.  These lines can be completely deleted in order to
     * re-solve from scratch.
     */
    Display1.uart.uart.$suggestSolution       = "UART0";
    Display1.uart.uart.txPin.$suggestSolution = "boosterpack.4";
    Display1.uart.uart.rxPin.$suggestSolution = "boosterpack.3";
    GPIO4.gpioPin.$suggestSolution            = "boosterpack.40";
    RF.rfAntennaPin0.$suggestSolution         = "DIO_28";
    RF.rfAntennaPin1.$suggestSolution         = "DIO_29";
    RF.rfAntennaPin2.$suggestSolution         = "DIO_30";
    Timer.rtc.$suggestSolution                = "RTC0";
    



    Regards,
    Sharan

  • I am not able to reproduce your problem.

    I ran your RX and TX code, and everything worked as expected.

    I have attached the complete code examples for your convenience (the example is based on the rfPacketRX/TX examples from the latest SDK, and I am using CCS 12.8.0)

    2211.demo.zip

    Siri

  • Hi,

    I compared the syscfg files, looks like you're using the latest SDK - simplelink_cc13xx_cc26xx_sdk@8.30.01.01?

      



    That's the main big difference, we've been trying the older SDK 7_41.

    Do you suggest to try with the new SDK?

    Regards,
    Sharan

  • Hi Siri,

    I verified with SDK 8.30, and it works!

    Now, I’d like to move forward with our original issue i.e. getting the chained command to work.

    Do you have any pointers or example references that could help?

    Best regards,
    Sharan





  • Not sure what chain you are trying to make, or what issues you are seeing, but the following example can be used as a reference with respect to implementing a chain.

    rfListenBeforeTalk

    BR

    Siri