From 58db663ae63857693711a15df412503add1b0fec Mon Sep 17 00:00:00 2001 From: lephe Date: Mon, 8 Aug 2016 15:01:33 +0200 Subject: [PATCH] Some time manipulation. Added the targets to the .gitignore file. --- .gitignore | 5 ++++ Makefile | 2 +- README.md | 2 +- TODO | 3 +-- gintdemo.g1a | Bin 42194 -> 41970 bytes include/internals/time.h | 16 +++++++++++ include/rtc.h | 14 +++++----- include/time.h | 49 ++++++++++++++++++++++++++++++--- libc.a | Bin 15700 -> 23214 bytes libgint.a | Bin 73134 -> 72826 bytes src/rtc/rtc_getTime.c | 27 +++++-------------- src/rtc/rtc_setTime.c | 7 ++++- src/time/asctime.c | 57 +++++++++++++++++++++++++++++++++++++++ src/time/ctime.c | 13 +++++++++ src/time/gmtime.c | 45 +++++++++++++++++++++++++++++++ src/time/mktime.c | 41 ++++++---------------------- src/time/time.c | 29 ++++++++++++++++++++ src/time/time_misc.c | 1 + src/time/time_util.c | 28 +++++++++++++++++++ 19 files changed, 268 insertions(+), 71 deletions(-) create mode 100644 include/internals/time.h create mode 100644 src/time/asctime.c create mode 100644 src/time/ctime.c create mode 100644 src/time/gmtime.c create mode 100644 src/time/time.c create mode 100644 src/time/time_util.c diff --git a/.gitignore b/.gitignore index 6caafaa..266d49b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,8 @@ build/** # Some notes. LIBC + +# Output files +libc.a +libgint.a +gintdemo.g1a diff --git a/Makefile b/Makefile index d6d809c..6081443 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ # Modules modules-gint = core keyboard mmu mpu rtc screen timer \ bopti display gray tales -modules-libc = setjmp string stdio stdlib +modules-libc = setjmp string stdio stdlib time # Targets target-g1a = gintdemo.g1a diff --git a/README.md b/README.md index 5892e31..f3b5fad 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ register access and implements a few standard functions. Building and installing ----------------------- -There a some dependencies: +There are some dependencies: * The `sh3eb-elf` toolchain somewhere in the PATH * The fxSDK installed and available in the PATH diff --git a/TODO b/TODO index 56f0be3..9abcd57 100644 --- a/TODO +++ b/TODO @@ -18,11 +18,10 @@ + partial transparency + gint vs. ML with 248x124 at (-60, -28) + call exit handlers -+ compute frequencies ++ compute frequencies and CLOCKS_PER_SEC + test all font encodings - improve exception handler debugging information (if possible) -- full rtc driver (time) - callbacks and complete user API ~ packed bit fields diff --git a/gintdemo.g1a b/gintdemo.g1a index ead9e3896ecfa1fd26cd34036cb168240568ae0e..3a5351fc8842e6a227d90d4ef400cc8858cd1f75 100644 GIT binary patch delta 3646 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 Vi$CXR4c&{#p}ubM{q}9&e*mB#sV4vc diff --git a/include/internals/time.h b/include/internals/time.h new file mode 100644 index 0000000..236dcf6 --- /dev/null +++ b/include/internals/time.h @@ -0,0 +1,16 @@ +#ifndef _INTERNALS_TIME_H +#define _INTERNALS_TIME_H 1 + +/* + isLeap() + Determines whether the given year is a leap year. +*/ +int isLeap(int year); + +/* + daysInMonth() + Returns number of days for the given month (between 0 and 11) and year. +*/ +int daysInMonth(int month, int year); + +#endif // _INTERNALS_TIME_H diff --git a/include/rtc.h b/include/rtc.h index 2266713..08d9880 100644 --- a/include/rtc.h +++ b/include/rtc.h @@ -15,9 +15,7 @@ /* struct RTCTime - Defines a point in time. This structure *is* the standard struct tm to - avoid useless data copy in the interface between this module and the - standard time module. + Defines a point in time. */ struct RTCTime { @@ -26,21 +24,21 @@ struct RTCTime int hours; // Hours in range 0-23 int month_day; // Day of month in range 1-31 int month; // Month in range 0-11 - int year; // Number of years since 1900 + int year; // Years (full value) int week_day; // Day of week in range 0(Sunday)-6(Saturday). - int year_day; // Day of the year in range 0-365. - int daylight_saving; // As far as I known the RTC does not use DST. }; /* rtc_getTime() - Reads the current time from the RTC. + Reads the current time from the RTC. There is no guarantee that the + week day is correct (use the time API for that). */ struct RTCTime rtc_getTime(void); /* rtc_setTime() - Sets the time in the RTC registers. + Sets the time in the RTC registers. The week day is set to 0 if greater + than 6. Other fields are not checked. */ void rtc_setTime(struct RTCTime time); diff --git a/include/time.h b/include/time.h index 2fd712a..107e4fc 100644 --- a/include/time.h +++ b/include/time.h @@ -29,7 +29,7 @@ struct tm int tm_year; // Number of years since 1900 int tm_wday; // Day of week in range 0(Sunday)-6(Saturday). int tm_yday; // Day of the year in range 0-365. - int tm_isdst; // Always -1 (not available). + int tm_isdst; // This will always be 0. }; /* @@ -57,6 +57,17 @@ typedef signed int time_t; */ clock_t clock(void); +/* + time() + Returns the current time as calendar time. If you need a broken-down + time, either use the RTC API or gmtime(). However, this function is + already based on mktime() (for hardware reasons) so it would be much + faster to use the RTC API if possible. + If timeptr is not NULL, it is set to the current time, that is, the + value that is returned. +*/ +time_t time(time_t *timeptr); + /* difftime() Returns the number of seconds between the given points. @@ -71,15 +82,45 @@ double difftime(time_t end, time_t beginning); // Time representation. //--- +/* + asctime() + Converts broken-down time to string representation on the form + "Wed Jun 30 21:49:08 1993\n". The returned string is statically + allocated and may be overwritten by any subsequent call to a time + function. +*/ +char *asctime(const struct tm *time); + +/* + ctime() + Converts calendar time to string representation on the form + "Wed Jun 30 21:49:08 1993\n". The returned string is statically + allocated and may be overwritten by any subsequent call to a time + function. +*/ +char *ctime(const time_t *timer); + + + //--- -// +// Time conversion. //--- /* mktime() - Computes fields tm_wday and tm_yday using the other fields. Member - structures outside their range are normalized and tm_isdst is set. + Converts broken-down time to calendar time. Computes structure fields + tm_wday and tm_yday using the other fields. Member structures outside + their range are normalized (e.g. 40 October becomes 9 November) and + tm_isdst is set. */ time_t mktime(struct tm *time); +/* + gmtime() + Converts calendar time to broken-down time. The returned pointer is + statically allocated and may be overwritten by any subsequent call to + a time function. +*/ +struct tm *gmtime(const time_t *t); + #endif // _TIME_H diff --git a/libc.a b/libc.a index b460e143f5afada1697270d43ba9f14e3aa6c039..87fbcfa2278e2a36eb1acb0b53f07c9b7f97a526 100644 GIT binary patch delta 4232 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 delta 437 zcmZ3tmGMf|1etmRGgEU5a|Hzh1rR_c6%>rjOu(WF3JF{c3=EV74~lu0 z#6ytzle0t|H#bXjL&eM?Zjx)^fw%#}_tN%2kzc3hfW(*B%wxoc#24GFXF37u29SR7 Q&9}|@Ve*?lSn)9f01cOHJ^%m! diff --git a/libgint.a b/libgint.a index ce45882548005403801e4a9a3bc8e91a326127a9..422f0d167ec81d3b3f27c719472267edcfc93ff4 100644 GIT binary patch delta 1697 zcmb7EdrVtZ82`@g1KL%o*M-|P)f$SF8Ma<%LD&exb(2W6L+2~#u*gd~B@WD72%%&a zanrEEL8eVzaOj+I(TwB99&wT^E*nl3aA7k_%jwDF zLCJ7m3==tB(8hC~wY!9PJRu+Em;{~YH1S-0-Vx4W8n<^{zKVw}+)&1KN=fAO#x1-A zVl1v!xX39J>3T|x3oDVc&)C#FO)x~uf8ma@o|P}Y6o^kt`nFBSVe0R7bN>$`NFuhX zia0)*9ITn*m;`-kI-ZNw`E$eFxb2Y0pN&=?ix~aSFRNqs?py^IZjewemgm>_jR2qm z7kvYygATNgcPEjf+i_@Eb{sDkcPwV+ye|x|?GbLwbv$=tE+9_nw;KX0eWcP5NG=Xn z83JZ~TeTrz(VJ@wty0B30aLlbOD-hIM^Xf@yD%&!Lz~xKxm9o86lPWtsoT6;t132! z)#eLH)$)^~plS0~R5v^x)=-1|vZ&Iwc^kA$e_d32orTnmhHxe@OH+;WT2j#}d+oK# zgqj4i+;n}~-Lzk?dRt|d^F@u~NWi}pwxG+{Q)@%#ar-N20!qZ5`lU~MuAPGB^>)gSQ{95sh3uLz zbzF@b_onjS5p=F1-|hWUIU4jR2zgmJb3Oy@!hOLiYsQw8a?x6}W6}CzW}3Cu+PF`( zZT@O{4+7msMPqiH(~)X=dTtU%9%%U>bB#_vG5tiw1Y}8h1$Z^y+3~E}ZUh}3>gYvR zaeZfzF%ck{eCcwvtn<+BzvmDDGQ>soDS z8kcpYM_X{Qp&$pl24bfziktTvVyDJMf}s(vFRg7pFvr)DmQS0Papuo&a*htQiKHIB zoyhYHw3>+PXnX9Wx-grn$gx?DN#s6ou_w0`s z`I^qLO~iPqPN7+<@W>;}LQY&UalUV?kE=@^4vovpuz5nQU^eUPfB!C6$wt#=g6uDVNi+_8CfVYc2e{}tztMNk>rm2oN8R7;8@(Q;}82DID>@O7wuMfvEZnq92 zBSc|nloPv^Q^(jHb_v(D4kvlzUgI9IE_;Aue*VnUDi))mRU{tQC(MT1_KRfVq%h+o zd&*Lt`P!`_IWjGeV9IIk4&$qe{LW@eG?qjR-shv| zkZKGZG7;Za2UEzKxeOP6QXK8&O#r~dcsc`EK?kw6?On*W+jh|Qh3&NMlI>P|US3k6 zaeX+$QOSFo+vnACclvhu@AUbM-8#3hf}h@WEtd~y%`JMD;7j=J{(z1TXsAXKe8X-O zF^!sP9D>ixIB#z8>N5pjqFY$S=QPCzVyS~uC>M)|xC^qITJ#Wb7YI~0Nuc~H3kS_5Lu*e$K{i)c8zp!Gg-g!XfkHrd}iEeTo$Xn!bF5DQ7OP?`x^zfTdfeJkxXsV$?Q&ccR)2*4% zM}JSs2+oWFg)8np7KJrLi2TwbHYLf1r!k+Lv?V(>axj@WR}H4=x*^6}Fn3|c+) zrUSY0W6MR9jyJrWHE!9mWo7F&l@*s26mbN!2tdo^mjG0_BSFGbU&zBI zDMiOMP_GmU4PN?=1s6-RhS0tt4^&MjJKmQn;@rh?96E*Xk~H)^esgh}>M}Le;{LWI zHTOCdop|<+6!sMTnZrrNj*p^cB4JtX)#^I$<&Nour$pCeJPJ?qKNl0b zCe48N`1hl$c=E0sgD~j62>={!KfDFcD@o=!E1po5Rn1XHw@xV`xz;`JA5pm6Q|5f|Q1Q>6B9axg ztC*d%?dO=EfT}PQ5iFNiD3*#i%eV56RGd#SzP2qCO-`g`i+S*+7y_l-bWaI1x9eJkD zt+>hE@tg20c9llj)$$c1jnU{;A> 12); } -static int year_day(int year, int year_bcd, int month, int month_day) -{ - int days_in_month[12] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - int leap; - int hundreds = integer8(year_bcd >> 8); - int day, i; - - leap = !(year & 3); // Take multiples of 4 - if(!((year_bcd >> 8) & 0xf)) leap = 0; // Remove multiples of 100 - if(!(hundreds & 3)) leap = 1; // Take multiples of 400 - - day = leap && (month > 2); - for(i = 0; i < month - 1; i++) day += days_in_month[i]; - return day + month_day - 1; -} - +/* + rtc_getTime() + Reads the current time from the RTC. There is no guarantee that the + week day is correct (use the time API for that). +*/ struct RTCTime rtc_getTime(void) { volatile struct mod_rtc *rtc = isSH3() ? RTC_SH7705 : RTC_SH7305; @@ -43,11 +31,8 @@ struct RTCTime rtc_getTime(void) time.hours = integer8(rtc->RHRCNT.BYTE); time.month_day = integer8(rtc->RDAYCNT.BYTE); time.month = integer8(rtc->RMONCNT.BYTE); - time.year = integer16(rtc->RYRCNT.WORD) - 1900; + time.year = integer16(rtc->RYRCNT.WORD); time.week_day = rtc->RWKCNT; - time.year_day = year_day(time.year + 1900, rtc->RYRCNT.WORD, - time.month, time.month_day); - time.daylight_saving = 0; return time; } diff --git a/src/rtc/rtc_setTime.c b/src/rtc/rtc_setTime.c index b00bcf5..d343c51 100644 --- a/src/rtc/rtc_setTime.c +++ b/src/rtc/rtc_setTime.c @@ -17,6 +17,11 @@ static int bcd16(int integer) return (bcd8(integer / 100) << 8) | bcd8(integer % 100); } +/* + rtc_setTime() + Sets the time in the RTC registers. The week day is set to 0 if greater + than 6. Other fields are not checked. +*/ void rtc_setTime(struct RTCTime time) { volatile struct mod_rtc *rtc = isSH3() ? RTC_SH7705 : RTC_SH7305; @@ -26,6 +31,6 @@ void rtc_setTime(struct RTCTime time) rtc->RHRCNT.BYTE = bcd8(time.hours); rtc->RDAYCNT.BYTE = bcd8(time.month_day); rtc->RMONCNT.BYTE = bcd8(time.month); - rtc->RYRCNT.WORD = bcd16(time.year + 1900); + rtc->RYRCNT.WORD = bcd16(time.year); rtc->RWKCNT = time.week_day < 7 ? time.week_day : 0; } diff --git a/src/time/asctime.c b/src/time/asctime.c new file mode 100644 index 0000000..ed3d0a3 --- /dev/null +++ b/src/time/asctime.c @@ -0,0 +1,57 @@ +#include + +static char str[26]; + +/* + asctime() + Converts broken-down time to string representation on the form + "Wed Jun 30 21:49:08 1993\n". The returned string is statically + allocated and may be overwritten by any subsequent call to a time + function. +*/ +char *asctime(const struct tm *time) +{ + const char *days[] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }, *months[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", + "Sep", "Oct", "Nov", "Dec" + }; + int year = time->tm_year + 1900; + + str[0] = days[time->tm_wday][0]; + str[1] = days[time->tm_wday][1]; + str[2] = days[time->tm_wday][2]; + str[3] = ' '; + + str[4] = months[time->tm_mon][0]; + str[5] = months[time->tm_mon][1]; + str[6] = months[time->tm_mon][2]; + str[7] = ' '; + + str[8] = '0' + (time->tm_mday / 10); + str[9] = '0' + (time->tm_mday % 10); + str[10] = ' '; + + str[11] = '0' + (time->tm_hour / 10); + str[12] = '0' + (time->tm_hour % 10); + str[13] = ':'; + str[14] = '0' + (time->tm_min / 10); + str[15] = '0' + (time->tm_min % 10); + str[16] = ':'; + str[17] = '0' + (time->tm_sec / 10); + str[18] = '0' + (time->tm_sec % 10); + str[19] = ' '; + + str[20] = '0' + (year / 1000); + year %= 1000; + str[21] = '0' + (year / 100); + year %= 100; + str[22] = '0' + (year / 10); + str[23] = '0' + (year % 10); + + str[24] = '\n'; + str[25] = 0; + + return str; +} diff --git a/src/time/ctime.c b/src/time/ctime.c new file mode 100644 index 0000000..f3768e0 --- /dev/null +++ b/src/time/ctime.c @@ -0,0 +1,13 @@ +#include + +/* + ctime() + Converts calendar time to string representation on the form + "Wed Jun 30 21:49:08 1993\n". The returned string is statically + allocated and may be overwritten by any subsequent call to a time + function. +*/ +char *ctime(const time_t *timer) +{ + return asctime(gmtime(timer)); +} diff --git a/src/time/gmtime.c b/src/time/gmtime.c new file mode 100644 index 0000000..4d84587 --- /dev/null +++ b/src/time/gmtime.c @@ -0,0 +1,45 @@ +#include +#include +#include + +static struct tm tm; + +/* + gmtime() + Converts calendar time to broken-down time. The returned pointer is + statically allocated and may be overwritten by any subsequent call to + a time function. +*/ +struct tm *gmtime(const time_t *timeptr) +{ + time_t t = *timeptr; + div_t d; + int sec; + + tm.tm_year = 1970; + tm.tm_mon = 0; + + sec = daysInMonth(tm.tm_mon, tm.tm_year) * 24 * 3600; + while(t >= sec) + { + t -= sec; + if(++tm.tm_mon == 12) + { + tm.tm_year++; + tm.tm_mon = 0; + } + sec = daysInMonth(tm.tm_mon, tm.tm_year) * 24 * 3600; + } + tm.tm_year -= 1900; + + d = div(sec, 24 * 3600); + tm.tm_mday = d.quot; + d = div(d.rem, 3600); + tm.tm_hour = d.quot; + d = div(d.rem, 60); + tm.tm_min = d.quot; + tm.tm_sec = d.rem; + + mktime(&tm); + return &tm; +} diff --git a/src/time/mktime.c b/src/time/mktime.c index e29b212..928cf6f 100644 --- a/src/time/mktime.c +++ b/src/time/mktime.c @@ -1,42 +1,17 @@ #include - -/* - isLeap() - Determines whether the given year is a leap year. -*/ -int isLeap(int year) -{ - int leap = !(year & 3); // Take multiples of 4 - if(!(year % 100)) leap = 0; // Remove multiples of 100 - if(!(year % 400)) leap = 1; // Take multiples of 400 - - return leap; -} - -/* - daysInMonth() - Returns number of days for the given month (between 0 and 11) and year. -*/ -int daysInMonth(int month, int year) -{ - int days[12] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 - }; - - if(month != 1) return days[month]; - return days[month] + isLeap(year); -} +#include /* mktime() - Computes fields tm_wday and tm_yday using the other fields. Member - structures outside their range are normalized and tm_isdst is set. + Converts broken-down time to calendar time. Computes structure fields + tm_wday and tm_yday using the other fields. Member structures outside + their range are normalized (e.g. 40 October becomes 9 November) and + tm_isdst is set. */ time_t mktime(struct tm *time) { - int first, leaps, yr; + int leaps, yr; int days, i; - time_t elapsed; // Normalizing time. time->tm_min += (time->tm_sec / 60); @@ -88,6 +63,6 @@ time_t mktime(struct tm *time) // days may become negative, so add the calendar period. if(days < 0) days += 146097; - return (24 * 3600) * days + 3600 * time->tm_hour + 60 * time->tm_min + - time->tm_sec; + return (time_t)((24 * 3600) * days + 3600 * time->tm_hour + + 60 * time->tm_min + time->tm_sec); } diff --git a/src/time/time.c b/src/time/time.c new file mode 100644 index 0000000..16189d4 --- /dev/null +++ b/src/time/time.c @@ -0,0 +1,29 @@ +#include +#include + +/* + time() + Returns the current time as calendar time. If you need a broken-down + time, either use the RTC API or gmtime(). However, this function is + already based on mktime() (for hardware reasons) so it would be much + faster to use the RTC API if possible. + If timeptr is not NULL, it is set to the current time, that is, the + value that is returned. +*/ +time_t time(time_t *timeptr) +{ + struct RTCTime rtc = rtc_getTime(); + struct tm tm; + time_t calendar; + + tm.tm_sec = rtc.seconds; + tm.tm_min = rtc.minutes; + tm.tm_hour = rtc.hours; + tm.tm_mday = rtc.month_day; + tm.tm_mon = rtc.month; + tm.tm_year = rtc.year - 1900; + + calendar = mktime(&tm); + if(timeptr) *timeptr = calendar; + return calendar; +} diff --git a/src/time/time_misc.c b/src/time/time_misc.c index c3d21d6..88e01fc 100644 --- a/src/time/time_misc.c +++ b/src/time/time_misc.c @@ -1,4 +1,5 @@ #include +#undef difftime /* clock() diff --git a/src/time/time_util.c b/src/time/time_util.c new file mode 100644 index 0000000..11c7048 --- /dev/null +++ b/src/time/time_util.c @@ -0,0 +1,28 @@ +#include + +/* + isLeap() + Determines whether the given year is a leap year. +*/ +int isLeap(int year) +{ + int leap = !(year & 3); // Take multiples of 4 + if(!(year % 100)) leap = 0; // Remove multiples of 100 + if(!(year % 400)) leap = 1; // Take multiples of 400 + + return leap; +} + +/* + daysInMonth() + Returns number of days for the given month (between 0 and 11) and year. +*/ +int daysInMonth(int month, int year) +{ + int days[12] = { + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 + }; + + if(month != 1) return days[month]; + return days[month] + isLeap(year); +}