Tool/software:
I have a problem with CMD_BLE_ADV that I can't run down. I am chaining three advertising packets and see the proper advertising packets sent (using WireShark) . I resend the chain of three every 30 msec and this can continue indefinitely. So far, everything is great.
The problems begin when a SCAN_REQ is received. The CPE transmits a proper SCAN_RSP (as verified by WireShark and the iPhone app which sent the SCAN_REQ). My advertiser call-back is notified with event "RF_EventRxEntryDone" (as requested in the RF_postCmd). The data in the received buffer matches the data shown on WireShark. I subsequently get a "Last Operation in chain finished" event callback with a normal status.
When I examine the data queue (in debugger) I see the first buffer holds the SCAN_REQ data and the rx_queue "pCurrEntry" now points to the second buffer. My call-back resets the DATA_ENTRY_FINISHED status back to DATA_ENTRY_PENDING after printing out the contents. My rx_data queue is a 4-entry circular buffer.
So far everything seems normal. However all subsequent CMD_BLE_ADV commands to the CPE terminate with "Invalid Parameter" (and no transmission of advertising packets).
I have attached the business code from my `radio.c` and debug screenshots showing 1) advertising working and 2) advertising failing after receiving SCAN_REQ.
As noted in comment, the setup code is the unedited "smartrf_settings.c" generated by studio7
All of this running on LP_CC2652R7.

<< lots of includes >>
#include "smartrf_settings.h"
static void data_init(void);
void radio_setup(void)
{
static RF_Object obj;
static RF_Params params;
BT_TRACE();
data_init();
RF_Params_init(¶ms);
d->handle = RF_open(&obj, &RF_prop, &RF_cmdBle5RadioSetup, ¶ms);
LL_ASSERT(d->handle);
}
// start advertising
static void start_adv_cb(RF_Handle handle, RF_CmdHandle command, RF_EventMask events)
{
// XXX it appears (from code examiniation), that events don't need to be cleared by CB
radio_log_events(events, __func__);
rfc_radioOp_t *op = RF_getCmdOp(handle, command);
LOG_DBG("cmd=%04x, status=%04x", op->commandNo, op->status);
radio_log_status(op->status, __func__);
if (events & RF_EventRxEntryDone)
{
// loop thru the rxqueue to process any completed packets
LOG_DBG("rx_queue: pCurrEntry=%p, pLastEntry=%p", (void *)d->rx_queue.pCurrEntry, (void *)d->rx_queue.pLastEntry);
for (rfc_dataEntryGeneral_t *first = d->rx_queue.pCurrEntry,
*p = first->pNextEntry = first->pNextEntry; p != first; p = p->pNextEntry)
{
if (p->status < DATA_ENTRY_FINISHED) continue;
uint8_t *data_p = &p->data;
uint8_t packetLen = data_p[0];
uint8_t *rx_data = &data_p[1];
LOG_DBG("rx_pkt: %p: %d bytes: [%02x ...]", (void *)p, packetLen, *rx_data);
LOG_HEXDUMP_DBG(rx_data, packetLen, "data");
// consume packet
p->status = DATA_ENTRY_PENDING;
}
}
// notify LLL when radio idle
if (events & RF_EventLastCmdDone)
isr_radio(NULL); // XXX NULL
}
// setup advertising parameters from data
static void init_adv_data(rfc_bleAdvPar_t *params)
{
params->pDeviceAddress = d->bt_addr;
params->advConfig.deviceAddrType = 1; // random
params->endTrigger.triggerType = TRIG_NEVER;
//params->endTrigger.triggerType = TRIG_NOW;
params->rxConfig.bAutoFlushIgnored = true;
params->rxConfig.bAutoFlushCrcErr = true;
params->advLen = d->adv_data_len;
params->pAdvData = d->adv_data;
params->scanRspLen = d->scan_rsp_len;
if (d->scan_rsp_len)
params->pScanRspData = d->scan_rsp_data;
else
params->pScanRspData = NULL;
params->rxConfig.bIncludeLenByte = 1;
//params->rxConfig.bIncludeCrc = 1;
params->rxConfig.bAppendRssi = 1;
params->rxConfig.bAppendStatus = 1;
//params->rxConfig.bAppendTimestamp = 1;
}
#define NUM_ADV_CHAN 3
void radio_start_adv(uint8_t chan_map)
{
const rfc_CMD_BLE_ADV_t proto_cmd_adv =
{
.commandNo = 0x1803,
.pParams = &d->adv_params,
.pOutput = &d->adv_output,
.condition = {
.rule = COND_ALWAYS, // value = 0
},
};
static rfc_CMD_BLE_ADV_t adv_cmds[NUM_ADV_CHAN];
BT_TRACE();
// chan_map must only specify `NUM_ADV_CHAN` lsbs
LL_ASSERT((chan_map & ~(BIT(NUM_ADV_CHAN)-1)) == 0);
// initialize adv_params from LLL data
init_adv_data(&d->adv_params);
// generate a advertise command chain for each channel in map
rfc_CMD_BLE_ADV_t *p = adv_cmds, *last_cmd = NULL;
for (int chan = 37; chan_map; ++chan, chan_map >>= 1)
{
if (chan_map & 1)
{
*p = proto_cmd_adv; // initialize cmd
p->channel = chan;
last_cmd = p++; // remember last generated...
last_cmd->pNextOp = p; // ...and chain to next
}
}
LL_ASSERT(last_cmd); // chan_map must nominate at least one channel
last_cmd->pNextOp = NULL; // close chain at last command
last_cmd->condition.rule = COND_NEVER;
RF_CmdHandle h = RF_postCmd(d->handle, (void *)&adv_cmds,
RF_PriorityNormal,
start_adv_cb,
RF_EventRxEntryDone);
LL_ASSERT(h);
}