How to determine anchor point times relative to k_uptime (eg LFCLK)

NCS 2.8.0, NRF52840 with accurate crystal LF CLK

I've been asked to tightly synchronize timestamps for data collected by external sensors on multiple boards.  The timestamps will be based on UTC time as provided by a single/common BLE central. Our boards have very accurate (~5 PPM) LF crystal that we use for our timestamping. I have studied the conn_time_sync example which uses the HCI VS commands to get the anchor point event count and timestamps.

I have created a BLE central that connects to the sensor boards which are acting as peripherals.  It is intended to send a message containing the UTC timestamp at a specific anchor point event.  The peripherals should receive this message, calculate the elapsed time since the anchor point event and adjust the UTC time by the elapsed time.   From the adjusted UTC time they calculate the delta from the LF clock (via k_uptime())   and all future timestamps should then be synchronized.

The problem I've discovered is that the anchor point timestamps are not sourced from the LF_CLK, according to the documentation:

The anchor_point_us in this event is a timestamp on the controller's clock.

The conn_time_sync sample reveals that controller clock is not directly accessible. (to my surprise!)   To workaround this, It starts an additional RTC clock and determines the offset between the RTC0 (controller clock) and the mirror clock during start up, relying on an assumption that the mirrored clock perfectly models the behavior of the controller clock.

Unfortunately for our purposes starting an additional RTC is problematic.  Our devices are battery powered with an extremely limited battery.  (~8mAH) starting an additional RTC will increase the power draw and reduce the operating time.  Furthermore, creating a mirror RTC is in my opinion rather complicated.  The information is present in the system, its just that the soft device controller is not giving access to its version of its clock that includes roll-overs.

1) Is there any other/new API that might make it possible to simply request the controller clock value via the HCI?  

2) Does MPSL perhaps provide a way to get the controller clock?

3) Perhaps there is some way I can determine the time elapsed since the actual anchor point during  the report and record the corresponding LF clock time? 

  • Hi Anthony,

    The problem I've discovered is that the anchor point timestamps are not sourced from the LF_CLK, according to the documentation:

    I think this may be a misunderstanding. There way the 32.768 kHz oscillator is accesses on the nRF52 is via the RTC, which runs direclty from this clock. So when you ahve an accurate 32.768 crystal, this will also be the accuracy of your RTC. Moreover, all RTCs run of the same oscillator, and will be syncrhoneous.

    1) Is there any other/new API that might make it possible to simply request the controller clock value via the HCI?  

    2) Does MPSL perhaps provide a way to get the controller clock?

    No, there is no method to read the RTC value. That said, it is possible to read the RTC directly if you modify the implementation (the nRF52840 as the rest of the nRF52 series is a single core device without TrustZone, so the application can read any peripheral registers). However, the sample implementation also writes to RTC registers (in the mirrored RTC), so you cannot simply switch.

    I have not though this fully through, but it may be possible to don't use an additional RTC instance, but that would requier a re-implementation. If you do not need additional RTC instances, I would not focus much about it, as the current consumption of an additional RTC instance is normally negigable (the current consumption caused by using 1 RTC instance is from the most part caused by the 32.768 kHz clock and regulator, which will not increase by addtion another RTC instance).

Related