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