changeset 60:50fca9562310

Add support for reading/writing to a DS1307 over TWI/IIC. Note that iic_read() appears to have a bug where it stops 1 byte earlier than expected, work around it for now by adding 1 in the gettod() function. tempctrl.c now prints the TOD as read from the RTC for each line.
author darius@Inchoate
date Thu, 30 Oct 2008 11:53:32 +1030
parents c72cf25881fe
children 0910ab6f0095
files Makefile ds1307.c ds1307.h tempctrl.c testavr.c
diffstat 5 files changed, 608 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Thu Oct 30 11:44:52 2008 +1030
+++ b/Makefile	Thu Oct 30 11:53:32 2008 +1030
@@ -3,7 +3,7 @@
 #
 
 PROG=	testavr
-SRCS=	1wire.c cons.c tempctrl.c testavr.c
+SRCS=	1wire.c cons.c tempctrl.c testavr.c ds1307.c
 .if defined(WITHUSB)
 SRCS+=	usb.c
 CFLAGS+=-DWITHUSB
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ds1307.c	Thu Oct 30 11:53:32 2008 +1030
@@ -0,0 +1,486 @@
+/*
+ * Interface to a DS1307
+ *
+ * Copyright (c) 2008
+ *      Daniel O'Connor <darius@dons.net.au>.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <util/twi.h>
+#include <util/delay.h>
+
+#include "ds1307.h"
+
+//#define TWDEBUG
+
+/* 
+ * ds1307_init
+ *
+ * Setup TWI interface
+ *
+ */
+int
+ds1307_init(void) {
+    TWSR = 0; 			/* TWI Prescaler = 1 */
+    
+#if F_CPU < 3600000UL
+    TWBR = 10;			/* Smallest valid TWBR */
+#else
+    TWBR = (F_CPU / 100000UL - 16) / 2;
+#endif
+
+    TWCR = _BV(TWEN);
+
+    return(0);
+}
+
+/*
+ * iic_read
+ *
+ * Read len bytes of data from address adr in slave sla into
+ * data. Presume that the slave auto-increments the address on
+ * successive reads.
+ *
+ * Returns the number of bytes read, or the following on failure.
+ * IIC_STFAIL	Could generate START condition (broken bus or busy).
+ * IIC_FAILARB	Failed bus arbitration.
+ * IIC_SLNAK	Slave NAK'd.
+ * IIC_NOREPLY	No reply (no such slave?)
+ * IIC_UNKNOWN	Unexpected return from TWI reg.
+ */
+int
+iic_read(uint8_t *data, uint8_t len, uint8_t adr, uint8_t sla) {
+    uint8_t	twst, twcr, cnt;
+
+    /* Generate START */
+    TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
+
+    /* Spin waiting for START to be generated */
+    while ((TWCR & _BV(TWINT)) == 0)
+	;
+    switch (twst = TW_STATUS) {
+	case TW_REP_START:	/* OK but shouldn't happen */
+	case TW_START:
+	    break;
+	    
+	case TW_MT_ARB_LOST:
+	    return IIC_FAILARB;
+	    break;
+
+	default:
+	    /* Not in start condition, bail */
+	    return IIC_UNKNOWN;
+    }
+#ifdef TWDEBUG
+    printf_P(PSTR("Sent START\r\n"));
+#endif
+    /* Send SLA+W */
+    TWDR = sla | TW_WRITE;
+    TWCR = _BV(TWINT) | _BV(TWEN);
+
+    /* Spin waiting for a response to be generated */
+    while ((TWCR & _BV(TWINT)) == 0)
+	;
+
+#ifdef TWDEBUG
+    printf_P(PSTR("Sent SLA+W\r\n"));
+#endif
+    switch (twst = TW_STATUS) {
+	case TW_MT_SLA_ACK:
+	    break;
+	    
+	case TW_MT_SLA_NACK:
+	    /* Send STOP */
+	    TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
+	    return IIC_SLNAK;
+
+	case TW_MT_ARB_LOST:
+	    return IIC_FAILARB;
+	    break;
+
+	default:
+	    /* Send STOP */
+	    TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
+	    return IIC_UNKNOWN;
+    }
+    /* Send address */
+    TWDR = adr;
+    TWCR = _BV(TWINT) | _BV(TWEN);
+
+    /* Spin waiting for a response to be generated */
+    while ((TWCR & _BV(TWINT)) == 0)
+	;
+#ifdef TWDEBUG
+    printf_P(PSTR("Sent address\r\n"));
+#endif
+    switch ((twst = TW_STATUS)) {
+	case TW_MT_DATA_ACK:
+	    break;
+
+	case TW_MT_DATA_NACK:
+	    /* Send STOP */
+	    TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
+	    return IIC_SLNAK;
+	    
+	case TW_MT_ARB_LOST:
+	    return IIC_FAILARB;
+
+	default:
+	    /* Send STOP */
+	    TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
+	    return IIC_UNKNOWN;
+    }
+    
+    /* Master receive cycle */
+    TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
+    while ((TWCR & _BV(TWINT)) == 0) /* wait for transmission */
+	;
+    
+#ifdef TWDEBUG
+    printf_P(PSTR("Sent START\r\n"));
+#endif    
+    switch ((twst = TW_STATUS)) {
+	case TW_REP_START: /* OK but shouldn't happen */
+	case TW_START:
+	    break;
+	    
+	case TW_MT_ARB_LOST:
+	    return IIC_FAILARB;
+	    
+	default:
+	    /* Send STOP */
+	    TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
+	    return IIC_UNKNOWN;
+    }
+
+    /* send SLA+R */
+    TWDR = sla | TW_READ;
+    TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
+
+    /* Spin waiting for a response to be generated */
+    while ((TWCR & _BV(TWINT)) == 0)
+	;
+#ifdef TWDEBUG
+    printf_P(PSTR("Sent SLA+R\r\n"));
+#endif
+    switch ((twst = TW_STATUS)) {
+	case TW_MR_SLA_ACK:
+	    break;
+
+	case TW_MR_SLA_NACK:
+	    /* Send STOP */
+	    TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
+	    return IIC_SLNAK;
+	    
+	case TW_MR_ARB_LOST:
+	    return IIC_FAILARB;
+	    
+	default:
+	    /* Send STOP */
+	    TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
+	    return IIC_UNKNOWN;
+    }
+
+    cnt = 0;
+    for (twcr = _BV(TWINT) | _BV(TWEN) | _BV(TWEA);
+	 len > 0; len--) {
+	/* Send NAK on last byte */
+	if (len == 1)
+	    twcr = _BV(TWINT) | _BV(TWEN); 
+	TWCR = twcr;		/* clear int to start transmission */
+	/* Spin waiting for a response to be generated */
+	while ((TWCR & _BV(TWINT)) == 0)
+	    ;
+#ifdef TWDEBUG
+	printf_P(PSTR("Data request done\r\n"));
+#endif
+	switch ((twst = TW_STATUS)) {
+	    case TW_MR_DATA_NACK:
+		/* Send STOP */
+		TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
+		return cnt;
+		
+	    case TW_MR_DATA_ACK:
+		*data++ = TWDR;
+		cnt++;
+		break;
+
+	    default:
+		return IIC_UNKNOWN;
+	}
+    }
+
+    /* Send STOP */
+    TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
+    return cnt;
+}
+
+/*
+ * iic_write
+ *
+ * Write len bytes of data from address adr in slave sla into
+ * data. Presume that the slave auto-increments the address on
+ * successive writes.
+ *
+ * Returns the number of bytes read, or the following on failure.
+ * IIC_STFAIL	Could generate START condition (broken bus or busy).
+ * IIC_FAILARB	Failed bus arbitration.
+ * IIC_SLNAK	Slave NAK'd.
+ * IIC_NOREPLY	No reply (no such slave?)
+ * IIC_UNKNOWN	Unexpected return from TWI reg.
+ */
+int
+iic_write(uint8_t *data, uint8_t len, uint8_t adr, uint8_t sla) {
+    uint8_t	twst, cnt;
+
+    /* Generate START */
+    TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
+
+    /* Spin waiting for START to be generated */
+    while ((TWCR & _BV(TWINT)) == 0)
+	;
+    switch (twst = TW_STATUS) {
+	case TW_REP_START:	/* OK but shouldn't happen */
+	case TW_START:
+	    break;
+	    
+	case TW_MT_ARB_LOST:
+	    return IIC_FAILARB;
+	    break;
+
+	default:
+	    /* Not in start condition, bail */
+	    return IIC_UNKNOWN;
+    }
+#ifdef TWDEBUG
+    printf_P(PSTR("Sent START\r\n"));
+#endif
+
+    /* Send SLA+W */
+    TWDR = sla | TW_WRITE;
+    TWCR = _BV(TWINT) | _BV(TWEN);
+
+    /* Spin waiting for a response to be generated */
+    while ((TWCR & _BV(TWINT)) == 0)
+	;
+
+#ifdef TWDEBUG
+    printf_P(PSTR("Sent SLA+W\r\n"));
+#endif
+    switch (twst = TW_STATUS) {
+	case TW_MT_SLA_ACK:
+	    break;
+	    
+	case TW_MT_SLA_NACK:
+	    /* Send STOP */
+	    TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
+	    return IIC_SLNAK;
+
+	case TW_MT_ARB_LOST:
+	    return IIC_FAILARB;
+	    break;
+
+	default:
+	    /* Send STOP */
+	    TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
+	    return IIC_UNKNOWN;
+    }
+    /* Send address */
+    TWDR = adr;
+    TWCR = _BV(TWINT) | _BV(TWEN);
+
+    /* Spin waiting for a response to be generated */
+    while ((TWCR & _BV(TWINT)) == 0)
+	;
+#ifdef TWDEBUG
+    printf_P(PSTR("Sent address\r\n"));
+#endif
+    switch ((twst = TW_STATUS)) {
+	case TW_MT_DATA_ACK:
+	    break;
+
+	case TW_MT_DATA_NACK:
+	    /* Send STOP */
+	    TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
+	    return IIC_SLNAK;
+	    
+	case TW_MT_ARB_LOST:
+	    return IIC_FAILARB;
+
+	default:
+	    /* Send STOP */
+	    TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
+	    return IIC_UNKNOWN;
+    }
+    
+    cnt = 0;
+    for (; len > 0; len--) {
+	TWDR = *data++;
+	TWCR = _BV(TWINT) | _BV(TWEN);
+	
+	/* Spin waiting for a response to be generated */
+	while ((TWCR & _BV(TWINT)) == 0)
+	    ;
+#ifdef TWDEBUG
+    printf_P(PSTR("Data sent\r\n"));
+#endif
+    switch ((twst = TW_STATUS)) {
+	    case TW_MT_DATA_NACK:
+		/* Send STOP */
+		TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
+		return cnt;
+		
+	    case TW_MT_DATA_ACK:
+		cnt++;
+		break;
+
+	    default:
+		return IIC_UNKNOWN;
+	}
+    }
+
+    /* Send STOP */
+    TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
+    return cnt;
+}
+
+/* 
+ * ds1307_gettod
+ *
+ * Read time of day from DS1307 into time
+ *
+ * Note that we canonify to 24hr mode.
+ *
+ */
+int
+ds1307_gettod(ds1307raw_t *time) {
+    int len;
+
+    len = iic_read((uint8_t *)time, sizeof(ds1307raw_t) + 1, 0, DS1307_ADR);
+    if (len < 0) {
+	printf_P(PSTR("iic_read failed - %d\r\n"), len);
+	return(0);
+    }
+
+#if 1
+    if (len != sizeof(ds1307raw_t)) {
+	printf_P(PSTR("Couldn't read from RTC, got %d bytes (vs %d)\r\n"), len, sizeof(ds1307raw_t));
+	return(0);
+    }
+#endif
+
+#ifdef TWDEBUG
+    int i;
+    
+    for (i = 0; i < len; i++)
+	printf_P(PSTR("0x%02x: 0x%02x\r\n"), i, *(((uint8_t *)time) + i));
+#endif
+
+    return(1);
+}
+
+/* 
+ * ds1307_settod
+ *
+ * Set the DS1307 with the supplied time, format like so
+ * sc 2008/10/29 23:45:30
+ *
+ */
+int
+ds1307_settod(char *date) {
+    ds1307raw_t rtime;
+    int i, year, month, day, hour, min, sec;
+
+    if ((i = sscanf_P(date, PSTR("%d/%d/%d %d:%d:%d"), &year, &month, &day, &hour, &min, &sec)) != 6) {
+	printf_P(PSTR("Couldn't parse date, got %d\r\n"), i);
+	return(0);
+    }
+
+    if (year > 1900)
+	year -= 1900;
+    
+    rtime.split.year10 = year / 10;
+    rtime.split.year = year % 10;
+    rtime.split.month10 = month / 10;
+    rtime.split.month = month % 10;
+    rtime.split.day10 = day / 10;
+    rtime.split.day = day % 10;
+    rtime.split.pmam = ((hour / 10) & 0x02) >> 1;
+    rtime.split.hour10 = (hour / 10) & 0x01;
+    rtime.split.hour = hour % 10;
+    rtime.split.min10 = min / 10;
+    rtime.split.min = min % 10;
+    rtime.split.sec10 = sec / 10;
+    rtime.split.sec = sec % 10;
+
+    rtime.split.ch = 0; // Enable clock
+    rtime.split.s1224 = 0; // 24 hour mode
+    rtime.split.dow = 0; // XXX: unused
+    rtime.split.out = 0; // No clock out
+    
+#if TWDEBUG
+    for (i = 0; i < sizeof(ds1307raw_t); i++)
+	printf_P(PSTR("0x%02x: 0x%02x\r\n"), i, *(((uint8_t *)rtime) + i));
+#endif
+    if ((i = iic_write((uint8_t *)&rtime, sizeof(ds1307raw_t), 0, DS1307_ADR)) != sizeof(ds1307raw_t))
+	printf_P(PSTR("Unable to write to RTC, only sent %d (vs %d)\r\n"), i, sizeof(ds1307raw_t));
+    
+    return(1);
+}
+
+/* 
+ * ds1307_printtime
+ *
+ * Print the time in rtime with trailer
+ *
+ */
+void
+ds1307_printtime(char *leader, char *trailer) {
+    ds1307raw_t rtime;
+    uint8_t hour;
+
+    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;
+	
+    printf_P(PSTR("%S%04d/%02d/%d %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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ds1307.h	Thu Oct 30 11:53:32 2008 +1030
@@ -0,0 +1,93 @@
+/*
+ * DS1307 headers
+ *
+ * Copyright (c) 2008
+ *      Daniel O'Connor <darius@dons.net.au>.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define IIC_STFAIL	-1
+#define IIC_FAILARB	-2
+#define IIC_SLNAK	-3
+#define IIC_NOREPLY	-4
+#define IIC_UNKNOWN	-99
+
+#define DS1307_ADR	0xd0	// DS1307's TWI address
+
+typedef struct {
+    uint8_t	year;
+    uint8_t	month;
+    uint8_t	day;
+    uint8_t	hour;
+    uint8_t	min;
+    uint8_t	sec;
+
+    uint8_t	ctrl;
+    uint8_t	ram[56];
+} ds1307_t;
+
+typedef union {
+    uint8_t	raw[8];
+    struct {
+	uint8_t sec	: 4;
+	uint8_t	sec10	: 3;	// Seconds (0-59)
+	uint8_t	ch	: 1;	// Clock enable (1 = off)
+	
+	uint8_t min	: 4;
+	uint8_t min10	: 3;	// Minutes (0-59)
+	uint8_t	pad0	: 1;
+	
+	uint8_t hour	: 4;
+	uint8_t	hour10	: 1;	// Hours
+	uint8_t	pmam	: 1;	// AM/PM => 1 = PM or extra bit for hour10
+	uint8_t	s1224	: 1;	// 1 = 12 hour mode
+	uint8_t pad1	: 1;
+
+	uint8_t dow	: 3;	// Day of the week (1-7)
+	uint8_t	pad2	: 5;	
+	
+	uint8_t	day	: 4;
+	uint8_t day10	: 2;	// Day of the month (1-31)
+	uint8_t pad3	: 2;
+	
+	uint8_t month	: 4;
+	uint8_t month10	: 1;
+	uint8_t	pad4 	: 3;	// Month (1-12)
+	
+	uint8_t year	: 4;
+	uint8_t	year10	: 4;	// Year (0-99)
+	
+	uint8_t	rs	: 2;	// Rate select
+	uint8_t	pad6	: 2;
+	uint8_t sqwe	: 1;	// Square wave enable
+	uint8_t pad5	: 2;
+	uint8_t	out	: 1;	// Output control enable
+    } split;
+} ds1307raw_t;
+	
+int	ds1307_init(void);
+int	iic_read(uint8_t *data, uint8_t len, uint8_t adr, uint8_t sla);
+int	iic_write(uint8_t *data, uint8_t len, uint8_t adr, uint8_t sla);
+int	ds1307_gettod(ds1307raw_t *time);
+int	ds1307_settod(char *date);
+void	ds1307_printtime(char *leader, char *trailer);
--- a/tempctrl.c	Thu Oct 30 11:44:52 2008 +1030
+++ b/tempctrl.c	Thu Oct 30 11:53:32 2008 +1030
@@ -39,6 +39,7 @@
 #include "cons.h"
 #include "1wire.h"
 #include "tempctrl.h"
+#include "ds1307.h"
 
 typedef struct {
     int32_t	sec;
@@ -335,7 +336,11 @@
     if (nextstate != '-')
 	currstate = nextstate;
 
+#if 0
     printf_P(PSTR("Time: %10ld, "), t);
+#else
+    ds1307_printtime(PSTR(""), PSTR(": "));
+#endif
     printtemp(PSTR("Target"), settings.target_temp, PSTR(", "));
     printtemp(PSTR("Fermenter"), fermenter_temp, PSTR(", "));
     printtemp(PSTR("Fridge"), fridge_temp, PSTR(", "));
@@ -552,12 +557,12 @@
     }
 #ifndef WITHUSB
     if (!strcasecmp_P(cmd, PSTR("beep"))) {
-	if (buf[8] == '1')
+	if (buf[8] == '1' || buf[8] == 'y')
 	    settings.dobeep = 1;
-	else if (buf[8] == '0')
+	else if (buf[8] == '0' || buf[8] == 'n')
 	    settings.dobeep = 0;
 	else
-	    printf_P(PSTR("Expected a 0 or 1\r\n"));
+	    printf_P(PSTR("Expected a y/1 or n/0\r\n"));
 	return;
     }
 #endif
@@ -630,4 +635,3 @@
 	    break;
     }
 }
-
--- a/testavr.c	Thu Oct 30 11:44:52 2008 +1030
+++ b/testavr.c	Thu Oct 30 11:53:32 2008 +1030
@@ -42,6 +42,7 @@
 #include "usb.h"
 #endif
 #include "tempctrl.h"
+#include "ds1307.h"
 
 /*
  * Mirror of the MCUCSR register, taken early during startup.
@@ -114,9 +115,15 @@
     /* Set up the one wire stuff */
     OWInit();
 
+    /* Setup IIC */
+    ds1307_init();
+    
     /* Init UART */
     cons_init();
     
+    /* Init temperature control stuff */
+    tempctrl_init();
+
     printf_P(PSTR("\r\n\r\n===============\r\n"
 		  "Inited!\r\n\r\n"));
 
@@ -135,8 +142,6 @@
     if ((mcucsr & _BV(JTRF)) == _BV(JTRF))
 	printf_P(PSTR("JTAG reset\r\n"));
 
-    tempctrl_init();
-    
     /* Ready to go! */
     sei();
 
@@ -204,10 +209,12 @@
 		      "we ROMID adr val Write data into a DS2502 PROM (adr & val in hex)\r\n"
 		      "rr ROMID         Read DS2502 PROM\r\n"
 		      "zz		Reset MCU\r\n"
+		      "gc               Get time of day\r\n"
+		      "sc time          Set time of day (time is YYYY/MM/DD HH:MM:SS)\r\n"
 #ifdef WITHUSB
 		      "us               Generate USB data\r\n"
 #endif
-		      "tc ...           Temperature control related (tc help for more)\r\n"));
+		      "tc ...           Temperature control related (tc help for more)\r\n"
 	
 	return;
     } else if (!strncasecmp_P((char *)cmd.buf, PSTR("zz"), 2)) {
@@ -549,9 +556,18 @@
     } else if (!strncasecmp_P((char *)cmd.buf, PSTR("us"), 2)) {
 	usb_gendata();
 #endif
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("gc"), 2)) {
+	ds1307_printtime(PSTR(""), PSTR("\r\n"));
+    } else if (!strncasecmp_P((char *)cmd.buf, PSTR("sc"), 2)) {
+	if (cmd.len < 17) {
+	    printf_P(PSTR("Command not long enough\r\n"));
+	} else {
+	    if (ds1307_settod(cmd.buf + 3) != 1)
+		printf_P(PSTR("Unable to set time of day\r\n"));
+	}
     } else {
 	printf_P(PSTR("Unknown command, help for a list\r\n"));
     }
 }
-    
 
+