From 07ce2df5da6265702e1d99556f46139f8b5b8611 Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Sun, 24 Jan 2016 20:02:30 +0100 Subject: write/verify scratchpad. proper formatting. warning comment. --- avr/1wire.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ avr/1wire.h | 4 ++++ avr/main.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 125 insertions(+), 9 deletions(-) (limited to 'avr') diff --git a/avr/1wire.c b/avr/1wire.c index affd80d..54c8dcc 100644 --- a/avr/1wire.c +++ b/avr/1wire.c @@ -6,6 +6,30 @@ /* danni@specs.de */ /* */ /************************************************************************/ + +/* modified by Florian Jung (flo@windfisch.org). + * Changelog: + * - try to drive parasite-powered devices via avr-builtin pullup + * - DS199X access functions + */ + +/* WARNING WARNING WARNING: + * this code VIOLATES THE 1-WIRE SPECIFICATION! Instead of "letting the + * line float" (which implies that it's gently pulled up to 5V by the + * pullup resistor), we're hard connecting the line against +5V, without + * any resistor in between. After some time, we let the line float, only + * held up by the (weak) AVR-internal pullup. + * + * THIS COULD DESTROY YOUR HARDWARE! you have been warned. + * + * (We do this because the internal pullup isn't strong enough to serve + * the DS1992 with power. The line is only hard-connected to +5V, when + * we're (sort of) sure that the DS1992 won't pull down the line to GND + * (since that would cause a short-circuit). Buuuut there's no guarantee, + * it just works[tm]) + */ + + #include #include #include @@ -176,6 +200,45 @@ void ds1992_read(uint16_t addr, uint8_t* buf, uint8_t len) buf[i] = w1_byte_rd(); } +void ds1992_scratch_write(uint16_t addr, const uint8_t* buf, uint8_t len) +{ + w1_byte_wr(SKIP_ROM); + w1_byte_wr(0x0F); // write scratchpad + w1_byte_wr((addr & 0x00FF)); + w1_byte_wr((addr & 0xFF00) >> 8); + for (int i=0; i < len; i++) + w1_byte_wr(buf[i]); +} + +uint8_t ds1992_scratch_verify(uint16_t addr, const uint8_t* buf, uint8_t len, uint8_t* es_reg_ptr) +{ + uint8_t status = 0; + + w1_byte_wr(SKIP_ROM); + w1_byte_wr(0xAA); // read scratchpad + + // check address bytes + if (w1_byte_rd() != (addr & 0x00FF)) status |= 0x01; + if (w1_byte_rd() != (addr & 0xFF00) >> 8) status |= 0x02; + + uint8_t es_reg = w1_byte_rd(); + *es_reg_ptr = es_reg; + // check E/S register + if (es_reg & 0x20) // PF: partial byte flag + status |= 0x04; + if (es_reg & 0x40) // OF: overflow flag + status |= 0x08; + if ((es_reg & 0x1F) != (addr & 0x1F) + (len-1)) + status |= 0x10; + + for (int i=0; i < len; i++) + if (w1_byte_rd() != buf[i]) + status |= 0xF0; + + return status; +} + + void w1_command( uint8_t command, uint8_t *id ) { uint8_t i; diff --git a/avr/1wire.h b/avr/1wire.h index accb132..af48d0b 100644 --- a/avr/1wire.h +++ b/avr/1wire.h @@ -24,4 +24,8 @@ uint8_t w1_byte_rd( void ); uint8_t w1_rom_search( uint8_t diff, uint8_t*id ); void w1_command( uint8_t command, uint8_t *id ); + +void ds1992_read(uint16_t addr, uint8_t* buf, uint8_t len); +void ds1992_scratch_write(uint16_t addr, const uint8_t* buf, uint8_t len); +uint8_t ds1992_scratch_verify(uint16_t addr, const uint8_t* buf, uint8_t len, uint8_t* es_reg_ptr); #endif diff --git a/avr/main.c b/avr/main.c index 6774d6e..15d98d3 100644 --- a/avr/main.c +++ b/avr/main.c @@ -55,6 +55,8 @@ void jump_to_bootloader(void) } static uchar replyBuffer[130]="Hello world initial"; +static uchar buf[33]; + usbMsgLen_t usbFunctionSetup(uchar data[8]) { usbRequest_t *rq = (void *) data; @@ -152,28 +154,75 @@ int main(void) sei(); // Enable interrupts after re-enumeration + uint8_t error = 0; while (1) { wdt_reset(); // keep the watchdog happy usbPoll(); - if (++c % (got_data ? 1000 : 3000) == 0) + if (++c % (error ? 12000 : got_data ? 1000 : 3000) == 0) { PORTC^=LED_BLUE; PORTC |= LED_RED | LED_GREEN; } if (c % 12000 == 0) { - uint8_t result = w1_reset(); - if (result == 0) // device detected + if (!got_data) // we want to read the token + { + uint8_t result = w1_reset(); + if (result == 0) // device detected + { + PORTC &= ~LED_GREEN; + ds1992_read(0, replyBuffer, 128); + } + else if (result == 1) // no presence pulse == no device detected + PORTC &= ~LED_RED; + else // short circuit detected + PORTC &= ~(LED_RED | LED_GREEN); + } + else // we want to WRITE the token (*shudder*!) { - PORTC &= ~LED_GREEN; - ds1992_read(0, replyBuffer, 128); + uint8_t result = w1_reset(); + if (result == 0) // device detected + { + PORTC &= ~LED_GREEN; + + cli(); + memcpy(buf, replyBuffer, 33); + got_data = 0; + sei(); + + uint16_t writepos = ((uint16_t)buf[32]) * 32; + ds1992_scratch_write(writepos, buf, 32); + + result = w1_reset(); + if (result != 0) + { + replyBuffer[0] = 0x01; + error = 1; + goto write_failed; + } + + uint8_t es_reg; + result = ds1992_scratch_verify(writepos, buf, 32, &es_reg); + if (result != 0) + { + replyBuffer[0] = 0x02; + error = 1; + goto write_failed; + } + + replyBuffer[0] = 0xFF; // success + error = 0; + + write_failed: + 1; + } + else if (result == 1) // no presence pulse == no device detected + PORTC &= ~LED_RED; + else // short circuit detected + PORTC &= ~(LED_RED | LED_GREEN); } - else if (result == 1) // no presence pulse == no device detected - PORTC &= ~LED_RED; - else // short circuit detected - PORTC &= ~(LED_RED | LED_GREEN); } } -- cgit v1.2.3