Doxtest  1
i2c.c
Go to the documentation of this file.
1 /**
2  \file i2c.c
3 
4  \ingroup i2c_grp
5 
6  \brief I2C Bus Master Driver Implementation
7 
8  \b Customer: Source Graphics
9 
10  \b Project: Cafissimo 1B
11 
12  \b Controller: Holtek HT46x232
13 
14  \b Compiler: Holtek C 2.02
15 
16  \b Created: 02.09.2005 Peter Horn, Micropool GmbH
17 
18  \b Copyright: (C) Micropool GmbH
19 
20  $Id: i2c.c 288 2006-02-22 14:43:47Z Peter Horn $
21 
22  \copydoc i2c_grp
23 
24  */
25 
26 ///////////////////////////////////////////////////////////////////////////////////////////////////
27 // Includes
28 ///////////////////////////////////////////////////////////////////////////////////////////////////
29 
30 #include "i2c.h"
31 #include "iodef.h"
32 
33 
34 ///////////////////////////////////////////////////////////////////////////////////////////////////
35 /**
36  \name Delay Macros
37 
38  These macros must be adjusted to the actual target hardware.
39  */
40 ///////////////////////////////////////////////////////////////////////////////////////////////////
41 
42 //@{
43 
44 /// Delay execution for 1us
45 #define delay_1us() { _nop(); _nop(); }
46 
47 /// Delay execution for 2us
48 #define delay_2us() { delay_1us(); delay_1us(); }
49 
50 
51 //@}
52 
53 ///////////////////////////////////////////////////////////////////////////////////////////////////
54 /**
55  \name I/O Port Access Macros
56 
57  These macros must be adjusted to the actual target hardware.
58  */
59 ///////////////////////////////////////////////////////////////////////////////////////////////////
60 
61 //@{
62 
63 /**
64  \brief Set SDA Output State
65 
66  \param state Pin state 0: Low, 1: Hi-Z
67 
68  Implements the target dependent method to set the SDA line.
69  */
70 #define set_sda(state) \
71 ( \
72  state ? \
73  (DIR_I2C_SDA = DIR_INPUT, _nop(), 0) : \
74  (IO_I2C_SDA = LOW, DIR_I2C_SDA = DIR_OUTPUT, 0) \
75 )
76 
77 /**
78  \brief Read SDA Input State
79 
80  \return Current level at the SDA pin
81  */
82 
83 #define get_sda() \
84  IO_I2C_SDA
85 
86 /**
87  \brief Set SCL Output State
88 
89  \param state Pin state 0: Low, 1 High
90 
91  Implements the target dependent method to set the SCL line.
92  */
93 #define set_scl(state) \
94 ( \
95  state ? \
96  (OUT_I2C_SCL = HIGH, 0) : \
97  (OUT_I2C_SCL = LOW, 0) \
98 )
99 
100 //@}
101 
102 ///////////////////////////////////////////////////////////////////////////////////////////////////
103 /**
104  \name Bit Transfer Macros
105 
106  The bit transfer operations are implemented as macros to reduce the call overhead.
107  */
108 ///////////////////////////////////////////////////////////////////////////////////////////////////
109 
110 //@{
111 
112 /**
113  \brief Output a bit
114 
115  \param databit Value of bit to output
116 
117  \par Timing diagram
118  <pre>
119  _______
120  SCL ___________/ 2us \__
121  _______ ______________
122  SDA _______X______________
123  </pre>
124 
125  \pre SCL must be LOW
126  */
127 
128 #define write_bit(databit) \
129 { \
130  set_sda(databit); \
131  set_scl(HIGH); \
132  delay_2us(); \
133  set_scl(LOW); \
134 }
135 
136 /**
137  \brief Read a bit
138 
139  \param databit lvalue to receive the read bit (e.g. name of a variable)
140 
141  \par Timing diagram
142  <pre>
143  _______
144  SCL ____/ 2us \__
145  _ __________ __
146  SDA _X__________X__
147  &nbsp;
148  ^- Sampling Point
149  </pre>
150 
151  \pre SCL must LOW
152  \post IO_SDA is Hi-Z
153  */
154 
155 #define read_bit(databit) \
156 { \
157  set_sda(HIGH); \
158  set_scl(HIGH); \
159  databit = get_sda(); \
160  set_scl(LOW); \
161 }
162 
163 //@}
164 
165 
166 ///////////////////////////////////////////////////////////////////////////////////////////////////
167 /// \name Public Functions
168 ///
169 /// Documentation is found in module header
170 ///////////////////////////////////////////////////////////////////////////////////////////////////
171 
172 //@{
173 
174 void i2c_start(void)
175 {
176  set_scl(HIGH);
177  set_sda(HIGH);
178  delay_1us();
179  set_sda(LOW);
180  delay_1us();
181  set_scl(LOW);
182 }
183 
184 ///////////////////////////////////////////////////////////////////////////////////////////////////
185 
186 void i2c_stop(void)
187 {
188  set_sda(LOW);
189  set_scl(HIGH);
190  delay_1us();
191  set_sda(HIGH);
192 }
193 
194 ///////////////////////////////////////////////////////////////////////////////////////////////////
195 
196 bool i2c_write(uint8 data)
197 {
198  uint8 todo = 8;
199  uint8 nack;
200 
201  do {
202  write_bit(data & 0x80);
203  data <<= 1;
204  todo--;
205  } while(todo);
206  read_bit(nack);
207 
208  //return !nack
209  if(nack)
210  return 0;
211  else
212  return 1;
213 }
214 
215 ///////////////////////////////////////////////////////////////////////////////////////////////////
216 
217 uint8 i2c_read(ack_t ack)
218 {
219  uint8 data = 0;
220  uint8 dbit;
221  uint8 todo = 8;
222 
223  do {
224  data <<= 1;
225  read_bit(dbit);
226  data |= dbit;
227  todo--;
228  } while(todo);
229  write_bit(!ack);
230 
231  return data;
232 }
233 
234 ///////////////////////////////////////////////////////////////////////////////////////////////////
235 
236 //@}
237