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.

CC2652R7: After SCAN_RSP generated by CPE, Advertising stops with status "Invalid Parameter"

Part Number: CC2652R7

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(&params);
    d->handle = RF_open(&obj, &RF_prop, &RF_cmdBle5RadioSetup, &params);

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