Open StarGate01 opened 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).
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?
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.
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.
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.