diff options
Diffstat (limited to 'avr/1wire.c')
-rw-r--r-- | avr/1wire.c | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/avr/1wire.c b/avr/1wire.c new file mode 100644 index 0000000..237abb9 --- /dev/null +++ b/avr/1wire.c @@ -0,0 +1,130 @@ +/************************************************************************/ +/* */ +/* Access Dallas 1-Wire Devices */ +/* */ +/* Author: Peter Dannegger */ +/* danni@specs.de */ +/* */ +/************************************************************************/ +#include <util/delay.h> +#include <avr/io.h> +#include <avr/interrupt.h> + +#ifndef W1_PIN +#define W1_PIN PA0 +#define W1_IN PINA +#define W1_OUT PORTA +#define W1_DDR DDRA +#endif + +uint8_t buff[2]; + +uint8_t w1_reset(void) +{ + uint8_t err; + + W1_OUT &= ~(1<<W1_PIN); + W1_DDR |= 1<<W1_PIN; + _delay_us(480 ); // 480 us + cli(); + W1_DDR &= ~(1<<W1_PIN); + _delay_us( 66 ); + err = W1_IN & (1<<W1_PIN); // no presence detect + sei(); + _delay_us( 480 - 66 ); + if( (W1_IN & (1<<W1_PIN)) == 0 ) // short circuit + err = 1; + return err; +} + + +uint8_t w1_bit_io( uint8_t b ) +{ + cli(); + W1_DDR |= 1<<W1_PIN; + _delay_us( 1 ); + if( b ) + W1_DDR &= ~(1<<W1_PIN); + _delay_us( 15 - 1 ); + if( (W1_IN & (1<<W1_PIN)) == 0 ) + b = 0; + _delay_us( 60 - 15 ); + W1_DDR &= ~(1<<W1_PIN); + sei(); + return b; +} + + +uint w1_byte_wr( uint8_t b ) +{ + uint8_t i = 8, j; + do{ + j = w1_bit_io( b & 1 ); + b >>= 1; + if( j ) + b |= 0x80; + }while( --i ); + return b; +} + + +uint w1_byte_rd( void ) +{ + return w1_byte_wr( 0xFF ); +} + + +uint8_t w1_rom_search( uint8_t diff, uint8_t idata *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 w1_command( uint8_t command, uint8_t idata *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 ); +} |