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.

LP-CC2652RB: Failed to send periodic adv data.

Part Number: LP-CC2652RB


Hi team,

Here's the request from the customer:

Customer follows the steps in the periodic advertising section of SimpleLink Tm CC13x2 / CC26x2 SDK BLE5-Stack User's Guide 2.02.01.00 to write codes for peripheral devices.

However, the host central device cannot receive the periodic adv data set by the GapAdv_SetPeriodicAdvData function, but can receive the data set by GapAdv_loadByHandle. The code segment of the periodic advertising part of the peripheral device configuration is attached as follows. He has checked the status returned by each function, and they all return SUCCESS.

// Periodic Advertising Intervals
#define PERIDIC_ADV_INTERVAL_MIN    160  
#define PERIDIC_ADV_INTERVAL_MAX    160 

/// Non-Connectable & Non-Scannable advertising set
#define GAPADV_PARAMS_AE_NC_NS {                                           \
  .eventProps = 0,                                                         \
  .primIntMin = 160,                                                       \
  .primIntMax = 160,                                                       \
  .primChanMap = GAP_ADV_CHAN_ALL,                                         \
  .peerAddrType = PEER_ADDRTYPE_PUBLIC_OR_PUBLIC_ID,                       \
  .peerAddr = { 0x74, 0xD2, 0x85, 0xD4, 0x63, 0xB4 },                      \
  .filterPolicy = GAP_ADV_WL_POLICY_ANY_REQ,                               \
  .txPower = GAP_ADV_TX_POWER_NO_PREFERENCE,                               \
  .primPhy = GAP_ADV_PRIM_PHY_1_MBPS,                                      \
  .secPhy = GAP_ADV_SEC_PHY_1_MBPS,                                        \
  .sid = 1                                                                \
}

static uint8 advHandleNCNS;      // Non-Connactable & Non-Scannable

static uint8_t periodicData[] =
{
  'P',
  'e',
  'r',
  'i',
  'o',
  'd',
  'i',
  'c',
  'A',
  'd',
  'v'
};

#define GAPADV_DATA_PERIODIC_ADV {                          \
   .operation = GAPADV_PERIODIC_ADV_DATA_COMPLETE,           \
   .dataLength = sizeof(periodicData),                       \
   .pData = periodicData                                     \
 }

// Advertisement data
static uint8_t advertData[] =
{
  0x0C,                         // Length of this data
  GAP_ADTYPE_LOCAL_NAME_SHORT,  // Type of this data
  'P',
  'e',
  'r',
  'i',
  'o',
  'd',
  'i',
  'c',
  'A',
  'd',
  'v',
  0x02,   // length of this data
  GAP_ADTYPE_FLAGS,
  GAP_ADTYPE_FLAGS_GENERAL | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
};

// Create non connectable & non scannable advertising set #3
GapAdv_params_t advParamNonConn = GAPADV_PARAMS_AE_NC_NS;

// Create Advertisement set #3 and assign handle
status = GapAdv_create(&SimplePeripheral_advCallback, &advParamNonConn, &advHandleNCNS);

// Load advertising data for set #3 that is statically allocated by the app
status = GapAdv_loadByHandle(advHandleNCNS, GAP_ADV_DATA_TYPE_ADV,
                             sizeof(advertData), advertData);

// Set event mask for set #3
status = GapAdv_setEventMask(advHandleNCNS,
                             GAP_ADV_EVT_MASK_START_AFTER_ENABLE |
                             GAP_ADV_EVT_MASK_END_AFTER_DISABLE |
                             GAP_ADV_EVT_MASK_SET_TERMINATED);

// Enable non connectable & non scannable advertising for set #3
status = GapAdv_enable(advHandleNCNS, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0);

// Set Periodic Advertising parameters
GapAdv_periodicAdvParams_t perParams = {PERIDIC_ADV_INTERVAL_MIN,
                                        PERIDIC_ADV_INTERVAL_MAX, 0x40};
status = GapAdv_SetPeriodicAdvParams(advHandleNCNS, &perParams);

GapAdv_periodicAdvData_t periodicDataParams = GAPADV_DATA_PERIODIC_ADV;
status = GapAdv_SetPeriodicAdvData(advHandleNCNS, &periodicDataParams);

// Enable the periodic advertising
status = GapAdv_SetPeriodicAdvEnable(1, advHandleNCNS);

Could you help check this case? Thanks.

Thanks and Regards,                                                        

Nick

  • Hi Nick,

    Thank you for reaching out to us. We will take a look at your queries and get back to you as soon as possible. In the meantime, can you provide us with the SDK version that is being used?

    Best Regards,

    Jan

  • Hi Jan,

    The SDK version is simplelink_cc13x2_26x2_sdk_5_10_00_48.

    Thanks and Regards,                                                        

    Nick

  • Hi Nick,

    Some additional code modifications must be made on the simple_central side in order to capture the periodic advertisements. These modifications are listed in the Synchronize with a Periodic Advertising Train section. Has the customer implemented these steps yet?

    Best Regards,

    Jan

  • Hi Jan,

    Here's customer's further reply:

    Attached is my simple_central code, the initialization code is as follows:

    void SimpleCentral_scanCb(uint32_t evt, void* pMsg, uintptr_t arg)
    {
      uint8_t event;
    
      if (evt & GAP_EVT_ADV_REPORT)
      {
        event = SC_EVT_ADV_REPORT;
      }
      else if (evt & GAP_EVT_SCAN_ENABLED)
      {
        event = SC_EVT_SCAN_ENABLED;
      }
      else if (evt & GAP_EVT_SCAN_DISABLED)
      {
        event = SC_EVT_SCAN_DISABLED;
      }
      else if (evt & GAP_EVT_INSUFFICIENT_MEMORY)
      {
        event = SC_EVT_INSUFFICIENT_MEM;
      }
      else
      {
        return;
      }
    
      if(SimpleCentral_enqueueMsg(event, SUCCESS, pMsg) != SUCCESS)
      {
        ICall_free(pMsg);
      }
    }
    
    GapScan_registerCb(SimpleCentral_scanCb, NULL);
    
    // Set Scanner Event Mask
    GapScan_setEventMask(GAP_EVT_SCAN_ENABLED | GAP_EVT_SCAN_DISABLED |
                       GAP_EVT_ADV_REPORT);
    
    // Set Scan PHY parameters
    GapScan_setPhyParams(DEFAULT_SCAN_PHY, SCAN_TYPE_PASSIVE,
                       DEFAULT_SCAN_INTERVAL, DEFAULT_SCAN_WINDOW);
    
    // Set Advertising report fields to keep
    temp16 = (SCAN_ADVRPT_FLD_ADDRESS | SCAN_ADVRPT_FLD_ADDRTYPE);
    GapScan_setParam(SCAN_PARAM_RPT_FIELDS, &temp16);
    // Set Scanning Primary PHY
    temp8 = SCAN_PRIM_PHY_1M;
    GapScan_setParam(SCAN_PARAM_PRIM_PHYS, &temp8);
    // Set LL Duplicate Filter
    temp8 = SCAN_FLT_DUP_ENABLE;
    GapScan_setParam(SCAN_PARAM_FLT_DUP, &temp8);
    
    temp16 = SCAN_FLT_PDU_NONCONNECTABLE_ONLY;
    GapScan_setParam(SCAN_PARAM_FLT_PDU_TYPE, &temp16);
    
    // Set initiating PHY parameters
    // INIT_PHYPARAM_MAX_CONN_INT = 80
    GapInit_setPhyParam(INIT_PHY_1M, INIT_PHYPARAM_CONN_INT_MIN,
    				  INIT_PHYPARAM_MIN_CONN_INT);
    GapInit_setPhyParam(INIT_PHY_1M, INIT_PHYPARAM_CONN_INT_MAX,
    				  INIT_PHYPARAM_MAX_CONN_INT);

    Customer added printing In the SC_EVT_ADV_REPORT broadcast scan report event which in function SimpleCentral_processAppMsg. The first phenomenon was that he didn't see the periodic broadcast data of pAdvRpt->periodicAdvInt != 0, and the second phenomenon was that he found the GapAdv_ loadByHandle broadcasts data set by simple_peripheral with the following code:

    static void SimpleCentral_processAppMsg(scEvt_t *pMsg)
    {
      bool safeToDealloc = TRUE;
    
      if (pMsg->hdr.event <= APP_EVT_EVENT_MAX)
      {
        BLE_LOG_INT_STR(0, BLE_LOG_MODULE_APP, "APP : App msg status=%d, event=%s\n", 0, appEventStrings[pMsg->hdr.event]);
      }
      else
      {
        BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : App msg status=%d, event=0x%x\n", 0, pMsg->hdr.event);
      }
    
      switch (pMsg->hdr.event)
      {
        case SC_EVT_KEY_CHANGE:
          SimpleCentral_handleKeys(pMsg->hdr.state);
          break;
    
        case SC_EVT_ADV_REPORT:
        {
          GapScan_Evt_AdvRpt_t* pAdvRpt = (GapScan_Evt_AdvRpt_t*) (pMsg->pData);
            if(0 != pAdvRpt->periodicAdvInt)
            {
             // this is a periodic advertisement
                Display_printf(dispHandle, SC_ROW_9, 0, "this is a periodic advertisement");
                SimpleCentral_doStopDiscovering(0);
            }
            else
            {
             // this is NOT a periodic advertisement
            }
            // reporting the advData according to the peripheral address
            if(pAdvRpt->addr[0] == 0x8c && pAdvRpt->addr[5] == 0x74) { // this is my peripheral address
                Display_printf(dispHandle, SC_ROW_NON_CONN, 0, "Discovered: %s", Util_convertBdAddr2Str(pAdvRpt->addr));
                int j = 0;
                Display_printf(dispHandle, SC_ROW_9 + 1, 0, "advertisement data len: %d", pAdvRpt->dataLen);
                for(j = 0; j < pAdvRpt->dataLen; j++) {
                    Display_printf(dispHandle, SC_ROW_9 + 2 + j, 0, "%x", *(pAdvRpt->pData + j));
                }
            }
          
    
          // Free report payload data
          if (pAdvRpt->pData != NULL)
          {
            ICall_free(pAdvRpt->pData);
          }
          break;
        }
        
        // ...
        
        default:
          // Do nothing.
          break;
    }

    Based on the steps in Synchronize with a Periodic Advertising Train, he was currently having trouble identifying periodic advertisers at step six:

    Thanks and Regards,                                                        

    Nick

  • Hi Nick,

    I would suggest they verify the advertiser is first actually sending periodic advertisements. This can be done by using a logic analyzer and using the RF debugging pins which you can enable like this. 

    https://dev.ti.com/tirex/content/simplelink_cc13xx_cc26xx_sdk_6_41_00_17/docs/ble5stack/ble_user_guide/html/ble-stack-5.x-guide/debugging-index.html#debugging-rf-output

    I would also suggest they use the GAPADV_PERIODIC_ADV_ENABLE_TX_POWER instead of using the 0x40 hex value.

    Once we confirm the advertiser is in fact sending periodic advertisements we can see how to get the central can sync to them.

    Kind Regards,

    Rogelio