Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

NRF52 reconnection problem

Hello. I am using ble_app_uart from sdk14.2. I use pca100401, softdevice s132.

Advertising is generated using timer RTC. Board advertises and stops advertising without errors if I it starts and I do not connect to it. However, when trying to reconnect after one connection and disconnection event with android device I receive an error. Error message in J-link RTT viewer states that error occurs at ..\..\..\main.c:1416 which is:

This is my main.c code:

/**@brief Application main function.
 */
int main(void)
 {
    uint32_t err_code;
    //bool     erase_bonds;
	timers_init();
    uart_init();
    log_init();
   // buttons_leds_init(&erase_bonds);
    ble_stack_init();
    gap_params_init();
    gatt_init();
    services_init();
    advertising_init();
    conn_params_init();

   
 SEGGER_RTT_WriteString(0, "Hello World_SEGGER!\n");
    //NRF_LOG_INFO("UART Start_NRF_LOG_INFO!");


/******************* MY CHANGES ****************/
gpio_config();
gpiote_init();
fstorage_init();

my_flash_begin();
timers_start();
nrf_gpio_pin_write(LED_2,0);
nrf_gpio_pin_write(LED_1,1);
/******************* MY CHANGES ****************/
					
    while(1)
    {
			if(begin_flag == 1)
			{
				if(advertising_started==0)
				 {
					 advertising_started =1;
					 device_beginning_service();
					 
					 sprintf((char*)string18,"advertising started\r\n");
					 SEGGER_RTT_WriteString(0,(char*)string18);
					
					 err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
					
					 APP_ERROR_CHECK(err_code);

				 }
		 
			}

This is the error I receive in J-link RTT viewer:

ble_advertising.h states that error means: the module is not initialized. 

I am thinking that it might be problem with connection or disconnection events. Here is how I describe them:

       case BLE_GAP_EVT_CONNECTED:
						 SEGGER_RTT_WriteString(0,"CONNECTION HAPPENED\n\r");
						 nrf_gpio_pin_write(LED_3, 0);
						 nrf_gpio_pin_write(LED_2, 1);
						 nrf_gpio_pin_write(LED_1, 1);
//            NRF_LOG_INFO("Connected");
						 app_timer_stop_all();
           /* err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
            APP_ERROR_CHECK(err_code);*/
            m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
					
            break;

case BLE_GAP_EVT_DISCONNECTED:
						 SEGGER_RTT_WriteString(0,"DISCONNECTION HAPPENED\n\r");
						 nrf_gpio_pin_write(LED_2, 0);
						 nrf_gpio_pin_write(LED_1, 1);
						 nrf_gpio_pin_write(LED_3, 1);
						 begin_flag = 0;
				     advertising_started = 0;
						 app_timer_stop_all();
				     err_code = app_timer_start(m_sleep_timer_id, SLEEP_TIMER_INTERVAL, NULL);  		  //start sleeping timer
				     APP_ERROR_CHECK(err_code);
            // LED indication will be changed when advertising starts.
            m_conn_handle = BLE_CONN_HANDLE_INVALID;
            break;

Would like to receive any suggestions why this is happening. Thank you.

  • Yes, you are correct, ble_advertising_init() is used once. Ok, I will do this.

    Best regards

  • Thanks to  problem was solved. He found out that by default, a variable is set in advertising init. There is a parameter called: init.config.ble_adv_in_disconnect_disabled which is set to false (0) by default. In ble_advertising.c there is an advertising event handler called ble_advertising_on_ble_evt() which is called in parallel with the eventhandler in main.c.

    The event handler in ble_advertising.c has the following: 

     // Upon disconnection, whitelist will be activated and direct advertising is started.
            case BLE_GAP_EVT_DISCONNECTED:
                on_disconnected(p_advertising, p_ble_evt);
                break;

    Inside on_disconnected(...) it will call ble_advertising_start() if (p_advertising->adv_modes_config.ble_adv_on_disconnect_disabled == false) : 

        if (p_ble_evt->evt.gap_evt.conn_handle == p_advertising->current_slave_link_conn_handle &&
            p_advertising->adv_modes_config.ble_adv_on_disconnect_disabled == false)
        {
           ret = ble_advertising_start(p_advertising, BLE_ADV_MODE_DIRECTED);
           if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
           {
               p_advertising->error_handler(ret);
           }
        }

    Since this is called at once when the disconnect happened, it would always be called before the timer from main decided to start advertising. 

    To solve this Edvin suggested to start advertising right after disconnection or to change ble_adv_on_disconnect_disabled in the advertising_init() function. Then advertising_init() looks like this:

    static void advertising_init(void)
    {
        uint32_t               err_code;
        ble_advertising_init_t init;
    
        memset(&init, 0, sizeof(init));
    
        init.advdata.name_type          = BLE_ADVDATA_FULL_NAME;
        init.advdata.include_appearance = false;
        init.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
    
        init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        init.srdata.uuids_complete.p_uuids  = m_adv_uuids;
    
        init.config.ble_adv_fast_enabled  = true;
        init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
        init.config.ble_adv_fast_timeout  = APP_ADV_TIMEOUT_IN_SECONDS;
        
        init.config.ble_adv_on_disconnect_disabled = true;
    
        init.evt_handler = on_adv_evt;
    
        err_code = ble_advertising_init(&m_advertising, &init);
        APP_ERROR_CHECK(err_code);
    
        ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
    }

Related