manueller import aus nem CVS checkout (ist eh nur zum testen)
[ds1820tousb.git] / ds1wire.h
CommitLineData
93ac315e
MPM
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
29static 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
51static 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
89static 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.048316 seconds and 4 git commands to generate.