samd/modtime: Change time.time_ns() to follow the RTC time.

That is done by adding the offset to epoch, following the scheme from the
RP2 port.  RTC and `ticks_us()` are not precisely in sync, and so the
difference between `time.time_ns()/1e9` and `time.time()` will increase by
more than 9 seconds/24h.  So applications should avoid using `time.time()`
and `time.time_ns()` in the same context.

Signed-off-by: robert-hh <robert@hammelrath.com>
This commit is contained in:
robert-hh 2025-03-26 09:24:19 +01:00 committed by Damien George
parent 2fda4bbe05
commit ff9e01782b
4 changed files with 18 additions and 4 deletions

View file

@ -133,6 +133,7 @@ static mp_obj_t machine_rtc_datetime_helper(size_t n_args, const mp_obj_t *args,
}
#endif
mp_hal_time_ns_set_from_rtc();
return mp_const_none;
}
}

View file

@ -28,6 +28,7 @@
#include "py/runtime.h"
#include "py/gc.h"
#include "py/mperrno.h"
#include "py/mphal.h"
#include "py/stackctrl.h"
#include "shared/readline/readline.h"
#include "shared/runtime/gchelper.h"
@ -45,6 +46,7 @@ extern void sercom_deinit_all(void);
void samd_main(void) {
mp_stack_set_top(&_estack);
mp_stack_set_limit(&_estack - &_sstack - 1024);
mp_hal_time_ns_set_from_rtc();
for (;;) {
gc_init(&_sheap, &_eheap);

View file

@ -28,6 +28,8 @@
#include "shared/timeutils/timeutils.h"
#include "modmachine.h"
static uint64_t time_us_64_offset_from_epoch;
// Return the localtime as an 8-tuple.
static mp_obj_t mp_time_localtime_get(void) {
timeutils_struct_time_t tm;
@ -54,3 +56,15 @@ static mp_obj_t mp_time_time_get(void) {
return mp_obj_new_int_from_uint(timeutils_mktime(
tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec));
}
void mp_hal_time_ns_set_from_rtc(void) {
timeutils_struct_time_t tm;
rtc_gettime(&tm);
uint64_t time_us = (uint64_t)timeutils_mktime(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour,
tm.tm_min, tm.tm_sec) * 1000000ULL;
time_us_64_offset_from_epoch = time_us - mp_hal_ticks_us_64();
}
uint64_t mp_hal_time_ns(void) {
return (time_us_64_offset_from_epoch + mp_hal_ticks_us_64()) * 1000ULL;
}

View file

@ -47,6 +47,7 @@ extern int mp_interrupt_char;
extern ringbuf_t stdin_ringbuf;
extern volatile uint32_t systick_ms;
uint64_t mp_hal_ticks_us_64(void);
void mp_hal_time_ns_set_from_rtc(void);
void mp_hal_set_interrupt_char(int c);
@ -94,10 +95,6 @@ static inline mp_uint_t mp_hal_ticks_cpu(void) {
}
#endif
static inline uint64_t mp_hal_time_ns(void) {
return mp_hal_ticks_us_64() * 1000;
}
// C-level pin HAL
#include "py/obj.h"