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

nrf52832 optimization Level 3 result ble cannot re-advertise

I am using BLE for NUS template example to create my app , and when I Compile my code with Keil 5.23.0.0 with optimization Level 0, It behaves good with the following operations:

 1. Download app to chip, connect with APP on mobilephone

 2. disconnet the ble connection on the phone

 3. connect with APP on the mobile phone, OK

But:     

  when I compile the code with optimization Level 3 , re-do the operation 1.2.3 ,  I cannot find the device when step 3

It seems than the chip stop advertiing when I disconnect the first time!

Any one met this case?

  • It seems like the application is testing the battery at startup and if the voltage is less than a certain level you put the application in system off mode. If I comment out enterSystemOff() inside battery_applications() in ADC.c my kit continues to advertise and I can connect. 

    I now see similar behavior as you. I can connect once, but after disconnecting the device doesn't start advertising again. Here is why:

    1. When you disconnect, a BLE_GAP_EVT_DISCONNECTED event is sent from the Softdevice to your application. 
    2. The advertising library picks up this event in ble_advertising_on_ble_evt() in ble_advertisign.c
    3. The advertising library calls on_disconnected().
    4. The library checks if it is ok to start advertising again:
      static void on_disconnected(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
      {
          uint32_t ret;
      
          p_advertising->whitelist_temporarily_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);
             }
          }
      }
    5. The problem is that you change the advertising mode configuration incorrectly in check_adv_mode_on_connect() which is called on every BLE_GAP_EVT_CONNECTED event. 
    6. You need zero-initialize the p_adv_modes_config structure to make sure it is not filled with garbage data and random variables. Typically we do it like this in the SDK:
      memset(&p_adv_modes_config, 0, sizeof(p_adv_modes_config));
    7. If you don't do this, then p_advertising->adv_modes_config.ble_adv_on_disconnect_disabled is going to get a random value. This value might be read as true and the advertising library will not start advertising again after you have disconnected. 

    After adding the memset() function I was able to reconnect. 

    One strange thing though, is that for me it didn't work with neither optimization level 0 nor level 3. I'm guessing it is a compiler thing. In your case, optimization level 0 caused the compiler to set p_advertising->adv_modes_config.ble_adv_on_disconnect_disabled to 0 at instantiation, but on level 3 it got some other value. In my case, it got the wrong value in both cases. 

    So the bottom line is: make sure to zero-initialize all the structs that you use to configure the Softdevice and SDK in general. 

     

Related