Device unable advertise after disconnecting from host

I am trying to troubleshoot a problem wherein the nRF5340 stops advertising and won't resume once a central has connected to it and disconnected. Occasionally, I am able to connect to the nRF5340, transfer some data, disconnect and have advertising resume. But more than half the time it will not resume and I can't get it to advertise again until I have reset the device.

My first thought was to debug this with printk statements to UART, which I already have in place. I re-enable the UART in prj.conf and in the devicetree overlay and am able to get debug statements, but if the UART is enabled, the problem never happens. Unfortunately, I cannot just leave the UART enabled and call it good, because of the need to minimize power consumption.

I've read a number of similar posts here on DevZone, but have not yet found anything that helps me to pin down the cause of the issue. I did note one poster observed removing some print statements seemed to magically fix the issue, and given the behavior varies with enabling the UART, I went through the parts of our code that seem related and commented out all printk statements, but no magic happened.

Loosely, my architecture is I have another micro sending commands to the nRF5340 via SPI.  The app core communicates with the net core via HCI to provide BTLE functionality.

I am using nRF Connect SDK version 1.7.1 and VSCode.

The nRF5340 resides on a custom board in a Fanstel BT40F module. I program and debug using an external J-Link.

I have the disconnected callback set thus:

static struct bt_conn_cb conn_callbacks =
{
   .connected    = bluetooth_app_connected,
   .disconnected = bluetooth_app_disconnected,
   #ifdef CONFIG_BT_NUS_SECURITY_ENABLED
      .security_changed = bluetooth_app_security_changed,
   #endif
};
And in the bluetooth_app_disconnected function, I check a flag to see if we were advertising prior to the connection, and if so, do the following:
k_work_submit(&m_start_advertising_worker);
...
Which ends up ultimately here:
err = bt_le_ext_adv_start(m_extended_advertising_set, &m_ext_adv_start_param);

Any pointers as to where I might ought to be investigating, or tools that might be useful in cracking the mystery, would be greatly appreciated. The fact that enabling the UART makes the problem go away takes away one of my best troubleshooting tools!

Scott

Parents
  • Hi Scott,

    I don't have any good ideas as to why the advertiser fails to start other than that it sounds like it may be timing related. Logging over RTT could be an alternative to using UART for figuring out what the error code is. However, there is a chance that RTT logging may mask the problem too considering it's using the same logging infrastructure.

    To troubleshoot this, I recommend you try one of the following steps:

    1. Increase the max. number of advertisement sets supported in the hci_rpsmg sample (BT controller) running on the network core through the CONFIG_BT_CTLR_ADV_SET symbol. It should be '1' by default. My idea with this is that there may be an internal state flag that is not cleared by the time advertising start is called making the stack try to configure a new advertisement set.

    2. Increase the max. number of supported BLE connections in the app with CONFIG_BT_MAX_CONN assuming the current limit is 1. 

    3. Place a breakpoint that will be hit if bt_le_ext_adv_start() returns with an error. Then use the debugger to check the error code.

    Kconfig settings to enable RTT logging

    CONFIG_LOG=y
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_LOG_BACKEND_RTT=y
    CONFIG_LOG_BACKEND_UART=n

    I would also recommend upgrading to a more recent SDK version if possible. While I can't guarantee it will resolve the specific issue you're encountering, there have been numerous improvements and bug fixes since v1.7.0.

    Best regards,

    Vidar

  • Thank you, Vidar.

    Your response was very helpful and I think helped me get to a resolution.

    I believe the idea you presented in your item #1 may have hit close to the truth.  You said:

    "My idea with this is that there may be an internal state flag that is not cleared by the time advertising start is called making the stack try to configure a new advertisement set."

    This got me thinking and looking. I found that in addition to the callback I mentioned above, there was other code calling for advertising to restart following a disconnect event. Maybe these two pieces of code, both calling for advertising restart in short succession, sometimes aligned in a way that created that bad state?  At any rate, once I had removed that other code, this problem SEEMS to have gone away. I'm going to do more extensive testing to verify, but it certainly seems to be fixed.

    Thanks again! I'm very grateful for your help on this.

    Scott

Reply
  • Thank you, Vidar.

    Your response was very helpful and I think helped me get to a resolution.

    I believe the idea you presented in your item #1 may have hit close to the truth.  You said:

    "My idea with this is that there may be an internal state flag that is not cleared by the time advertising start is called making the stack try to configure a new advertisement set."

    This got me thinking and looking. I found that in addition to the callback I mentioned above, there was other code calling for advertising to restart following a disconnect event. Maybe these two pieces of code, both calling for advertising restart in short succession, sometimes aligned in a way that created that bad state?  At any rate, once I had removed that other code, this problem SEEMS to have gone away. I'm going to do more extensive testing to verify, but it certainly seems to be fixed.

    Thanks again! I'm very grateful for your help on this.

    Scott

Children
No Data
Related