Random BLE disconnections and occasional system hang on nRF52832 using bare-metal SDK (external RTC used)

We are facing an intermittent issue on an nRF52832–based product using bare-metal Nordic nRF5 SDK (non-NCS, non-Zephyr) BLE implementation.

Observed behavior:

BLE initializes correctly; advertising and connection establishment work as expected

Communication remains stable initially after power-up

After running for some time:

The BLE connection disconnects randomly, and

In some cases, the board appears to get stuck/hang (no BLE activity, no further application progress)

The issue is non-deterministic and does not correlate with boot or a specific user action

Software details:

SoC: nRF52832

SDK: Latest available nRF5 SDK (bare-metal)

SoftDevice: S132 (exact version can be shared if required)

OS: None (bare-metal)

Migration to NCS/Zephyr is not possible, as the project is in the final stage

Clock configuration verification:

32 MHz HF crystal: verified and stable (validated using standalone test code)

32.768 kHz LF crystal: verified and stable (validated using standalone test code)

No observed clock startup failures during normal operation

System specifics:

An external RTC is used for application timekeeping

Internal RTC peripherals are not used by the application

SoftDevice configuration has not been modified beyond required initialization

Additional observations:

In the “stuck” condition, the board does not reset automatically

No HardFault or watchdog reset is observed (watchdog currently disabled)

Power remains stable during the event

Request for guidance:

On nRF52832, are there known issues where:

External RTC usage can interfere with SoftDevice timing or scheduling?

Blocking sections, critical regions, or long interrupt latencies can cause both BLE disconnects and system hang?

Does the SoftDevice require uninterrupted access to internal RTC/LFCLK, regardless of application timekeeping source?

Are there specific SoftDevice asserts, events, or debug registers recommended to monitor for random disconnects or hangs?

Could this be caused by missed radio events, supervision timeout, or improper low-power handling over long runtimes?

Below is the log captured around the disconnection/hang event for reference:

nRF Connect, 2026-01-01

Sensor_Demo_d3 (EE:CE:3A:AC:83:D3)

V 11:28:27.412 Connecting to EE:CE:3A:AC:83:D3...

D 11:28:27.412 gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, preferred PHY = LE 1M)

D 11:28:30.483 [Callback] Connection state changed with status: 0 and new state: CONNECTED (2)

I 11:28:30.483 Connected to EE:CE:3A:AC:83:D3

D 11:28:30.483 wait(1600ms)

D 11:28:30.511 [Broadcast] Action received: android.bluetooth.device.action.ACL_CONNECTED

D 11:28:30.884 [Callback] Connection state changed with status: 19 and new state: DISCONNECTED (0)

W 11:28:30.884 Connection terminated by peer (status 19)

I 11:28:30.884 Disconnected

D 11:28:30.911 [Broadcast] Action received: android.bluetooth.device.action.ACL_DISCONNECTED

V 11:29:19.478 Removing bond information...

D 11:29:19.478 device.removeBond() (hidden)

D 11:29:19.584 [Broadcast] Action received: android.bluetooth.device.action.BOND_STATE_CHANGED, bond state changed to: NONE (10), reason: REMOVED (9)

I 11:29:19.584 Bond information lost, reason: REMOVED (9)

D 11:29:25.048 gatt.close()

D 11:29:25.049 wait(200)

V 11:29:25.258 Connecting to EE:CE:3A:AC:83:D3...

D 11:29:25.259 gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, preferred PHY = LE 1M)

D 11:29:55.369 [Callback] Connection state changed with status: 147 and new state: DISCONNECTED (0)

E 11:29:55.370 Error 147 (0x93): GATT CONN TIMEOUT

I 11:29:55.370 Disconnected

D 11:30:03.355 gatt.close()

D 11:30:03.357 wait(200)

V 11:30:03.559 Connecting to EE:CE:3A:AC:83:D3...

D 11:30:03.559 gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, preferred PHY = LE 1M)

D 11:30:04.118 [Callback] Connection state changed with status: 0 and new state: CONNECTED (2)

I 11:30:04.118 Connected to EE:CE:3A:AC:83:D3

V 11:30:04.119 Discovering services...

D 11:30:04.119 gatt.discoverServices()

D 11:30:04.147 [Broadcast] Action received: android.bluetooth.device.action.ACL_CONNECTED

D 11:30:04.216 [Broadcast] Action received: android.bluetooth.device.extra.PAIRING_VARIANT, pairing variant: CONSENT

D 11:30:04.218 [Broadcast] Action received: android.bluetooth.device.action.BOND_STATE_CHANGED, bond state changed to: BONDING (11)

I 11:30:04.709 Connection parameters updated (interval: 7.5ms, latency: 0, timeout: 5000ms)

D 11:30:04.818 [Callback] Services discovered with status: 0

I 11:30:04.818 Services discovered

V 11:30:04.830 Generic Access (0x1800)

- Device Name [R W] (0x2A00)

- Appearance [R] (0x2A01)

- Peripheral Preferred Connection Parameters [R] (0x2A04)

- Central Address Resolution [R] (0x2AA6)

Generic Attribute (0x1801)

Unknown Service (00001000-1112-1314-1516-171819202122)

- Unknown Characteristic [N R W WNR] (00001003-1112-1314-1516-171819202122)

   Client Characteristic Configuration (0x2902)

Battery Service (0x180F)

- Battery Level [N R W WNR] (0x2A19)

   Client Characteristic Configuration (0x2902)

Device Information (0x180A)

- Manufacturer Name String [R] (0x2A29)

- Model Number String [R] (0x2A24)

- Serial Number String [R] (0x2A25)

- Hardware Revision String [R] (0x2A27)

- Firmware Revision String [R] (0x2A26)

D 11:30:04.830 gatt.setCharacteristicNotification(00001003-1112-1314-1516-171819202122, true)

D 11:30:04.832 gatt.setCharacteristicNotification(00002a19-0000-1000-8000-00805f9b34fb, true)

I 11:30:04.895 Connection parameters updated (interval: 48.75ms, latency: 0, timeout: 5000ms)

D 11:30:09.363 [Broadcast] Action received: android.bluetooth.device.action.BOND_STATE_CHANGED, bond state changed to: NONE (10), reason: REMOVED (9)

I 11:30:09.363 Bonding failed, reason: REMOVED (9)

I 11:30:10.035 Connection parameters updated (interval: 47.5ms, latency: 0, timeout: 4000ms)

V 11:30:10.166 Disconnecting...

D 11:30:10.166 gatt.disconnect()

D 11:30:10.182 [Callback] Connection state changed with status: 0 and new state: DISCONNECTED (0)

I 11:30:10.182 Disconnected

D 11:30:11.315 [Broadcast] Action received: android.bluetooth.device.action.ACL_DISCONNECTED

D 11:30:11.505 gatt.close()

D 11:30:11.506 wait(200)

V 11:30:11.708 Connecting to EE:CE:3A:AC:83:D3...

D 11:30:11.708 gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, preferred PHY = LE 1M)

D 11:30:41.789 [Callback] Connection state changed with status: 147 and new state: DISCONNECTED (0)

E 11:30:41.789 Error 147 (0x93): GATT CONN TIMEOUT

I 11:30:41.789 Disconnected

D 11:30:54.877 gatt.close()

D 11:30:54.878 wait(200)

V 11:30:55.080 Connecting to EE:CE:3A:AC:83:D3...

D 11:30:55.080 gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, preferred PHY = LE 1M)

D 11:30:55.655 [Callback] Connection state changed with status: 0 and new state: CONNECTED (2)

I 11:30:55.655 Connected to EE:CE:3A:AC:83:D3

V 11:30:55.656 Discovering services...

D 11:30:55.656 gatt.discoverServices()

Parents
  • Hi,

    You write that internal RTC is not used by the application, but it is used by the SoftDevice (which always use RTC0). Regarding the use of external RTC I do not immediately see how that could be relevant (given that it is anyway not used by the SoftDevice).

    Blocking the SoftDevice for too long can be problematic so critical sections should be short, and you should not use higher interrupt priorities for the application. See Interrupt priority levels. If this cause a problem, the SoftDvice will assert. Note that there is no way to recover from a SoftDevice assert, so you need to reset after that (but should log the assert, and create a support ticket with the assert address if you need more information about it).

    I do not believe this is the reason for the issue, though. Do you have logs from the nRF? The Android log you have posted indicate that the bonding data is deleted on he phone side, and in that case, the nRF will by default not accept pairing again. If this is the problem, that can be resolved by allowing re-pairing as shown in this post with the handling of the PM_EVT_CONN_SEC_CONFIG_REQ event.

    If this is not the problem, it would be interesting with a sniffer trace and potentially also a log from the nRF side.

  • RTT: Log.........
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> PRS: Function: nrfx_prs_acquire, error code: NRF_SUCCESS.
    <info> SPI: Function: nrfx_spi_init, error code: NRF_SUCCESS.
    <info> SPI: Function: nrfx_spi_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_RX.
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_RX.
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_RX.
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_RX.
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_RX.
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_RX.
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_RX.
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_RX.
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (1)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (1)
    <info> TWIM: Transfer type: XFER_RX.
    Logs dropped (1)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (1)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (1)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (1)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (1)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (1)
    <info> TWIM: Transfer type: XFER_RX.
    Logs dropped (1)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (1)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (1)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (1)
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    Logs dropped (1)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (1)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (1)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (1)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (1)
    <info> TWIM: Transfer type: XFER_RX.
    Logs dropped (1)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (1)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (1)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (1)
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    Logs dropped (1)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (1)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (1)
    <info> TWIM: Transfer buffers length: primary: 8, secondary: 0.
    Logs dropped (1)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (1)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (1)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (1)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (1)
    <info> TWIM: Transfer type: XFER_RX.
    Logs dropped (1)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (1)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (1)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (1)
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    Logs dropped (1)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (1)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (1)
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    Logs dropped (1)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (1)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (1)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (1)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (1)
    <info> TWIM: Transfer type: XFER_RX.
    Logs dropped (1)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (1)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (1)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (1)
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    Logs dropped (1)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (1)
    <info> CLOCK: Function: nrfx_clock_init, error code: NRF_SUCCESS.
    Logs dropped (1)
    <info> CLOCK: Module enabled.
    Logs dropped (1)
    <info> clock: Function: nrf_drv_clock_init, error code: NRF_SUCCESS.
    <info> app: Initialized.
    Logs dropped (1)
    <info> app_timer: RTC: initialized.
    Logs dropped (1)
    <info> app: Initialized (size: 32 x 36 = 1152 bytes)
    Logs dropped (1)
    <info> app: Core: Log.......
    
    Logs dropped (2)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (2)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (2)
    <info> TWIM: Transfer buffers length: primary: 3, secondary: 0.
    Logs dropped (2)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (2)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (2)
    <info> TWIM: Transfer buffers length: primary: 3, secondary: 0.
    Logs dropped (2)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (2)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (3)
    <info> TWIM: Transfer buffers length: primary: 3, secondary: 0.
    Logs dropped (3)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (3)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (3)
    <info> TWIM: Transfer buffers length: primary: 3, secondary: 0.
    Logs dropped (3)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (3)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (3)
    <info> TWIM: Transfer buffers length: primary: 3, secondary: 0.
    Logs dropped (3)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (3)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (4)
    <info> TWIM: Transfer buffers length: primary: 3, secondary: 0.
    Logs dropped (3)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (4)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (3)
    <info> TWIM: Transfer buffers length: primary: 3, secondary: 0.
    Logs dropped (2)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (4)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (3)
    <info> TWIM: Transfer buffers length: primary: 3, secondary: 0.
    Logs dropped (2)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (4)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (3)
    <info> TWIM: Transfer buffers length: primary: 3, secondary: 0.
    Logs dropped (4)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (3)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (5)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (4)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (3)
    <info> TWIM: Transfer type: XFER_RX.
    Logs dropped (5)
    <info> TWIM: Transfer buffers length: primary: 5, secondary: 0.
    Logs dropped (4)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (3)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (5)
    <info> TWIM: Transfer buffers length: primary: 10, secondary: 0.
    Logs dropped (4)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (3)
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (5)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (4)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (5)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (9)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (6)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_RX.
    Logs dropped (9)
    <info> TWIM: Transfer buffers length: primary: 5, secondary: 0.
    Logs dropped (5)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (10)
    <info> TWIM: Transfer buffers length: primary: 10, secondary: 0.
    Logs dropped (5)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (10)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (4)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    Logs dropped (6)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (12)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (6)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_RX.
    Logs dropped (12)
    <info> TWIM: Transfer buffers length: primary: 5, secondary: 0.
    Logs dropped (6)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (12)
    <info> TWIM: Transfer buffers length: primary: 10, secondary: 0.
    Logs dropped (6)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (12)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (6)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_RX.
    Logs dropped (12)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (6)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (12)
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    Logs dropped (6)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (12)
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    Logs dropped (6)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (9)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (2)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_RX.
    Logs dropped (7)
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    Logs dropped (9)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_RX.
    Logs dropped (15)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (9)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (15)
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    Logs dropped (9)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (10)
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    Logs dropped (7)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_TX.
    Logs dropped (12)
    <info> TWIM: Transfer buffers length: primary: 1, secondary: 0.
    Logs dropped (2)
    <warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
    <info> TWIM: Transfer type: XFER_RX.
    Logs dropped (7)
    <info> TWIM: Transfer buffers length: primary: 2, secondary: 0.
    
    Log 2026-01-02 14_47_57.txt

    Hi Einar,

    Thanks for the explanation.

    I have NRF logs (RTT-based) when the device is running under a debugger, but the issue is that it never hangs in that setup. The random disconnects and the occasional freeze only happen during long standalone runs, so I haven’t been able to capture a SoftDevice assert or a HardFault in the moment. The logs look normal right up to the disconnect.

    About bonding: I did see the phone removing the bond on the Android side, but even when bonding isn’t involved, we still get “Error 8 (0x8): GATT CONN TIMEOUT.” In some long runs the device stops responding completely. It stops advertising and stops producing any logs, so it seems like something deeper than just bonding.

    I can share the application logs if that helps.

    What would you recommend as the next steps to narrow this down?
    Should I:

    • Enable full PM event logging
    • Capture a sniffer trace (and if so, what should I focus on)
    • Add more SoftDevice and reset-reason logging
    • Monitor radio notifications for possible missed events

    Also, one more question:
    What is the recommended way to capture callstack and register data if a HardFault or SoftDevice assert ever does occur? I’d like to add a simple blackbox-style capture so I can get the fault context even if the device freezes during long-term operation.

    Thanks again for your help.

  • Hi,

    Ramesh Polasa said:
    I can share the application logs if that helps.

    Yes, that will be very usefull. The Android devices sees a timeout, but that can be caused by a number of things. If there was a SoftDevice assert, or another unhandled error on the nRF side, that would terminate the link immediately, that would cause a timeout (disconnect reason 0x8) on the Android side.

    There are also a number of other potential causes, such as inaccurate sleep clock, so it could be interesting to know your exact 32.768 kHz crystal and which load caps you have used. Though I would expect you should see problems more often if that was the rase.

    Ramesh Polasa said:
    What would you recommend as the next steps to narrow this down?

    Primarily I would start by error logging on the nRF, so that we can see if there are errors or asserts, or unexpected resets. A sniffer trace is also useful, this could show if the nRF simply stops responding (as would be the case of an error), or if the problem could be on the Android side.

    Ramesh Polasa said:
    What is the recommended way to capture callstack and register data if a HardFault or SoftDevice assert ever does occur? I’d like to add a simple blackbox-style capture so I can get the fault context even if the device freezes during long-term operation.

    In case of SoftDevice assert, log the PC of the assert that is passed to the error handler (see app_error_fault_handler() implementation). With this and the exact SoftDevice version I can look up which assert this was in the SoftDevice. For Hardfaults I would start with enabling the HardFault handling library as you have logging. This will then print information about the error in the log. Enable this by setting HARDFAULT_HANDLER_ENABLED to 1 in your sdk_config.h.

Reply
  • Hi,

    Ramesh Polasa said:
    I can share the application logs if that helps.

    Yes, that will be very usefull. The Android devices sees a timeout, but that can be caused by a number of things. If there was a SoftDevice assert, or another unhandled error on the nRF side, that would terminate the link immediately, that would cause a timeout (disconnect reason 0x8) on the Android side.

    There are also a number of other potential causes, such as inaccurate sleep clock, so it could be interesting to know your exact 32.768 kHz crystal and which load caps you have used. Though I would expect you should see problems more often if that was the rase.

    Ramesh Polasa said:
    What would you recommend as the next steps to narrow this down?

    Primarily I would start by error logging on the nRF, so that we can see if there are errors or asserts, or unexpected resets. A sniffer trace is also useful, this could show if the nRF simply stops responding (as would be the case of an error), or if the problem could be on the Android side.

    Ramesh Polasa said:
    What is the recommended way to capture callstack and register data if a HardFault or SoftDevice assert ever does occur? I’d like to add a simple blackbox-style capture so I can get the fault context even if the device freezes during long-term operation.

    In case of SoftDevice assert, log the PC of the assert that is passed to the error handler (see app_error_fault_handler() implementation). With this and the exact SoftDevice version I can look up which assert this was in the SoftDevice. For Hardfaults I would start with enabling the HardFault handling library as you have logging. This will then print information about the error in the log. Enable this by setting HARDFAULT_HANDLER_ENABLED to 1 in your sdk_config.h.

Children
No Data
Related