| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- #include "bsp_rtc.h"
- #include "ctime.h"
- #include "stdint.h"
- #include "stdio.h"
- #include "time.h"
- #include "string.h"
- #include "gd32f4xx_libopt.h"
- #include "clock.h"
- #define RT_LIBC_TZ_DEFAULT_HOUR 8
- #define RT_LIBC_TZ_DEFAULT_MIN 0
- #define RT_LIBC_TZ_DEFAULT_SEC 0
- static const short __spm[13] =
- {
- 0,
- (31),
- (31 + 28),
- (31 + 28 + 31),
- (31 + 28 + 31 + 30),
- (31 + 28 + 31 + 30 + 31),
- (31 + 28 + 31 + 30 + 31 + 30),
- (31 + 28 + 31 + 30 + 31 + 30 + 31),
- (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31),
- (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30),
- (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31),
- (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30),
- (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31),
- };
- #define rt_align(n) __attribute__((aligned(n)))
- rt_align(8) static const char *days = "Sun Mon Tue Wed Thu Fri Sat ";
- rt_align(8) static const char *months = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ";
- #ifndef __isleap
- static int __isleap(int year)
- {
- /* every fourth year is a leap year except for century years that are
- * not divisible by 400. */
- /* return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); */
- return (!(year % 4) && ((year % 100) || !(year % 400)));
- }
- #endif
- static void num2str(char *c, int i)
- {
- c[0] = i / 10 + '0';
- c[1] = i % 10 + '0';
- }
- static volatile int32_t _current_tz_offset_sec = \
- RT_LIBC_TZ_DEFAULT_HOUR * 3600U + RT_LIBC_TZ_DEFAULT_MIN * 60U + RT_LIBC_TZ_DEFAULT_SEC;
- void fr_tz_set(int32_t offset_sec)
- {
- _current_tz_offset_sec = offset_sec;
- }
- int32_t fr_tz_get(void)
- {
- return _current_tz_offset_sec;
- }
- int8_t fr_tz_is_dst(void)
- {
- return 0U; /* TODO */
- }
- struct tm *gmtime_r(const time_t *timep, struct tm *r)
- {
- int i;
- int work;
- if(timep == NULL || r == NULL)
- {
- return NULL;
- }
- memset(r, NULL, sizeof(struct tm));
- work = *timep % (24*60*60);
- r->tm_sec = work % 60;
- work /= 60;
- r->tm_min = work % 60;
- r->tm_hour = work / 60;
- work = (int)(*timep / (24*60*60));
- r->tm_wday = (4 + work) % 7;
- for (i = 1970;; ++i)
- {
- int k = __isleap(i) ? 366 : 365;
- if (work >= k)
- work -= k;
- else
- break;
- }
- r->tm_year = i - 1900;
- r->tm_yday = work;
- r->tm_mday = 1;
- if (__isleap(i) && (work > 58))
- {
- if (work == 59)
- r->tm_mday = 2; /* 29.2. */
- work -= 1;
- }
- for (i = 11; i && (__spm[i] > work); --i);
- r->tm_mon = i;
- r->tm_mday += work - __spm[i];
- r->tm_isdst = 0U;
- return r;
- }
- struct tm* localtime_r(const time_t* t, struct tm* r)
- {
- time_t local_tz;
- local_tz = *t + fr_tz_get();
- return gmtime_r(&local_tz, r);
- }
- struct tm* localtime(const time_t* t)
- {
- static struct tm tmp;
- return localtime_r(t, &tmp);
- }
- time_t timegm(struct tm * const t)
- {
- time_t day;
- time_t i;
- time_t years;
- if(t == NULL)
- {
- return (time_t)-1;
- }
- years = (time_t)t->tm_year - 70;
- if (t->tm_sec > 60) /* seconds after the minute - [0, 60] including leap second */
- {
- t->tm_min += t->tm_sec / 60;
- t->tm_sec %= 60;
- }
- if (t->tm_min >= 60) /* minutes after the hour - [0, 59] */
- {
- t->tm_hour += t->tm_min / 60;
- t->tm_min %= 60;
- }
- if (t->tm_hour >= 24) /* hours since midnight - [0, 23] */
- {
- t->tm_mday += t->tm_hour / 24;
- t->tm_hour %= 24;
- }
- if (t->tm_mon >= 12) /* months since January - [0, 11] */
- {
- t->tm_year += t->tm_mon / 12;
- t->tm_mon %= 12;
- }
- while (t->tm_mday > __spm[1 + t->tm_mon])
- {
- if (t->tm_mon == 1 && __isleap(t->tm_year + 1900))
- {
- --t->tm_mday;
- }
- t->tm_mday -= __spm[t->tm_mon];
- ++t->tm_mon;
- if (t->tm_mon > 11)
- {
- t->tm_mon = 0;
- ++t->tm_year;
- }
- }
- if (t->tm_year < 70)
- {
- return (time_t) -1;
- }
- /* Days since 1970 is 365 * number of years + number of leap years since 1970 */
- day = years * 365 + (years + 1) / 4;
- /* After 2100 we have to substract 3 leap years for every 400 years
- This is not intuitive. Most mktime implementations do not support
- dates after 2059, anyway, so we might leave this out for it's
- bloat. */
- if (years >= 131)
- {
- years -= 131;
- years /= 100;
- day -= (years >> 2) * 3 + 1;
- if ((years &= 3) == 3)
- years--;
- day -= years;
- }
- day += t->tm_yday = __spm[t->tm_mon] + t->tm_mday - 1 +
- (__isleap(t->tm_year + 1900) & (t->tm_mon > 1));
- /* day is now the number of days since 'Jan 1 1970' */
- i = 7;
- t->tm_wday = (int)((day + 4) % i); /* Sunday=0, Monday=1, ..., Saturday=6 */
- i = 24;
- day *= i;
- i = 60;
- return ((day + t->tm_hour) * i + t->tm_min) * i + t->tm_sec;
- }
- time_t mktime(struct tm * const t)
- {
- time_t timestamp;
- timestamp = timegm(t);
- timestamp = timestamp - fr_tz_get();
- return timestamp;
- }
- char* asctime_r(const struct tm *t, char *buf)
- {
- if(t == NULL || buf == NULL)
- {
- return NULL;
- }
- memset(buf, NULL, 26);
- /* Checking input validity */
- if ((int)strlen(days) <= (t->tm_wday << 2) || (int)strlen(months) <= (t->tm_mon << 2))
- {
- *(int*) buf = *(int*) days;
- *(int*) (buf + 4) = *(int*) months;
- num2str(buf + 8, t->tm_mday);
- if (buf[8] == '0')
- buf[8] = ' ';
- buf[10] = ' ';
- num2str(buf + 11, t->tm_hour);
- buf[13] = ':';
- num2str(buf + 14, t->tm_min);
- buf[16] = ':';
- num2str(buf + 17, t->tm_sec);
- buf[19] = ' ';
- num2str(buf + 20, 2000 / 100);
- num2str(buf + 22, 2000 % 100);
- buf[24] = '\n';
- buf[25] = '\0';
- return buf;
- }
- /* "Wed Jun 30 21:49:08 1993\n" */
- *(int*) buf = *(int*) (days + (t->tm_wday << 2));
- *(int*) (buf + 4) = *(int*) (months + (t->tm_mon << 2));
- num2str(buf + 8, t->tm_mday);
- if (buf[8] == '0')
- buf[8] = ' ';
- buf[10] = ' ';
- num2str(buf + 11, t->tm_hour);
- buf[13] = ':';
- num2str(buf + 14, t->tm_min);
- buf[16] = ':';
- num2str(buf + 17, t->tm_sec);
- buf[19] = ' ';
- num2str(buf + 20, (t->tm_year + 1900) / 100);
- num2str(buf + 22, (t->tm_year + 1900) % 100);
- buf[24] = '\n';
- buf[25] = '\0';
- return buf;
- }
- char *asctime(const struct tm *timeptr)
- {
- static char buf[26];
- return asctime_r(timeptr, buf);
- }
- char *ctime_r(const time_t * tim_p, char * result)
- {
- struct tm tm;
- return asctime_r(localtime_r(tim_p, &tm), result);
- }
- char *ctime(const time_t *tim_p)
- {
- return asctime(localtime(tim_p));
- }
- #if (!defined __ARMCC_VERSION) && (!defined __CC_ARM) && (!defined __ICCARM__)
- double difftime(time_t time1, time_t time2)
- {
- return (double)(time1 - time2);
- }
- #endif
- time_t time(time_t *t)
- {
- time_t _t;
- //TODO
- struct timeval tv;
- bsp_rtc_get_timeval(&tv);
- _t = tv.tv_sec;
- if (t)
- *t = _t;
- return _t;
- }
- clock_t clock(void)
- {
- return fr_tick_get(); // TODO should return cpu usage time
- }
- int stime(const time_t *t)
- {
- //TODO
- if(t==NULL)
- return -1;
- bsp_rtc_set_time_stamp(*t);
- return 0;
- }
- int gettimeofday(struct timeval *tv, struct timezone *tz)
- {
- /* The use of the timezone structure is obsolete;
- * the tz argument should normally be specified as NULL.
- * The tz_dsttime field has never been used under Linux.
- * Thus, the following is purely of historic interest.
- */
- if(tz != NULL)
- {
- tz->tz_dsttime = DST_NONE;
- tz->tz_minuteswest = -(fr_tz_get() / 60);
- }
- if (tv != NULL)
- {
- tv->tv_sec = 0;
- tv->tv_usec = 0;
- bsp_rtc_get_timeval(tv);
- }
- //rt_set_errno(EINVAL);
- return 0;
- }
|