HiBLE won't stop scanning using CyBle_GapcStopScan();

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

HI there, I am using the CYBLE-012011-00 and I am having trouble programming my BLE to stop scanning even after following the required steps. Please see below my code. It is acting as an observer to an advertiser.

void StackEventHandler(uint32 event, void* eventParam)

{

    /*local variables*/

   CYBLE_GAPC_ADV_REPORT_T advReport;

  

    switch(event)

    {

      

        case CYBLE_EVT_STACK_ON:    /*BLE stack ON*/

                /*Start Scanning*/

                if(CYBLE_ERROR_OK==CyBle_GapcStartScan(CYBLE_SCANNING_FAST))

                {

                    printf("Started to Scan\r\n");

                }

            break;

        case CYBLE_EVT_GAPC_SCAN_PROGRESS_RESULT:

                advReport=*(CYBLE_GAPC_ADV_REPORT_T *)eventParam;

            break;

              

         case  CYBLE_EVT_GAPC_SCAN_START_STOP:

                UART_H2B_UartPutString("\r\nCYBLE_EVT_GAPC_SCAN_START_STOP\r\n");

            break;

              

        default:

            break;

    }

}

/********************************************************************************************************

* Function Name : BLE();

********************************************************************************************************/

int BLE(void)

{

    CYBLE_API_RESULT_T apiResult;

    CYBLE_STATE_T CYBLE_State;

    CyGlobalIntEnable;

    Connection_end = 0;

  

    while(Connection_end == 0)

    {

        apiResult = CyBle_Start(StackEventHandler);

        CyBle_GapcStartScan(CYBLE_SCANNING_FAST);

        CyBle_ProcessEvents();

    }

   

    while(CYBLE_State != CYBLE_STATE_DISCONNECTED)

    {

        CyBle_GapcStopScan();

        CyBle_ProcessEvents();

        CYBLE_State = CyBle_GetState();

     }

}

Essentially it remains in CYBLE_State = CYBLE_SCANNING

1) Has anyone else had a similar problem and if so is there a solution?

2) I can use CYBLE_SetState() to get to CYBLE_State = CYBLE_STATE_DISCONNECTED. However when I go into deepsleep I am waking up with no other interrupts, So I suspect it may still not be actually functioning correctly.

Any help would be greatly appreciated!

0 Likes
1 Solution
Anonymous
Not applicable

When you call the CybleStopScan(), the stack isn't fully finished stopping until it returns the CYBLE_EVT_GAPC_SCAN_START_STOP callback event.

Thus, I would suggest having your code call the CyBle_GapcStopScan(); function, and then wait until the event occurrs, rather than attempting to call the CyBle_GapcStopScan(); over and over until the BLE state changes. Because there is an abstraction/layer between the stop scan, and the scan being stopped, possibly you are calling the CyBle_GapcStopScan(); between the stack successfully stopping scanning and the stop event occurring, which then could lead to the stop event occurring again (since you call the stop scan again), which could be the cause of the wakeup.

I would suggest a change to your code to look like this:

void StackEventHandler(uint32 event, void* eventParam)

{

    /*local variables*/

   CYBLE_GAPC_ADV_REPORT_T advReport;

 

    switch(event)

    {

     

        case CYBLE_EVT_STACK_ON:    /*BLE stack ON*/

                /*Start Scanning*/

                if(CYBLE_ERROR_OK==CyBle_GapcStartScan(CYBLE_SCANNING_FAST))

                {

                    printf("Started to Scan\r\n");

                }

            break;

        case CYBLE_EVT_GAPC_SCAN_PROGRESS_RESULT:

                advReport=*(CYBLE_GAPC_ADV_REPORT_T *)eventParam;

            break;

             

         case  CYBLE_EVT_GAPC_SCAN_START_STOP:

                UART_H2B_UartPutString("\r\nCYBLE_EVT_GAPC_SCAN_START_STOP\r\n");

            break;

             

        default:

            break;

    }

}

/********************************************************************************************************

* Function Name : BLE();

********************************************************************************************************/

int BLE(void)

{

    CYBLE_API_RESULT_T apiResult;

    CYBLE_STATE_T CYBLE_State;

    CyGlobalIntEnable;

    Connection_end = 0;

 

        apiResult = CyBle_Start(StackEventHandler);

    //scanstart is being called when the stack_on event occurs, so we don't need to call it up here

    //CyBle_GapcStartScan(CYBLE_SCANNING_FAST);

    while(Connection_end == 0) //Assuming this is getting set to !0 after running at least once

    {

        CyBle_ProcessEvents();

        //Set Connection_end = 1 when ready to stop scanning

    }

    CyBle_GapcStopScan();

    while(CYBLE_State != CYBLE_STATE_DISCONNECTED)

    {

        CyBle_ProcessEvents();

        CYBLE_State = CyBle_GetState();

     }

}

Some notes on your code:

It seems like you are calling the Cyble_Start() inside a while loop; This only needs to be called once before BLE usage, not polling/continuously

Same with the CyBle_GapcStopScan() and the CyBle_GapcStartScan() functions.

CyBle_ProcessEvents() should basically be run every x ms to comply with the BLE processing time requirements where x is the connection interval of the BLE settings (under the BLE component). Generally I would put it in the main loop of my code, and then just loop back to main using flags to trigger one-time operations as an "event based" architecture of code. This also simplifies the code you need to write for loops and checking states. It does however make the flags and signaling more complicated proportionally.

View solution in original post

0 Likes
2 Replies
ShengY_96
Employee
Employee
10 sign-ins 5 sign-ins Welcome!

Hi Patrick

Per the post code:

{

Connection_end = 0;

while(Connection_end == 0)

    {

        apiResult = CyBle_Start(StackEventHandler);

        CyBle_GapcStartScan(CYBLE_SCANNING_FAST);

        CyBle_ProcessEvents();

    }

}

As the variable: Connection_end is init to 0, so the condition while(Connection_end == 0) is always 1. Which means  the CyBle_GapcStartScan(CYBLE_SCNANING_FAST); is called in while(1) loop. Does this your designed function?

Thanks & Regards

Jenson

0 Likes
Anonymous
Not applicable

When you call the CybleStopScan(), the stack isn't fully finished stopping until it returns the CYBLE_EVT_GAPC_SCAN_START_STOP callback event.

Thus, I would suggest having your code call the CyBle_GapcStopScan(); function, and then wait until the event occurrs, rather than attempting to call the CyBle_GapcStopScan(); over and over until the BLE state changes. Because there is an abstraction/layer between the stop scan, and the scan being stopped, possibly you are calling the CyBle_GapcStopScan(); between the stack successfully stopping scanning and the stop event occurring, which then could lead to the stop event occurring again (since you call the stop scan again), which could be the cause of the wakeup.

I would suggest a change to your code to look like this:

void StackEventHandler(uint32 event, void* eventParam)

{

    /*local variables*/

   CYBLE_GAPC_ADV_REPORT_T advReport;

 

    switch(event)

    {

     

        case CYBLE_EVT_STACK_ON:    /*BLE stack ON*/

                /*Start Scanning*/

                if(CYBLE_ERROR_OK==CyBle_GapcStartScan(CYBLE_SCANNING_FAST))

                {

                    printf("Started to Scan\r\n");

                }

            break;

        case CYBLE_EVT_GAPC_SCAN_PROGRESS_RESULT:

                advReport=*(CYBLE_GAPC_ADV_REPORT_T *)eventParam;

            break;

             

         case  CYBLE_EVT_GAPC_SCAN_START_STOP:

                UART_H2B_UartPutString("\r\nCYBLE_EVT_GAPC_SCAN_START_STOP\r\n");

            break;

             

        default:

            break;

    }

}

/********************************************************************************************************

* Function Name : BLE();

********************************************************************************************************/

int BLE(void)

{

    CYBLE_API_RESULT_T apiResult;

    CYBLE_STATE_T CYBLE_State;

    CyGlobalIntEnable;

    Connection_end = 0;

 

        apiResult = CyBle_Start(StackEventHandler);

    //scanstart is being called when the stack_on event occurs, so we don't need to call it up here

    //CyBle_GapcStartScan(CYBLE_SCANNING_FAST);

    while(Connection_end == 0) //Assuming this is getting set to !0 after running at least once

    {

        CyBle_ProcessEvents();

        //Set Connection_end = 1 when ready to stop scanning

    }

    CyBle_GapcStopScan();

    while(CYBLE_State != CYBLE_STATE_DISCONNECTED)

    {

        CyBle_ProcessEvents();

        CYBLE_State = CyBle_GetState();

     }

}

Some notes on your code:

It seems like you are calling the Cyble_Start() inside a while loop; This only needs to be called once before BLE usage, not polling/continuously

Same with the CyBle_GapcStopScan() and the CyBle_GapcStartScan() functions.

CyBle_ProcessEvents() should basically be run every x ms to comply with the BLE processing time requirements where x is the connection interval of the BLE settings (under the BLE component). Generally I would put it in the main loop of my code, and then just loop back to main using flags to trigger one-time operations as an "event based" architecture of code. This also simplifies the code you need to write for loops and checking states. It does however make the flags and signaling more complicated proportionally.

0 Likes