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); }