changeset 33:0aa6bf4b98ae

- Don't wrap individual debug statements in ifdef, use a conditionally defined macro instead. - Add OWProgROM routine, can't remember if I actually tested it tho :)
author darius
date Tue, 23 Oct 2007 10:51:35 +0930
parents b0cb873c0206
children 2b8278ec5adb
files 1wire-config.h 1wire.c 1wire.h
diffstat 3 files changed, 156 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/1wire-config.h	Sun Apr 23 22:57:16 2006 +0930
+++ b/1wire-config.h	Tue Oct 23 10:51:35 2007 +0930
@@ -54,6 +54,11 @@
  */
 #define OWSETBUSHIGH()		PORTD &= ~_BV(4)
 
+/* Turn Vpp on (ie put +12V on the bus
+ * This is optional, if it is undefined OWProgROM always fails */
+#define OWSETVPPON()		PORTD |= _BV(5)
+#define OWSETVPPOFF()		PORTD &= ~_BV(5)
+
 /* _delay_us can only do a delay of 768/clock_freq */
 #if F_CPU > 16000000
 #error F_CPU > 16MHz, delays need adjusting
@@ -70,3 +75,21 @@
 	_delay_us(48);	_delay_us(48);  _delay_us(48);  _delay_us(48);  \
 	_delay_us(48);_delay_us(48);  _delay_us(48); } while (0)	/* 480 usec */
 #define OWDELAY_I do { _delay_us(48); _delay_us(22); } while (0)	/* 70 usec */
+
+void		uart_putsP(const char *addr);
+void		uart_puts(const char *addr);
+void		uart_puts_hex(uint8_t a);
+void		uart_puts_dec(uint8_t a, uint8_t l);
+#if OW_DEBUG
+void		uart_putsP(const char *addr);
+void		uart_puts(const char *addr);
+void		uart_puts_hex(uint8_t a);
+void		uart_puts_dec(uint8_t a, uint8_t l);
+
+#define OWPUTS(x)		uart_puts(x)
+#define OWPUTSP(x)		uart_putsP(x)
+#else
+#define OWPUTS(x)
+#define OWPUTSP(x)
+#endif
+
--- a/1wire.c	Sun Apr 23 22:57:16 2006 +0930
+++ b/1wire.c	Tue Oct 23 10:51:35 2007 +0930
@@ -43,13 +43,6 @@
 #include "1wire.h"
 #include "1wire-config.h"
 
-#if OW_DEBUG
-void		uart_putsP(const char *addr);
-void		uart_puts(const char *addr);
-void		uart_getc();
-char		uart_putc(char c);
-#endif
-
 static uint8_t OW_LastDevice = 0;
 static uint8_t OW_LastDiscrepancy = 0;
 static uint8_t OW_LastFamilyDiscrepancy = 0;
@@ -250,9 +243,7 @@
 	if (do_reset) {
 	    /* reset the 1-wire
 	     * if there are no parts on 1-wire, return 0 */
-#if OW_DEBUG
-	    uart_putsP(PSTR("Resetting\n\r"));
-#endif
+	    OWPUTSP(PSTR("Resetting\n\r"));
 	    switch (OWTouchReset()) {
 		case 0:
 		    break;
@@ -261,9 +252,7 @@
 		    /* reset the search */
 		    OW_LastDiscrepancy = 0;
 		    OW_LastFamilyDiscrepancy = 0;
-#if OW_DEBUG
-		    uart_putsP(PSTR("No devices on bus\n\r"));
-#endif
+		    OWPUTSP(PSTR("No devices on bus\n\r"));
 		    return OW_NOPRESENCE;
 		    break;
 		
@@ -271,9 +260,7 @@
 		    /* reset the search */
 		    OW_LastDiscrepancy = 0;
 		    OW_LastFamilyDiscrepancy = 0;
-#if OW_DEBUG
-		    uart_putsP(PSTR("Bus appears to be being held low\n\r"));
-#endif
+		    OWPUTSP(PSTR("Bus appears to be being held low\n\r"));
 		    return OW_BADWIRE;
 		break;
 		    
@@ -299,14 +286,14 @@
 
 #if OW_DEBUG
 	    sprintf_P(errstr, PSTR("bit_test = %d\n\r"), bit_test);
-	    uart_puts(errstr);
+	    OWPUTSP(errstr);
 #endif
 
 	    /* check for no devices on 1-wire */
 	    if (bit_test == 3) {
 #if OW_DEBUG
 		sprintf_P(errstr, PSTR("bit_test = %d\n\r"), bit_test);
-		uart_puts(errstr);
+		OWPUTSP(errstr);
 #endif
 		return(OW_BADWIRE);
 	    }
@@ -365,7 +352,7 @@
 	    if (lastcrc8) {
 #if OW_DEBUG
 		sprintf_P(errstr, PSTR("Bad CRC (%d)\n\r"), lastcrc8);
-		uart_puts(errstr);
+		OWPUTSP(errstr);
 #endif
 		next_result = OW_BADCRC;
 	    } else {
@@ -374,7 +361,7 @@
 		OW_LastDevice = (OW_LastDiscrepancy == 0);
 #if OW_DEBUG
 		sprintf_P(errstr, PSTR("Last device = %d\n\r"), OW_LastDevice);
-		uart_puts(errstr);
+		OWPUTSP(errstr);
 #endif
 		next_result = OW_FOUND;
 	    }
@@ -415,7 +402,132 @@
     116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53
 };
 
+/*-----------------------------------------------------------------------------
+ * Update *crc based on the value of x
+ */
 void
 OWCRC(uint8_t x, uint8_t *crc) {
     *crc = pgm_read_byte(&dscrc_table[(*crc) ^ x]);
 }
+
+/*-----------------------------------------------------------------------------
+ * Program a DS2502's memory
+ *
+ * Arguments
+ * ROM - ROM ID (or NULL to send SKIP_ROM)
+ * start  - Start address (bytes)
+ * len    - Length of data to write
+ * data   - Data to write
+ * exact  - If true, only accept exact matches for programming,
+ *          otherwise only ensure the bits we requested were 
+ *          programmed [to 0]
+ * status - If true program status rather than memory
+ *
+ * Returns..
+ *  0 if all is OK
+ *  1 if the programming was unsuccessful
+ *  2 if the parameters were invalid
+ *  3 if the DS2502 didn't respond appropriately (also happens if the
+ *  module doesn't exist)
+ */
+uint8_t
+OWProgROM(uint8_t *ROM, uint8_t start, uint8_t len, uint8_t *data, uint8_t exact, uint8_t status) {
+#if defined(OWSETVPPON) && defined(OWSETVPPOFF)
+    uint8_t	crc, i, tmp;
+    
+    /* Stupid programmer detection */
+    if (status) {
+	if (start  + len > 3)
+	    return(2);
+    } else {
+	if (start  + len > 127)
+	    return(2);
+    }
+    
+    if (len < 1)
+	return(2);
+    
+    OWDELAY_I;
+    if (OWTouchReset() != 0) {
+	uart_putsP(PSTR("No presence pulse\n\r"));
+	return(3);
+    }
+    
+    crc = 0;
+    
+    /* Send the command */
+    if (status) {
+	OWSendCmd(ROM, OW_WRITE_STATUS);
+	OWCRC(OW_WRITE_STATUS, &crc);
+    } else {
+	OWSendCmd(ROM, OW_WRITE_MEMORY);
+	OWCRC(OW_WRITE_MEMORY, &crc);
+    }
+    
+    /* And the start address
+     * (2 bytes even though one would do)
+     */
+    OWWriteByte(start);
+    OWCRC(start, &crc);
+
+    OWWriteByte(0x00);
+    OWCRC(0x00, &crc);
+
+    for (i = 0; i < len; i++) {
+	uart_putsP(PSTR("Programming "));
+	uart_puts_hex(data[i]);
+	uart_putsP(PSTR(" to "));
+	uart_puts_hex(start + i);
+	uart_putsP(PSTR("\n\r"));
+
+	OWWriteByte(data[i]);
+	OWCRC(data[i], &crc);
+    
+	tmp = OWReadByte();
+	
+	if (crc != tmp) {
+	    uart_putsP(PSTR("CRC mismatch "));
+	    uart_puts_hex(crc);
+	    uart_putsP(PSTR(" vs "));
+	    uart_puts_hex(tmp);
+	    uart_putsP(PSTR("\n\r"));
+
+	    OWTouchReset();
+	    return(3);
+	}
+	
+	OWSETVPPON();
+	OWDELAY_H;
+	OWSETVPPOFF();
+
+	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) {
+	    uart_putsP(PSTR("Readback mismatch "));
+	    uart_puts_hex(data[i]);
+	    uart_putsP(PSTR(" vs "));
+	    uart_puts_hex(data[i]);
+	    uart_putsP(PSTR("\n\r"));
+	    
+	    OWTouchReset();
+	    return(3);
+	}
+	
+	/* The DS2502 loads it's CRC register with the address of the
+	 * next byte */
+	crc = 0;
+	OWCRC(start + i + 1, &crc);
+    }
+
+    return(0);
+#else
+    return(1);
+#endif
+}
+
--- a/1wire.h	Sun Apr 23 22:57:16 2006 +0930
+++ b/1wire.h	Tue Oct 23 10:51:35 2007 +0930
@@ -40,6 +40,7 @@
 uint8_t		OWNext(uint8_t *ROM, uint8_t do_reset, uint8_t alarm_only);
 void		OWCRC(uint8_t x, uint8_t *crc);
 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);
 
 /* Return codes for OWFirst()/OWNext() */
 #define OW_BADWIRE		-3