From cf0c0143df08f855a3840d46115b542aef87ac08 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Wed, 4 Dec 2024 21:01:45 +0100 Subject: [PATCH 1/3] esp32: Fix RTC initialization from datetime. Signed-off-by: Sebastian Romero --- ports/esp32/machine_rtc.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ports/esp32/machine_rtc.c b/ports/esp32/machine_rtc.c index 087ba9d69efe7..6c6c44a61b13d 100644 --- a/ports/esp32/machine_rtc.c +++ b/ports/esp32/machine_rtc.c @@ -101,7 +101,7 @@ static mp_obj_t machine_rtc_make_new(const mp_obj_type_t *type, size_t n_args, s return (mp_obj_t)&machine_rtc_obj; } -static mp_obj_t machine_rtc_datetime_helper(mp_uint_t n_args, const mp_obj_t *args) { +static mp_obj_t machine_rtc_datetime_helper(mp_uint_t n_args, const mp_obj_t *args, bool use_init_format) { if (n_args == 1) { // Get time @@ -131,21 +131,26 @@ static mp_obj_t machine_rtc_datetime_helper(mp_uint_t n_args, const mp_obj_t *ar mp_obj_get_array_fixed_n(args[1], 8, &items); struct timeval tv = {0}; - tv.tv_sec = timeutils_seconds_since_epoch(mp_obj_get_int(items[0]), mp_obj_get_int(items[1]), mp_obj_get_int(items[2]), mp_obj_get_int(items[4]), mp_obj_get_int(items[5]), mp_obj_get_int(items[6])); - tv.tv_usec = mp_obj_get_int(items[7]); + if (use_init_format) { + tv.tv_sec = timeutils_seconds_since_epoch(mp_obj_get_int(items[0]), mp_obj_get_int(items[1]), mp_obj_get_int(items[2]), mp_obj_get_int(items[3]), mp_obj_get_int(items[4]), mp_obj_get_int(items[5])); + tv.tv_usec = mp_obj_get_int(items[6]); + } else { + tv.tv_sec = timeutils_seconds_since_epoch(mp_obj_get_int(items[0]), mp_obj_get_int(items[1]), mp_obj_get_int(items[2]), mp_obj_get_int(items[4]), mp_obj_get_int(items[5]), mp_obj_get_int(items[6])); + tv.tv_usec = mp_obj_get_int(items[7]); + } settimeofday(&tv, NULL); return mp_const_none; } } static mp_obj_t machine_rtc_datetime(size_t n_args, const mp_obj_t *args) { - return machine_rtc_datetime_helper(n_args, args); + return machine_rtc_datetime_helper(n_args, args, false); } static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_rtc_datetime_obj, 1, 2, machine_rtc_datetime); static mp_obj_t machine_rtc_init(mp_obj_t self_in, mp_obj_t date) { mp_obj_t args[2] = {self_in, date}; - machine_rtc_datetime_helper(2, args); + machine_rtc_datetime_helper(2, args, true); return mp_const_none; } From 9a3b29f9a22b32825fdec5114d173593149a40dc Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 5 Dec 2024 13:33:34 +0100 Subject: [PATCH 2/3] esp32: Allow RTC init with only date. Signed-off-by: Sebastian Romero --- ports/esp32/machine_rtc.c | 13 +++++++++---- py/obj.c | 19 +++++++++++++++++++ py/obj.h | 1 + 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/ports/esp32/machine_rtc.c b/ports/esp32/machine_rtc.c index 6c6c44a61b13d..0e5e6855e7ea1 100644 --- a/ports/esp32/machine_rtc.c +++ b/ports/esp32/machine_rtc.c @@ -126,15 +126,20 @@ static mp_obj_t machine_rtc_datetime_helper(mp_uint_t n_args, const mp_obj_t *ar return mp_obj_new_tuple(8, tuple); } else { // Set time - mp_obj_t *items; - mp_obj_get_array_fixed_n(args[1], 8, &items); struct timeval tv = {0}; if (use_init_format) { - tv.tv_sec = timeutils_seconds_since_epoch(mp_obj_get_int(items[0]), mp_obj_get_int(items[1]), mp_obj_get_int(items[2]), mp_obj_get_int(items[3]), mp_obj_get_int(items[4]), mp_obj_get_int(items[5])); - tv.tv_usec = mp_obj_get_int(items[6]); + size_t seq_len; + mp_ob_get_array_min_max(args[1], 3, 8, &seq_len, &items); + mp_int_t hour = seq_len > 3 ? mp_obj_get_int(items[3]) : 0; + mp_int_t minute = seq_len > 4 ? mp_obj_get_int(items[4]) : 0; + mp_int_t second = seq_len > 5 ? mp_obj_get_int(items[5]) : 0; + mp_int_t subsecond = seq_len > 6 ? mp_obj_get_int(items[6]) : 0; + tv.tv_sec = timeutils_seconds_since_epoch(mp_obj_get_int(items[0]), mp_obj_get_int(items[1]), mp_obj_get_int(items[2]), hour, minute, second); + tv.tv_usec = subsecond; } else { + mp_obj_get_array_fixed_n(args[1], 8, &items); tv.tv_sec = timeutils_seconds_since_epoch(mp_obj_get_int(items[0]), mp_obj_get_int(items[1]), mp_obj_get_int(items[2]), mp_obj_get_int(items[4]), mp_obj_get_int(items[5]), mp_obj_get_int(items[6])); tv.tv_usec = mp_obj_get_int(items[7]); } diff --git a/py/obj.c b/py/obj.c index 1606ad5209e7b..abda5fe8f5c71 100644 --- a/py/obj.c +++ b/py/obj.c @@ -448,6 +448,25 @@ void mp_obj_get_array_fixed_n(mp_obj_t o, size_t len, mp_obj_t **items) { } } +void mp_ob_get_array_min_max(mp_obj_t o, size_t min_len, size_t max_len, size_t *len, mp_obj_t **items) { + mp_obj_get_array(o, len, items); + if (*len < min_len) { + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE + mp_raise_ValueError(MP_ERROR_TEXT("tuple/list length too short")); + #else + mp_raise_msg_varg(&mp_type_ValueError, + MP_ERROR_TEXT("requested minimum length %d but object has length %d"), (int)min_len, (int)*len); + #endif + } else if (*len > max_len) { + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE + mp_raise_ValueError(MP_ERROR_TEXT("tuple/list length too long")); + #else + mp_raise_msg_varg(&mp_type_ValueError, + MP_ERROR_TEXT("requested maximum length %d but object has length %d"), (int)max_len, (int)*len); + #endif + } +} + // is_slice determines whether the index is a slice index size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool is_slice) { mp_int_t i; diff --git a/py/obj.h b/py/obj.h index d942e1bbf7b28..dd951e4e25ef5 100644 --- a/py/obj.h +++ b/py/obj.h @@ -1045,6 +1045,7 @@ bool mp_obj_get_complex_maybe(mp_obj_t self_in, mp_float_t *real, mp_float_t *im #endif void mp_obj_get_array(mp_obj_t o, size_t *len, mp_obj_t **items); // *items may point inside a GC block void mp_obj_get_array_fixed_n(mp_obj_t o, size_t len, mp_obj_t **items); // *items may point inside a GC block +void mp_ob_get_array_min_max(mp_obj_t o, size_t min_len, size_t max_len, size_t *len, mp_obj_t **items); // *items may point inside a GC block size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool is_slice); mp_obj_t mp_obj_id(mp_obj_t o_in); mp_obj_t mp_obj_len(mp_obj_t o_in); From 9afbeb13f6b344b0af2c0fa8f9480d87a9a81e53 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 5 Dec 2024 15:24:44 +0100 Subject: [PATCH 3/3] esp32: Add test for RTC init. Signed-off-by: Sebastian Romero --- tests/ports/esp32/machine_rtc_init.exp | 4 +++ tests/ports/esp32/machine_rtc_init.py | 46 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 tests/ports/esp32/machine_rtc_init.exp create mode 100644 tests/ports/esp32/machine_rtc_init.py diff --git a/tests/ports/esp32/machine_rtc_init.exp b/tests/ports/esp32/machine_rtc_init.exp new file mode 100644 index 0000000000000..3bc971f6b44db --- /dev/null +++ b/tests/ports/esp32/machine_rtc_init.exp @@ -0,0 +1,4 @@ +2024 12 26 3 6 30 20 +2024 12 26 3 +requested maximum length 8 but object has length 9 +requested minimum length 3 but object has length 2 \ No newline at end of file diff --git a/tests/ports/esp32/machine_rtc_init.py b/tests/ports/esp32/machine_rtc_init.py new file mode 100644 index 0000000000000..c53dd589978bc --- /dev/null +++ b/tests/ports/esp32/machine_rtc_init.py @@ -0,0 +1,46 @@ +# Test init behaviour of machine.RTC. + +try: + from machine import RTC +except ImportError: + print("SKIP") + raise SystemExit + +rtc = RTC() + +year = 2024 +month = 12 +day = 26 +# weekday is 3 (Thursday) +hour = 6 +minute = 30 +second = 20 +microsecond = 0 +tzinfo = 0 + +# Save datetime. +orig_datetime = rtc.datetime() + +# Set datetime to a known value using init. +rtc.init((year, month, day, hour, minute, second, microsecond, tzinfo)) +now = rtc.datetime() +print(now[0], now[1], now[2], now[3], now[4], now[5], now[6]) + +# Test with date only. +rtc.init((year, month, day)) +print(now[0], now[1], now[2], now[3]) + +# Test with too many arguments. +try: + rtc.init((year, month, day, hour, minute, second, microsecond, tzinfo, 1234)) +except ValueError as e: + print(e) + +# Test with too few arguments. +try: + rtc.init((year, month)) +except ValueError as e: + print(e) + +# Restore datetime. +rtc.datetime(orig_datetime) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy