/************************************************************************/ /* */ /* Access Dallas 1-Wire Devices */ /* */ /* Author: Peter Dannegger */ /* 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 #include "1wire.h" #ifndef W1_PIN #define W1_PIN PB4 #define W1_IN PINB #define W1_OUT PORTB #define W1_DDR DDRB #endif uint8_t buff[2]; #define hard_gnd do { W1_OUT &= ~(1<>= 1; if( j ) b |= 0x80; } while( --i ); soft_vcc; return b; } uint8_t w1_byte_rd( void ) { return w1_byte_wr( 0xFF ); } /* uint8_t w1_rom_search( uint8_t diff, uint8_t *id ) { uint8_t i, j, next_diff; uint8_t b; if( w1_reset() ) return PRESENCE_ERR; // error, no device found w1_byte_wr( SEARCH_ROM ); // ROM search command next_diff = LAST_DEVICE; // unchanged on last device i = 8 * 8; // 8 bytes do { j = 8; // 8 bits do { b = w1_bit_io( 1 ); // read bit if( w1_bit_io( 1 ) ) // read complement bit { if( b ) // 11 return DATA_ERR; // data error } else { if( !b ) // 00 = 2 devices { if( diff > i || ((*id & 1) && diff != i) ) { b = 1; // now 1 next_diff = i; // next pass 0 } } } w1_bit_io( b ); // write bit *id >>= 1; if( b ) // store bit *id |= 0x80; i--; } while( --j ); id++; // next byte } while( i ); return next_diff; // to continue search }*/ void ds1992_read(uint16_t addr, uint8_t* buf, uint8_t len) { w1_byte_wr(SKIP_ROM); w1_byte_wr(0xF0); // read w1_byte_wr((addr & 0x00FF)); w1_byte_wr((addr & 0xFF00) >> 8); for (int i=0; i < len; i++) 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 ds1992_scratch_copy(uint16_t addr, uint8_t es_reg) { w1_byte_wr(SKIP_ROM); w1_byte_wr(0x55); // copy scratchpad to memory w1_byte_wr((addr & 0x00FF)); w1_byte_wr((addr & 0xFF00) >> 8); w1_byte_wr(es_reg); while(w1_byte_rd() != 0); } void w1_command( uint8_t command, uint8_t *id ) { uint8_t i; w1_reset(); if( id ) { w1_byte_wr( MATCH_ROM ); // to a single device i = 8; do { w1_byte_wr( *id ); id++; } while( --i ); } else { w1_byte_wr( SKIP_ROM ); // to all devices } w1_byte_wr( command ); }