]> rtime.felk.cvut.cz Git - sysless.git/blob - arch/arm/mach-lpc23xx/libs/1-wire/1-wire-drv.c
lpc23xx library - updated 1 wire driver and driver for ds18S20. It still needs some...
[sysless.git] / arch / arm / mach-lpc23xx / libs / 1-wire / 1-wire-drv.c
1
2 /**
3  *      @file   1-wire-drv.c
4  *      @author Bc. Jiri Kubias jiri.kubias@gmail.com 
5  *
6  *      @brief  Software common 1wire driver
7  *      This driver is based on Maxim implementation. The driver supports
8  *      one (one pin is used for IO operation) or two pin implementation 
9  *      (one pin as input, and second pin as output). External pullup is mandatory 
10  *      for output pin. When hi level driver is done the driver can be reinitiated 
11  *      for another pin sets. The bus is always left in HI state. 
12  *
13  *      @note   This driver uses TIMER3 
14  *              
15  */
16
17
18 #include <lpc2xxx.h>                    /* LPC23xx definitions                */
19 #include <types.h>
20
21 typedef uint32_t reg_size;      ///< reg_size must be the addres size of register 
22 static reg_size dir;            ///< GPIO DIRX register
23 static reg_size set;            ///< GPIO SETX register
24 static reg_size clr;            ///< GPIO CLRX register
25 static reg_size port_wire;      ///< GPIO PORTX register
26 static uint8_t pin_read;        ///< place where the 1-wire is connected for reading
27 static uint8_t pin_write;       ///< place where the 1-wire is connected for writing
28 static uint32_t tim_1us;
29
30
31
32
33
34 /**
35  *  Wait specified time in ms
36  *  @param tim_ms       time to wait
37  *
38  */
39 void inline wire_delay(uint32_t tim_ms) 
40 {
41         T3TCR = 1; 
42         while(T3TC < ( tim_1us * (tim_ms))); 
43         T3TCR = 3;
44 }
45
46
47 /**
48  *  Sets the output pin to output and drive it low
49  *
50  */
51 static inline void wire_low (void)
52 {
53         *((reg_size *)dir) |= (1<<pin_write);           
54         *((reg_size *)clr) = (1<<pin_write);
55 }
56
57 /**
58  *  Release the pin and sets it as input. The high level is produced by pullup
59  *
60  */
61 static inline void wire_high (void)
62 {
63         *((reg_size *)dir) &= ~(1<<pin_write);     
64 }
65
66 /**
67  *  Setrs the pin as input and return its value
68  *
69  */
70 static inline uint8_t wire_read (void)
71 {
72         
73         *((reg_size *)dir) &= ~(1<<pin_read);   
74         return (unsigned char) ((*((reg_size *)port_wire) >> pin_read) & 1);
75 }
76
77 /**
78  *  Reset the 1wire bus, read and return the presence bit
79  *      @return         presence detect state
80  */
81 uint8_t wire_reset(void)
82
83 {
84         uint8_t presence_detect = 0;;
85         
86         wire_low();                     // Drive the bus low
87         wire_delay(480);
88         wire_read();                    // Release the bus
89         wire_delay(70); 
90         presence_detect = wire_read();  //Sample for presence pulse from slave
91         wire_delay(410);
92         wire_high ();                   // Release the bus
93         
94         return presence_detect;
95 }       
96
97 /**
98  *      Write one bit to 1-wire 
99  *      @param  write_bit value to write 
100  */
101 static void wire_write_bit (uint8_t write_bit)
102 {
103         if (write_bit)
104         {
105                 wire_low();                             // Drive the bus low
106                 wire_delay(6);
107                 wire_high ();                           // Release the bus
108                 wire_delay(64);
109         }
110         else
111         {
112                 wire_low();                             // Drive the bus low
113                 wire_delay(60); // delay 60 microsecond (us)
114                 wire_high ();                           // Release the bus
115                 wire_delay(10); // delay 10 microsecond (us)
116         }
117 }       
118
119
120 /**
121  *      Read one bit from 1-wire 
122  *      @return         readed bit state
123  */
124 static uint8_t wire_read_bit (void)
125 {
126         uint8_t read_data;  
127         wire_low();
128         wire_delay(6);
129         wire_high ();
130         wire_delay(9);
131         read_data = wire_read();
132         wire_delay(55);
133         return read_data;
134 }
135
136 /**
137  *      Write one byte to 1-wire 
138  *      @param  write_data value to write 
139  */
140 void wire_write_byte(uint8_t write_data)
141 {
142         uint8_t loop;
143         
144         for (loop = 0; loop < 8; loop++)
145         {
146                 wire_write_bit(write_data & 0x01);      //Sending LS-bit first
147                 write_data >>= 1;                                       // shift the data byte for the next bit to send
148         }       
149 }       
150
151 /**
152  *      Read one byte from 1-wire 
153  *      @return         readed byte from 1wire
154  */
155 uint8_t wire_read_byte(void)
156 {
157         unsigned char loop, result=0;
158         
159         for (loop = 0; loop < 8; loop++)
160         {
161                 
162                 result >>= 1;                           // shift the result to get it ready for the next bit to receive
163                 if (wire_read_bit())
164                 result |= 0x80;                         // if result is one, then set MS-bit
165         }
166         return result;
167 }       
168
169
170 /**
171  *      Initialize the 1wire driver for given parameters
172  *      @param  port    The the port where the IO pins are located
173  *      @param  pin_in_num      The number of input pin
174  *      @param  pin_out_num     The number of output pin
175  *      @param  f_tim   The frequency which is set for timer3
176  *
177  *      @example init_1_wire(FIO1, 10, 10, 72000000);   // when the input and output pin is the same
178  *      @example init_1_wire(FIO1, 10, 11, 72000000);   // when the input and output pin are different
179  */
180 void init_1_wire(uint8_t port, uint8_t pin_in_num, uint8_t pin_out_num, uint32_t f_tim)
181 {
182         dir = (uint32_t) &FIO0DIR + port * 0x20;
183         set = (uint32_t) &FIO0SET + port * 0x20;
184         clr = (uint32_t) &FIO0CLR + port * 0x20;
185         port_wire = (uint32_t) &FIO0PIN + port * 0x20;
186         pin_read  = pin_in_num;
187         pin_write = pin_out_num;
188
189         PCONP |= (1<<23);
190         T3TCR = 3; // Enable and reset, timer is set as free runing
191         T3CTCR = 0;
192         T3PR = 0;
193         
194         tim_1us = f_tim / 1000000;
195 }       
196
197
198 /**
199  *      Reset 1-wire  and test for presence bit
200  *      @return         1 if no device found
201  */
202 uint8_t wire_detect_device(void)
203 {
204         if (wire_reset())               
205                 return 1;
206         else            
207                 return 0;
208 }
209