Mercurial > ~darius > hgwebdir.cgi > avr-lib
diff ds1307.c @ 19:b5e4591b6570
- Satisfy new compiler
- Put strings in PROGMEM
- Add various time functions
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Sat, 31 Jan 2015 23:27:10 +1030 |
parents | 119688bb743f |
children |
line wrap: on
line diff
--- a/ds1307.c Sat Jan 31 23:26:21 2015 +1030 +++ b/ds1307.c Sat Jan 31 23:27:10 2015 +1030 @@ -474,33 +474,105 @@ } /* - * ds1307_printtime + * ds1307_printnow * - * Print the time in rtime with trailer + * Print the current time of day * */ void -ds1307_printtime(char *leader, char *trailer) { +ds1307_printnow(const char *leader, const char *trailer) { ds1307raw_t rtime; - uint8_t hour; + ds1307_t time; if (ds1307_gettod(&rtime) != 1) return; - // Handle 12/24 hour time - hour = rtime.split.hour10 * 10 + rtime.split.hour; - if (rtime.split.s1224) { - if (rtime.split.pmam) - hour += 12; - } else - hour += (rtime.split.pmam << 1) * 10; - + ds1307_cook(&rtime, &time); + ds1307_printtime(&time, leader, trailer); +} + +/* + * ds1307_printtime + * + * Print time with header & trailer + * + */ +void +ds1307_printtime(ds1307_t *time, const char *leader, const char *trailer) { printf_P(PSTR("%S%04d/%02d/%02d %02d:%02d:%02d%S"), leader, - 1900 + rtime.split.year10 * 10 + rtime.split.year, - rtime.split.month10 * 10 + rtime.split.month, - rtime.split.day10 * 10 + rtime.split.day, - hour, - rtime.split.min10 * 10 + rtime.split.min, - rtime.split.sec10 * 10 + rtime.split.sec, - trailer); + 1900 + time->year, time->month, time->day, + time->hour, time->min, time->sec, trailer); +} + +/* + * ds1307_cook + * + * Convert a ds1307raw_t to ds1307_t + */ +void +ds1307_cook(ds1307raw_t *raw, ds1307_t *cooked) { + cooked->year = raw->split.year + raw->split.year10 * 10; + cooked->month = raw->split.month + raw->split.month10 * 10; + cooked->day = raw->split.day + raw->split.day10 * 10; + + /* Handle 12/24 hour time */ + cooked->hour = raw->split.hour10 * 10 + raw->split.hour; + if (raw->split.s1224) { + if (raw->split.pmam) + cooked->hour += 12; + } else + cooked->hour += (raw->split.pmam << 1) * 10; + + cooked->min = raw->split.min + raw->split.min10 * 10; + cooked->sec = raw->split.sec + raw->split.sec10 * 10; } + +/* + * ds1307_totimet + * + * Convert a ds1307_t to time_t + * + */ +#define SECONDS_PER_DAY 86400 +static uint8_t dayspermonth[] = { 31, 27, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; +static uint8_t dayspermonth_leap[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +static int +isleapyear(int year) { + return ((!(year % 4) && (year % 100)) || !(year % 400)) ? 1 : 0; +} + +time_t +ds1307_totimet(ds1307_t *time) { + time_t t = 0; + int16_t i; + + for (i = time->year + 1900; i > 1970; i--) + t += (isleapyear(i) ? 366 : 365) * SECONDS_PER_DAY; + for (i = time->month; i > 1; i--) + t += (isleapyear(i) ? dayspermonth_leap[i] : dayspermonth[i]) * SECONDS_PER_DAY; + t += (time->day - 1) * SECONDS_PER_DAY; + t += time->hour * 60 * 60; + t += time->min * 60; + t += time->sec; + t += 65535; // XXX: this is magical :( + return(t); +} + +/* + * ds1307_time + * + * Return TOD as a time_t + * + */ +time_t +ds1307_time(void) { + ds1307raw_t r; + ds1307_t c; + + if (ds1307_gettod(&r) == 0) + return -1; + + ds1307_cook(&r, &c); + return ds1307_totimet(&c); +}