This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

BLUETOOTH CONNECTION ISSUE

Hi,

  • we developed a  2D-3D mouse .It contains a 2D sensor and a 3D sensor  and 4 touchpads for left click,right click and 3D motion enabling.
  • The SDK we are using for developing our application is   "nRF5_SDK_16.0.0_98a08e2"  and examples "ble_app_hids_mouse" .
  • We are using timer interrupt(app_timer) for reading and updating 2D ,3D sensor data and also to updating battery level  to host pc and the gpio interrupt is using for updating the  mouse clicks to host pc.
  • In our code we are enabling  all these interrupt after the bluetooth connection was established between our mouse and host pc .ie On "BLE_GAP_EVT_CONNECTEDevent  in main.c file  under "ble_evt_handler" function .Please look the below screen shot for better under standings.

  • Then we try to connect to our device  to host pc the connection was not establishing  in pc and its shows  "Try connecting your device again " .please look the below screen shot.

  • We find out the reason for this issue after some research and also with the support of nordic . ie,There are several other BLE events that are waiting to happen right after establishing a connection (BLE_GAP_EVT_CONNECTED event), as Service discovery, MTU update, data length update, PHY update, etc. if we are running so many things directly from inside the handling of the BLE_GAP_EVT_CONNECTED event we risk delaying and blocking other pending BLE softdevice events, and as a consequence perhaps even drop the connection if things take too much time. 
  • So our solution to counter this issue was instead of enabling all the interrupt inside the BLE_GAP_EVT_CONNECTED event we just enabled a single shot timer with delay 1 sec here  and inside this timer handler we enabled all these interrupt.
  • After this change in code we continuously  tested  our device on several PC .The result was uneven in different PC.ie, In some PC connectivity issue is showing and in some PC Its not showing .
  • For detailed analysis we take the sniffer traces  of both PC which showing the connectivity issue and also the PC which not showing connectivity issue . Sniffer traces are attaching below.

PC_WITH_CONNECTION_ISSUE.pcapng

PC_WITHOUT_CONNECTION_ISSUE.pcapng

  • After the analysis of sniffer trace of both pc we comes to a conclusion. The PC with connection issue is taking more time to complete the  BLE softdevice events(Service discovery, MTU update, data length update, PHY update, etc).The PC without connection issue is taking less time to complete the  BLE softdevice events(Service discovery, MTU update, data length update, PHY update, etc).

  • Why this time difference is showing in different PC ?
  • when we increased the single shot timer interval to 5 sec connection issue was not showing in any PC but we can't allow this much delay to enable the all features in our device after the BLE connection was established.
  • Please help us to find a proper solution to counter this issue.  

NOTE :- Refer the sniffer trace from "Number"  4200 in  PC_WITH_CONNECTION_ISSUE. Refer the sniffer trace from "Number" 8656 in PC_WITHOUT_CONNECTION_ISSUE.

  • Hello Nandhu,

    Hope you are doing fine.

    We are very low on capacity due to low staffing because of summer holidays in Norway. I will try to look into this as soon as I can, hopefully in the beginning of next week.

  • Hi Edvin,

          I am doing well what about you?. Thanks for the quick reply .

  • I am fine thank you Slight smile

    I have checked the sniffer trace. I can't see any obvious reasons for why the PC disconnects. Since the PC sends the LL_TERMINATE_IND packet, the connection is not timing out. It should have said that there was a timeout reason if there was something that wasn't replied to, but since it says "Remote User Terminated Connection", that suggests that there is no timeout. However, I checked the usual suspects (5 seconds and 30 seconds before the timeout), and there is nothing that isn't replied to, as far as I can tell. 

    You say that the issue goes away if you delay the peripheral initialization with 5 seconds instead of 1 second, is that correct?

    If you are using an app_timer to trigger this, what IRQ is your app_timer running? What is APP_TIMER_CONFIG_IRQ_PRIORITY in your sdk_config.h?

    Just for testing, can you try something like this:

    volatile bool m_init_periph = false;
    
    
    ...
    
    
    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        switch()
            case BLE_GAP_EVT_CONNECTED:
                NRF_LOG_INFO("connected");
                //peripherals_enable();
                m_init_periph = true;
                ...
                break;
            ...
            
            
    }
    
    
    int main(void)
    {
        ...
        
        for(;;)
        {
            if(m_init_periph)
            {
                m_init_periph = false;
                peripherals_enable();
            }
            idle_state_handle();
        }
    }

    This will move the peripheral initialization to the main context, allowing all other incoming events to interrupt this. 

    What IRQ are your peripherals running? Is it possible that any of these can delay the softdevice? In S132 interrupt priorities 5, 6 and 7 should be fine to use. 4 is reserved for the softdevice, while 2 and 3 can be used for time critical peripherals, but you should not spend too much time in these interrupts. anything below 1 is off limits.

    So does any of the peripherals you initialize use the priority below 5?

  • Hi Edvin,

    Edvin said:
    I have checked the sniffer trace. I can't see any obvious reasons for why the PC disconnects.

     I already told you that after we changed the timer interrupt delay to 5sec connection issue was not showing . Both the traces i posted to you have this change that is why you can't  see any issue but did you notice the time difference  to complete the  BLE softdevice events(Service discovery, MTU update, data length update, PHY update, etc) in both trace.

    If you want a sniffer trace with PC is disconnecting . Please refer the below trace (from number 2800).In this trace two times our device shows the connection problem.

    CONNECTION_PROBLEM.pcapng 

     

    Edvin said:
    You say that the issue goes away if you delay the peripheral initialization with 5 seconds instead of 1 second, is that correct?

     yes.

    Edvin said:
    what IRQ is your app_timer running?

     Inside the "ble_evt_handler" . Now peripherals_enable() is used to start the timer . Please refer the below code  for better clarification.

    /**@brief Function for enabling all peripherals.
     *
     * @details This function will be called after 1s in the device connected to the host pc.
     *
     * @param[in]   p_context   Pointer used for passing some arbitrary information (context) from the
     *                          app_start_timer() call to the timeout handler.
     * void peripherals_enable_timeout_handler(void * p_event_data, uint16_t event_size)  
     **/
     
     
    static void peripherals_enable_timeout_handler(void * p_context)  
    {
         
         ret_code_t err_code;
         
         nrf_gpio_pin_set(BSP_LED_2);       /* Green led will off */
         
         err_code = app_spi_enable();       /* Enabling  2D movement */
         APP_ERROR_CHECK(err_code); 
    
         motion_3d_module_enable();         /* Enabling  3D movement */ 
    
         saadc_timer_enable();              /* SAADC timer will enable so the saadc conversion will start */
         
         if (nrf_gpio_pin_read(PIN_BASE_SENSE) == false)   /* Docked Event*/
         {
               DOCKED   = true;
               touchpad_disable();  /* Disable touchpad   */
         }
         else                                              /* Un_docked Event */
         {  
               DOCKED   = false;
               touchpad_enable();  /* Enable touchpad     */
         }
    
    
    }
    
    
    
    
    /**@brief Function for the Timer initialization.
     *
     * @details Initializes the timer module.
     */
    static void peripherals_enable_timer_init(void)
    {
            ret_code_t err_code;
    
            // Create battery timer.
            err_code = app_timer_create(&peripherals_enable_timer_id,
                                        APP_TIMER_MODE_SINGLE_SHOT,
                                        peripherals_enable_timeout_handler);
            APP_ERROR_CHECK(err_code);
    }
    
    /** Function for enabling the peripherals_enable timer**/
    static void  peripherals_enable(void)
    {
        ret_code_t err_code;
        err_code = app_timer_start(peripherals_enable_timer_id, PERIPHERALS_ENABLE_DELAY_INTERVAL, NULL);
        APP_ERROR_CHECK(err_code);   
     
    }
    
    
    
    
    /** Function for disabling the peripherals_enable timer **/
    static void  peripherals_enable_stop(void)
    {
        uint32_t err_code;  
        err_code = app_timer_stop(peripherals_enable_timer_id);
        APP_ERROR_CHECK(err_code); 
     
    }

     

    Edvin said:
    What is APP_TIMER_CONFIG_IRQ_PRIORITY in your sdk_config.h?

     APP_TIMER_CONFIG_IRQ_PRIORITY = 6

    Edvin said:
    Just for testing, can you try something like this:

      We did the test but same issue was showing . The connection was not establishing with PC.

    Edvin said:
    So does any of the peripherals you initialize use the priority below 5?

     No. The peripherals are only using gpio and timer interrupts and both of its priority level is 6. 

  • Well, I assumed that the trace named PC_WITH_CONNECTION_ISSUE contained the issue. Apparently it did not. 

    So from the last sniffer trace, that actually shows the issue, you can see that the peripheral (nRF) stops responsing. There is your issue. 

    I guess you already know all the tricks, but does the log say anything? It may be an APP_ERROR_CHECK(err_code) or a hardfault.

    Are you able to reproduce this while debugging? does the log say anything? Does the execution stop, or is the application still running?

    Possibly right after you receive the encryption event.

    BR,
    Edvin

Related