summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--cc3200/application.mk2
-rw-r--r--cc3200/fatfs/src/diskio.c6
-rw-r--r--cc3200/ftp/ftp.c8
-rw-r--r--cc3200/mods/moduos.c4
-rw-r--r--cc3200/mods/modutime.c185
-rw-r--r--cc3200/mods/pybrtc.c10
-rw-r--r--lib/timeutils/timeutils.c211
-rw-r--r--lib/timeutils/timeutils.h (renamed from cc3200/mods/modutime.h)23
-rw-r--r--stmhal/Makefile2
-rw-r--r--stmhal/moduos.c3
-rw-r--r--stmhal/modutime.c205
-rw-r--r--stmhal/portmodules.h2
12 files changed, 262 insertions, 399 deletions
diff --git a/cc3200/application.mk b/cc3200/application.mk
index f3ed40a72b..29be228bd1 100644
--- a/cc3200/application.mk
+++ b/cc3200/application.mk
@@ -21,6 +21,7 @@ APP_INC += -I$(BUILD)/genhdr
APP_INC += -I../lib/fatfs
APP_INC += -I../lib/mp-readline
APP_INC += -I../lib/netutils
+APP_INC += -I../lib/timeutils
APP_INC += -I../stmhal
APP_CPPDEFINES = -Dgcc -DTARGET_IS_CC3200 -DSL_FULL -DUSE_FREERTOS
@@ -144,6 +145,7 @@ APP_LIB_SRC_C = $(addprefix lib/,\
libc/string0.c \
mp-readline/readline.c \
netutils/netutils.c \
+ timeutils/timeutils.c \
)
APP_STM_SRC_C = $(addprefix stmhal/,\
diff --git a/cc3200/fatfs/src/diskio.c b/cc3200/fatfs/src/diskio.c
index 8a6b5704d7..55e7e1916e 100644
--- a/cc3200/fatfs/src/diskio.c
+++ b/cc3200/fatfs/src/diskio.c
@@ -15,12 +15,12 @@
#if MICROPY_HW_HAS_SDCARD
#include "sd_diskio.h" /* SDCARD disk IO API */
#endif
-#include "modutime.h"
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "rom_map.h"
#include "prcm.h"
+#include "timeutils.h"
/* Definitions of physical drive number for each drive */
#define SFLASH 0 /* Map SFLASH drive to drive number 0 */
@@ -192,13 +192,13 @@ DWORD get_fattime (
void
)
{
- mod_struct_time tm;
+ timeutils_struct_time_t tm;
uint32_t seconds;
uint16_t mseconds;
// Get the time from the on-chip RTC and convert it to struct_time
MAP_PRCMRTCGet(&seconds, &mseconds);
- mod_time_seconds_since_2000_to_struct_time(seconds, &tm);
+ timeutils_seconds_since_2000_to_struct_time(seconds, &tm);
return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) |
((tm.tm_mday) << 16) | ((tm.tm_hour) << 11) |
diff --git a/cc3200/ftp/ftp.c b/cc3200/ftp/ftp.c
index ebc9dcd9a0..3dc0923ce2 100644
--- a/cc3200/ftp/ftp.c
+++ b/cc3200/ftp/ftp.c
@@ -40,7 +40,6 @@
#include "ftp.h"
#include "simplelink.h"
#include "modwlan.h"
-#include "modutime.h"
#include "debug.h"
#include "serverstask.h"
#include "ff.h"
@@ -49,6 +48,7 @@
#include "diskio.h"
#include "sd_diskio.h"
#include "updater.h"
+#include "timeutils.h"
/******************************************************************************
@@ -884,7 +884,7 @@ static int ftp_print_eplf_item (char *dest, uint32_t destsize, FILINFO *fno) {
uint16_t mseconds;
uint mindex = (((fno->fdate >> 5) & 0x0f) > 0) ? (((fno->fdate >> 5) & 0x0f) - 1) : 0;
uint day = ((fno->fdate & 0x1f) > 0) ? (fno->fdate & 0x1f) : 1;
- uint fseconds = mod_time_seconds_since_2000(1980 + ((fno->fdate >> 9) & 0x7f),
+ uint fseconds = timeutils_seconds_since_2000(1980 + ((fno->fdate >> 9) & 0x7f),
(fno->fdate >> 5) & 0x0f,
fno->fdate & 0x1f,
(fno->ftime >> 11) & 0x1f,
@@ -912,12 +912,12 @@ static int ftp_print_eplf_item (char *dest, uint32_t destsize, FILINFO *fno) {
}
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name) {
- mod_struct_time tm;
+ timeutils_struct_time_t tm;
uint32_t tseconds;
uint16_t mseconds;
char *type = "d";
- mod_time_seconds_since_2000_to_struct_time((FTP_UNIX_TIME_20150101 - FTP_UNIX_TIME_20000101), &tm);
+ timeutils_seconds_since_2000_to_struct_time((FTP_UNIX_TIME_20150101 - FTP_UNIX_TIME_20000101), &tm);
MAP_PRCMRTCGet(&tseconds, &mseconds);
if (FTP_UNIX_SECONDS_180_DAYS < tseconds - (FTP_UNIX_TIME_20150101 - FTP_UNIX_TIME_20000101)) {
diff --git a/cc3200/mods/moduos.c b/cc3200/mods/moduos.c
index 72f848cfef..71b70be296 100644
--- a/cc3200/mods/moduos.c
+++ b/cc3200/mods/moduos.c
@@ -38,11 +38,11 @@
#include "diskio.h"
#include "sflash_diskio.h"
#include "file.h"
-#include "modutime.h"
#include "random.h"
#include "sd_diskio.h"
#include "mpexception.h"
#include "version.h"
+#include "timeutils.h"
/// \module os - basic "operating system" services
///
@@ -285,7 +285,7 @@ STATIC mp_obj_t os_stat(mp_obj_t path_in) {
} else {
mode |= 0x8000; // stat.S_IFREG
}
- mp_int_t seconds = mod_time_seconds_since_2000(
+ mp_int_t seconds = timeutils_seconds_since_2000(
1980 + ((fno.fdate >> 9) & 0x7f),
(fno.fdate >> 5) & 0x0f,
fno.fdate & 0x1f,
diff --git a/cc3200/mods/modutime.c b/cc3200/mods/modutime.c
index 07896512d8..dc4fcf152c 100644
--- a/cc3200/mods/modutime.c
+++ b/cc3200/mods/modutime.c
@@ -32,7 +32,7 @@
#include MICROPY_HAL_H
#include "py/nlr.h"
#include "py/obj.h"
-#include "modutime.h"
+#include "timeutils.h"
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
@@ -41,126 +41,11 @@
#include "pybrtc.h"
#include "mpexception.h"
-
-// LEAPOCH corresponds to 2000-03-01, which is a mod-400 year, immediately
-// after Feb 29. We calculate seconds as a signed integer relative to that.
-//
-// Our timebase is relative to 2000-01-01.
-
-#define LEAPOCH ((31 + 29) * 86400)
-
-#define DAYS_PER_400Y (365*400 + 97)
-#define DAYS_PER_100Y (365*100 + 24)
-#define DAYS_PER_4Y (365*4 + 1)
-
-
/// \module time - time related functions
///
/// The `time` module provides functions for getting the current time and date,
/// and for sleeping.
-STATIC const uint16_t days_since_jan1[]= { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
-
-STATIC bool is_leap_year(mp_uint_t year) {
- return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
-}
-
-// Month is one based
-STATIC mp_uint_t mod_time_days_in_month(mp_uint_t year, mp_uint_t month) {
- mp_uint_t mdays = days_since_jan1[month] - days_since_jan1[month - 1];
- if (month == 2 && is_leap_year(year)) {
- mdays++;
- }
- return mdays;
-}
-
-// compute the day of the year, between 1 and 366
-// month should be between 1 and 12, date should start at 1
-STATIC mp_uint_t mod_time_year_day(mp_uint_t year, mp_uint_t month, mp_uint_t date) {
- mp_uint_t yday = days_since_jan1[month - 1] + date;
- if (month >= 3 && is_leap_year(year)) {
- yday += 1;
- }
- return yday;
-}
-
-// returns the number of seconds, as an integer, since 2000-01-01
-mp_uint_t mod_time_seconds_since_2000(mp_uint_t year, mp_uint_t month, mp_uint_t date, mp_uint_t hour, mp_uint_t minute, mp_uint_t second) {
- return
- second
- + minute * 60
- + hour * 3600
- + (mod_time_year_day(year, month, date) - 1
- + ((year - 2000 + 3) / 4) // add a day each 4 years starting with 2001
- - ((year - 2000 + 99) / 100) // subtract a day each 100 years starting with 2001
- + ((year - 2000 + 399) / 400) // add a day each 400 years starting with 2001
- ) * 86400
- + (year - 2000) * 31536000;
-}
-
-void mod_time_seconds_since_2000_to_struct_time(mp_uint_t t, mod_struct_time *tm) {
- // The following algorithm was adapted from musl's __secs_to_tm and adapted
- // for differences in Micro Python's timebase.
-
- mp_int_t seconds = t - LEAPOCH;
-
- mp_int_t days = seconds / 86400;
- seconds %= 86400;
- tm->tm_hour = seconds / 3600;
- tm->tm_min = seconds / 60 % 60;
- tm->tm_sec = seconds % 60;
-
- mp_int_t wday = (days + 2) % 7; // Mar 1, 2000 was a Wednesday (2)
- if (wday < 0) {
- wday += 7;
- }
- tm->tm_wday = wday;
-
- mp_int_t qc_cycles = days / DAYS_PER_400Y;
- days %= DAYS_PER_400Y;
- if (days < 0) {
- days += DAYS_PER_400Y;
- qc_cycles--;
- }
- mp_int_t c_cycles = days / DAYS_PER_100Y;
- if (c_cycles == 4) {
- c_cycles--;
- }
- days -= (c_cycles * DAYS_PER_100Y);
-
- mp_int_t q_cycles = days / DAYS_PER_4Y;
- if (q_cycles == 25) {
- q_cycles--;
- }
- days -= q_cycles * DAYS_PER_4Y;
-
- mp_int_t years = days / 365;
- if (years == 4) {
- years--;
- }
- days -= (years * 365);
-
- tm->tm_year = 2000 + years + 4 * q_cycles + 100 * c_cycles + 400 * qc_cycles;
-
- // Note: days_in_month[0] corresponds to March
- STATIC const int8_t days_in_month[] = {31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29};
-
- mp_int_t month;
- for (month = 0; days_in_month[month] <= days; month++) {
- days -= days_in_month[month];
- }
-
- tm->tm_mon = month + 2;
- if (tm->tm_mon >= 12) {
- tm->tm_mon -= 12;
- tm->tm_year++;
- }
- tm->tm_mday = days + 1; // Make one based
- tm->tm_mon++; // Make one based
-
- tm->tm_yday = mod_time_year_day(tm->tm_year, tm->tm_mon, tm->tm_mday);
-}
-
/// \function localtime([secs])
/// Convert a time expressed in seconds since Jan 1, 2000 into an 8-tuple which
/// contains: (year, month, mday, hour, minute, second, weekday, yearday)
@@ -175,14 +60,14 @@ void mod_time_seconds_since_2000_to_struct_time(mp_uint_t t, mod_struct_time *tm
/// yearday is 1-366
STATIC mp_obj_t time_localtime(mp_uint_t n_args, const mp_obj_t *args) {
if (n_args == 0 || args[0] == mp_const_none) {
- mod_struct_time tm;
+ timeutils_struct_time_t tm;
uint32_t seconds;
uint16_t mseconds;
// get the seconds and the milliseconds from the RTC
MAP_PRCMRTCGet(&seconds, &mseconds);
mseconds = RTC_CYCLES_U16MS(mseconds);
- mod_time_seconds_since_2000_to_struct_time(seconds, &tm);
+ timeutils_seconds_since_2000_to_struct_time(seconds, &tm);
mp_obj_t tuple[8] = {
mp_obj_new_int(tm.tm_year),
@@ -197,8 +82,8 @@ STATIC mp_obj_t time_localtime(mp_uint_t n_args, const mp_obj_t *args) {
return mp_obj_new_tuple(8, tuple);
} else {
mp_int_t seconds = mp_obj_get_int(args[0]);
- mod_struct_time tm;
- mod_time_seconds_since_2000_to_struct_time(seconds, &tm);
+ timeutils_struct_time_t tm;
+ timeutils_seconds_since_2000_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),
@@ -231,64 +116,10 @@ STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments));
}
- mp_int_t year = mp_obj_get_int(elem[0]);
- mp_int_t month = mp_obj_get_int(elem[1]);
- mp_int_t mday = mp_obj_get_int(elem[2]);
- mp_int_t hours = mp_obj_get_int(elem[3]);
- mp_int_t minutes = mp_obj_get_int(elem[4]);
- mp_int_t seconds = mp_obj_get_int(elem[5]);
+ 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])));
- // Normalize the tuple. This allows things like:
- //
- // tm_tomorrow = list(time.localtime())
- // tm_tomorrow[2] += 1 # Adds 1 to mday
- // tomorrow = time.mktime(tm_tommorrow)
- //
- // And not have to worry about all the weird overflows.
- //
- // You can subtract dates/times this way as well.
-
- minutes += seconds / 60;
- if ((seconds = seconds % 60) < 0) {
- seconds += 60;
- minutes--;
- }
-
- hours += minutes / 60;
- if ((minutes = minutes % 60) < 0) {
- minutes += 60;
- hours--;
- }
-
- mday += hours / 24;
- if ((hours = hours % 24) < 0) {
- hours += 24;
- mday--;
- }
-
- month--; // make month zero based
- year += month / 12;
- if ((month = month % 12) < 0) {
- month += 12;
- year--;
- }
- month++; // back to one based
-
- while (mday < 1) {
- if (--month == 0) {
- month = 12;
- year--;
- }
- mday += mod_time_days_in_month(year, month);
- }
- while (mday > mod_time_days_in_month(year, month)) {
- mday -= mod_time_days_in_month(year, month);
- if (++month == 13) {
- month = 1;
- year++;
- }
- }
- return mp_obj_new_int_from_uint(mod_time_seconds_since_2000(year, month, mday, hours, minutes, seconds));
}
MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime);
diff --git a/cc3200/mods/pybrtc.c b/cc3200/mods/pybrtc.c
index 95b676d4a3..d57e11167c 100644
--- a/cc3200/mods/pybrtc.c
+++ b/cc3200/mods/pybrtc.c
@@ -31,7 +31,6 @@
#include MICROPY_HAL_H
#include "py/obj.h"
#include "py/runtime.h"
-#include "modutime.h"
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
@@ -40,6 +39,7 @@
#include "pybrtc.h"
#include "pybsleep.h"
#include "mpcallback.h"
+#include "timeutils.h"
/// \moduleref pyb
/// \class RTC - real time clock
@@ -82,7 +82,7 @@ void pybrtc_init(void) {
// fresh reset; configure the RTC Calendar
// set the date to 1st Jan 2015
// set the time to 00:00:00
- uint32_t seconds = mod_time_seconds_since_2000(2015, 1, 1, 0, 0, 0);
+ uint32_t seconds = timeutils_seconds_since_2000(2015, 1, 1, 0, 0, 0);
// Mark the RTC in use first
MAP_PRCMRTCInUseSet();
@@ -137,7 +137,7 @@ STATIC void pyb_rtc_callback_disable (mp_obj_t self_in) {
/// `weekday` is 0-6 for Monday through Sunday.
///
mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
- mod_struct_time tm;
+ timeutils_struct_time_t tm;
uint32_t seconds;
uint16_t mseconds;
@@ -145,7 +145,7 @@ mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
// get the seconds and the milliseconds from the RTC
MAP_PRCMRTCGet(&seconds, &mseconds);
mseconds = RTC_CYCLES_U16MS(mseconds);
- mod_time_seconds_since_2000_to_struct_time(seconds, &tm);
+ timeutils_seconds_since_2000_to_struct_time(seconds, &tm);
mp_obj_t tuple[8] = {
mp_obj_new_int(tm.tm_year),
@@ -172,7 +172,7 @@ mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
tm.tm_sec = mp_obj_get_int(items[6]);
mseconds = mp_obj_get_int(items[7]);
- seconds = mod_time_seconds_since_2000(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
+ seconds = timeutils_seconds_since_2000(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
mseconds = RTC_U16MS_CYCLES(mseconds);
MAP_PRCMRTCSet(seconds, mseconds);
diff --git a/lib/timeutils/timeutils.c b/lib/timeutils/timeutils.c
new file mode 100644
index 0000000000..77e5f043f1
--- /dev/null
+++ b/lib/timeutils/timeutils.c
@@ -0,0 +1,211 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2015 Daniel Campora
+ *
+ * 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 "timeutils.h"
+
+// LEAPOCH corresponds to 2000-03-01, which is a mod-400 year, immediately
+// after Feb 29. We calculate seconds as a signed integer relative to that.
+//
+// Our timebase is is relative to 2000-01-01.
+
+#define LEAPOCH ((31 + 29) * 86400)
+
+#define DAYS_PER_400Y (365*400 + 97)
+#define DAYS_PER_100Y (365*100 + 24)
+#define DAYS_PER_4Y (365*4 + 1)
+
+STATIC const uint16_t days_since_jan1[]= { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
+
+bool timeutils_is_leap_year(mp_uint_t year) {
+ return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
+}
+
+// month is one based
+mp_uint_t timeutils_days_in_month(mp_uint_t year, mp_uint_t month) {
+ mp_uint_t mdays = days_since_jan1[month] - days_since_jan1[month - 1];
+ if (month == 2 && timeutils_is_leap_year(year)) {
+ mdays++;
+ }
+ return mdays;
+}
+
+// compute the day of the year, between 1 and 366
+// month should be between 1 and 12, date should start at 1
+mp_uint_t timeutils_year_day(mp_uint_t year, mp_uint_t month, mp_uint_t date) {
+ mp_uint_t yday = days_since_jan1[month - 1] + date;
+ if (month >= 3 && timeutils_is_leap_year(year)) {
+ yday += 1;
+ }
+ return yday;
+}
+
+void timeutils_seconds_since_2000_to_struct_time(mp_uint_t t, timeutils_struct_time_t *tm) {
+ // The following algorithm was adapted from musl's __secs_to_tm and adapted
+ // for differences in Micro Python's timebase.
+
+ mp_int_t seconds = t - LEAPOCH;
+
+ mp_int_t days = seconds / 86400;
+ seconds %= 86400;
+ tm->tm_hour = seconds / 3600;
+ tm->tm_min = seconds / 60 % 60;
+ tm->tm_sec = seconds % 60;
+
+ mp_int_t wday = (days + 2) % 7; // Mar 1, 2000 was a Wednesday (2)
+ if (wday < 0) {
+ wday += 7;
+ }
+ tm->tm_wday = wday;
+
+ mp_int_t qc_cycles = days / DAYS_PER_400Y;
+ days %= DAYS_PER_400Y;
+ if (days < 0) {
+ days += DAYS_PER_400Y;
+ qc_cycles--;
+ }
+ mp_int_t c_cycles = days / DAYS_PER_100Y;
+ if (c_cycles == 4) {
+ c_cycles--;
+ }
+ days -= (c_cycles * DAYS_PER_100Y);
+
+ mp_int_t q_cycles = days / DAYS_PER_4Y;
+ if (q_cycles == 25) {
+ q_cycles--;
+ }
+ days -= q_cycles * DAYS_PER_4Y;
+
+ mp_int_t years = days / 365;
+ if (years == 4) {
+ years--;
+ }
+ days -= (years * 365);
+
+ /* We will compute tm_yday at the very end
+ mp_int_t leap = !years && (q_cycles || !c_cycles);
+
+ tm->tm_yday = days + 31 + 28 + leap;
+ if (tm->tm_yday >= 365 + leap) {
+ tm->tm_yday -= 365 + leap;
+ }
+
+ tm->tm_yday++; // Make one based
+ */
+
+ tm->tm_year = 2000 + years + 4 * q_cycles + 100 * c_cycles + 400 * qc_cycles;
+
+ // Note: days_in_month[0] corresponds to March
+ STATIC const int8_t days_in_month[] = {31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29};
+
+ mp_int_t month;
+ for (month = 0; days_in_month[month] <= days; month++) {
+ days -= days_in_month[month];
+ }
+
+ tm->tm_mon = month + 2;
+ if (tm->tm_mon >= 12) {
+ tm->tm_mon -= 12;
+ tm->tm_year++;
+ }
+ tm->tm_mday = days + 1; // Make one based
+ tm->tm_mon++; // Make one based
+
+ tm->tm_yday = timeutils_year_day(tm->tm_year, tm->tm_mon, tm->tm_mday);
+}
+
+// returns the number of seconds, as an integer, since 2000-01-01
+mp_uint_t timeutils_seconds_since_2000(mp_uint_t year, mp_uint_t month,
+ mp_uint_t date, mp_uint_t hour, mp_uint_t minute, mp_uint_t second) {
+ return
+ second
+ + minute * 60
+ + hour * 3600
+ + (timeutils_year_day(year, month, date) - 1
+ + ((year - 2000 + 3) / 4) // add a day each 4 years starting with 2001
+ - ((year - 2000 + 99) / 100) // subtract a day each 100 years starting with 2001
+ + ((year - 2000 + 399) / 400) // add a day each 400 years starting with 2001
+ ) * 86400
+ + (year - 2000) * 31536000;
+}
+
+mp_uint_t timeutils_mktime(mp_uint_t year, mp_uint_t month, mp_uint_t mday,
+ mp_uint_t hours, mp_uint_t minutes, mp_uint_t seconds) {
+
+ // Normalize the tuple. This allows things like:
+ //
+ // tm_tomorrow = list(time.localtime())
+ // tm_tomorrow[2] += 1 # Adds 1 to mday
+ // tomorrow = time.mktime(tm_tommorrow)
+ //
+ // And not have to worry about all the weird overflows.
+ //
+ // You can subtract dates/times this way as well.
+
+ minutes += seconds / 60;
+ if ((seconds = seconds % 60) < 0) {
+ seconds += 60;
+ minutes--;
+ }
+
+ hours += minutes / 60;
+ if ((minutes = minutes % 60) < 0) {
+ minutes += 60;
+ hours--;
+ }
+
+ mday += hours / 24;
+ if ((hours = hours % 24) < 0) {
+ hours += 24;
+ mday--;
+ }
+
+ month--; // make month zero based
+ year += month / 12;
+ if ((month = month % 12) < 0) {
+ month += 12;
+ year--;
+ }
+ month++; // back to one based
+
+ while (mday < 1) {
+ if (--month == 0) {
+ month = 12;
+ year--;
+ }
+ mday += timeutils_days_in_month(year, month);
+ }
+ while (mday > timeutils_days_in_month(year, month)) {
+ mday -= timeutils_days_in_month(year, month);
+ if (++month == 13) {
+ month = 1;
+ year++;
+ }
+ }
+ return timeutils_seconds_since_2000(year, month, mday, hours, minutes, seconds);
+}
diff --git a/cc3200/mods/modutime.h b/lib/timeutils/timeutils.h
index 17481a0644..d6e3536ad7 100644
--- a/cc3200/mods/modutime.h
+++ b/lib/timeutils/timeutils.h
@@ -25,10 +25,10 @@
* THE SOFTWARE.
*/
-#ifndef MODUTIME_H_
-#define MODUTIME_H_
+#ifndef __MICROPY_INCLUDED_LIB_TIMEUTILS_H__
+#define __MICROPY_INCLUDED_LIB_TIMEUTILS_H__
-typedef struct {
+typedef struct _timeutils_struct_time_t {
uint16_t tm_year; // i.e. 2014
uint8_t tm_mon; // 1..12
uint8_t tm_mday; // 1..31
@@ -37,12 +37,19 @@ typedef struct {
uint8_t tm_sec; // 0..59
uint8_t tm_wday; // 0..6 0 = Monday
uint16_t tm_yday; // 1..366
-} mod_struct_time;
+} timeutils_struct_time_t;
+bool timeutils_is_leap_year(mp_uint_t year);
+mp_uint_t timeutils_days_in_month(mp_uint_t year, mp_uint_t month);
+mp_uint_t timeutils_year_day(mp_uint_t year, mp_uint_t month, mp_uint_t date);
-extern mp_uint_t mod_time_seconds_since_2000(mp_uint_t year, mp_uint_t month, mp_uint_t date,
- mp_uint_t hour, mp_uint_t minute, mp_uint_t second);
+void timeutils_seconds_since_2000_to_struct_time(mp_uint_t t,
+ timeutils_struct_time_t *tm);
-extern void mod_time_seconds_since_2000_to_struct_time(mp_uint_t t, mod_struct_time *tm);
+mp_uint_t timeutils_seconds_since_2000(mp_uint_t year, mp_uint_t month,
+ mp_uint_t date, mp_uint_t hour, mp_uint_t minute, mp_uint_t second);
-#endif // MODUTIME_H_
+mp_uint_t timeutils_mktime(mp_uint_t year, mp_uint_t month, mp_uint_t mday,
+ mp_uint_t hours, mp_uint_t minutes, mp_uint_t seconds);
+
+#endif // __MICROPY_INCLUDED_LIB_TIMEUTILS_H__
diff --git a/stmhal/Makefile b/stmhal/Makefile
index 60f05669b2..5751ad4059 100644
--- a/stmhal/Makefile
+++ b/stmhal/Makefile
@@ -42,6 +42,7 @@ INC += -I$(USBDEV_DIR)/core/inc -I$(USBDEV_DIR)/class/inc
#INC += -I$(USBHOST_DIR)
INC += -I../lib/mp-readline
INC += -I../lib/netutils
+INC += -I../lib/timeutils
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion
CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_MOD) $(CFLAGS_CORTEX_M4) $(COPT)
@@ -94,6 +95,7 @@ SRC_LIB = $(addprefix lib/,\
fatfs/option/ccsbcs.c \
mp-readline/readline.c \
netutils/netutils.c \
+ timeutils/timeutils.c \
)
SRC_C = \
diff --git a/stmhal/moduos.c b/stmhal/moduos.c
index 24f2e0f1f2..55404c77bd 100644
--- a/stmhal/moduos.c
+++ b/stmhal/moduos.c
@@ -34,6 +34,7 @@
#include "genhdr/mpversion.h"
#include "lib/fatfs/ff.h"
#include "lib/fatfs/diskio.h"
+#include "timeutils.h"
#include "rng.h"
#include "file.h"
#include "sdcard.h"
@@ -322,7 +323,7 @@ STATIC mp_obj_t os_stat(mp_obj_t path_in) {
} else {
mode |= 0x8000; // stat.S_IFREG
}
- mp_int_t seconds = mod_time_seconds_since_2000(
+ mp_int_t seconds = timeutils_seconds_since_2000(
1980 + ((fno.fdate >> 9) & 0x7f),
(fno.fdate >> 5) & 0x0f,
fno.fdate & 0x1f,
diff --git a/stmhal/modutime.c b/stmhal/modutime.c
index b918b1e9a7..75605a37c3 100644
--- a/stmhal/modutime.c
+++ b/stmhal/modutime.c
@@ -30,6 +30,7 @@
#include "py/nlr.h"
#include "py/obj.h"
+#include "timeutils.h"
#include "portmodules.h"
#include "rtc.h"
@@ -38,141 +39,6 @@
/// The `time` module provides functions for getting the current time and date,
/// and for sleeping.
-STATIC const uint16_t days_since_jan1[]= { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
-
-STATIC bool is_leap_year(mp_uint_t year) {
- return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
-}
-
-// Month is one based
-STATIC mp_uint_t mod_time_days_in_month(mp_uint_t year, mp_uint_t month) {
- mp_uint_t mdays = days_since_jan1[month] - days_since_jan1[month - 1];
- if (month == 2 && is_leap_year(year)) {
- mdays++;
- }
- return mdays;
-}
-
-// compute the day of the year, between 1 and 366
-// month should be between 1 and 12, date should start at 1
-STATIC mp_uint_t mod_time_year_day(mp_uint_t year, mp_uint_t month, mp_uint_t date) {
- mp_uint_t yday = days_since_jan1[month - 1] + date;
- if (month >= 3 && is_leap_year(year)) {
- yday += 1;
- }
- return yday;
-}
-
-// returns the number of seconds, as an integer, since 2000-01-01
-mp_uint_t mod_time_seconds_since_2000(mp_uint_t year, mp_uint_t month, mp_uint_t date, mp_uint_t hour, mp_uint_t minute, mp_uint_t second) {
- return
- second
- + minute * 60
- + hour * 3600
- + (mod_time_year_day(year, month, date) - 1
- + ((year - 2000 + 3) / 4) // add a day each 4 years starting with 2001
- - ((year - 2000 + 99) / 100) // subtract a day each 100 years starting with 2001
- + ((year - 2000 + 399) / 400) // add a day each 400 years starting with 2001
- ) * 86400
- + (year - 2000) * 31536000;
-}
-
-// LEAPOCH corresponds to 2000-03-01, which is a mod-400 year, immediately
-// after Feb 29. We calculate seconds as a signed integer relative to that.
-//
-// Our timebase is is relative to 2000-01-01.
-
-#define LEAPOCH ((31 + 29) * 86400)
-
-#define DAYS_PER_400Y (365*400 + 97)
-#define DAYS_PER_100Y (365*100 + 24)
-#define DAYS_PER_4Y (365*4 + 1)
-
-typedef struct {
- uint16_t tm_year; // i.e. 2014
- uint8_t tm_mon; // 1..12
- uint8_t tm_mday; // 1..31
- uint8_t tm_hour; // 0..23
- uint8_t tm_min; // 0..59
- uint8_t tm_sec; // 0..59
- uint8_t tm_wday; // 0..6 0 = Monday
- uint16_t tm_yday; // 1..366
-} mod_struct_time;
-
-STATIC void mod_time_seconds_since_2000_to_struct_time(mp_uint_t t, mod_struct_time *tm) {
- // The following algorithm was adapted from musl's __secs_to_tm and adapted
- // for differences in Micro Python's timebase.
-
- mp_int_t seconds = t - LEAPOCH;
-
- mp_int_t days = seconds / 86400;
- seconds %= 86400;
- tm->tm_hour = seconds / 3600;
- tm->tm_min = seconds / 60 % 60;
- tm->tm_sec = seconds % 60;
-
- mp_int_t wday = (days + 2) % 7; // Mar 1, 2000 was a Wednesday (2)
- if (wday < 0) {
- wday += 7;
- }
- tm->tm_wday = wday;
-
- mp_int_t qc_cycles = days / DAYS_PER_400Y;
- days %= DAYS_PER_400Y;
- if (days < 0) {
- days += DAYS_PER_400Y;
- qc_cycles--;
- }
- mp_int_t c_cycles = days / DAYS_PER_100Y;
- if (c_cycles == 4) {
- c_cycles--;
- }
- days -= (c_cycles * DAYS_PER_100Y);
-
- mp_int_t q_cycles = days / DAYS_PER_4Y;
- if (q_cycles == 25) {
- q_cycles--;
- }
- days -= q_cycles * DAYS_PER_4Y;
-
- mp_int_t years = days / 365;
- if (years == 4) {
- years--;
- }
- days -= (years * 365);
-
- /* We will compute tm_yday at the very end
- mp_int_t leap = !years && (q_cycles || !c_cycles);
-
- tm->tm_yday = days + 31 + 28 + leap;
- if (tm->tm_yday >= 365 + leap) {
- tm->tm_yday -= 365 + leap;
- }
-
- tm->tm_yday++; // Make one based
- */
-
- tm->tm_year = 2000 + years + 4 * q_cycles + 100 * c_cycles + 400 * qc_cycles;
-
- // Note: days_in_month[0] corresponds to March
- STATIC const int8_t days_in_month[] = {31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29};
-
- mp_int_t month;
- for (month = 0; days_in_month[month] <= days; month++) {
- days -= days_in_month[month];
- }
-
- tm->tm_mon = month + 2;
- if (tm->tm_mon >= 12) {
- tm->tm_mon -= 12;
- tm->tm_year++;
- }
- tm->tm_mday = days + 1; // Make one based
- tm->tm_mon++; // Make one based
-
- tm->tm_yday = mod_time_year_day(tm->tm_year, tm->tm_mon, tm->tm_mday);
-}
-
/// \function localtime([secs])
/// Convert a time expressed in seconds since Jan 1, 2000 into an 8-tuple which
/// contains: (year, month, mday, hour, minute, second, weekday, yearday)
@@ -201,13 +67,13 @@ STATIC mp_obj_t time_localtime(mp_uint_t n_args, const mp_obj_t *args) {
mp_obj_new_int(time.Minutes),
mp_obj_new_int(time.Seconds),
mp_obj_new_int(date.WeekDay - 1),
- mp_obj_new_int(mod_time_year_day(2000 + date.Year, date.Month, date.Date)),
+ mp_obj_new_int(timeutils_year_day(2000 + date.Year, date.Month, date.Date)),
};
return mp_obj_new_tuple(8, tuple);
} else {
mp_int_t seconds = mp_obj_get_int(args[0]);
- mod_struct_time tm;
- mod_time_seconds_since_2000_to_struct_time(seconds, &tm);
+ timeutils_struct_time_t tm;
+ timeutils_seconds_since_2000_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),
@@ -240,64 +106,9 @@ STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "mktime needs a tuple of length 8 or 9 (%d given)", len));
}
- mp_int_t year = mp_obj_get_int(elem[0]);
- mp_int_t month = mp_obj_get_int(elem[1]);
- mp_int_t mday = mp_obj_get_int(elem[2]);
- mp_int_t hours = mp_obj_get_int(elem[3]);
- mp_int_t minutes = mp_obj_get_int(elem[4]);
- mp_int_t seconds = mp_obj_get_int(elem[5]);
-
- // Normalise the tuple. This allows things like:
- //
- // tm_tomorrow = list(time.localtime())
- // tm_tomorrow[2] += 1 # Adds 1 to mday
- // tomorrow = time.mktime(tm_tommorrow)
- //
- // And not have to worry about all the weird overflows.
- //
- // You can subtract dates/times this way as well.
-
- minutes += seconds / 60;
- if ((seconds = seconds % 60) < 0) {
- seconds += 60;
- minutes--;
- }
-
- hours += minutes / 60;
- if ((minutes = minutes % 60) < 0) {
- minutes += 60;
- hours--;
- }
-
- mday += hours / 24;
- if ((hours = hours % 24) < 0) {
- hours += 24;
- mday--;
- }
-
- month--; // make month zero based
- year += month / 12;
- if ((month = month % 12) < 0) {
- month += 12;
- year--;
- }
- month++; // back to one based
-
- while (mday < 1) {
- if (--month == 0) {
- month = 12;
- year--;
- }
- mday += mod_time_days_in_month(year, month);
- }
- while (mday > mod_time_days_in_month(year, month)) {
- mday -= mod_time_days_in_month(year, month);
- if (++month == 13) {
- month = 1;
- year++;
- }
- }
- return mp_obj_new_int_from_uint(mod_time_seconds_since_2000(year, month, mday, hours, minutes, seconds));
+ 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);
@@ -328,7 +139,7 @@ STATIC mp_obj_t time_time(void) {
RTC_TimeTypeDef time;
HAL_RTC_GetTime(&RTCHandle, &time, FORMAT_BIN);
HAL_RTC_GetDate(&RTCHandle, &date, FORMAT_BIN);
- return mp_obj_new_int(mod_time_seconds_since_2000(2000 + date.Year, date.Month, date.Date, time.Hours, time.Minutes, time.Seconds));
+ return mp_obj_new_int(timeutils_seconds_since_2000(2000 + date.Year, date.Month, date.Date, time.Hours, time.Minutes, time.Seconds));
}
MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
diff --git a/stmhal/portmodules.h b/stmhal/portmodules.h
index 66354f7723..8c2ee6bf87 100644
--- a/stmhal/portmodules.h
+++ b/stmhal/portmodules.h
@@ -34,5 +34,3 @@ extern const mp_obj_module_t mp_module_usocket;
// additional helper functions exported by the modules
MP_DECLARE_CONST_FUN_OBJ(mod_os_sync_obj);
-
-mp_uint_t mod_time_seconds_since_2000(mp_uint_t year, mp_uint_t month, mp_uint_t date, mp_uint_t hour, mp_uint_t minute, mp_uint_t second);