RetiredWizard 2024-04-26 22:49:21 +02:00 zatwierdzone przez GitHub
commit b107a141d5
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
9 zmienionych plików z 234 dodań i 3 usunięć

Wyświetl plik

@ -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 \

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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__

Wyświetl plik

@ -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

Wyświetl plik

@ -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];

Wyświetl plik

@ -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)

Wyświetl plik

@ -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) {

Wyświetl plik

@ -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)