diff --git a/ports/mimxrt/board_init.c b/ports/mimxrt/board_init.c index 82af620a8d..398fafc6c3 100644 --- a/ports/mimxrt/board_init.c +++ b/ports/mimxrt/board_init.c @@ -100,6 +100,8 @@ void board_init(void) { #if MICROPY_PY_MACHINE_I2S machine_i2s_init0(); #endif + // RTC + machine_rtc_start(); } void USB_OTG1_IRQHandler(void) { diff --git a/ports/mimxrt/machine_rtc.c b/ports/mimxrt/machine_rtc.c index f08e73fa55..e0d33554b5 100644 --- a/ports/mimxrt/machine_rtc.c +++ b/ports/mimxrt/machine_rtc.c @@ -40,13 +40,31 @@ typedef struct _machine_rtc_obj_t { STATIC const machine_rtc_obj_t machine_rtc_obj = {{&machine_rtc_type}}; uint32_t us_offset = 0; +// Start the RTC Timer. +void machine_rtc_start(void) { + + SNVS_LP_SRTC_StartTimer(SNVS); + // If the date is not set, set it to a more recent start date, + // MicroPython's first commit. + snvs_lp_srtc_datetime_t srtc_date; + SNVS_LP_SRTC_GetDatetime(SNVS, &srtc_date); + if (srtc_date.year <= 1970) { + srtc_date = (snvs_lp_srtc_datetime_t) { + .year = 2013, + .month = 10, + .day = 14, + .hour = 19, + .minute = 53, + .second = 11, + }; + SNVS_LP_SRTC_SetDatetime(SNVS, &srtc_date); + } +} + STATIC mp_obj_t machine_rtc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { // Check arguments. mp_arg_check_num(n_args, n_kw, 0, 0, false); - // Start up the RTC if needed. - SNVS_LP_SRTC_StartTimer(SNVS); - // Return constant object. return (mp_obj_t)&machine_rtc_obj; } diff --git a/ports/mimxrt/modmachine.h b/ports/mimxrt/modmachine.h index 6502eea09f..ed1c4e34a0 100644 --- a/ports/mimxrt/modmachine.h +++ b/ports/mimxrt/modmachine.h @@ -48,5 +48,6 @@ void machine_sdcard_init0(void); void mimxrt_sdram_init(void); void machine_i2s_init0(); void machine_i2s_deinit_all(void); +void machine_rtc_start(void); #endif // MICROPY_INCLUDED_MIMXRT_MODMACHINE_H diff --git a/ports/mimxrt/modutime.c b/ports/mimxrt/modutime.c index d3be7c2ea6..822e2771d2 100644 --- a/ports/mimxrt/modutime.c +++ b/ports/mimxrt/modutime.c @@ -95,7 +95,16 @@ MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime); STATIC mp_obj_t time_time(void) { snvs_lp_srtc_datetime_t t; SNVS_LP_SRTC_GetDatetime(SNVS, &t); - return mp_obj_new_int_from_ull(timeutils_seconds_since_epoch(t.year, t.month, t.day, t.hour, t.minute, t.second)); + // EPOCH is 1970 for this port, which leads to the following trouble: + // timeutils_seconds_since_epoch() calls timeutils_seconds_since_2000(), and + // timeutils_seconds_since_2000() subtracts 2000 from year, but uses + // an unsigned number for seconds, That causes an underrun, which is not + // fixed by adding the TIMEUTILS_SECONDS_1970_TO_2000. + // Masking it to 32 bit for year < 2000 fixes it. + return mp_obj_new_int_from_ull( + timeutils_seconds_since_epoch(t.year, t.month, t.day, t.hour, t.minute, t.second) + & (t.year < 2000 ? 0xffffffff : 0xffffffffffff) + ); } STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time); diff --git a/shared/timeutils/timeutils.h b/shared/timeutils/timeutils.h index 66e2a77f13..9f4b500caa 100644 --- a/shared/timeutils/timeutils.h +++ b/shared/timeutils/timeutils.h @@ -69,6 +69,7 @@ static inline uint64_t timeutils_mktime(mp_uint_t year, mp_int_t month, mp_int_t static inline uint64_t timeutils_seconds_since_epoch(mp_uint_t year, mp_uint_t month, mp_uint_t date, mp_uint_t hour, mp_uint_t minute, mp_uint_t second) { + // TODO this will give incorrect results for dates before 2000/1/1 return timeutils_seconds_since_2000(year, month, date, hour, minute, second) + TIMEUTILS_SECONDS_1970_TO_2000; }