manueller import aus nem CVS checkout (ist eh nur zum testen)
[ds1820tousb.git] / ds1wire.h
1 /* $Id: ds1wire.h,v 1.2 2010/03/23 07:57:04 simimeie Exp $
2  * Basic operations for dallas / maxim 1wire bus
3  * (C) Michael "Fox" Meier 2009
4  */
5
6 #ifndef __DS1WIRE_H__
7 #define __DS1WIRE_H__
8
9 #include <util/delay.h>
10
11 /* This macro is redundant after powerup, as all bits zero is the default
12  * state after powerup. */
13 #define ds1wire_init(port, bit) {\
14   DDR##port &= (uint8_t)~(_BV(bit));  /* Do not actively drive the bus */ \
15   PORT##port &= (uint8_t)~(_BV(bit)); /* Always output a 0, so we just need to change */ \
16                                       /* the DDR register to pull the bus low. */ \
17 }
18
19 /* Reset the 1 wire bus. Works by driving it low for > 480 us.
20  * we do 500 to make sure.
21  * We then read the presence pulse 60 us after releasing the bus,
22  * and wait for another 420+1 us for the bus to become free.
23  * Returns 1 if there was a presence pulse, and 0 otherwise.
24  * takes about 981 usec to execute.
25  */
26 #define ds1wire_reset(port, bit) \
27   __ds1wire_reset(&DDR##port, &PIN##port, _BV(bit))
28
29 static inline uint8_t __ds1wire_reset(volatile uint8_t * ddr, volatile uint8_t * pin, uint8_t bv) {
30   uint8_t ret;
31   *ddr |= bv; /* drive the bus low */
32   _delay_ms(0.50);
33   *ddr &= (uint8_t)~bv; /* release the bus */
34   _delay_us(60.0);
35   ret = ((*pin & bv) == 0);
36   _delay_ms(0.421);
37   return ret;
38 }
39
40 /* Actively pull down the 1 wire bus. For hard resetting parasite powered
41  * probes that have gone bonkers. */
42 #define ds1wire_pulldown(port, bit) {\
43   PORT##port &= (uint8_t)~(_BV(bit)); /* Output 0 (sucking away the current from the pullup) */ \
44   DDR##port |= _BV(bit);  /* Actively drive the bus */ \
45 }
46
47 /* Read a bit from the 1 wire bus. takes 61 usec to execute. */
48 #define ds1wire_read(port, bit) \
49   __ds1wire_read(&DDR##port, &PIN##port, _BV(bit))
50
51 static inline uint8_t __ds1wire_read(volatile uint8_t * ddr, volatile uint8_t * pin, uint8_t bv) {
52   uint8_t ret;
53   *ddr |= bv; /* drive the bus low */
54   _delay_us(5.0); /* everything > 1 us should suffice, more to be sure. */
55   *ddr &= (uint8_t)~bv; /* release the bus */
56   _delay_us(6.0); /* Wait for the probe to pull the bus */
57   ret = ((*pin & bv) != 0);
58   _delay_us(50.0); /* after that the bus is free again */
59   return ret;
60 }
61
62 /* Sends a 0 bit to the 1 wire bus. takes 61 usec to execute. */
63 #define ds1wire_send0(port, bit) {\
64   DDR##port |= _BV(bit); /* pull low */ \
65   _delay_us(60.0); /* worst case timing */ \
66   DDR##port &= (uint8_t)~_BV(bit); /* release */ \
67   _delay_us(1.0); /* bus is free again after that */ \
68   }
69
70 /* Sends a 1 bit to the 1 wire bus. takes 61 usec to execute. */
71 #define ds1wire_send1(port, bit) {\
72   DDR##port |= _BV(bit); /* pull low */ \
73   _delay_us(10.0); /* everything > 1 us should suffice, try to be close to 15 us. */ \
74   DDR##port &= (uint8_t)~_BV(bit); /* release */ \
75   _delay_us(51.0); /* bus is free again after that */ \
76 }
77
78 /* Enable power for parasite powered probes. Warning: You must
79  * not forget to call parasitepoweroff after some time! */
80 #define ds1wire_parasitepoweron(port, bit) { \
81   PORT##port |= _BV(bit); \
82   DDR##port |= _BV(bit); \
83 }
84
85 /* Disable power for parasite powered probes. */
86 #define ds1wire_parasitepoweroff(port, bit) \
87   ds1wire_init(port, bit)
88
89 static inline uint8_t ds1wire_calccrc8(uint8_t shiftreg, uint8_t data)
90 {
91   uint8_t i;
92   for (i = 0; i < 8; i++) {
93     /* XOR LSB of shiftreg with LSB of data */
94     uint8_t feedback = (shiftreg & 0x01) ^ (data & 0x01);
95     shiftreg >>= 1; /* first position in shiftreg now is 0 - important for below! */
96     if (feedback == 1) {
97       shiftreg = shiftreg ^ 0x8C; /* binary 10001100 */
98     }
99     data >>= 1;
100   }
101   return shiftreg; 
102 }
103
104 #endif /* __DS1WIRE_H__ */
This page took 0.082798 seconds and 3 git commands to generate.