#### Re: NRF52 and timing - actual state and what functions to use?

Martin Kozusky

Dne 06.01.2020 v 18:31 Andy Ross napsal(a):
On 1/5/20 4:30 AM, Martin Kozusky [newsgroups] wrote:
1 - what is the best solution to call my function every 1ms (or will
it be 1.007ms?), is it ok just to use k_timer? Is "next expiration
time" calculated just by adding period to current time (that would
make a big time diff after many calls) or does it use
k_uptime_get*number of expirations to calculate next expiration
time?
Periodic k_timer's do not work in fractional ticks, no. If you
schedule a 1000ms timeout it will be rounded up internally to exactly
33 hardware cycles, and that process will repeat each cycle.  So you
would see the ~993 Hz tick rate you calculated.  If you want to work
in fractional ticks, the application needs to do that math itself.
is it 1000ms timeout = 33 cycles, or 1ms timeout = 33 cycles? This is acceptable for short-term timeouts.

2 - what is the best solution for most precise long-term time
keeping?  Let's say i don't want more that 1 minute diff in 20
days. Can I just use k_uptime_get?
Long term time is kept as a 64 bit count of ticks, so it's not subject
to the kind of round-off errors that periodic timers are.  As long as
your app isn't dropping or delaying the counter interrupts, the uptime
value should be as accurate as your crystal is.

If you want to get 1 callback per second as a long term average, you
can (with care) compute your timeout as an offset from system start or
some other time reference instead of "now" (i.e. the Nth timeout will
happen at "N * 1000ms", plus a little precision slop due to the clock
mismatch).  There's actually an API change which will make this kind
of code significantly easier, see
https://github.com/zephyrproject-rtos/zephyr/issues/21305
When this gets into 2.2, can I use "k_uptime_ticks() / 32768" to get the exact time in seconds?

As far as using a different oscillator to drive the timer, that's
possible but requires some driver fiddling.  I'll let the Nordic folks
speak to that.  One option might be to use the generic ARM SysTick
driver, which doesn't have the rate mismatch issues of the 32kHz
timer, but doesn't have the low power idle characteristics.
On another project, I would like to be sleeping most of the time to save power and want to be woken by pin interrupt or 1 sec timeout, so it is good idea to have clock in low-power.

BTW: When I enter to sleep by k_sleep(), is there  any change in power consumption besides thread being put to sleep? Or do I have to call device_set_power_state(DEVICE_PM_LOW_POWER_STATE) to enter low-power mode? Will I be automaticaly put to DEVICE_PM_ACTIVE_STATE when there is an pin interrupt and is there any way how to get number of ticks I've been in low-power mode since I was woken by pin interrupt? (are ticks also incremented in low-power mode?) (on bare-metal I would set RTC modulo to wake after 1 second, go to low-power and if I got woken earlier by pin interrupt, I would read RTC counter to get the exact time I was sleeping or if I got woken by RTC INT, I would know it was exactly 1 sec, then do some stuff, again setup RTC, go to sleep  ... is this even possible with Zephyr and NRF52832? )

Andy
Thanks,
Martin