# HG changeset patch # User darius # Date 1193102495 -34200 # Node ID 0aa6bf4b98ae0cb97edebcbc2db507f45fd19cb5 # Parent b0cb873c0206edaa755e51028abf764baaf9c8c2 - 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 :) diff -r b0cb873c0206 -r 0aa6bf4b98ae 1wire-config.h --- 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 + diff -r b0cb873c0206 -r 0aa6bf4b98ae 1wire.c --- 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 +} + diff -r b0cb873c0206 -r 0aa6bf4b98ae 1wire.h --- 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