changeset 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 0876867347de
children 76a6bad110e2
files 1wire.c 1wire.h Makefile.avr ds1307.c ds1307.h
diffstat 5 files changed, 157 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
--- a/1wire.c	Sat Jan 31 23:26:21 2015 +1030
+++ b/1wire.c	Sat Jan 31 23:27:10 2015 +1030
@@ -43,11 +43,15 @@
 static uint8_t OW_LastDiscrepancy = 0;
 static uint8_t OW_LastFamilyDiscrepancy = 0;
 
-const PROGMEM char *OWProgROM_Status[] = {
-    "OK",
-    "no HW support",
-    "Invalid params",
-    "module missing/broken"
+static const char __str1[] PROGMEM = "OK";
+static const char __str2[] PROGMEM = "no HW support";
+static const char __str3[] PROGMEM = "Invalid params";
+static const char __str4[] PROGMEM = "module missing/broken";
+PGM_P const OWProgROM_Status[] PROGMEM = {
+    __str1,
+    __str2,
+    __str3,
+    __str4
 };
 
 /*-----------------------------------------------------------------------------
@@ -306,56 +310,57 @@
 
 	    /* check for no devices on 1-wire */
 	    if (bit_test == 3) {
+		/* 11 */
 		OWPRINTFP(PSTR("bit_test = %d\r\n"), bit_test);
-		return(OW_BADWIRE);
+		return(OW_NOMODULES);
 	    }
+	    /* all devices coupled have 0 or 1 */
+	    if (bit_test != 0)
+		/* 10 or 01 */
+		search_direction = !(bit_test & 0x01);  /* bit write value for search */
 	    else {
-		/* all devices coupled have 0 or 1 */
-		if (bit_test > 0)
-		    search_direction = !(bit_test & 0x01);  /* bit write value for search */
-		else {
-		    /* if this discrepancy is before the Last Discrepancy
-		     * on a previous OWNext then pick the same as last time */
-		    if (bit_number < OW_LastDiscrepancy)
-			search_direction = ((ROM[rom_byte_number] & rom_byte_mask) > 0);
-		    else
-			/* if equal to last pick 1, if not then pick 0 */
-			search_direction = (bit_number == OW_LastDiscrepancy);
+		/* 00 */
+		/* if this discrepancy is before the Last Discrepancy
+		 * on a previous OWNext then pick the same as last time */
+		if (bit_number < OW_LastDiscrepancy)
+		    search_direction = (ROM[rom_byte_number] & rom_byte_mask) > 0;
+		else
+		    /* if equal to last pick 1, if not then pick 0 */
+		    search_direction = bit_number == OW_LastDiscrepancy;
 
-		    /* if 0 was picked then record its position in LastZero */
-		    if (search_direction == 0) {
-			last_zero = bit_number;
+		/* if 0 was picked then record its position in LastZero */
+		if (search_direction == 0) {
+		    last_zero = bit_number;
 
-			/* check for Last discrepancy in family */
-			if (last_zero < 9)
-			    OW_LastFamilyDiscrepancy = last_zero;
-		    }
+		    /* check for Last discrepancy in family */
+		    if (last_zero < 9)
+			OW_LastFamilyDiscrepancy = last_zero;
 		}
+	    }
 
-		/* set or clear the bit in the ROM byte rom_byte_number
-		 * with mask rom_byte_mask */
-		if (search_direction == 1)
-		    ROM[rom_byte_number] |= rom_byte_mask;
-		else
-		    ROM[rom_byte_number] &= ~rom_byte_mask;
+	    /* set or clear the bit in the ROM byte rom_byte_number
+	     * with mask rom_byte_mask */
+	    if (search_direction == 1)
+		ROM[rom_byte_number] |= rom_byte_mask;
+	    else
+		ROM[rom_byte_number] &= ~rom_byte_mask;
 
-		/* serial number search direction write bit */
-		OWWriteBit(search_direction);
+	    /* serial number search direction write bit */
+	    OWWriteBit(search_direction);
 
-		/* increment the byte counter bit_number
-		 * and shift the mask rom_byte_mask */
-		bit_number++;
-		rom_byte_mask <<= 1;
+	    /* increment the byte counter bit_number
+	     * and shift the mask rom_byte_mask */
+	    bit_number++;
+	    rom_byte_mask <<= 1;
 
-		/* if the mask is 0 then go to new ROM byte rom_byte_number
-		 * and reset mask */
-		if (rom_byte_mask == 0) {
-		    OWCRC(ROM[rom_byte_number], &crcaccum);  /* accumulate the CRC */
-		    lastcrc8 = crcaccum;
+	    /* if the mask is 0 then go to new ROM byte rom_byte_number
+	     * and reset mask */
+	    if (rom_byte_mask == 0) {
+		OWCRC(ROM[rom_byte_number], &crcaccum);  /* accumulate the CRC */
+		lastcrc8 = crcaccum;
 		  
-		    rom_byte_number++;
-		    rom_byte_mask = 1;
-		}
+		rom_byte_number++;
+		rom_byte_mask = 1;
 	    }
 	} while (rom_byte_number < 8);  /* loop until through all ROM bytes 0-7 */
 
@@ -389,7 +394,7 @@
 
 }
 
-uint8_t PROGMEM dscrc_table[] = { 
+const uint8_t dscrc_table[] PROGMEM = {
     0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
     157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
     35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
@@ -508,13 +513,8 @@
 
 	tmp = OWReadByte();
 
-	/* Check the bits we turned off are off */
-/*
-        for (i = 0; i < 8; i++)
-	    if (!(data[i] & 1 << i) && (tmp & 1 << i))
-	        return(-3);
-*/
-	if ((!data[i] & tmp) != 0) {
+	/* Verify */
+	if (data[i] != tmp) {
 	    cons_putsP(PSTR("Readback mismatch "));
 	    cons_puts_hex(data[i]);
 	    cons_putsP(PSTR(" vs "));
--- a/1wire.h	Sat Jan 31 23:26:21 2015 +1030
+++ b/1wire.h	Sat Jan 31 23:27:10 2015 +1030
@@ -40,9 +40,8 @@
 void		OWSendCmd(uint8_t *ROM, uint8_t cmd);
 uint8_t		OWProgROM(uint8_t *ROM, uint8_t start, uint8_t len, uint8_t *data, uint8_t exact, uint8_t status);
 int16_t		OWGetTemp(uint8_t *ROM);
-const PROGMEM char *OWTempStatusStr(int16_t val, uint8_t shrt);
-extern const PROGMEM char *OWProgROM_Status[];
-
+PROGMEM const char *OWTempStatusStr(int16_t val, uint8_t shrt);
+extern PGM_P const OWProgROM_Status[] PROGMEM;
 
 /* Return codes for OWFirst()/OWNext() */
 #define OW_BADWIRE		-3
--- a/Makefile.avr	Sat Jan 31 23:26:21 2015 +1030
+++ b/Makefile.avr	Sat Jan 31 23:27:10 2015 +1030
@@ -10,10 +10,10 @@
 
 # Programs
 TPREFIX?=
-AS=${TPREFIX}/avr-as
-CC=${TPREFIX}/avr-gcc
-OBJCOPY=${TPREFIX}/avr-objcopy
-OBJDUMP=${TPREFIX}/avr-objdump
+AS=${TPREFIX}avr-as
+CC=${TPREFIX}avr-gcc
+OBJCOPY=${TPREFIX}avr-objcopy
+OBJDUMP=${TPREFIX}avr-objdump
 SED=sed
 TAIL=tail
 
--- 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);
+}
--- a/ds1307.h	Sat Jan 31 23:26:21 2015 +1030
+++ b/ds1307.h	Sat Jan 31 23:27:10 2015 +1030
@@ -42,9 +42,6 @@
     uint8_t	hour;
     uint8_t	min;
     uint8_t	sec;
-
-    uint8_t	ctrl;
-    uint8_t	ram[56];
 } ds1307_t;
 
 typedef union {
@@ -85,10 +82,16 @@
 	uint8_t	out	: 1;	// Output control enable
     } split;
 } ds1307raw_t;
-	
+
+typedef int32_t time_t;
+
 int	ds1307_init(void);
 int8_t	iic_read(uint8_t *data, uint8_t len, uint8_t adr, uint8_t sla);
 int8_t	iic_write(uint8_t *data, uint8_t len, uint8_t adr, uint8_t sla);
 int8_t	ds1307_gettod(ds1307raw_t *time);
 int8_t	ds1307_settod(char *date);
-void	ds1307_printtime(char *leader, char *trailer);
+void	ds1307_printtime(ds1307_t *time, const char *leader, const char *trailer);
+void	ds1307_printnow(const char *leader, const char *trailer);
+void	ds1307_cook(ds1307raw_t *raw, ds1307_t *cooked);
+time_t	ds1307_totimet(ds1307_t *time);
+time_t	ds1307_time(void);