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

BLE_HCI_INSTANT_PASSED Disconnection Reason

Hi Team,

We are seeing an intermittent issue where BLE connection disconnects abruptly due to reason BLE_HCI_INSTANT_PASSED (0x28). We are using nRF SDK version 15.2.0. The mobile device is Moto G7 Power which runs on Android OS. We have seen this issue 8 times in past month with the same device. Please help us with the following queries:

1. When can this happen? I have seen a stack overflow post explaining the possible reasons. Is that an exhaustive explanation?

2. How can we prevent it? Our customers can have multiple types of devices hence we are looking at a firmware level solution. We came across this link to extend connection event length. Can that help?

Thanks in advance

Parents
  • Hi Kenneth,

    Thanks for prompt response. I have few follow-ups questions:

    >> setting higher tolerance of the LFCLK source when init the softdevice may help

    1. How can we set that? Is this a config in sdk_config.h?

    2. What is the value that we can set? Is there some guidance around it?

    >> enabling (or increasing) slave latency on the link will help

    3. I think this can be done only by peer device. Is it possible for the peripheral to set slave latency?

    >> peer is operating at the maximum range (or much 2.4GHz interference from other devices),

    4. Will it help to mitigate this issue if we introduce a guidance to our customers to not use other BLE devices when operating our product?

  • pranesa said:

    1. How can we set that? Is this a config in sdk_config.h?

    2. What is the value that we can set? Is there some guidance around it?

    You can find in the sdk_config the following defines:

    NRF_SDH_CLOCK_LF_SRC
    NRF_SDH_CLOCK_LF_RC_CTIV
    NRF_SDH_CLOCK_LF_RC_TEMP_CTIV
    NRF_SDH_CLOCK_LF_ACCURACY

    It is the NRF_SDH_CLOCK_LF_ACCURACY that set the accuracy used in the LL to compute timing. If either peer have a LFCLK that is out of spec, then increasing this value may help, however it will also increase current consumption, since the peripheral now will increase the receive window on each connection event. You can in the online power profile for instance see how increasing clock accuracy impact the average current consumption in a connection:
    https://devzone.nordicsemi.com/nordic/power/w/opp/2/online-power-profiler-for-ble

    It is very difficult to comment by how much this value should be increased if the LFCLK is out of spec, but increase it so that average current consumption still meet your battery lifetime can be considered.

    pranesa said:

    >> enabling (or increasing) slave latency on the link will help

    3. I think this can be done only by peer device. Is it possible for the peripheral to set slave latency?

    It is the central device that control this yes, however the peripheral device can request the peer to update the connection parameters, and in most cases it seems that the central device will go ahead and accept and initiate connection parameter updates based on these parameters.

    In your project these are typically set in gap_params_init()->sd_ble_gap_ppcp_set() and conn_params_init()->sd_ble_gap_conn_param_update(). The ble_conn_params module can be configured to send a connection parameter update request if the parameters are outside the preferred ones. Typically you can find that the preferred SLAVE_LATENCY is set in main.c, however in sdk_config.h you can find that there is a define that control by how much slave latency can differ without sending a connection parameter update request. This define is called NRF_BLE_CONN_PARAMS_MAX_SLAVE_LATENCY_DEVIATION. So in other words you should check both these parameters and if you have ble_conn_params module enabled in your application. 

    pranesa said:

    >> peer is operating at the maximum range (or much 2.4GHz interference from other devices),

    4. Will it help to mitigate this issue if we introduce a guidance to our customers to not use other BLE devices when operating our product?

    I don't believe that this help, I don't think interference is a big problem overall. Instead you can possible add some description that if you experience frequent disconnect change location/move it closer if possible, since that will also influence the signal to noise ratio and improve link budget overall.

Reply
  • pranesa said:

    1. How can we set that? Is this a config in sdk_config.h?

    2. What is the value that we can set? Is there some guidance around it?

    You can find in the sdk_config the following defines:

    NRF_SDH_CLOCK_LF_SRC
    NRF_SDH_CLOCK_LF_RC_CTIV
    NRF_SDH_CLOCK_LF_RC_TEMP_CTIV
    NRF_SDH_CLOCK_LF_ACCURACY

    It is the NRF_SDH_CLOCK_LF_ACCURACY that set the accuracy used in the LL to compute timing. If either peer have a LFCLK that is out of spec, then increasing this value may help, however it will also increase current consumption, since the peripheral now will increase the receive window on each connection event. You can in the online power profile for instance see how increasing clock accuracy impact the average current consumption in a connection:
    https://devzone.nordicsemi.com/nordic/power/w/opp/2/online-power-profiler-for-ble

    It is very difficult to comment by how much this value should be increased if the LFCLK is out of spec, but increase it so that average current consumption still meet your battery lifetime can be considered.

    pranesa said:

    >> enabling (or increasing) slave latency on the link will help

    3. I think this can be done only by peer device. Is it possible for the peripheral to set slave latency?

    It is the central device that control this yes, however the peripheral device can request the peer to update the connection parameters, and in most cases it seems that the central device will go ahead and accept and initiate connection parameter updates based on these parameters.

    In your project these are typically set in gap_params_init()->sd_ble_gap_ppcp_set() and conn_params_init()->sd_ble_gap_conn_param_update(). The ble_conn_params module can be configured to send a connection parameter update request if the parameters are outside the preferred ones. Typically you can find that the preferred SLAVE_LATENCY is set in main.c, however in sdk_config.h you can find that there is a define that control by how much slave latency can differ without sending a connection parameter update request. This define is called NRF_BLE_CONN_PARAMS_MAX_SLAVE_LATENCY_DEVIATION. So in other words you should check both these parameters and if you have ble_conn_params module enabled in your application. 

    pranesa said:

    >> peer is operating at the maximum range (or much 2.4GHz interference from other devices),

    4. Will it help to mitigate this issue if we introduce a guidance to our customers to not use other BLE devices when operating our product?

    I don't believe that this help, I don't think interference is a big problem overall. Instead you can possible add some description that if you experience frequent disconnect change location/move it closer if possible, since that will also influence the signal to noise ratio and improve link budget overall.

Children
  • Hi Kenneth,

    >> I don't believe that this help, I don't think interference is a big problem overall.

    In our case, the master is a mobile device connecting to our peripheral. Can a mobile device concurrently connected to multiple other BLE devices like smart watch, headset etc. have budget issue for BLE link with our peripheral? 

    Thanks

  • That may have some impact yes, it could then depend on the scheduling and priority on the mobile phone when the various connections overlap, ideally those links that are doing LL procedures that contain operations from a specific instance should have priority. I do not know how this is handled today in the various mobile operating systems and stacks, it may even vary between chipsets in the mobile phone.

    Best regards,
    Kenneth

  • Hi Kenneth,

    Thanks for helping us with this issue.

    Currently NRF_SDH_CLOCK_LF_ACCURACY is set to 7 which translates to 20 PPM accuracy. We have seen a recommendation in code documentation that we should use 500 PPM accuracy if we are using NRF_CLOCK_LF_SRC_RC (RC oscillator). We are using NRF_CLOCK_LF_SRC_XTAL (crystal oscillator). I have the following query:

    1. Should we move to NRF_CLOCK_LF_SRC_RC along with 500 PPM accuracy? or can we get same accuracy by moving to 500 PPM accuracy and keeping clock source as crystal oscillator?

  • Hi Kenneth,

    I want to understand the problem-3 in a better way.

    When we say a peripheral executing any operation that have higher priority than the BLE link, should we just consider operations supported by softdevice here like BLE advertising, Flash memory access, etc. mentioned in the scheduling priorities link shared by you above? Given we run a separate freertos task to poll softdevice events, should its priority be highest among other application tasks?

    In our setup, we currently support only one BLE connection but as soon as one master is connected to our peripheral we don't stop advertising but switch to a non-connectable advertisement to advertise device state as Busy. Can that advertisement conflict with the operation of already established BLE link?

    We also access flash to retrieve security keys required to enable handshake on the established BLE link, can that also impact the BLE link operation?

    Thanks

  • karnram said:
    When we say a peripheral executing any operation that have higher priority than the BLE link, should we just consider operations supported by softdevice here like BLE advertising, Flash memory access, etc. mentioned in the scheduling priorities link shared by you above?

     Yes. 

    karnram said:
    Given we run a separate freertos task to poll softdevice events, should its priority be highest among other application tasks?

    That doesn't matter, as these control procedures are fully handled by the softdevice. 

    karnram said:
    In our setup, we currently support only one BLE connection but as soon as one master is connected to our peripheral we don't stop advertising but switch to a non-connectable advertisement to advertise device state as Busy. Can that advertisement conflict with the operation of already established BLE link?

    It is possible that advertisement event and connection event may overlap at some instances, since they are asynchronous events they will from time to time overlap in time, in such case the advertisement event may sometimes get the timeslot and thereby the connection event may be skipped one period. Example of advertisement event may get the "timeslot" is simply because it first reserved the "timeslot", the next reserved "timeslot" will be calculated when the previous ended. It's not must that can be done to avoid this, though you may try to reduce the risk of this to occur for several periods in a row by having a connection interval and advertisement interval that differs. E.g. if connection interval is 200ms, then make sure the advertisement is not the same interval or a multiple of the same interval, actually it may better that the advertisement interval is 210ms, 410ms, 610ms or similar to make sure that if there is an overlap at a specific time, the next interval is not overlapping. (I added +10ms for the advertisement interval here compared to the connection interval, since there is always a 0-10ms random delay on advertisement intervals as specified by BT spec.) 

    karnram said:
    We also access flash to retrieve security keys required to enable handshake on the established BLE link, can that also impact the BLE link operation?

    Reading should not be a problem no, only flash erase and flash write operations may have some impact. 

    pranesa said:

    Currently NRF_SDH_CLOCK_LF_ACCURACY is set to 7 which translates to 20 PPM accuracy. We have seen a recommendation in code documentation that we should use 500 PPM accuracy if we are using NRF_CLOCK_LF_SRC_RC (RC oscillator). We are using NRF_CLOCK_LF_SRC_XTAL (crystal oscillator). I have the following query:

    1. Should we move to NRF_CLOCK_LF_SRC_RC along with 500 PPM accuracy? or can we get same accuracy by moving to 500 PPM accuracy and keeping clock source as crystal oscillator?

    I assume you have an external crystal here with 20ppm tolerance, but even if you are using a crystal with 20ppm tolerance, you may consider to initiate the softdevice by specifying a 50ppm or 100ppm tolerance, this will increase the time window when receiving to allow some more drift if there is an LFCLK in the peer that is out of spec.

    Considering you are already using an external crystal I don't see the need to change to internal RC and 500ppm, but you could add some logic in your application that if you experience a disconnect with a peer due to BLE_HCI_INSTANT_PASSED, then it could on next startup initialize the softdevice with a higher tolerance (even as high as 250ppm when using external clock) to indirectly check if the problem goes away.

    This isn't exact science, but hopefully my comments make sense.

Related