kopia lustrzana https://github.com/micropython/micropython
Merge 57623bcee4
into e60e8079a7
commit
b107a141d5
|
@ -267,6 +267,7 @@ DRIVERS_SRC_C += $(addprefix modules/,\
|
|||
machine/pin.c \
|
||||
machine/timer.c \
|
||||
machine/rtcounter.c \
|
||||
machine/rtc.c \
|
||||
machine/temp.c \
|
||||
os/microbitfs.c \
|
||||
board/modboard.c \
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2023 Damien P. George
|
||||
*
|
||||
* 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/obj.h"
|
||||
#include "shared/timeutils/timeutils.h"
|
||||
#include "ports/nrf/modules/machine/rtc.h"
|
||||
|
||||
// Return the localtime as an 8-tuple.
|
||||
static mp_obj_t mp_time_localtime_get(void) {
|
||||
mp_int_t seconds = ticks_ms_64() / 1000;
|
||||
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);
|
||||
}
|
||||
|
||||
static mp_obj_t mp_time_time_get(void) {
|
||||
return mp_obj_new_int((ticks_ms_64() + rtc_offset[1]) / 1000);
|
||||
}
|
|
@ -65,6 +65,12 @@
|
|||
#define MICROPY_PY_MACHINE_RTCOUNTER_ENTRY
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_MACHINE_RTC
|
||||
#define MICROPY_PY_MACHINE_RTC_ENTRY { MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&machine_rtc_type) },
|
||||
#else
|
||||
#define MICROPY_PY_MACHINE_RTC_ENTRY
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_MACHINE_TIMER_NRF
|
||||
#define MICROPY_PY_MACHINE_TIMER_ENTRY { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&machine_timer_type) },
|
||||
#else
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
|
||||
#include "py/obj.h"
|
||||
|
||||
#if MICROPY_PY_MACHINE_RTC
|
||||
extern const mp_obj_type_t machine_rtc_type;
|
||||
#endif
|
||||
|
||||
void machine_init(void);
|
||||
|
||||
#endif // __MICROPY_INCLUDED_NRF5_MODMACHINE_H__
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Nick Moore for Adafruit Industries
|
||||
* Copyright (c) 2021 "Krzysztof Adamski" <k@japko.eu>
|
||||
*
|
||||
* 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 "modmachine.h"
|
||||
|
||||
#if MICROPY_PY_MACHINE_RTC
|
||||
|
||||
#include "py/mphal.h"
|
||||
#include "shared/timeutils/timeutils.h"
|
||||
#include "rtc.h"
|
||||
|
||||
|
||||
// These values are placed before and after the current RTC count. They are
|
||||
// used to determine if the RTC count is valid. These randomly-generated values
|
||||
// will be set when the RTC value is set in order to mark the RTC as valid. If
|
||||
// the system crashes or reboots, these values will remain undisturbed and the
|
||||
// RTC offset will remain valid.
|
||||
//
|
||||
// If MicroPython is updated or these symbols shift around, the prefix and
|
||||
// suffix will no longer match, and the time will no longer be valid.
|
||||
#define RTC_OFFSET_CHECK_PREFIX 0x25ea7e2a
|
||||
#define RTC_OFFSET_CHECK_SUFFIX 0x2b80b69e
|
||||
|
||||
void rtc_offset_check(void) {
|
||||
// If the prefix and suffix are not valid, zero-initialize the RTC offset.
|
||||
if ((rtc_offset[0] != RTC_OFFSET_CHECK_PREFIX) || (rtc_offset[2] != RTC_OFFSET_CHECK_SUFFIX)) {
|
||||
rtc_offset[1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_get_time(timeutils_struct_time_t *tm) {
|
||||
uint64_t ticks_s = ticks_ms_64() / 1000;
|
||||
timeutils_seconds_since_2000_to_struct_time(rtc_offset[1] + ticks_s, tm);
|
||||
}
|
||||
|
||||
void rtc_set_time(timeutils_struct_time_t *tm) {
|
||||
uint64_t ticks_s = ticks_ms_64() / 1000;
|
||||
uint32_t epoch_s = timeutils_seconds_since_2000(
|
||||
tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec
|
||||
);
|
||||
rtc_offset[1] = epoch_s - ticks_s;
|
||||
|
||||
// Set the prefix and suffix in order to indicate the time is valid. This
|
||||
// must be done after the offset is updated, in case there is a crash or
|
||||
// power failure.
|
||||
rtc_offset[0] = RTC_OFFSET_CHECK_PREFIX;
|
||||
rtc_offset[2] = RTC_OFFSET_CHECK_SUFFIX;
|
||||
}
|
||||
|
||||
typedef struct _machine_rtc_obj_t {
|
||||
mp_obj_base_t base;
|
||||
} machine_rtc_obj_t;
|
||||
|
||||
// singleton RTC object
|
||||
static const machine_rtc_obj_t machine_rtc_obj = {{&machine_rtc_type}};
|
||||
|
||||
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);
|
||||
|
||||
// return constant object
|
||||
return (mp_obj_t)&machine_rtc_obj;
|
||||
}
|
||||
|
||||
static mp_obj_t machine_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
if (n_args == 1) {
|
||||
timeutils_struct_time_t t;
|
||||
|
||||
rtc_get_time(&t);
|
||||
|
||||
mp_obj_t tuple[8] = {
|
||||
mp_obj_new_int(t.tm_year),
|
||||
mp_obj_new_int(t.tm_mon),
|
||||
mp_obj_new_int(t.tm_mday),
|
||||
mp_obj_new_int(t.tm_wday),
|
||||
mp_obj_new_int(t.tm_hour),
|
||||
mp_obj_new_int(t.tm_min),
|
||||
mp_obj_new_int(t.tm_sec),
|
||||
mp_obj_new_int(0)
|
||||
};
|
||||
|
||||
return mp_obj_new_tuple(8, tuple);
|
||||
} else {
|
||||
mp_obj_t *items;
|
||||
|
||||
mp_obj_get_array_fixed_n(args[1], 8, &items);
|
||||
|
||||
timeutils_struct_time_t t = {
|
||||
.tm_year = mp_obj_get_int(items[0]),
|
||||
.tm_mon = mp_obj_get_int(items[1]),
|
||||
.tm_mday = mp_obj_get_int(items[2]),
|
||||
.tm_hour = mp_obj_get_int(items[4]),
|
||||
.tm_min = mp_obj_get_int(items[5]),
|
||||
.tm_sec = mp_obj_get_int(items[6]),
|
||||
};
|
||||
// Deliberately ignore the weekday argument and compute the proper value
|
||||
t.tm_wday = timeutils_calc_weekday(t.tm_year, t.tm_mon, t.tm_mday);
|
||||
|
||||
rtc_set_time(&t);
|
||||
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_rtc_datetime_obj, 1, 2, machine_rtc_datetime);
|
||||
|
||||
static const mp_rom_map_elem_t machine_rtc_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_datetime), MP_ROM_PTR(&machine_rtc_datetime_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
|
|
@ -0,0 +1,4 @@
|
|||
extern uint64_t ticks_ms_64(void);
|
||||
|
||||
// This is the time in seconds since 2000 that the RTC was started.
|
||||
__attribute__((section(".uninitialized"))) static uint32_t rtc_offset[3];
|
|
@ -240,10 +240,26 @@
|
|||
#define MICROPY_PY_MACHINE_RTCOUNTER (0)
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_PY_MACHINE_RTC
|
||||
#define MICROPY_PY_MACHINE_RTC (1)
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_PY_TIME_TICKS
|
||||
#define MICROPY_PY_TIME_TICKS (1)
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_PY_TIME_GMTIME_LOCALTIME_MKTIME
|
||||
#define MICROPY_PY_TIME_GMTIME_LOCALTIME_MKTIME (1)
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_PY_TIME_TIME_TIME_NS
|
||||
#define MICROPY_PY_TIME_TIME_TIME_NS (1)
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_PY_TIME_INCLUDEFILE
|
||||
#define MICROPY_PY_TIME_INCLUDEFILE "ports/nrf/modtime.c"
|
||||
#endif
|
||||
|
||||
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
|
||||
#define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (0)
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ void mp_nrf_start_lfclk(void) {
|
|||
}
|
||||
#endif
|
||||
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTART);
|
||||
rtc_offset_check();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,8 +139,7 @@ void rtc1_init_time_ticks(void) {
|
|||
nrfx_rtc_enable(&rtc1);
|
||||
}
|
||||
|
||||
mp_uint_t mp_hal_ticks_ms(void) {
|
||||
// Compute: (rtc_overflows << 24 + COUNTER) * 1000 / 32768
|
||||
uint64_t ticks_ms_64(void) { // Compute: (rtc_overflows << 24 + COUNTER) * 1000 / 32768
|
||||
//
|
||||
// Note that COUNTER * 1000 / 32768 would overflow during calculation, so use
|
||||
// the less obvious * 125 / 4096 calculation (overflow secure).
|
||||
|
@ -151,7 +151,11 @@ mp_uint_t mp_hal_ticks_ms(void) {
|
|||
uint32_t counter;
|
||||
// guard against overflow irq
|
||||
RTC1_GET_TICKS_ATOMIC(rtc1, overflows, counter)
|
||||
return (overflows << 9) * 1000 + (counter * 125 / 4096);
|
||||
return ((uint64_t)overflows << 9) * 1000 + (counter * 125 / 4096);
|
||||
}
|
||||
|
||||
mp_uint_t mp_hal_ticks_ms(void) {
|
||||
return ticks_ms_64();
|
||||
}
|
||||
|
||||
mp_uint_t mp_hal_ticks_us(void) {
|
||||
|
|
|
@ -74,6 +74,7 @@ void rtc1_init_time_ticks();
|
|||
mp_uint_t mp_hal_ticks_ms(void);
|
||||
#define mp_hal_ticks_us() (0)
|
||||
#endif
|
||||
extern void rtc_offset_check(void);
|
||||
|
||||
// TODO: empty implementation for now. Used by machine_spi.c:69
|
||||
#define mp_hal_delay_us_fast(p)
|
||||
|
|
Ładowanie…
Reference in New Issue