From 8edc3aacdda7b65ad6dd6ad4af0bb1a570ef9f47 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Sun, 13 Jun 2021 16:42:19 +0200 Subject: [PATCH] mimxrt/modutime: Extend the time module. Methods added: - time.time() - time.time_ns() - time.gmtime() - time.localtime() - time.mktime() The rp2 port was uses as the template for the change. --- ports/mimxrt/Makefile | 1 + ports/mimxrt/machine_rtc.c | 2 +- ports/mimxrt/modutime.c | 81 ++++++++++++++++++++++++++++++++++++++ ports/mimxrt/mphalport.c | 9 +++++ ports/mimxrt/mphalport.h | 4 -- 5 files changed, 92 insertions(+), 5 deletions(-) diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 638c6b124..3b530a970 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -150,6 +150,7 @@ SRC_C = \ hal/flexspi_nor_flash.c \ lib/mp-readline/readline.c \ lib/libc/string0.c \ + lib/timeutils/timeutils.c \ lib/utils/gchelper_native.c \ lib/utils/mpirq.c \ lib/utils/printf.c \ diff --git a/ports/mimxrt/machine_rtc.c b/ports/mimxrt/machine_rtc.c index 4de3419c1..76f414925 100644 --- a/ports/mimxrt/machine_rtc.c +++ b/ports/mimxrt/machine_rtc.c @@ -42,7 +42,7 @@ uint32_t us_offset = 0; // Calculate the weekday from the date. // The result is zero based with 0 = Monday. // by Michael Keith and Tom Craver, 1990. -static int calc_weekday(int y, int m, int d) { +int calc_weekday(int y, int m, int d) { return ((d += m < 3 ? y-- : y - 2, 23 * m / 9 + d + 4 + y / 4 - y / 100 + y / 400) + 6) % 7; } diff --git a/ports/mimxrt/modutime.c b/ports/mimxrt/modutime.c index bbdbda44e..a47bc073f 100644 --- a/ports/mimxrt/modutime.c +++ b/ports/mimxrt/modutime.c @@ -25,11 +25,92 @@ * THE SOFTWARE. */ +#include "py/runtime.h" +#include "lib/timeutils/timeutils.h" #include "extmod/utime_mphal.h" +#include "fsl_snvs_lp.h" + +extern int calc_weekday(int y, int m, int d); + +// localtime([secs]) +// Convert a time expressed in seconds since the Epoch into an 8-tuple which +// contains: (year, month, mday, hour, minute, second, weekday, yearday) +// If secs is not provided or None, then the current time from the RTC is used. +STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { + if (n_args == 0 || args[0] == mp_const_none) { + // Get current date and time. + snvs_lp_srtc_datetime_t t; + SNVS_LP_SRTC_GetDatetime(SNVS, &t); + mp_obj_t tuple[8] = { + mp_obj_new_int(t.year), + mp_obj_new_int(t.month), + mp_obj_new_int(t.day), + mp_obj_new_int(t.hour), + mp_obj_new_int(t.minute), + mp_obj_new_int(t.second), + mp_obj_new_int(calc_weekday(t.year, t.month, t.day)), + mp_obj_new_int(timeutils_year_day(t.year, t.month, t.day)), + }; + return mp_obj_new_tuple(8, tuple); + } else { + // Convert given seconds to tuple. + mp_int_t seconds = mp_obj_get_int(args[0]); + timeutils_struct_time_t tm; + timeutils_seconds_since_epoch_to_struct_time(seconds, &tm); + mp_obj_t tuple[8] = { + tuple[0] = mp_obj_new_int(tm.tm_year), + tuple[1] = mp_obj_new_int(tm.tm_mon), + tuple[2] = mp_obj_new_int(tm.tm_mday), + tuple[3] = mp_obj_new_int(tm.tm_hour), + tuple[4] = mp_obj_new_int(tm.tm_min), + tuple[5] = mp_obj_new_int(tm.tm_sec), + tuple[6] = mp_obj_new_int(tm.tm_wday), + tuple[7] = mp_obj_new_int(tm.tm_yday), + }; + return mp_obj_new_tuple(8, tuple); + } +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(time_localtime_obj, 0, 1, time_localtime); + +// mktime() +// This is inverse function of localtime. It's argument is a full 8-tuple +// which expresses a time as per localtime. It returns an integer which is +// the number of seconds since the Epoch. +STATIC mp_obj_t time_mktime(mp_obj_t tuple) { + size_t len; + mp_obj_t *elem; + mp_obj_get_array(tuple, &len, &elem); + + // localtime generates a tuple of len 8. CPython uses 9, so we accept both. + if (len < 8 || len > 9) { + mp_raise_TypeError(MP_ERROR_TEXT("mktime needs a tuple of length 8 or 9")); + } + + return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]), + mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]), mp_obj_get_int(elem[3]), + mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5]))); +} +MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime); + +// time() +// Return the number of seconds since the Epoch. +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)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time); STATIC const mp_rom_map_elem_t time_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_utime) }, + { MP_ROM_QSTR(MP_QSTR_gmtime), MP_ROM_PTR(&time_localtime_obj) }, + { MP_ROM_QSTR(MP_QSTR_localtime), MP_ROM_PTR(&time_localtime_obj) }, + { MP_ROM_QSTR(MP_QSTR_mktime), MP_ROM_PTR(&time_mktime_obj) }, + + { MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&time_time_obj) }, + { MP_ROM_QSTR(MP_QSTR_time_ns), MP_ROM_PTR(&mp_utime_time_ns_obj) }, + { MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&mp_utime_sleep_obj) }, { MP_ROM_QSTR(MP_QSTR_sleep_ms), MP_ROM_PTR(&mp_utime_sleep_ms_obj) }, { MP_ROM_QSTR(MP_QSTR_sleep_us), MP_ROM_PTR(&mp_utime_sleep_us_obj) }, diff --git a/ports/mimxrt/mphalport.c b/ports/mimxrt/mphalport.c index faecafbbc..942deae5b 100644 --- a/ports/mimxrt/mphalport.c +++ b/ports/mimxrt/mphalport.c @@ -28,8 +28,10 @@ #include "py/runtime.h" #include "py/stream.h" #include "py/mphal.h" +#include "lib/timeutils/timeutils.h" #include "ticks.h" #include "tusb.h" +#include "fsl_snvs_lp.h" #include CPU_HEADER_H @@ -94,3 +96,10 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { // USARTx->USART.DATA.bit.DATA = *str++; // } } + +uint64_t mp_hal_time_ns(void) { + snvs_lp_srtc_datetime_t t; + SNVS_LP_SRTC_GetDatetime(SNVS, &t); + uint64_t s = timeutils_seconds_since_epoch(t.year, t.month, t.day, t.hour, t.minute, t.second); + return s * 1000000000ULL; +} diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h index 0db11836f..94f43001d 100644 --- a/ports/mimxrt/mphalport.h +++ b/ports/mimxrt/mphalport.h @@ -76,9 +76,5 @@ static inline mp_uint_t mp_hal_ticks_cpu(void) { return 0; } -static inline uint64_t mp_hal_time_ns(void) { - // TODO: Implement this function. - return 0UL; -} #endif // MICROPY_INCLUDED_MIMXRT_MPHALPORT_H -- GitLab