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.

CC2640R2F: Failed to re-enable scan in simplecentral project

Part Number: CC2640R2F


I am working with simplecentral project and SDK 2.2.

My design is using simplecentral as a pure listener, it would start scan periodically, to lower power consumption, i wanna stop scanning after gets specific data and start a timer at the same time. After the timer triggered, in the callback function, it would start scan (call GapScan_enable). If the device fails getting data wanted, it would stop scan after the duration (set by users) and start again in next scan period (i set the device with infinite mode).

When it comes to my code, i find that the device runs to error when calling GapScan_enable in function registered to util timer. My codes:

#define SC_EVT_OPEN_SCAN 0x0B


#define SC_SCAN_PERIOD 8000


// Clock instance for scan events.
static Clock_Struct clkScanOpen;

//construct clock at GAP_DEVICE_INIT_DONE_EVENT
Util_constructClock(&clkScanOpen, SimpleCentral_clockHandler,
                          SC_SCAN_PERIOD, 0, false, SC_EVT_OPEN_SCAN);

.....
if(GapScan_disable() != SUCCESS)//;
  {
    SC_Log_info0("Gap Scan disable failed");
  }
//start clock at SC_EVT_ADV_REPORT
Util_startClock(&clkScanOpen);


...

void SimpleCentral_clockHandler(UArg arg)
{
  uint8_t evtId = (uint8_t) (arg & 0xFF);

  switch (evtId)
  {
    case SC_EVT_READ_RSSI:
      SimpleCentral_enqueueMsg(SC_EVT_READ_RSSI, (uint8_t) (arg >> 8) , NULL);
      break;

    case SC_EVT_READ_RPA:
      // Restart timer
      Util_startClock(&clkRpaRead);
      // Let the application handle the event
      SimpleCentral_enqueueMsg(SC_EVT_READ_RPA, 0, NULL);
      break;
    case SC_EVT_OPEN_SCAN:
      //re-enable scan here
      GapScan_enable(scanPeriod, scanDuration, 0);
      SC_Log_info0("clock Handler SC_EVT_OPEN_SCAN");
      break;

    default:
      break;
  }
}

Is there anything wrong with my codes?

Looking forward to anything helpful.

  • Try to use "GapScan_enable(0, DEFAULT_SCAN_DURATION, 0);" instead of "GapScan_enable(scanPeriod, scanDuration, 0);"
  • I have tried this way, but it doesn't work. It seems that only if i call GapScan_disable manually, and try to re-enable it in the timer callback function, the problem will appear.

  • Try to call "GapScan_disable" befoer you call "GapScan_enable(scanPeriod, scanDuration, 0);"
  • Sure, i did. Please view the code above, i call GapScan_disable right before start the util clock.

    After the clock triggered, i call GapScan_enable.

  • I add the following red code to test restart scan when button is pressed. If you do the same test, does it work?

    static void SimpleCentral_processAppMsg(scEvt_t *pMsg)
    {
      bool safeToDealloc = TRUE;

      switch (pMsg->hdr.event)
      {
        case SC_EVT_KEY_CHANGE:
          SimpleCentral_handleKeys(pMsg->hdr.state);
          GapScan_disable();
          GapScan_enable(8000, 6000, 0);
          break;

  • I have no key in my current board, so i add these codes to my util clock callback function, it's the same problem.

    I debugged and found the program was stuck here when running into GapScan_enable:

    uint32_t icall_directAPI( uint8_t service , icall_lite_id_t id, ... )
    {
      va_list argp;
      uint32_t res;
      icallLiteMsg_t liteMsg;
    
      // The following will push all parameter in the runtime stack.
      // This need to be call before any other local declaration of variable....
      va_start(argp, id);
    
      // Test that the API is not called in a Hwi or Swi context
      {
        BIOS_ThreadType threadtype = BIOS_getThreadType();
    
        if (threadtype == BIOS_ThreadType_Hwi ||
            threadtype == BIOS_ThreadType_Swi)
        {
    #ifdef HALNODEBUG
    #else /* ! HALNODEBUG */
          ICall_abort();
    #endif /* HALNODEBUG */
        }
      }

    It finally runs into ICall_abort(); which is a dead loop.

  • I would suggest you to add a button or GPI to your board and test my code revision first.
  • Well, this means lots of work for me, and what would it prove? Is there anything unreasonable in my code?
  • Becasue I don't see you call "GapScan_disable();" right before your "GapScan_enable(scanPeriod, scanDuration, 0);" and I won't to check if this causes the issue.

  • HAHA, you should ask me earlier, i call GapScan_disable here:

    It's called right before starting the clock and re-enable when clock triggered.

    You can see the codes in the beginning of the post.

  • I told you to call "GapScan_disable();" right before your "GapScan_enable(scanPeriod, scanDuration, 0);" which means

        case SC_EVT_OPEN_SCAN:
          GapScan_disable();
          //re-enable scan here
          GapScan_enable(scanPeriod, scanDuration, 0);
          SC_Log_info0("clock Handler SC_EVT_OPEN_SCAN");
          break;
    

  • emmm, please keep calm, i didn't mean to offend, but i also told you i have tried as you told me, i put the two sentence
    GapScan_disable();
    GapScan_enable(scanPeriod, scanDuration, 0);
    in the clock callback although it's not in line with the original function demands. And it didn't work...
    It seems that only if i call GapScan relevant function, the codes will run to ICall_abort.
    Is it possible that the problem is due to lack of flash or ram memory?
  • Hi 
    I solved this problem by chance, since i have ran out of ideas, and i saw other events in the util event callback, they're so simple, they never put complicated things here, just put task in queue. This inspires me, i add my event to appmsg event and process it in SimpleCentral_processAppMsg and then it runs well.

    I haven't find out the difference, but i'm about to post this question.

    Thank you for your time, thank you very much.