diff options
| author | robert-hh <robert@hammelrath.com> | 2022-09-15 15:58:54 +0200 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2022-10-25 23:20:09 +1100 |
| commit | fc9d66fac64422a6a6ea4a79bfd8b2460cc8e9e8 (patch) | |
| tree | 9d3e627d16ece04d56ce49bdd46c1a27884b0a0f | |
| parent | be31fde012e0cf522ec9d70f50923a0a899f438c (diff) | |
samd/machine_rtc: Add the machine.RTC class.
Methods implemented are:
- rtc.init(date)
- rtc.datetime([new_date])
- rtc.calibration(value)
The presence of this class can be controlled by MICROPY_PY_MACHINE_RTC. If
the RTC module is used, the time module uses the RTC as well.
For boards without a 32kHz crystal, using RTC makes no sense, since it will
then use the ULP32K oscillator, which is not precise at all. Therefore, it
will by default only be enabled for boards using a crystal, but can be
enabled in the respective mpconfigboard.h.
| -rw-r--r-- | ports/samd/Makefile | 1 | ||||
| -rw-r--r-- | ports/samd/fatfs_port.c | 6 | ||||
| -rw-r--r-- | ports/samd/machine_rtc.c | 181 | ||||
| -rw-r--r-- | ports/samd/mcu/samd21/clock_config.c | 17 | ||||
| -rw-r--r-- | ports/samd/mcu/samd21/mpconfigmcu.h | 6 | ||||
| -rw-r--r-- | ports/samd/mcu/samd51/clock_config.c | 20 | ||||
| -rw-r--r-- | ports/samd/mcu/samd51/mpconfigmcu.h | 6 | ||||
| -rw-r--r-- | ports/samd/modmachine.c | 3 | ||||
| -rw-r--r-- | ports/samd/modmachine.h | 3 | ||||
| -rw-r--r-- | ports/samd/modutime.c | 30 | ||||
| -rw-r--r-- | ports/samd/samd_soc.c | 7 |
11 files changed, 263 insertions, 17 deletions
diff --git a/ports/samd/Makefile b/ports/samd/Makefile index abec4e83a..e6e592a03 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -94,6 +94,7 @@ SRC_C += \ machine_i2c.c \ machine_led.c \ machine_pin.c \ + machine_rtc.c \ machine_spi.c \ machine_timer.c \ machine_uart.c \ diff --git a/ports/samd/fatfs_port.c b/ports/samd/fatfs_port.c index 9ee1764eb..a3e3f1b67 100644 --- a/ports/samd/fatfs_port.c +++ b/ports/samd/fatfs_port.c @@ -33,9 +33,13 @@ extern uint32_t time_offset; MP_WEAK DWORD get_fattime(void) { + #if MICROPY_PY_MACHINE_RTC + return (RTC->MODE2.CLOCK.reg >> 1) + (20 << 25); + #else + extern void rtc_gettime(timeutils_struct_time_t *tm); timeutils_struct_time_t tm; - timeutils_seconds_since_epoch_to_struct_time(mp_hal_ticks_ms_64() / 1000 + time_offset, &tm); return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) | ((tm.tm_mday) << 16) | ((tm.tm_hour) << 11) | ((tm.tm_min) << 5) | (tm.tm_sec / 2); + #endif } diff --git a/ports/samd/machine_rtc.c b/ports/samd/machine_rtc.c new file mode 100644 index 000000000..57bfa998e --- /dev/null +++ b/ports/samd/machine_rtc.c @@ -0,0 +1,181 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Damien P. George + * Copyright (c) 2022 "Robert Hammelrath" <robert@hammelrath.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/runtime.h" +#include "shared/timeutils/timeutils.h" +#include "modmachine.h" +#include "py/mphal.h" +#include "sam.h" + +#if MICROPY_PY_MACHINE_RTC + +typedef struct _machine_rtc_obj_t { + mp_obj_base_t base; + mp_obj_t callback; +} machine_rtc_obj_t; + +// Singleton RTC object. +STATIC const machine_rtc_obj_t machine_rtc_obj = {{&machine_rtc_type}}; + +// Start the RTC Timer. +void machine_rtc_start(bool force) { + #if defined(MCU_SAMD21) + + if (RTC->MODE2.CTRL.bit.ENABLE == 0 || force) { + // Enable the 1k Clock + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK8 | GCLK_CLKCTRL_ID_RTC; + + RTC->MODE2.CTRL.reg = RTC_MODE2_CTRL_SWRST; + while (RTC->MODE2.STATUS.bit.SYNCBUSY) { + } + RTC->MODE2.CTRL.reg = + RTC_MODE2_CTRL_MODE_CLOCK | + RTC_MODE2_CTRL_PRESCALER_DIV1024 | + RTC_MODE2_CTRL_ENABLE; + while (RTC->MODE2.STATUS.bit.SYNCBUSY) { + } + } + + #elif defined(MCU_SAMD51) + + if (RTC->MODE2.CTRLA.bit.ENABLE == 0 || force) { + RTC->MODE2.CTRLA.reg = RTC_MODE2_CTRLA_SWRST; + while (RTC->MODE2.SYNCBUSY.bit.SWRST) { + } + RTC->MODE2.CTRLA.reg = + RTC_MODE2_CTRLA_MODE_CLOCK | + RTC_MODE2_CTRLA_CLOCKSYNC | + RTC_MODE2_CTRLA_PRESCALER_DIV1024 | + RTC_MODE2_CTRLA_ENABLE; + while (RTC->MODE2.SYNCBUSY.bit.ENABLE) { + } + } + #endif +} + +// Get the time from the RTC and put it into a tm struct. +void rtc_gettime(timeutils_struct_time_t *tm) { + tm->tm_year = RTC->MODE2.CLOCK.bit.YEAR + 2000; + tm->tm_mon = RTC->MODE2.CLOCK.bit.MONTH; + tm->tm_mday = RTC->MODE2.CLOCK.bit.DAY; + tm->tm_hour = RTC->MODE2.CLOCK.bit.HOUR; + tm->tm_min = RTC->MODE2.CLOCK.bit.MINUTE; + tm->tm_sec = RTC->MODE2.CLOCK.bit.SECOND; +} + +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); + // RTC was already started at boot time. So nothing to do here. + // Return constant object. + return (mp_obj_t)&machine_rtc_obj; +} + +STATIC mp_obj_t machine_rtc_datetime_helper(size_t n_args, const mp_obj_t *args) { + // Rtc *rtc = RTC; + if (n_args == 1) { + // Get date and time. + timeutils_struct_time_t tm; + rtc_gettime(&tm); + + mp_obj_t tuple[8] = { + mp_obj_new_int(tm.tm_year), + mp_obj_new_int(tm.tm_mon), + mp_obj_new_int(tm.tm_mday), + mp_obj_new_int(timeutils_calc_weekday(tm.tm_year, tm.tm_mon, tm.tm_mday)), + mp_obj_new_int(tm.tm_hour), + mp_obj_new_int(tm.tm_min), + mp_obj_new_int(tm.tm_sec), + mp_obj_new_int(0), + }; + return mp_obj_new_tuple(8, tuple); + } else { + // Set date and time. + mp_obj_t *items; + mp_obj_get_array_fixed_n(args[1], 8, &items); + + uint32_t date = + RTC_MODE2_CLOCK_YEAR(mp_obj_get_int(items[0]) % 100) | + RTC_MODE2_CLOCK_MONTH(mp_obj_get_int(items[1])) | + RTC_MODE2_CLOCK_DAY(mp_obj_get_int(items[2])) | + RTC_MODE2_CLOCK_HOUR(mp_obj_get_int(items[4])) | + RTC_MODE2_CLOCK_MINUTE(mp_obj_get_int(items[5])) | + RTC_MODE2_CLOCK_SECOND(mp_obj_get_int(items[6])); + + RTC->MODE2.CLOCK.reg = date; + #if defined(MCU_SAMD21) + while (RTC->MODE2.STATUS.bit.SYNCBUSY) { + } + #elif defined(MCU_SAMD51) + while (RTC->MODE2.SYNCBUSY.bit.CLOCKSYNC) { + } + #endif + + return mp_const_none; + } +} + +STATIC mp_obj_t machine_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) { + return machine_rtc_datetime_helper(n_args, args); +} +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); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_rtc_init_obj, machine_rtc_init); + +// calibration(cal) +// When the argument is a number in the range [-16 to 15], set the calibration value. +STATIC mp_obj_t machine_rtc_calibration(mp_obj_t self_in, mp_obj_t cal_in) { + int8_t cal = 0; + // Make it negative for a "natural" behavior: + // value > 0: faster, value < 0: slower + cal = -mp_obj_get_int(cal_in); + RTC->MODE2.FREQCORR.reg = (uint8_t)cal; + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_rtc_calibration_obj, machine_rtc_calibration); + +STATIC const mp_rom_map_elem_t machine_rtc_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_rtc_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_datetime), MP_ROM_PTR(&machine_rtc_datetime_obj) }, + { MP_ROM_QSTR(MP_QSTR_calibration), MP_ROM_PTR(&machine_rtc_calibration_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(machine_rtc_locals_dict, machine_rtc_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + machine_rtc_type, + MP_QSTR_RTC, + MP_TYPE_FLAG_NONE, + make_new, machine_rtc_make_new, + locals_dict, &machine_rtc_locals_dict + ); + +#endif // MICROPY_PY_MACHINE_RTC diff --git a/ports/samd/mcu/samd21/clock_config.c b/ports/samd/mcu/samd21/clock_config.c index a195cb692..00f743cc4 100644 --- a/ports/samd/mcu/samd21/clock_config.c +++ b/ports/samd/mcu/samd21/clock_config.c @@ -141,7 +141,7 @@ void init_clocks(uint32_t cpu_freq) { // GCLK3: 1Mhz for the us-counter (TC4/TC5) // GCLK4: 32kHz from crystal, if present // GCLK5: 48MHz from DFLL for USB - // GCLK8: 1kHz clock for WDT + // GCLK8: 1kHz clock for WDT and RTC NVMCTRL->CTRLB.bit.MANW = 1; // errata "Spurious Writes" NVMCTRL->CTRLB.bit.RWS = 1; // 1 read wait state for 48MHz @@ -203,6 +203,11 @@ void init_clocks(uint32_t cpu_freq) { SYSCTRL_DFLLCTRL_BPLCKC | SYSCTRL_DFLLCTRL_ENABLE; while (SYSCTRL->PCLKSR.bit.DFLLLCKF == 0) { } + // Set GCLK8 to 1 kHz. + GCLK->GENDIV.reg = GCLK_GENDIV_ID(8) | GCLK_GENDIV_DIV(32); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC32K | GCLK_GENCTRL_ID(8); + while (GCLK->STATUS.bit.SYNCBUSY) { + } #else // MICROPY_HW_XOSC32K @@ -242,6 +247,11 @@ void init_clocks(uint32_t cpu_freq) { GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(1); while (GCLK->STATUS.bit.SYNCBUSY) { } + // Set GCLK8 to 1 kHz. + GCLK->GENDIV.reg = GCLK_GENDIV_ID(8) | GCLK_GENDIV_DIV(32); + GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K | GCLK_GENCTRL_ID(8); + while (GCLK->STATUS.bit.SYNCBUSY) { + } #endif // MICROPY_HW_XOSC32K @@ -252,11 +262,6 @@ void init_clocks(uint32_t cpu_freq) { GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(3); while (GCLK->STATUS.bit.SYNCBUSY) { } - // Set GCLK8 to 1 kHz. - GCLK->GENDIV.reg = GCLK_GENDIV_ID(8) | GCLK_GENDIV_DIV(32); - GCLK->GENCTRL.reg = GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K | GCLK_GENCTRL_ID(8); - while (GCLK->STATUS.bit.SYNCBUSY) { - } } void enable_sercom_clock(int id) { diff --git a/ports/samd/mcu/samd21/mpconfigmcu.h b/ports/samd/mcu/samd21/mpconfigmcu.h index 8d155f93a..331df8e21 100644 --- a/ports/samd/mcu/samd21/mpconfigmcu.h +++ b/ports/samd/mcu/samd21/mpconfigmcu.h @@ -28,6 +28,12 @@ #define MICROPY_HW_UART_TXBUF (1) #endif +#ifndef MICROPY_PY_MACHINE_RTC +#if MICROPY_HW_XOSC32K +#define MICROPY_PY_MACHINE_RTC (1) +#endif +#endif + #define CPU_FREQ (48000000) #define DFLL48M_FREQ (48000000) #define MAX_CPU_FREQ (48000000) diff --git a/ports/samd/mcu/samd51/clock_config.c b/ports/samd/mcu/samd51/clock_config.c index 3bc4616de..c5f508cae 100644 --- a/ports/samd/mcu/samd51/clock_config.c +++ b/ports/samd/mcu/samd51/clock_config.c @@ -215,16 +215,19 @@ void init_clocks(uint32_t cpu_freq) { #if MICROPY_HW_XOSC32K // OSCILLATOR CONTROL + // Enable the clock for RTC + OSC32KCTRL->RTCCTRL.reg = OSC32KCTRL_RTCCTRL_RTCSEL_XOSC1K; // Setup XOSC32K OSC32KCTRL->INTFLAG.reg = OSC32KCTRL_INTFLAG_XOSC32KRDY | OSC32KCTRL_INTFLAG_XOSC32KFAIL; - OSC32KCTRL->XOSC32K.bit.CGM = OSC32KCTRL_XOSC32K_CGM_HS_Val; - OSC32KCTRL->XOSC32K.bit.XTALEN = 1; // 0: Generator 1: Crystal - OSC32KCTRL->XOSC32K.bit.EN32K = 1; - OSC32KCTRL->XOSC32K.bit.ONDEMAND = 0; - OSC32KCTRL->XOSC32K.bit.RUNSTDBY = 1; - OSC32KCTRL->XOSC32K.bit.STARTUP = 4; OSC32KCTRL->CFDCTRL.bit.CFDEN = 1; // Fall back to internal Osc on crystal fail - OSC32KCTRL->XOSC32K.bit.ENABLE = 1; + OSC32KCTRL->XOSC32K.reg = + OSC32KCTRL_XOSC32K_CGM_HS | + OSC32KCTRL_XOSC32K_XTALEN | + OSC32KCTRL_XOSC32K_EN32K | + OSC32KCTRL_XOSC32K_EN1K | + OSC32KCTRL_XOSC32K_RUNSTDBY | + OSC32KCTRL_XOSC32K_STARTUP(4) | + OSC32KCTRL_XOSC32K_ENABLE; // make sure osc32kcrtl is ready while (OSC32KCTRL->STATUS.bit.XOSC32KRDY == 0) { } @@ -270,6 +273,9 @@ void init_clocks(uint32_t cpu_freq) { #else // MICROPY_HW_XOSC32K + // Enable the clock for RTC + OSC32KCTRL->RTCCTRL.reg = OSC32KCTRL_RTCCTRL_RTCSEL_ULP1K; + // Derive GCLK1 from DFLL48M at DPLL0_REF_FREQ as defined in mpconfigboard.h (e.g. 32768 Hz) GCLK->GENCTRL[1].reg = ((DFLL48M_FREQ + DPLLx_REF_FREQ / 2) / DPLLx_REF_FREQ) << GCLK_GENCTRL_DIV_Pos | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL; diff --git a/ports/samd/mcu/samd51/mpconfigmcu.h b/ports/samd/mcu/samd51/mpconfigmcu.h index 666370c98..541fba900 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.h +++ b/ports/samd/mcu/samd51/mpconfigmcu.h @@ -28,6 +28,12 @@ #define MICROPY_PY_URANDOM_SEED_INIT_FUNC (trng_random_u32()) unsigned long trng_random_u32(void); +#ifndef MICROPY_PY_MACHINE_RTC +#if MICROPY_HW_XOSC32K +#define MICROPY_PY_MACHINE_RTC (1) +#endif +#endif + // Due to a limitation in the TC counter for us, the ticks period is 2**29 #define MICROPY_PY_UTIME_TICKS_PERIOD (0x20000000) diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index ce5fef76f..12e9f7c34 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -238,6 +238,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&machine_timer_type) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) }, { MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&machine_wdt_type) }, + #if MICROPY_PY_MACHINE_RTC + { MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&machine_rtc_type) }, + #endif { MP_ROM_QSTR(MP_QSTR_idle), MP_ROM_PTR(&machine_idle_obj) }, { MP_ROM_QSTR(MP_QSTR_disable_irq), MP_ROM_PTR(&machine_disable_irq_obj) }, diff --git a/ports/samd/modmachine.h b/ports/samd/modmachine.h index e99ca990f..8f85e1498 100644 --- a/ports/samd/modmachine.h +++ b/ports/samd/modmachine.h @@ -38,5 +38,8 @@ extern const mp_obj_type_t machine_spi_type; extern const mp_obj_type_t machine_timer_type; extern const mp_obj_type_t machine_uart_type; extern const mp_obj_type_t machine_wdt_type; +#if MICROPY_PY_MACHINE_RTC +extern const mp_obj_type_t machine_rtc_type; +#endif #endif // MICROPY_INCLUDED_SAMD_MODMACHINE_H diff --git a/ports/samd/modutime.c b/ports/samd/modutime.c index 4169c15d9..6b0413449 100644 --- a/ports/samd/modutime.c +++ b/ports/samd/modutime.c @@ -29,20 +29,34 @@ #include "shared/timeutils/timeutils.h" #include "mphalport.h" +#if !MICROPY_PY_MACHINE_RTC uint32_t time_offset = 0; +#endif // !MICROPY_PY_MACHINE_RTC // localtime([secs]) STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { timeutils_struct_time_t tm; mp_int_t seconds; + + #if MICROPY_PY_MACHINE_RTC + extern void rtc_gettime(timeutils_struct_time_t *tm); + if (n_args == 0 || args[0] == mp_const_none) { + rtc_gettime(&tm); + } else { + seconds = mp_obj_get_int(args[0]); + timeutils_seconds_since_epoch_to_struct_time(seconds, &tm); + } + + #else if (n_args == 0 || args[0] == mp_const_none) { - // seconds = pyb_rtc_get_us_since_epoch() / 1000 / 1000; seconds = mp_hal_ticks_ms_64() / 1000 + time_offset; } else { seconds = mp_obj_get_int(args[0]); time_offset = seconds - mp_hal_ticks_ms_64() / 1000; } timeutils_seconds_since_epoch_to_struct_time(seconds, &tm); + + #endif // MICROPY_PY_MACHINE_RTC mp_obj_t tuple[8] = { tuple[0] = mp_obj_new_int(tm.tm_year), tuple[1] = mp_obj_new_int(tm.tm_mon), @@ -50,8 +64,8 @@ STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { 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), + tuple[6] = mp_obj_new_int(timeutils_calc_weekday(tm.tm_year, tm.tm_mon, tm.tm_mday)), + tuple[7] = mp_obj_new_int(timeutils_year_day(tm.tm_year, tm.tm_mon, tm.tm_mday)), }; return mp_obj_new_tuple(8, tuple); } @@ -76,7 +90,17 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime); // time() STATIC mp_obj_t time_time(void) { + #if MICROPY_PY_MACHINE_RTC + extern void rtc_gettime(timeutils_struct_time_t *tm); + timeutils_struct_time_t tm; + rtc_gettime(&tm); + 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)); + + #else return mp_obj_new_int_from_uint(mp_hal_ticks_ms_64() / 1000 + time_offset); + + #endif // MICROPY_PY_MACHINE_RTC } STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time); diff --git a/ports/samd/samd_soc.c b/ports/samd/samd_soc.c index 3608306e8..bd3eea536 100644 --- a/ports/samd/samd_soc.c +++ b/ports/samd/samd_soc.c @@ -38,6 +38,10 @@ #include "tusb.h" #include "mphalport.h" +#if MICROPY_PY_MACHINE_RTC +extern void machine_rtc_start(bool force); +#endif + static void usb_init(void) { // Init USB clock #if defined(MCU_SAMD21) @@ -114,4 +118,7 @@ void samd_init(void) { #if defined(MCU_SAMD51) mp_hal_ticks_cpu_enable(); #endif + #if MICROPY_PY_MACHINE_RTC + machine_rtc_start(false); + #endif } |
