summaryrefslogtreecommitdiff
path: root/avr/1wire.c
diff options
context:
space:
mode:
Diffstat (limited to 'avr/1wire.c')
-rw-r--r--avr/1wire.c130
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 );
+}