diff 1wire.c @ 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 5898fba6593c
line wrap: on
line diff
--- 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
+}
+