apache / mynewt-nimble

Apache mynewt
https://mynewt.apache.org/
Apache License 2.0
664 stars 384 forks source link

NRF52: Use with MCU_LFCLK_SOURCE: LFRC #1207

Open StarGate01 opened 2 years ago

StarGate01 commented 2 years ago

Hi, I want to use Nimble on a NRF52832 board which does not contain an external low frequency crystal (LFXO) - specifically, I want to build InfiniTime for a P8 smartwatch variant. To generate the low frequency clock, a signal can either be synthesized using the internal high frequency clock (LFSYNT), or it can be derived from an integrated RC clock (LFRC): https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Fclock.html .

Using LFSYNT works great, however I would like to use the RC clock (LFRC) due to the high energy usage of the high frequency clock. Unfortunately, Nimble does not function correctly in this mode. Although it does advertise itself via BLE, no connection can be established.

The documentation at https://mynewt.apache.org/latest/network/ble_setup/ble_lp_clock.html does not mention the RC clock anywhere. Is this an unsupported mode? How could I enable this mode? Is these any example code which is known to be working in this configuration? Thanks for any help.

andrzej-kaczmarek commented 2 years ago

LFRC needs to be calibrated to improve accuracy to 500ppm before it can be used as LP clock source for NimBLE. You need to set BLE_LL_SCA: 500 to let NimBLE know accuracy of sleep clock (i.e. 500ppm) and then perform LFRC calibration (I don't think Mynewt does it automatically).

StarGate01 commented 2 years ago

Thank you for the help. I configured the ppm parameter to be 500, and implemented a simple calibration loop:

void calibrate_loop(nrf_drv_clock_evt_type_t event) {
  // 16 * 0.25s = 4s calibration cycle
  nrf_drv_clock_calibration_start(16, calibrate_loop);
}
...
nrf_drv_clock_lfclk_request(NULL);
nrfx_clock_lfclk_start();
#if(CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LFCLK_RC)
    nrf_drv_clock_calibration_start(0, calibrate_loop);
#endif

I have confirmed the LFRC clock to be running by inspecting the registers, and the Nimble BLE link layer seems to be receiving IRQ events from the LPRC associated RTC0 (I think TIMER5 is used) as well.

However, connecting via Bluetooth still fails. Are there any other options I have to configure? Is it possible to somehow validate or debug the timing requirements?

fanoush commented 2 years ago

here is some piece of code to do the calibration that looks a bit different can it be that the calibration loop you have there is somehow stalled and doesn't work correctly? my guess is that if the next scheduling via nrf_drv_clock_calibration_start would fail (because it is still in progress or something) it would simply break the loop and stop.

StarGate01 commented 2 years ago

Thanks for the link, I adjusted the calibration loop to this:

void calibrate_loop(nrf_drv_clock_evt_type_t event) {
  // 10 * 0.25s = 2.5s calibration cycle
  if (event == NRF_DRV_CLOCK_EVT_CAL_DONE) {
    NRF_LOG_INFO("Calibration done, scheduling next one");
    nrf_drv_clock_calibration_start(10, calibrate_loop);
  }
}

I enabled debug output for Nimble and the NRF SDK. It seems that the initialization and calibration loop does its job, at least as far as the NRF SDK is concerned.

<info> CLOCK: Function: nrfx_clock_init, error code: NRF_SUCCESS.
<info> CLOCK: Module enabled.
<info> clock: Function: nrf_drv_clock_init, error code: NRF_SUCCESS.
<warning> clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS.
<warning> CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS.
<info> app: Calibration done, scheduling next one

The following log prints every 2.5s (Lines might be out of order due to threading or RTT buffer latency)

<warning> CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS.
<info> app: Calibration done, scheduling next one
<warning> clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS.

The GAP advertisment call is logged as follows:

GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=0 own_addr_type=1 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0

NRF connect on my phone does only sporadically receive these advertisements.

Once a peer tries to connect, the following is logged:

<info> app: Advertising event : BLE_GAP_EVENT_CONNECT
<info> app: connection established; status=0 
<info> app: [SPIMASTER] Wakeup
<info> app: [TWIMASTER] Wakeup
<info> app: [SpiNorFlash] ID on Wakeup: 21
<info> app: [SpiNorFlash] Wakeup
<info> app: Calibration done, scheduling next one
<warning> clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS.
<info> app: [LCD] Wakeup
GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=0 own_addr_type=1 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0
<info> app: Advertising event : BLE_GAP_EVENT_DISCONNECT
<info> app: disconnect; reason=574
GATT procedure initiated: discover service by uuid; uuid=0x1805
<info> app: [Discovery] Starting discovery
<info> app: [Discovery] Discover next service
<info> app: [CTS] Starting discovery

According to https://mynewt.apache.org/latest/network/ble_hs/ble_hs_return_codes.html, a return code of 574 means "Connection Failed to be Established".

Could the calibration cycle interfere with the Bluetooth functionality?

InfiniTime uses FreeRTOS instead of mynewt, but still uses nimble as a library. Could that cause timing issues?

For reference, I attached two more logs with timestamps. One with LFSYNT and one with LFRC. Using LFSYNT, NRF connect receives an advertisement reliably every ~60 ms, and everything else Bluetooth works as well.

LFSYNT ``` [2022-03-17T23:03:13.800Z, +020441ms] CLOCK: Function: nrfx_clock_init, error code: NRF_SUCCESS. [2022-03-17T23:03:13.800Z, +020441ms] CLOCK: Module enabled. [2022-03-17T23:03:13.800Z, +020441ms] clock: Function: nrf_drv_clock_init, error code: NRF_SUCCESS. [2022-03-17T23:03:13.800Z, +020441ms] app: Logger task started! [2022-03-17T23:03:13.800Z, +020441ms] GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=0 own_addr_type=1 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0 [2022-03-17T23:03:13.800Z, +020441ms] app: systemtask task started! [2022-03-17T23:03:13.800Z, +020441ms] app: Last reset reason : Soft reset [2022-03-17T23:03:13.800Z, +020441ms] app: [SpiNorFlash] Manufacturer : 133, Memory type : 96, memory density : 22 [2022-03-17T23:03:13.865Z, +020506ms] app: DISABLE [2022-03-17T23:03:23.227Z, +029868ms] app: --------------------------------------- [2022-03-17T23:03:23.227Z, +029868ms] Free heap : 840 [2022-03-17T23:03:23.227Z, +029868ms] app: Task [IDL] - 59 [2022-03-17T23:03:23.227Z, +029868ms] app: Task [MAI] - 91 [2022-03-17T23:03:23.227Z, +029868ms] app: Task [dis] - 480 [2022-03-17T23:03:23.227Z, +029868ms] app: Task [LOG] - 104 [2022-03-17T23:03:23.227Z, +029868ms] app: Task [Tmr] - 245 [2022-03-17T23:03:23.227Z, +029868ms] app: Task [Hea] - 427 [2022-03-17T23:03:23.227Z, +029868ms] app: Task [ll] - 472 [2022-03-17T23:03:23.227Z, +029868ms] app: Task [ble] - 431 [2022-03-17T23:03:26.868Z, +033508ms] app: DimTimerCallback [2022-03-17T23:03:26.868Z, +033508ms] app: Dim timeout -> Dim screen [2022-03-17T23:03:28.834Z, +035474ms] app: IdleTimerCallback [2022-03-17T23:03:28.834Z, +035474ms] app: Idle timeout -> Going to sleep [2022-03-17T23:03:28.834Z, +035474ms] app: [systemtask] Going to sleep [2022-03-17T23:03:28.834Z, +035474ms] app: DISABLE [2022-03-17T23:03:29.420Z, +036061ms] app: [LCD] Sleep [2022-03-17T23:03:29.420Z, +036061ms] app: [SPIMASTER] sleep [2022-03-17T23:03:29.420Z, +036061ms] app: [TWIMASTER] Sleep [2022-03-17T23:03:32.982Z, +039622ms] app: --------------------------------------- [2022-03-17T23:03:32.982Z, +039622ms] Free heap : 840 [2022-03-17T23:03:32.982Z, +039622ms] app: Task [MAI] - 91 [2022-03-17T23:03:32.982Z, +039622ms] app: Task [IDL] - 59 [2022-03-17T23:03:32.982Z, +039622ms] app: Task [Tmr] - 245 [2022-03-17T23:03:32.982Z, +039622ms] app: Task [LOG] - 104 [2022-03-17T23:03:32.982Z, +039622ms] app: Task [dis] - 480 [2022-03-17T23:03:32.982Z, +039622ms] app: Task [ll] - 472 [2022-03-17T23:03:32.982Z, +039622ms] app: Task [ble] - 431 [2022-03-17T23:03:32.982Z, +039622ms] app: Task [Hea] - 427 [2022-03-17T23:03:36.137Z, +042778ms] app: Advertising event : BLE_GAP_EVENT_CONNECT [2022-03-17T23:03:36.137Z, +042778ms] app: connection established; status=0 [2022-03-17T23:03:36.137Z, +042778ms] app: [SPIMASTER] Wakeup [2022-03-17T23:03:36.137Z, +042778ms] app: [TWIMASTER] Wakeup [2022-03-17T23:03:36.137Z, +042778ms] app: [SpiNorFlash] ID on Wakeup: 21 [2022-03-17T23:03:36.137Z, +042778ms] app: [SpiNorFlash] Wakeup [2022-03-17T23:03:36.330Z, +042971ms] app: [LCD] Wakeup [2022-03-17T23:03:36.703Z, +043343ms] GATT procedure initiated: discover service by uuid; uuid=0x1805 [2022-03-17T23:03:36.723Z, +043364ms] app: [Discovery] Starting discovery [2022-03-17T23:03:36.723Z, +043364ms] app: [Discovery] Discover next service [2022-03-17T23:03:36.723Z, +043364ms] app: [CTS] Starting discovery [2022-03-17T23:03:36.763Z, +043404ms] GATT procedure initiated: discover service by uuid; uuid=0x1811 [2022-03-17T23:03:36.816Z, +043457ms] app: Advertising event : BLE_GAP_EVENT_CONN_UPDATE [2022-03-17T23:03:36.816Z, +043457ms] app: connection updated; status=0 [2022-03-17T23:03:36.816Z, +043457ms] app: CTS not found [2022-03-17T23:03:36.816Z, +043457ms] app: [Discovery] Discover next service [2022-03-17T23:03:36.816Z, +043457ms] app: [ANS] Starting discovery [2022-03-17T23:03:36.816Z, +043457ms] app: ANS not found [2022-03-17T23:03:36.816Z, +043457ms] app: End of service discovery [2022-03-17T23:03:37.907Z, +044548ms] app: Advertising event : BLE_GAP_EVENT_CONN_UPDATE [2022-03-17T23:03:37.907Z, +044548ms] app: connection updated; status=0 [2022-03-17T23:03:42.826Z, +049467ms] app: --------------------------------------- [2022-03-17T23:03:42.826Z, +049467ms] Free heap : 728 [2022-03-17T23:03:42.826Z, +049467ms] app: Task [MAI] - 91 [2022-03-17T23:03:42.826Z, +049467ms] app: Task [IDL] - 59 [2022-03-17T23:03:42.826Z, +049467ms] app: Task [dis] - 480 [2022-03-17T23:03:42.826Z, +049467ms] app: Task [LOG] - 104 [2022-03-17T23:03:42.826Z, +049467ms] app: Task [Tmr] - 245 [2022-03-17T23:03:42.826Z, +049467ms] app: Task [Hea] - 427 [2022-03-17T23:03:42.826Z, +049467ms] app: Task [ll] - 446 [2022-03-17T23:03:42.826Z, +049467ms] app: Task [ble] - 294 [2022-03-17T23:03:49.122Z, +055763ms] app: DimTimerCallback [2022-03-17T23:03:49.122Z, +055763ms] app: Dim timeout -> Dim screen [2022-03-17T23:03:50.402Z, +057043ms] GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=0 own_addr_type=1 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0 [2022-03-17T23:03:50.495Z, +057135ms] app: Advertising event : BLE_GAP_EVENT_DISCONNECT [2022-03-17T23:03:50.495Z, +057135ms] app: disconnect; reason=531 [2022-03-17T23:03:51.180Z, +057820ms] app: IdleTimerCallback [2022-03-17T23:03:51.180Z, +057820ms] app: Idle timeout -> Going to sleep [2022-03-17T23:03:51.180Z, +057820ms] app: [systemtask] Going to sleep [2022-03-17T23:03:51.180Z, +057820ms] app: DISABLE [2022-03-17T23:03:51.764Z, +058405ms] app: [LCD] Sleep [2022-03-17T23:03:51.764Z, +058405ms] app: [SPIMASTER] sleep [2022-03-17T23:03:51.764Z, +058405ms] app: [TWIMASTER] Sleep [2022-03-17T23:03:52.662Z, +059303ms] app: --------------------------------------- [2022-03-17T23:03:52.662Z, +059303ms] Free heap : 728 [2022-03-17T23:03:52.662Z, +059303ms] app: Task [MAI] - 91 [2022-03-17T23:03:52.662Z, +059303ms] app: Task [IDL] - 59 [2022-03-17T23:03:52.662Z, +059303ms] app: Task [Tmr] - 245 [2022-03-17T23:03:52.662Z, +059303ms] app: Task [LOG] - 104 [2022-03-17T23:03:52.662Z, +059303ms] app: Task [Hea] - 427 [2022-03-17T23:03:52.662Z, +059303ms] app: Task [dis] - 480 [2022-03-17T23:03:52.662Z, +059303ms] app: Task [ll] - 446 [2022-03-17T23:03:52.662Z, +059303ms] app: Task [ble] - 294 RTT connection on TCP port 19021 ended. Waiting for next connection... ``` Disconnect reason 531 is "Remote User Terminated Connection", I disconnected manually on my phone.
LFRC ``` [2022-03-17T23:11:00.405Z, +018748ms] CLOCK: Function: nrfx_clock_init, error code: NRF_SUCCESS. [2022-03-17T23:11:00.405Z, +018748ms] CLOCK: Module enabled. [2022-03-17T23:11:00.405Z, +018748ms] clock: Function: nrf_drv_clock_init, error code: NRF_SUCCESS. [2022-03-17T23:11:00.405Z, +018748ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:00.405Z, +018748ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:00.405Z, +018748ms] app: Logger task started! [2022-03-17T23:11:00.405Z, +018748ms] GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=0 own_addr_type=1 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0 [2022-03-17T23:11:00.426Z, +018770ms] app: DISABLE [2022-03-17T23:11:01.214Z, +019558ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:01.214Z, +019558ms] app: Calibration done, scheduling next one [2022-03-17T23:11:01.214Z, +019558ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:03.674Z, +022017ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:03.674Z, +022017ms] app: Calibration done, scheduling next one [2022-03-17T23:11:03.674Z, +022017ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:06.232Z, +024576ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:06.232Z, +024576ms] app: Calibration done, scheduling next one [2022-03-17T23:11:06.232Z, +024576ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:08.694Z, +027038ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:08.694Z, +027038ms] app: Calibration done, scheduling next one [2022-03-17T23:11:08.694Z, +027038ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:09.776Z, +028119ms] app: --------------------------------------- [2022-03-17T23:11:09.776Z, +028119ms] Free heap : 840 [2022-03-17T23:11:09.787Z, +028131ms] app: Task [MAI] - 95 [2022-03-17T23:11:09.787Z, +028131ms] app: Task [IDL] - 59 [2022-03-17T23:11:09.787Z, +028131ms] app: Task [Hea] - 427 [2022-03-17T23:11:09.787Z, +028131ms] app: Task [LOG] - 104 [2022-03-17T23:11:09.787Z, +028131ms] app: Task [Tmr] - 245 [2022-03-17T23:11:09.787Z, +028131ms] app: Task [dis] - 471 [2022-03-17T23:11:09.787Z, +028131ms] app: Task [ll] - 472 [2022-03-17T23:11:09.787Z, +028131ms] app: Task [ble] - 431 [2022-03-17T23:11:11.255Z, +029599ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:11.255Z, +029599ms] app: Calibration done, scheduling next one [2022-03-17T23:11:11.255Z, +029599ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:13.421Z, +031765ms] app: DimTimerCallback [2022-03-17T23:11:13.421Z, +031765ms] app: Dim timeout -> Dim screen [2022-03-17T23:11:13.813Z, +032156ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:13.813Z, +032156ms] app: Calibration done, scheduling next one [2022-03-17T23:11:13.813Z, +032156ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:15.385Z, +033729ms] app: IdleTimerCallback [2022-03-17T23:11:15.385Z, +033729ms] app: Idle timeout -> Going to sleep [2022-03-17T23:11:15.385Z, +033729ms] app: [systemtask] Going to sleep [2022-03-17T23:11:15.385Z, +033729ms] app: DISABLE [2022-03-17T23:11:16.069Z, +034413ms] app: [LCD] Sleep [2022-03-17T23:11:16.069Z, +034413ms] app: [SPIMASTER] sleep [2022-03-17T23:11:16.069Z, +034413ms] app: [TWIMASTER] Sleep [2022-03-17T23:11:16.266Z, +034609ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:16.266Z, +034609ms] app: Calibration done, scheduling next one [2022-03-17T23:11:16.266Z, +034609ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:18.832Z, +037176ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:18.832Z, +037176ms] app: Calibration done, scheduling next one [2022-03-17T23:11:18.832Z, +037176ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:19.627Z, +037971ms] app: --------------------------------------- [2022-03-17T23:11:19.627Z, +037971ms] Free heap : 840 [2022-03-17T23:11:19.627Z, +037971ms] app: Task [MAI] - 95 [2022-03-17T23:11:19.627Z, +037971ms] app: Task [IDL] - 59 [2022-03-17T23:11:19.627Z, +037971ms] app: Task [Tmr] - 245 [2022-03-17T23:11:19.627Z, +037971ms] app: Task [LOG] - 104 [2022-03-17T23:11:19.627Z, +037971ms] app: Task [dis] - 471 [2022-03-17T23:11:19.627Z, +037971ms] app: Task [ll] - 472 [2022-03-17T23:11:19.627Z, +037971ms] app: Task [ble] - 431 [2022-03-17T23:11:19.627Z, +037971ms] app: Task [Hea] - 427 [2022-03-17T23:11:21.299Z, +039643ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:21.299Z, +039643ms] app: Calibration done, scheduling next one [2022-03-17T23:11:21.299Z, +039643ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:23.866Z, +042209ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:23.866Z, +042209ms] app: Calibration done, scheduling next one [2022-03-17T23:11:23.866Z, +042209ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:26.327Z, +044670ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:26.327Z, +044670ms] app: Calibration done, scheduling next one [2022-03-17T23:11:26.327Z, +044670ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:28.898Z, +047241ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:28.898Z, +047241ms] app: Calibration done, scheduling next one [2022-03-17T23:11:28.898Z, +047241ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:29.395Z, +047739ms] app: --------------------------------------- [2022-03-17T23:11:29.395Z, +047739ms] Free heap : 840 [2022-03-17T23:11:29.395Z, +047739ms] app: Task [MAI] - 95 [2022-03-17T23:11:29.395Z, +047739ms] app: Task [IDL] - 59 [2022-03-17T23:11:29.395Z, +047739ms] app: Task [Tmr] - 245 [2022-03-17T23:11:29.395Z, +047739ms] app: Task [LOG] - 104 [2022-03-17T23:11:29.395Z, +047739ms] app: Task [ble] - 431 [2022-03-17T23:11:29.395Z, +047739ms] app: Task [ll] - 472 [2022-03-17T23:11:29.395Z, +047739ms] app: Task [Hea] - 427 [2022-03-17T23:11:29.395Z, +047739ms] app: Task [dis] - 471 [2022-03-17T23:11:31.370Z, +049714ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:31.370Z, +049714ms] app: Calibration done, scheduling next one [2022-03-17T23:11:31.370Z, +049714ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:33.937Z, +052280ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:33.937Z, +052280ms] app: Calibration done, scheduling next one [2022-03-17T23:11:33.937Z, +052280ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:36.405Z, +054749ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:36.405Z, +054749ms] app: Calibration done, scheduling next one [2022-03-17T23:11:36.405Z, +054749ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:38.976Z, +057319ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:38.976Z, +057319ms] app: Calibration done, scheduling next one [2022-03-17T23:11:38.976Z, +057319ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:39.173Z, +057516ms] app: --------------------------------------- [2022-03-17T23:11:39.173Z, +057516ms] Free heap : 840 [2022-03-17T23:11:39.173Z, +057516ms] app: Task [MAI] - 95 [2022-03-17T23:11:39.173Z, +057516ms] app: Task [IDL] - 59 [2022-03-17T23:11:39.173Z, +057516ms] app: Task [Tmr] - 245 [2022-03-17T23:11:39.173Z, +057516ms] app: Task [LOG] - 104 [2022-03-17T23:11:39.173Z, +057516ms] app: Task [Hea] - 427 [2022-03-17T23:11:39.173Z, +057516ms] app: Task [ll] - 472 [2022-03-17T23:11:39.173Z, +057516ms] app: Task [dis] - 471 [2022-03-17T23:11:39.173Z, +057516ms] app: Task [ble] - 431 [2022-03-17T23:11:41.438Z, +059782ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:41.438Z, +059782ms] app: Calibration done, scheduling next one [2022-03-17T23:11:41.438Z, +059782ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:43.999Z, +062342ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:43.999Z, +062342ms] app: Calibration done, scheduling next one [2022-03-17T23:11:43.999Z, +062342ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:46.471Z, +064815ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:46.471Z, +064815ms] app: Calibration done, scheduling next one [2022-03-17T23:11:46.471Z, +064815ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:48.937Z, +067281ms] app: --------------------------------------- [2022-03-17T23:11:48.937Z, +067281ms] Free heap : 840 [2022-03-17T23:11:48.947Z, +067291ms] app: Task [MAI] - 95 [2022-03-17T23:11:48.947Z, +067291ms] app: Task [IDL] - 59 [2022-03-17T23:11:48.947Z, +067291ms] app: Task [Tmr] - 245 [2022-03-17T23:11:48.947Z, +067291ms] app: Task [LOG] - 104 [2022-03-17T23:11:48.947Z, +067291ms] app: Task [dis] - 471 [2022-03-17T23:11:48.947Z, +067291ms] app: Task [ll] - 472 [2022-03-17T23:11:48.947Z, +067291ms] app: Task [ble] - 431 [2022-03-17T23:11:48.947Z, +067291ms] app: Task [Hea] - 427 [2022-03-17T23:11:49.034Z, +067377ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:49.034Z, +067377ms] app: Advertising event : BLE_GAP_EVENT_CONNECT [2022-03-17T23:11:49.034Z, +067377ms] app: connection established; status=0 [2022-03-17T23:11:49.034Z, +067377ms] app: [SPIMASTER] Wakeup [2022-03-17T23:11:49.034Z, +067377ms] app: [TWIMASTER] Wakeup [2022-03-17T23:11:49.034Z, +067377ms] app: [SpiNorFlash] ID on Wakeup: 21 [2022-03-17T23:11:49.034Z, +067377ms] app: [SpiNorFlash] Wakeup [2022-03-17T23:11:49.034Z, +067377ms] app: Calibration done, scheduling next one [2022-03-17T23:11:49.034Z, +067377ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:49.228Z, +067572ms] app: [LCD] Wakeup [2022-03-17T23:11:49.239Z, +067583ms] GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=0 own_addr_type=1 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0 [2022-03-17T23:11:49.334Z, +067678ms] app: Advertising event : BLE_GAP_EVENT_DISCONNECT [2022-03-17T23:11:49.334Z, +067678ms] app: disconnect; reason=574 [2022-03-17T23:11:49.548Z, +067891ms] GATT procedure initiated: discover service by uuid; uuid=0x1805 [2022-03-17T23:11:49.630Z, +067974ms] app: [Discovery] Starting discovery [2022-03-17T23:11:49.630Z, +067974ms] app: [Discovery] Discover next service [2022-03-17T23:11:49.630Z, +067974ms] app: [CTS] Starting discovery [2022-03-17T23:11:51.501Z, +069844ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:51.501Z, +069844ms] app: Calibration done, scheduling next one [2022-03-17T23:11:51.501Z, +069844ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:54.060Z, +072403ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:54.060Z, +072403ms] app: Calibration done, scheduling next one [2022-03-17T23:11:54.060Z, +072403ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:56.521Z, +074865ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:56.521Z, +074865ms] app: Calibration done, scheduling next one [2022-03-17T23:11:56.521Z, +074865ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:58.801Z, +077145ms] app: --------------------------------------- [2022-03-17T23:11:58.801Z, +077145ms] Free heap : 728 [2022-03-17T23:11:58.801Z, +077145ms] app: Task [MAI] - 95 [2022-03-17T23:11:58.801Z, +077145ms] app: Task [IDL] - 59 [2022-03-17T23:11:58.801Z, +077145ms] app: Task [Hea] - 427 [2022-03-17T23:11:58.801Z, +077145ms] app: Task [LOG] - 104 [2022-03-17T23:11:58.801Z, +077145ms] app: Task [Tmr] - 245 [2022-03-17T23:11:58.801Z, +077145ms] app: Task [dis] - 471 [2022-03-17T23:11:58.801Z, +077145ms] app: Task [ll] - 448 [2022-03-17T23:11:58.801Z, +077145ms] app: Task [ble] - 301 [2022-03-17T23:11:59.082Z, +077426ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:11:59.082Z, +077426ms] app: Calibration done, scheduling next one [2022-03-17T23:11:59.082Z, +077426ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:01.549Z, +079893ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:01.640Z, +079984ms] app: Calibration done, scheduling next one [2022-03-17T23:12:01.640Z, +079984ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:02.032Z, +080375ms] app: DimTimerCallback [2022-03-17T23:12:02.032Z, +080375ms] app: Dim timeout -> Dim screen [2022-03-17T23:12:04.006Z, +082350ms] app: IdleTimerCallback [2022-03-17T23:12:04.006Z, +082350ms] app: Idle timeout -> Going to sleep [2022-03-17T23:12:04.006Z, +082350ms] app: [systemtask] Going to sleep [2022-03-17T23:12:04.006Z, +082350ms] app: DISABLE [2022-03-17T23:12:04.104Z, +082448ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:04.104Z, +082448ms] app: Advertising event : BLE_GAP_EVENT_CONNECT [2022-03-17T23:12:04.104Z, +082448ms] app: connection established; status=0 [2022-03-17T23:12:04.104Z, +082448ms] app: Calibration done, scheduling next one [2022-03-17T23:12:04.104Z, +082448ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:04.333Z, +082676ms] GAP procedure initiated: advertise; disc_mode=2[2022-03-17T23:12:04.343Z, +082687ms] adv_channel_map=0 own_addr_type=1 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0 [2022-03-17T23:12:04.405Z, +082748ms] app: Advertising event : BLE_GAP_EVENT_DISCONNECT [2022-03-17T23:12:04.405Z, +082748ms] app: disconnect; reason=574 [2022-03-17T23:12:04.548Z, +082892ms] GATT procedure initiated: discover service by uuid; uuid=0x1805 [2022-03-17T23:12:04.601Z, +082944ms] app: [Discovery] Starting discovery [2022-03-17T23:12:04.601Z, +082944ms] app: [Discovery] Discover next service [2022-03-17T23:12:04.601Z, +082944ms] app: [CTS] Starting discovery [2022-03-17T23:12:04.601Z, +082944ms] app: [LCD] Sleep [2022-03-17T23:12:04.601Z, +082944ms] app: [SPIMASTER] sleep [2022-03-17T23:12:04.601Z, +082944ms] app: [TWIMASTER] Sleep [2022-03-17T23:12:06.659Z, +085002ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:06.659Z, +085002ms] app: Calibration done, scheduling next one [2022-03-17T23:12:06.659Z, +085002ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:08.538Z, +086881ms] app: --------------------------------------- [2022-03-17T23:12:08.538Z, +086881ms] Free heap : 728 [2022-03-17T23:12:08.538Z, +086881ms] app: Task [MAI] - 95 [2022-03-17T23:12:08.538Z, +086881ms] app: Task [IDL] - 59 [2022-03-17T23:12:08.538Z, +086881ms] app: Task [Tmr] - 245 [2022-03-17T23:12:08.538Z, +086881ms] app: Task [LOG] - 104 [2022-03-17T23:12:08.538Z, +086881ms] app: Task [dis] - 471 [2022-03-17T23:12:08.538Z, +086881ms] app: Task [ll] - 448 [2022-03-17T23:12:08.538Z, +086881ms] app: Task [Hea] - 421 [2022-03-17T23:12:08.538Z, +086881ms] app: Task [ble] - 301 [2022-03-17T23:12:09.123Z, +087467ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:09.123Z, +087467ms] app: Calibration done, scheduling next one [2022-03-17T23:12:09.123Z, +087467ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:11.691Z, +090035ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:11.691Z, +090035ms] app: Calibration done, scheduling next one [2022-03-17T23:12:11.691Z, +090035ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:14.154Z, +092498ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:14.154Z, +092498ms] app: Calibration done, scheduling next one [2022-03-17T23:12:14.154Z, +092498ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:16.726Z, +095070ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:16.726Z, +095070ms] app: Calibration done, scheduling next one [2022-03-17T23:12:16.726Z, +095070ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:18.397Z, +096740ms] app: --------------------------------------- [2022-03-17T23:12:18.397Z, +096740ms] Free heap : 728 [2022-03-17T23:12:18.397Z, +096740ms] app: Task [MAI] - 95 [2022-03-17T23:12:18.397Z, +096740ms] app: Task [IDL] - 59 [2022-03-17T23:12:18.397Z, +096740ms] app: Task [Tmr] - 245 [2022-03-17T23:12:18.397Z, +096740ms] app: Task [LOG] - 104 [2022-03-17T23:12:18.397Z, +096740ms] app: Task [Hea] - 421 [2022-03-17T23:12:18.397Z, +096740ms] app: Task [ll] - 448 [2022-03-17T23:12:18.397Z, +096740ms] app: Task [ble] - 301 [2022-03-17T23:12:18.397Z, +096740ms] app: Task [dis] - 471 [2022-03-17T23:12:19.189Z, +097532ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:19.189Z, +097532ms] app: Calibration done, scheduling next one [2022-03-17T23:12:19.189Z, +097532ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:21.751Z, +100095ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:21.751Z, +100095ms] app: Calibration done, scheduling next one [2022-03-17T23:12:21.751Z, +100095ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:24.218Z, +102562ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:24.218Z, +102562ms] app: Calibration done, scheduling next one [2022-03-17T23:12:24.218Z, +102562ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:26.780Z, +105123ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:26.780Z, +105123ms] app: Calibration done, scheduling next one [2022-03-17T23:12:26.780Z, +105123ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:28.168Z, +106511ms] app: --------------------------------------- [2022-03-17T23:12:28.168Z, +106511ms] Free heap : 728 [2022-03-17T23:12:28.168Z, +106511ms] app: Task [MAI] - 95 [2022-03-17T23:12:28.168Z, +106511ms] app: Task [IDL] - 59 [2022-03-17T23:12:28.168Z, +106511ms] app: Task [Tmr] - 245 [2022-03-17T23:12:28.168Z, +106511ms] app: Task [LOG] - 104 [2022-03-17T23:12:28.168Z, +106511ms] app: Task [ble] - 301 [2022-03-17T23:12:28.168Z, +106511ms] app: Task [ll] - 448 [2022-03-17T23:12:28.168Z, +106511ms] app: Task [dis] - 471 [2022-03-17T23:12:28.168Z, +106511ms] app: Task [Hea] - 421 [2022-03-17T23:12:29.242Z, +107586ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:29.242Z, +107586ms] app: Calibration done, scheduling next one [2022-03-17T23:12:29.242Z, +107586ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:31.801Z, +110145ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:31.801Z, +110145ms] app: Calibration done, scheduling next one [2022-03-17T23:12:31.801Z, +110145ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:34.265Z, +112608ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:34.265Z, +112608ms] app: Advertising event : BLE_GAP_EVENT_CONNECT [2022-03-17T23:12:34.265Z, +112608ms] app: connection established; status=0 [2022-03-17T23:12:34.276Z, +112620ms] app: [SPIMASTER] Wakeup [2022-03-17T23:12:34.276Z, +112620ms] app: [TWIMASTER] Wakeup [2022-03-17T23:12:34.276Z, +112620ms] app: [SpiNorFlash] ID on Wakeup: 21 [2022-03-17T23:12:34.276Z, +112620ms] app: [SpiNorFlash] Wakeup [2022-03-17T23:12:34.276Z, +112620ms] app: Calibration done, scheduling next one [2022-03-17T23:12:34.276Z, +112620ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:34.466Z, +112809ms] app: [LCD] Wakeup [2022-03-17T23:12:34.558Z, +112902ms] GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=0 own_addr_type=1 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0 [2022-03-17T23:12:34.558Z, +112902ms] app: Advertising event : BLE_GAP_EVENT_DISCONNECT [2022-03-17T23:12:34.558Z, +112902ms] app: disconnect; reason=574 [2022-03-17T23:12:34.854Z, +113198ms] GATT procedure initiated: discover service by uuid; uuid=0x1805 [2022-03-17T23:12:34.864Z, +113208ms] app: [Discovery] Starting discovery [2022-03-17T23:12:34.864Z, +113208ms] app: [Discovery] Discover next service [2022-03-17T23:12:34.864Z, +113208ms] app: [CTS] Starting discovery [2022-03-17T23:12:36.823Z, +115167ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:36.834Z, +115177ms] app: Calibration done, scheduling next one [2022-03-17T23:12:36.834Z, +115177ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:38.010Z, +116354ms] app: --------------------------------------- [2022-03-17T23:12:38.010Z, +116354ms] Free heap : 728 [2022-03-17T23:12:38.010Z, +116354ms] app: Task [dis] - 471 [2022-03-17T23:12:38.010Z, +116354ms] app: Task [IDL] - 59 [2022-03-17T23:12:38.010Z, +116354ms] app: Task [MAI] - 95 [2022-03-17T23:12:38.010Z, +116354ms] app: Task [Hea] - 421 [2022-03-17T23:12:38.010Z, +116354ms] app: Task [Tmr] - 245 [2022-03-17T23:12:38.010Z, +116354ms] app: Task [LOG] - 104 [2022-03-17T23:12:38.010Z, +116354ms] app: Task [ll] - 448 [2022-03-17T23:12:38.010Z, +116354ms] app: Task [ble] - 301 [2022-03-17T23:12:39.379Z, +117722ms] CLOCK: Function: nrfx_clock_calibration_start, error code: NRF_SUCCESS. [2022-03-17T23:12:39.379Z, +117722ms] app: Calibration done, scheduling next one [2022-03-17T23:12:39.379Z, +117722ms] clock: Function: nrf_drv_clock_calibration_start, error code: NRF_SUCCESS. RTT connection on TCP port 19021 ended. Waiting for next connection... ``` I tried to connect three times. It took a while until I received the first advertisement.

Using a debugger, I found that ble_ll_com.c:ble_ll_conn_event_start_cb gets called very late, instead of pretty much instantly (like when using HFSYNT) when a phone tries to conenct. The disconnection event ble_ll_conn_event_end is fired directly after.

The callstack looks like this:

ble_ll_conn_event_start_cb@0x00021054 (libs/mynewt-nimble/nimble/controller/src/ble_ll_conn.c:1346)
ble_ll_sched_execute_item@0x00026fea (libs/mynewt-nimble/nimble/controller/src/ble_ll_sched.c:1475)
ble_ll_sched_run@0x00027046 (libs/mynewt-nimble/nimble/controller/src/ble_ll_sched.c:1513)
hal_timer_chk_queue@0x000286c4 (libs/mynewt-nimble/porting/nimble/src/hal_timer.c:275)
hal_rtc_timer_irq_handler@0x00028736 (libs/mynewt-nimble/porting/nimble/src/hal_timer.c:383)
nrf52_timer5_irq_handler@0x00028744 (libs/mynewt-nimble/porting/nimble/src/hal_timer.c:434)
RTC0_IRQHandler@0x0000ba4c (main.cpp:223)
<signal handler called>@0xffffffed (Unknown Source:0)

So maybe the BLE event handler queue is not processed fast enough? Or there is no event generated in time because of timing issues?

Since this code differs from the upstream nimble, (according to the InfiniTime commit log, the version bundled with InfiniTime 1.3.0 is nimble 1.3 master, commit 82153e744833821e20e9a8b0d61c38b2b0dbcfe1), I tried to update the included nimble to the most recent master - however, I was not able to successfully compile that combination yet.

Thank you for your continued help.

StarGate01 commented 2 years ago

I fixed the problem, I adjusted the file nimble/drivers/nrf52/src/ble_phys.c as follows:

(In the Nimble upstream this is nrf_clock_task_trigger, but that function does the exact same thing)

The nrf_drv_clock_hfclock_* functions maintain an internal usage count to decide if the HF clock should be stopped or started, and since the HF clock is used for LF RC calibration as well I suspect that could have cause some contention issues.

I fixed this in my InfiniTime fork (see https://github.com/StarGate01/InfiniTime/commit/8878206c3a1646c85f111637f3138cce4369cb26). Since Nimble does not depend (I think) on the NRF SDK and its clock functions so far, I am hesitant to upstream this change. What do you think? How could the LFRC calibration / RFCLK-HFCLK contention be resolved?

andrzej-kaczmarek commented 2 years ago

@StarGate01 we probably don't want to introduce dependency to nRF SDK, but recently we switched that code to use nrfx anyway (i.e. nrf_clock_task_trigger instead of using NRF_CLOCK->TASK_... directly) so if there's refcounting equivalent in nrfx for hfclk it can be used upstream

StarGate01 commented 2 years ago

@andrzej-kaczmarek Okay. It seems that the nrfx libs have no functionality to perform that reference counting, compare https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_clock.c and https://github.com/jamesmunns/nRF5-sdk/blob/master/components/drivers_nrf/clock/nrf_drv_clock.c .

I thought about checking nrfx_clock_is_calibrating before turning the hfclock off in ble_phy_rfclk_disable, which would probably work. However, the calibration procedure could still turn off the hfclock once it is done, even though the bletooth stack is currently using it.

What do you think about using a weak symbol? Defining something like

__weak void nrf_drv_clock_hfclk_request(void * p_handler_item) {
    nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART);
}

should work (?)

The same would have to be done with nrf_drv_clock_init, which initializes the refcounter.

sjanc commented 2 years ago

is this issues solved or something stil should be done on nimble side?

StarGate01 commented 2 years ago

I resolved the issue in the code I work on by applying the modification detailed above. However, that was in a custom fork of Nimble. My idea was to upstream this patch, even though I don't need it there anymore.