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.

CC2640R2L: Timer exception.

Part Number: CC2640R2L

Hi team,

Here's the request from the customer:

He want to implement the functionality of broadcast switching using two timers. Switching the custom broadcast packet when the event of timer A is triggered, switching the standard broadcast packet when the timer B event is triggered and looping for 30s.

However, when the first broadcast packet is switched, the timing is abnormal, and other trigger events are abnormal too such as serial ports and buttons.

What happened and  how to fix it.

Code is shown in the following figure:

#define SP_ADV_SOS_EVT_PERIOD                300
advInt = 160


Util_constructClock(&advsos, SimplePeripheral_clockHandler,
                      SP_ADV_SOS_EVT_PERIOD, 0, false, (UArg)&argadvsos);
                      
Util_constructClock(&advupade, SimplePeripheral_clockHandler,
                      advInt * 0.625, 0, false, (UArg)&argadvupade);


static void adv_init()
{
    //Method 1
    if (sos_state == 1)
        memcpy(updateAdvData, advertDataNew, sizeof(advertDataNew));
    else if(sos_state == 0)
        memcpy(updateAdvData, advertData, sizeof(advertData));

    bStatus_t status = FAILURE;

    status = GapAdv_prepareLoadByHandle(advHandleLegacy,GAP_ADV_FREE_OPTION_ADV_DATA);
    SIMPLEPERIPHERAL_ASSERT(status == SUCCESS);

    // Load advertising data for set #1 that is statically allocated by the app
    status = GapAdv_loadByHandle(advHandleLegacy, GAP_ADV_DATA_TYPE_ADV,
                                 sizeof(updateAdvData), updateAdvData);
    SIMPLEPERIPHERAL_ASSERT(status == SUCCESS);


    //Method 2
/*
        GapAdv_params_t advParamLegacy;

        advParamLegacy.eventProps = GAP_ADV_PROP_CONNECTABLE | GAP_ADV_PROP_SCANNABLE | GAP_ADV_PROP_LEGACY;
        advParamLegacy.primIntMin = advInt;
        advParamLegacy.primIntMax = advInt;
        advParamLegacy.primChanMap = GAP_ADV_CHAN_ALL;
        advParamLegacy.peerAddrType = PEER_ADDRTYPE_PUBLIC_OR_PUBLIC_ID;
        //memcpy(advParamLegacy.peerAddr, pPkt->devAddr, B_ADDR_LEN);
        advParamLegacy.filterPolicy = GAP_ADV_WL_POLICY_ANY_REQ;
        advParamLegacy.primPhy = GAP_ADV_PRIM_PHY_1_MBPS;
        advParamLegacy.secPhy  = GAP_ADV_SEC_PHY_1_MBPS;
        advParamLegacy.sid     = 0;

        // Create Advertisement set #1 and assign handle
        status = GapAdv_create(&SimplePeripheral_advCallback, &advParamLegacy,
                               &advHandleLegacy);
        SIMPLEPERIPHERAL_ASSERT(status == SUCCESS);

        // Load advertising data for set #1 that is statically allocated by the app
        status = GapAdv_loadByHandle(advHandleLegacy, GAP_ADV_DATA_TYPE_ADV,
                                     sizeof(updateAdvData), updateAdvData);
        SIMPLEPERIPHERAL_ASSERT(status == SUCCESS);

        // Load scan response data for set #1 that is statically allocated by the app
        status = GapAdv_loadByHandle(advHandleLegacy, GAP_ADV_DATA_TYPE_SCAN_RSP,
                                     sizeof(scanRspData), scanRspData);
        SIMPLEPERIPHERAL_ASSERT(status == SUCCESS);

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

    // Enable legacy advertising for set #1
    status = GapAdv_enable(advHandleLegacy, GAP_ADV_ENABLE_OPTIONS_USE_MAX, 0);

    SIMPLEPERIPHERAL_ASSERT(status == SUCCESS);
*/
}

static void SimplePeripheral_processAppMsg(spEvt_t *pMsg)
{
  bool dealloc = TRUE;

  switch (pMsg->event)
  {
    ...
    case SP_ADV_SOS_EVT:
        sos_start_handler();
        break;

    case SP_ADV_UPDATE_EVT:
        adv_start_handler();
        break;

    default:
      // Do nothing.
      break;
  }
}

static void sos_start_handler(void)
{
    flag_status.adv_clock_ticks++;
    Util_startClock(&advsos);
    if (flag_status.adv_clock_ticks == 50)
    {
        Uart0_Write("Stop\r\n", 6);
        flag_status.adv_clock_ticks = 0;
        GapAdv_disable(advHandleLegacy);
        sos_state = 0;
        adv_init();
        Util_stopClock(&advsos);
        Util_stopClock(&advupade);
    }
    else
    {
        Uart0_Write("sos\r\n", 5);
        sos_state = 1;
        adv_init();        
    }
}

static void adv_start_handler(void)
{
    Uart0_Write("adv\r\n", 5);
    Util_startClock(&advupade);
    sos_state = 0;
    adv_init();
}

Could you help check this case? Thanks.

Best Regards,                                                       

Nick

  • Hi Nick,

    It does not seem correct to "create" the advertisement set more than once. I would recommend the function "GapAdv_create()" is called only once, and to only update the advertising data as mentioned in the User's Guide.

    The customer should also consider using two advertising sets to achieve this. In that case, each advertising set would be enable / disable based on the timers.

    I hope this will help,

    Best regards,