?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 6

Line No. Rev Author Line
1 6 kaklik <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
3 <title>Procyon AVRlib: i2c.c Source File</title>
4 <link href="dox.css" rel="stylesheet" type="text/css">
5 </head><body>
6 <!-- Generated by Doxygen 1.4.2 -->
7 <div class="qindex"><a class="qindex" href="main.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="globals.html">Globals</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
8 <h1>i2c.c</h1><a href="i2c_8c.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment">00001 <span class="comment">/*! \file i2c.c \brief I2C interface using AVR Two-Wire Interface (TWI) hardware. */</span>
9 00002 <span class="comment">//*****************************************************************************</span>
10 00003 <span class="comment">//</span>
11 00004 <span class="comment">// File Name : 'i2c.c'</span>
12 00005 <span class="comment">// Title : I2C interface using AVR Two-Wire Interface (TWI) hardware</span>
13 00006 <span class="comment">// Author : Pascal Stang - Copyright (C) 2002-2003</span>
14 00007 <span class="comment">// Created : 2002.06.25</span>
15 00008 <span class="comment">// Revised : 2003.03.02</span>
16 00009 <span class="comment">// Version : 0.9</span>
17 00010 <span class="comment">// Target MCU : Atmel AVR series</span>
18 00011 <span class="comment">// Editor Tabs : 4</span>
19 00012 <span class="comment">//</span>
20 00013 <span class="comment">// This code is distributed under the GNU Public License</span>
21 00014 <span class="comment">// which can be found at http://www.gnu.org/licenses/gpl.txt</span>
22 00015 <span class="comment">//</span>
23 00016 <span class="comment">//*****************************************************************************</span>
24 00017
25 00018 <span class="preprocessor">#include &lt;avr/io.h&gt;</span>
26 00019 <span class="preprocessor">#include &lt;avr/interrupt.h&gt;</span>
27 00020
28 00021 <span class="preprocessor">#include "<a class="code" href="i2c_8h.html">i2c.h</a>"</span>
29 00022
30 00023 <span class="preprocessor">#include "<a class="code" href="rprintf_8h.html">rprintf.h</a>"</span> <span class="comment">// include printf function library</span>
31 00024 <span class="preprocessor">#include "<a class="code" href="uart2_8h.html">uart2.h</a>"</span>
32 00025
33 00026 <span class="comment">// Standard I2C bit rates are:</span>
34 00027 <span class="comment">// 100KHz for slow speed</span>
35 00028 <span class="comment">// 400KHz for high speed</span>
36 00029
37 00030 <span class="comment">//#define I2C_DEBUG</span>
38 00031
39 00032 <span class="comment">// I2C state and address variables</span>
40 00033 <span class="keyword">static</span> <span class="keyword">volatile</span> eI2cStateType I2cState;
41 00034 <span class="keyword">static</span> u08 I2cDeviceAddrRW;
42 00035 <span class="comment">// send/transmit buffer (outgoing data)</span>
43 00036 <span class="keyword">static</span> u08 I2cSendData[I2C_SEND_DATA_BUFFER_SIZE];
44 00037 <span class="keyword">static</span> u08 I2cSendDataIndex;
45 00038 <span class="keyword">static</span> u08 I2cSendDataLength;
46 00039 <span class="comment">// receive buffer (incoming data)</span>
47 00040 <span class="keyword">static</span> u08 I2cReceiveData[I2C_RECEIVE_DATA_BUFFER_SIZE];
48 00041 <span class="keyword">static</span> u08 I2cReceiveDataIndex;
49 00042 <span class="keyword">static</span> u08 I2cReceiveDataLength;
50 00043
51 00044 <span class="comment">// function pointer to i2c receive routine</span><span class="comment"></span>
52 00045 <span class="comment">//! I2cSlaveReceive is called when this processor</span>
53 00046 <span class="comment"></span><span class="comment">// is addressed as a slave for writing</span>
54 00047 <span class="keyword">static</span> void (*i2cSlaveReceive)(u08 receiveDataLength, u08* recieveData);<span class="comment"></span>
55 00048 <span class="comment">//! I2cSlaveTransmit is called when this processor</span>
56 00049 <span class="comment"></span><span class="comment">// is addressed as a slave for reading</span>
57 00050 <span class="keyword">static</span> u08 (*i2cSlaveTransmit)(u08 transmitDataLengthMax, u08* transmitData);
58 00051
59 00052 <span class="comment">// functions</span>
60 <a name="l00053"></a><a class="code" href="i2csw_8h.html#a1">00053</a> <span class="keywordtype">void</span> <a class="code" href="i2c_8c.html#a10">i2cInit</a>(<span class="keywordtype">void</span>)
61 00054 {
62 00055 <span class="comment">// set pull-up resistors on I2C bus pins</span>
63 00056 <span class="comment">// TODO: should #ifdef these</span>
64 00057 sbi(PORTC, 0); <span class="comment">// i2c SCL on ATmega163,323,16,32,etc</span>
65 00058 sbi(PORTC, 1); <span class="comment">// i2c SDA on ATmega163,323,16,32,etc</span>
66 00059 sbi(PORTD, 0); <span class="comment">// i2c SCL on ATmega128,64</span>
67 00060 sbi(PORTD, 1); <span class="comment">// i2c SDA on ATmega128,64</span>
68 00061
69 00062 <span class="comment">// clear SlaveReceive and SlaveTransmit handler to null</span>
70 00063 i2cSlaveReceive = 0;
71 00064 i2cSlaveTransmit = 0;
72 00065 <span class="comment">// set i2c bit rate to 100KHz</span>
73 00066 <a class="code" href="i2c_8c.html#a11">i2cSetBitrate</a>(100);
74 00067 <span class="comment">// enable TWI (two-wire interface)</span>
75 00068 sbi(TWCR, TWEN);
76 00069 <span class="comment">// set state</span>
77 00070 I2cState = I2C_IDLE;
78 00071 <span class="comment">// enable TWI interrupt and slave address ACK</span>
79 00072 sbi(TWCR, TWIE);
80 00073 sbi(TWCR, TWEA);
81 00074 <span class="comment">//outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));</span>
82 00075 <span class="comment">// enable interrupts</span>
83 00076 sei();
84 00077 }
85 00078
86 <a name="l00079"></a><a class="code" href="i2c_8h.html#a39">00079</a> <span class="keywordtype">void</span> <a class="code" href="i2c_8c.html#a11">i2cSetBitrate</a>(u16 bitrateKHz)
87 00080 {
88 00081 u08 bitrate_div;
89 00082 <span class="comment">// set i2c bitrate</span>
90 00083 <span class="comment">// SCL freq = F_CPU/(16+2*TWBR))</span>
91 00084 <span class="preprocessor"> #ifdef TWPS0</span>
92 00085 <span class="preprocessor"></span> <span class="comment">// for processors with additional bitrate division (mega128)</span>
93 00086 <span class="comment">// SCL freq = F_CPU/(16+2*TWBR*4^TWPS)</span>
94 00087 <span class="comment">// set TWPS to zero</span>
95 00088 cbi(TWSR, TWPS0);
96 00089 cbi(TWSR, TWPS1);
97 00090 <span class="preprocessor"> #endif</span>
98 00091 <span class="preprocessor"></span> <span class="comment">// calculate bitrate division </span>
99 00092 bitrate_div = ((F_CPU/1000l)/bitrateKHz);
100 00093 <span class="keywordflow">if</span>(bitrate_div &gt;= 16)
101 00094 bitrate_div = (bitrate_div-16)/2;
102 00095 outb(TWBR, bitrate_div);
103 00096 }
104 00097
105 <a name="l00098"></a><a class="code" href="i2c_8h.html#a40">00098</a> <span class="keywordtype">void</span> <a class="code" href="i2c_8c.html#a12">i2cSetLocalDeviceAddr</a>(u08 deviceAddr, u08 genCallEn)
106 00099 {
107 00100 <span class="comment">// set local device address (used in slave mode only)</span>
108 00101 outb(TWAR, ((deviceAddr&amp;0xFE) | (genCallEn?1:0)) );
109 00102 }
110 00103
111 <a name="l00104"></a><a class="code" href="i2c_8h.html#a41">00104</a> <span class="keywordtype">void</span> <a class="code" href="i2c_8c.html#a13">i2cSetSlaveReceiveHandler</a>(<span class="keywordtype">void</span> (*i2cSlaveRx_func)(u08 receiveDataLength, u08* recieveData))
112 00105 {
113 00106 i2cSlaveReceive = i2cSlaveRx_func;
114 00107 }
115 00108
116 <a name="l00109"></a><a class="code" href="i2c_8h.html#a42">00109</a> <span class="keywordtype">void</span> <a class="code" href="i2c_8c.html#a14">i2cSetSlaveTransmitHandler</a>(u08 (*i2cSlaveTx_func)(u08 transmitDataLengthMax, u08* transmitData))
117 00110 {
118 00111 i2cSlaveTransmit = i2cSlaveTx_func;
119 00112 }
120 00113
121 <a name="l00114"></a><a class="code" href="i2c_8h.html#a43">00114</a> <span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code" href="i2c_8c.html#a15">i2cSendStart</a>(<span class="keywordtype">void</span>)
122 00115 {
123 00116 <span class="comment">// send start condition</span>
124 00117 outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
125 00118 }
126 00119
127 <a name="l00120"></a><a class="code" href="i2c_8h.html#a44">00120</a> <span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code" href="i2c_8c.html#a16">i2cSendStop</a>(<span class="keywordtype">void</span>)
128 00121 {
129 00122 <span class="comment">// transmit stop condition</span>
130 00123 <span class="comment">// leave with TWEA on for slave receiving</span>
131 00124 outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)|BV(TWSTO));
132 00125 }
133 00126
134 <a name="l00127"></a><a class="code" href="i2c_8h.html#a45">00127</a> <span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code" href="i2c_8c.html#a17">i2cWaitForComplete</a>(<span class="keywordtype">void</span>)
135 00128 {
136 00129 <span class="comment">// wait for i2c interface to complete operation</span>
137 00130 <span class="keywordflow">while</span>( !(inb(TWCR) &amp; BV(TWINT)) );
138 00131 }
139 00132
140 <a name="l00133"></a><a class="code" href="i2c_8h.html#a46">00133</a> <span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code" href="i2c_8c.html#a18">i2cSendByte</a>(u08 data)
141 00134 {
142 00135 <span class="comment">// save data to the TWDR</span>
143 00136 outb(TWDR, data);
144 00137 <span class="comment">// begin send</span>
145 00138 outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT));
146 00139 }
147 00140
148 <a name="l00141"></a><a class="code" href="i2c_8h.html#a47">00141</a> <span class="keyword">inline</span> <span class="keywordtype">void</span> <a class="code" href="i2c_8c.html#a19">i2cReceiveByte</a>(u08 ackFlag)
149 00142 {
150 00143 <span class="comment">// begin receive over i2c</span>
151 00144 <span class="keywordflow">if</span>( ackFlag )
152 00145 {
153 00146 <span class="comment">// ackFlag = TRUE: ACK the recevied data</span>
154 00147 outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
155 00148 }
156 00149 <span class="keywordflow">else</span>
157 00150 {
158 00151 <span class="comment">// ackFlag = FALSE: NACK the recevied data</span>
159 00152 outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT));
160 00153 }
161 00154 }
162 00155
163 <a name="l00156"></a><a class="code" href="i2c_8h.html#a48">00156</a> <span class="keyword">inline</span> u08 <a class="code" href="i2c_8c.html#a20">i2cGetReceivedByte</a>(<span class="keywordtype">void</span>)
164 00157 {
165 00158 <span class="comment">// retieve received data byte from i2c TWDR</span>
166 00159 <span class="keywordflow">return</span>( inb(TWDR) );
167 00160 }
168 00161
169 <a name="l00162"></a><a class="code" href="i2c_8h.html#a49">00162</a> <span class="keyword">inline</span> u08 <a class="code" href="i2c_8c.html#a21">i2cGetStatus</a>(<span class="keywordtype">void</span>)
170 00163 {
171 00164 <span class="comment">// retieve current i2c status from i2c TWSR</span>
172 00165 <span class="keywordflow">return</span>( inb(TWSR) );
173 00166 }
174 00167
175 <a name="l00168"></a><a class="code" href="i2c_8h.html#a50">00168</a> <span class="keywordtype">void</span> <a class="code" href="i2c_8c.html#a22">i2cMasterSend</a>(u08 deviceAddr, u08 length, u08* data)
176 00169 {
177 00170 u08 i;
178 00171 <span class="comment">// wait for interface to be ready</span>
179 00172 <span class="keywordflow">while</span>(I2cState);
180 00173 <span class="comment">// set state</span>
181 00174 I2cState = I2C_MASTER_TX;
182 00175 <span class="comment">// save data</span>
183 00176 I2cDeviceAddrRW = (deviceAddr &amp; 0xFE); <span class="comment">// RW cleared: write operation</span>
184 00177 <span class="keywordflow">for</span>(i=0; i&lt;length; i++)
185 00178 I2cSendData[i] = *data++;
186 00179 I2cSendDataIndex = 0;
187 00180 I2cSendDataLength = length;
188 00181 <span class="comment">// send start condition</span>
189 00182 <a class="code" href="i2c_8c.html#a15">i2cSendStart</a>();
190 00183 }
191 00184
192 <a name="l00185"></a><a class="code" href="i2c_8h.html#a51">00185</a> <span class="keywordtype">void</span> <a class="code" href="i2c_8c.html#a23">i2cMasterReceive</a>(u08 deviceAddr, u08 length, u08* data)
193 00186 {
194 00187 u08 i;
195 00188 <span class="comment">// wait for interface to be ready</span>
196 00189 <span class="keywordflow">while</span>(I2cState);
197 00190 <span class="comment">// set state</span>
198 00191 I2cState = I2C_MASTER_RX;
199 00192 <span class="comment">// save data</span>
200 00193 I2cDeviceAddrRW = (deviceAddr|0x01); <span class="comment">// RW set: read operation</span>
201 00194 I2cReceiveDataIndex = 0;
202 00195 I2cReceiveDataLength = length;
203 00196 <span class="comment">// send start condition</span>
204 00197 <a class="code" href="i2c_8c.html#a15">i2cSendStart</a>();
205 00198 <span class="comment">// wait for data</span>
206 00199 <span class="keywordflow">while</span>(I2cState);
207 00200 <span class="comment">// return data</span>
208 00201 <span class="keywordflow">for</span>(i=0; i&lt;length; i++)
209 00202 *data++ = I2cReceiveData[i];
210 00203 }
211 00204
212 <a name="l00205"></a><a class="code" href="i2c_8h.html#a52">00205</a> u08 <a class="code" href="i2c_8c.html#a24">i2cMasterSendNI</a>(u08 deviceAddr, u08 length, u08* data)
213 00206 {
214 00207 u08 retval = I2C_OK;
215 00208
216 00209 <span class="comment">// disable TWI interrupt</span>
217 00210 cbi(TWCR, TWIE);
218 00211
219 00212 <span class="comment">// send start condition</span>
220 00213 <a class="code" href="i2c_8c.html#a15">i2cSendStart</a>();
221 00214 <a class="code" href="i2c_8c.html#a17">i2cWaitForComplete</a>();
222 00215
223 00216 <span class="comment">// send device address with write</span>
224 00217 <a class="code" href="i2c_8c.html#a18">i2cSendByte</a>( deviceAddr &amp; 0xFE );
225 00218 <a class="code" href="i2c_8c.html#a17">i2cWaitForComplete</a>();
226 00219
227 00220 <span class="comment">// check if device is present and live</span>
228 00221 <span class="keywordflow">if</span>( inb(TWSR) == TW_MT_SLA_ACK)
229 00222 {
230 00223 <span class="comment">// send data</span>
231 00224 <span class="keywordflow">while</span>(length)
232 00225 {
233 00226 <a class="code" href="i2c_8c.html#a18">i2cSendByte</a>( *data++ );
234 00227 <a class="code" href="i2c_8c.html#a17">i2cWaitForComplete</a>();
235 00228 length--;
236 00229 }
237 00230 }
238 00231 <span class="keywordflow">else</span>
239 00232 {
240 00233 <span class="comment">// device did not ACK it's address,</span>
241 00234 <span class="comment">// data will not be transferred</span>
242 00235 <span class="comment">// return error</span>
243 00236 retval = I2C_ERROR_NODEV;
244 00237 }
245 00238
246 00239 <span class="comment">// transmit stop condition</span>
247 00240 <span class="comment">// leave with TWEA on for slave receiving</span>
248 00241 <a class="code" href="i2c_8c.html#a16">i2cSendStop</a>();
249 00242 <span class="keywordflow">while</span>( !(inb(TWCR) &amp; BV(TWSTO)) );
250 00243
251 00244 <span class="comment">// enable TWI interrupt</span>
252 00245 sbi(TWCR, TWIE);
253 00246
254 00247 <span class="keywordflow">return</span> retval;
255 00248 }
256 00249
257 <a name="l00250"></a><a class="code" href="i2c_8h.html#a53">00250</a> u08 <a class="code" href="i2c_8c.html#a25">i2cMasterReceiveNI</a>(u08 deviceAddr, u08 length, u08 *data)
258 00251 {
259 00252 u08 retval = I2C_OK;
260 00253
261 00254 <span class="comment">// disable TWI interrupt</span>
262 00255 cbi(TWCR, TWIE);
263 00256
264 00257 <span class="comment">// send start condition</span>
265 00258 <a class="code" href="i2c_8c.html#a15">i2cSendStart</a>();
266 00259 <a class="code" href="i2c_8c.html#a17">i2cWaitForComplete</a>();
267 00260
268 00261 <span class="comment">// send device address with read</span>
269 00262 <a class="code" href="i2c_8c.html#a18">i2cSendByte</a>( deviceAddr | 0x01 );
270 00263 <a class="code" href="i2c_8c.html#a17">i2cWaitForComplete</a>();
271 00264
272 00265 <span class="comment">// check if device is present and live</span>
273 00266 <span class="keywordflow">if</span>( inb(TWSR) == TW_MR_SLA_ACK)
274 00267 {
275 00268 <span class="comment">// accept receive data and ack it</span>
276 00269 <span class="keywordflow">while</span>(length &gt; 1)
277 00270 {
278 00271 <a class="code" href="i2c_8c.html#a19">i2cReceiveByte</a>(TRUE);
279 00272 <a class="code" href="i2c_8c.html#a17">i2cWaitForComplete</a>();
280 00273 *data++ = <a class="code" href="i2c_8c.html#a20">i2cGetReceivedByte</a>();
281 00274 <span class="comment">// decrement length</span>
282 00275 length--;
283 00276 }
284 00277
285 00278 <span class="comment">// accept receive data and nack it (last-byte signal)</span>
286 00279 <a class="code" href="i2c_8c.html#a19">i2cReceiveByte</a>(FALSE);
287 00280 <a class="code" href="i2c_8c.html#a17">i2cWaitForComplete</a>();
288 00281 *data++ = <a class="code" href="i2c_8c.html#a20">i2cGetReceivedByte</a>();
289 00282 }
290 00283 <span class="keywordflow">else</span>
291 00284 {
292 00285 <span class="comment">// device did not ACK it's address,</span>
293 00286 <span class="comment">// data will not be transferred</span>
294 00287 <span class="comment">// return error</span>
295 00288 retval = I2C_ERROR_NODEV;
296 00289 }
297 00290
298 00291 <span class="comment">// transmit stop condition</span>
299 00292 <span class="comment">// leave with TWEA on for slave receiving</span>
300 00293 <a class="code" href="i2c_8c.html#a16">i2cSendStop</a>();
301 00294
302 00295 <span class="comment">// enable TWI interrupt</span>
303 00296 sbi(TWCR, TWIE);
304 00297
305 00298 <span class="keywordflow">return</span> retval;
306 00299 }
307 00300 <span class="comment">/*</span>
308 00301 <span class="comment">void i2cMasterTransferNI(u08 deviceAddr, u08 sendlength, u08* senddata, u08 receivelength, u08* receivedata)</span>
309 00302 <span class="comment">{</span>
310 00303 <span class="comment"> // disable TWI interrupt</span>
311 00304 <span class="comment"> cbi(TWCR, TWIE);</span>
312 00305 <span class="comment"></span>
313 00306 <span class="comment"> // send start condition</span>
314 00307 <span class="comment"> i2cSendStart();</span>
315 00308 <span class="comment"> i2cWaitForComplete();</span>
316 00309 <span class="comment"></span>
317 00310 <span class="comment"> // if there's data to be sent, do it</span>
318 00311 <span class="comment"> if(sendlength)</span>
319 00312 <span class="comment"> {</span>
320 00313 <span class="comment"> // send device address with write</span>
321 00314 <span class="comment"> i2cSendByte( deviceAddr &amp; 0xFE );</span>
322 00315 <span class="comment"> i2cWaitForComplete();</span>
323 00316 <span class="comment"> </span>
324 00317 <span class="comment"> // send data</span>
325 00318 <span class="comment"> while(sendlength)</span>
326 00319 <span class="comment"> {</span>
327 00320 <span class="comment"> i2cSendByte( *senddata++ );</span>
328 00321 <span class="comment"> i2cWaitForComplete();</span>
329 00322 <span class="comment"> sendlength--;</span>
330 00323 <span class="comment"> }</span>
331 00324 <span class="comment"> }</span>
332 00325 <span class="comment"></span>
333 00326 <span class="comment"> // if there's data to be received, do it</span>
334 00327 <span class="comment"> if(receivelength)</span>
335 00328 <span class="comment"> {</span>
336 00329 <span class="comment"> // send repeated start condition</span>
337 00330 <span class="comment"> i2cSendStart();</span>
338 00331 <span class="comment"> i2cWaitForComplete();</span>
339 00332 <span class="comment"></span>
340 00333 <span class="comment"> // send device address with read</span>
341 00334 <span class="comment"> i2cSendByte( deviceAddr | 0x01 );</span>
342 00335 <span class="comment"> i2cWaitForComplete();</span>
343 00336 <span class="comment"></span>
344 00337 <span class="comment"> // accept receive data and ack it</span>
345 00338 <span class="comment"> while(receivelength &gt; 1)</span>
346 00339 <span class="comment"> {</span>
347 00340 <span class="comment"> i2cReceiveByte(TRUE);</span>
348 00341 <span class="comment"> i2cWaitForComplete();</span>
349 00342 <span class="comment"> *receivedata++ = i2cGetReceivedByte();</span>
350 00343 <span class="comment"> // decrement length</span>
351 00344 <span class="comment"> receivelength--;</span>
352 00345 <span class="comment"> }</span>
353 00346 <span class="comment"></span>
354 00347 <span class="comment"> // accept receive data and nack it (last-byte signal)</span>
355 00348 <span class="comment"> i2cReceiveByte(TRUE);</span>
356 00349 <span class="comment"> i2cWaitForComplete();</span>
357 00350 <span class="comment"> *receivedata++ = i2cGetReceivedByte();</span>
358 00351 <span class="comment"> }</span>
359 00352 <span class="comment"> </span>
360 00353 <span class="comment"> // transmit stop condition</span>
361 00354 <span class="comment"> // leave with TWEA on for slave receiving</span>
362 00355 <span class="comment"> i2cSendStop();</span>
363 00356 <span class="comment"> while( !(inb(TWCR) &amp; BV(TWSTO)) );</span>
364 00357 <span class="comment"></span>
365 00358 <span class="comment"> // enable TWI interrupt</span>
366 00359 <span class="comment"> sbi(TWCR, TWIE);</span>
367 00360 <span class="comment">}</span>
368 00361 <span class="comment">*/</span>
369 00362 <span class="comment"></span>
370 00363 <span class="comment">//! I2C (TWI) interrupt service routine</span>
371 <a name="l00364"></a><a class="code" href="i2c_8c.html#a26">00364</a> <span class="comment"></span><a class="code" href="a2d_8c.html#a10">SIGNAL</a>(SIG_2WIRE_SERIAL)
372 00365 {
373 00366 <span class="comment">// read status bits</span>
374 00367 u08 status = inb(TWSR) &amp; TWSR_STATUS_MASK;
375 00368
376 00369 <span class="keywordflow">switch</span>(status)
377 00370 {
378 00371 <span class="comment">// Master General</span>
379 00372 <span class="keywordflow">case</span> TW_START: <span class="comment">// 0x08: Sent start condition</span>
380 00373 <span class="keywordflow">case</span> TW_REP_START: <span class="comment">// 0x10: Sent repeated start condition</span>
381 00374 <span class="preprocessor"> #ifdef I2C_DEBUG</span>
382 00375 <span class="preprocessor"></span> <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
383 00376 rprintf(<span class="stringliteral">"I2C: M-&gt;START\r\n"</span>);
384 00377 <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
385 00378 <span class="preprocessor"> #endif</span>
386 00379 <span class="preprocessor"></span> <span class="comment">// send device address</span>
387 00380 <a class="code" href="i2c_8c.html#a18">i2cSendByte</a>(I2cDeviceAddrRW);
388 00381 <span class="keywordflow">break</span>;
389 00382
390 00383 <span class="comment">// Master Transmitter &amp; Receiver status codes</span>
391 00384 <span class="keywordflow">case</span> TW_MT_SLA_ACK: <span class="comment">// 0x18: Slave address acknowledged</span>
392 00385 <span class="keywordflow">case</span> TW_MT_DATA_ACK: <span class="comment">// 0x28: Data acknowledged</span>
393 00386 <span class="preprocessor"> #ifdef I2C_DEBUG</span>
394 00387 <span class="preprocessor"></span> <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
395 00388 rprintf(<span class="stringliteral">"I2C: MT-&gt;SLA_ACK or DATA_ACK\r\n"</span>);
396 00389 <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
397 00390 <span class="preprocessor"> #endif</span>
398 00391 <span class="preprocessor"></span> <span class="keywordflow">if</span>(I2cSendDataIndex &lt; I2cSendDataLength)
399 00392 {
400 00393 <span class="comment">// send data</span>
401 00394 <a class="code" href="i2c_8c.html#a18">i2cSendByte</a>( I2cSendData[I2cSendDataIndex++] );
402 00395 }
403 00396 <span class="keywordflow">else</span>
404 00397 {
405 00398 <span class="comment">// transmit stop condition, enable SLA ACK</span>
406 00399 <a class="code" href="i2c_8c.html#a16">i2cSendStop</a>();
407 00400 <span class="comment">// set state</span>
408 00401 I2cState = I2C_IDLE;
409 00402 }
410 00403 <span class="keywordflow">break</span>;
411 00404 <span class="keywordflow">case</span> TW_MR_DATA_NACK: <span class="comment">// 0x58: Data received, NACK reply issued</span>
412 00405 <span class="preprocessor"> #ifdef I2C_DEBUG</span>
413 00406 <span class="preprocessor"></span> <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
414 00407 rprintf(<span class="stringliteral">"I2C: MR-&gt;DATA_NACK\r\n"</span>);
415 00408 <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
416 00409 <span class="preprocessor"> #endif</span>
417 00410 <span class="preprocessor"></span> <span class="comment">// store final received data byte</span>
418 00411 I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
419 00412 <span class="comment">// continue to transmit STOP condition</span>
420 00413 <span class="keywordflow">case</span> TW_MR_SLA_NACK: <span class="comment">// 0x48: Slave address not acknowledged</span>
421 00414 <span class="keywordflow">case</span> TW_MT_SLA_NACK: <span class="comment">// 0x20: Slave address not acknowledged</span>
422 00415 <span class="keywordflow">case</span> TW_MT_DATA_NACK: <span class="comment">// 0x30: Data not acknowledged</span>
423 00416 <span class="preprocessor"> #ifdef I2C_DEBUG</span>
424 00417 <span class="preprocessor"></span> <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
425 00418 rprintf(<span class="stringliteral">"I2C: MTR-&gt;SLA_NACK or MT-&gt;DATA_NACK\r\n"</span>);
426 00419 <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
427 00420 <span class="preprocessor"> #endif</span>
428 00421 <span class="preprocessor"></span> <span class="comment">// transmit stop condition, enable SLA ACK</span>
429 00422 <a class="code" href="i2c_8c.html#a16">i2cSendStop</a>();
430 00423 <span class="comment">// set state</span>
431 00424 I2cState = I2C_IDLE;
432 00425 <span class="keywordflow">break</span>;
433 00426 <span class="keywordflow">case</span> TW_MT_ARB_LOST: <span class="comment">// 0x38: Bus arbitration lost</span>
434 00427 <span class="comment">//case TW_MR_ARB_LOST: // 0x38: Bus arbitration lost</span>
435 00428 <span class="preprocessor"> #ifdef I2C_DEBUG</span>
436 00429 <span class="preprocessor"></span> <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
437 00430 rprintf(<span class="stringliteral">"I2C: MT-&gt;ARB_LOST\r\n"</span>);
438 00431 <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
439 00432 <span class="preprocessor"> #endif</span>
440 00433 <span class="preprocessor"></span> <span class="comment">// release bus</span>
441 00434 outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT));
442 00435 <span class="comment">// set state</span>
443 00436 I2cState = I2C_IDLE;
444 00437 <span class="comment">// release bus and transmit start when bus is free</span>
445 00438 <span class="comment">//outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));</span>
446 00439 <span class="keywordflow">break</span>;
447 00440 <span class="keywordflow">case</span> TW_MR_DATA_ACK: <span class="comment">// 0x50: Data acknowledged</span>
448 00441 <span class="preprocessor"> #ifdef I2C_DEBUG</span>
449 00442 <span class="preprocessor"></span> <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
450 00443 rprintf(<span class="stringliteral">"I2C: MR-&gt;DATA_ACK\r\n"</span>);
451 00444 <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
452 00445 <span class="preprocessor"> #endif</span>
453 00446 <span class="preprocessor"></span> <span class="comment">// store received data byte</span>
454 00447 I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
455 00448 <span class="comment">// fall-through to see if more bytes will be received</span>
456 00449 <span class="keywordflow">case</span> TW_MR_SLA_ACK: <span class="comment">// 0x40: Slave address acknowledged</span>
457 00450 <span class="preprocessor"> #ifdef I2C_DEBUG</span>
458 00451 <span class="preprocessor"></span> <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
459 00452 rprintf(<span class="stringliteral">"I2C: MR-&gt;SLA_ACK\r\n"</span>);
460 00453 <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
461 00454 <span class="preprocessor"> #endif</span>
462 00455 <span class="preprocessor"></span> <span class="keywordflow">if</span>(I2cReceiveDataIndex &lt; (I2cReceiveDataLength-1))
463 00456 <span class="comment">// data byte will be received, reply with ACK (more bytes in transfer)</span>
464 00457 <a class="code" href="i2c_8c.html#a19">i2cReceiveByte</a>(TRUE);
465 00458 <span class="keywordflow">else</span>
466 00459 <span class="comment">// data byte will be received, reply with NACK (final byte in transfer)</span>
467 00460 <a class="code" href="i2c_8c.html#a19">i2cReceiveByte</a>(FALSE);
468 00461 <span class="keywordflow">break</span>;
469 00462
470 00463 <span class="comment">// Slave Receiver status codes</span>
471 00464 <span class="keywordflow">case</span> TW_SR_SLA_ACK: <span class="comment">// 0x60: own SLA+W has been received, ACK has been returned</span>
472 00465 <span class="keywordflow">case</span> TW_SR_ARB_LOST_SLA_ACK: <span class="comment">// 0x68: own SLA+W has been received, ACK has been returned</span>
473 00466 <span class="keywordflow">case</span> TW_SR_GCALL_ACK: <span class="comment">// 0x70: GCA+W has been received, ACK has been returned</span>
474 00467 <span class="keywordflow">case</span> TW_SR_ARB_LOST_GCALL_ACK: <span class="comment">// 0x78: GCA+W has been received, ACK has been returned</span>
475 00468 <span class="preprocessor"> #ifdef I2C_DEBUG</span>
476 00469 <span class="preprocessor"></span> <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
477 00470 rprintf(<span class="stringliteral">"I2C: SR-&gt;SLA_ACK\r\n"</span>);
478 00471 <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
479 00472 <span class="preprocessor"> #endif</span>
480 00473 <span class="preprocessor"></span> <span class="comment">// we are being addressed as slave for writing (data will be received from master)</span>
481 00474 <span class="comment">// set state</span>
482 00475 I2cState = I2C_SLAVE_RX;
483 00476 <span class="comment">// prepare buffer</span>
484 00477 I2cReceiveDataIndex = 0;
485 00478 <span class="comment">// receive data byte and return ACK</span>
486 00479 outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
487 00480 <span class="keywordflow">break</span>;
488 00481 <span class="keywordflow">case</span> TW_SR_DATA_ACK: <span class="comment">// 0x80: data byte has been received, ACK has been returned</span>
489 00482 <span class="keywordflow">case</span> TW_SR_GCALL_DATA_ACK: <span class="comment">// 0x90: data byte has been received, ACK has been returned</span>
490 00483 <span class="preprocessor"> #ifdef I2C_DEBUG</span>
491 00484 <span class="preprocessor"></span> <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
492 00485 rprintf(<span class="stringliteral">"I2C: SR-&gt;DATA_ACK\r\n"</span>);
493 00486 <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
494 00487 <span class="preprocessor"> #endif</span>
495 00488 <span class="preprocessor"></span> <span class="comment">// get previously received data byte</span>
496 00489 I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
497 00490 <span class="comment">// check receive buffer status</span>
498 00491 <span class="keywordflow">if</span>(I2cReceiveDataIndex &lt; I2C_RECEIVE_DATA_BUFFER_SIZE)
499 00492 {
500 00493 <span class="comment">// receive data byte and return ACK</span>
501 00494 <a class="code" href="i2c_8c.html#a19">i2cReceiveByte</a>(TRUE);
502 00495 <span class="comment">//outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));</span>
503 00496 }
504 00497 <span class="keywordflow">else</span>
505 00498 {
506 00499 <span class="comment">// receive data byte and return NACK</span>
507 00500 <a class="code" href="i2c_8c.html#a19">i2cReceiveByte</a>(FALSE);
508 00501 <span class="comment">//outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT));</span>
509 00502 }
510 00503 <span class="keywordflow">break</span>;
511 00504 <span class="keywordflow">case</span> TW_SR_DATA_NACK: <span class="comment">// 0x88: data byte has been received, NACK has been returned</span>
512 00505 <span class="keywordflow">case</span> TW_SR_GCALL_DATA_NACK: <span class="comment">// 0x98: data byte has been received, NACK has been returned</span>
513 00506 <span class="preprocessor"> #ifdef I2C_DEBUG</span>
514 00507 <span class="preprocessor"></span> <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
515 00508 rprintf(<span class="stringliteral">"I2C: SR-&gt;DATA_NACK\r\n"</span>);
516 00509 <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
517 00510 <span class="preprocessor"> #endif</span>
518 00511 <span class="preprocessor"></span> <span class="comment">// receive data byte and return NACK</span>
519 00512 <a class="code" href="i2c_8c.html#a19">i2cReceiveByte</a>(FALSE);
520 00513 <span class="comment">//outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT));</span>
521 00514 <span class="keywordflow">break</span>;
522 00515 <span class="keywordflow">case</span> TW_SR_STOP: <span class="comment">// 0xA0: STOP or REPEATED START has been received while addressed as slave</span>
523 00516 <span class="preprocessor"> #ifdef I2C_DEBUG</span>
524 00517 <span class="preprocessor"></span> <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
525 00518 rprintf(<span class="stringliteral">"I2C: SR-&gt;SR_STOP\r\n"</span>);
526 00519 <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
527 00520 <span class="preprocessor"> #endif</span>
528 00521 <span class="preprocessor"></span> <span class="comment">// switch to SR mode with SLA ACK</span>
529 00522 outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
530 00523 <span class="comment">// i2c receive is complete, call i2cSlaveReceive</span>
531 00524 <span class="keywordflow">if</span>(i2cSlaveReceive) i2cSlaveReceive(I2cReceiveDataIndex, I2cReceiveData);
532 00525 <span class="comment">// set state</span>
533 00526 I2cState = I2C_IDLE;
534 00527 <span class="keywordflow">break</span>;
535 00528
536 00529 <span class="comment">// Slave Transmitter</span>
537 00530 <span class="keywordflow">case</span> TW_ST_SLA_ACK: <span class="comment">// 0xA8: own SLA+R has been received, ACK has been returned</span>
538 00531 <span class="keywordflow">case</span> TW_ST_ARB_LOST_SLA_ACK: <span class="comment">// 0xB0: GCA+R has been received, ACK has been returned</span>
539 00532 <span class="preprocessor"> #ifdef I2C_DEBUG</span>
540 00533 <span class="preprocessor"></span> <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
541 00534 rprintf(<span class="stringliteral">"I2C: ST-&gt;SLA_ACK\r\n"</span>);
542 00535 <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
543 00536 <span class="preprocessor"> #endif</span>
544 00537 <span class="preprocessor"></span> <span class="comment">// we are being addressed as slave for reading (data must be transmitted back to master)</span>
545 00538 <span class="comment">// set state</span>
546 00539 I2cState = I2C_SLAVE_TX;
547 00540 <span class="comment">// request data from application</span>
548 00541 <span class="keywordflow">if</span>(i2cSlaveTransmit) I2cSendDataLength = i2cSlaveTransmit(I2C_SEND_DATA_BUFFER_SIZE, I2cSendData);
549 00542 <span class="comment">// reset data index</span>
550 00543 I2cSendDataIndex = 0;
551 00544 <span class="comment">// fall-through to transmit first data byte</span>
552 00545 <span class="keywordflow">case</span> TW_ST_DATA_ACK: <span class="comment">// 0xB8: data byte has been transmitted, ACK has been received</span>
553 00546 <span class="preprocessor"> #ifdef I2C_DEBUG</span>
554 00547 <span class="preprocessor"></span> <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
555 00548 rprintf(<span class="stringliteral">"I2C: ST-&gt;DATA_ACK\r\n"</span>);
556 00549 <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
557 00550 <span class="preprocessor"> #endif</span>
558 00551 <span class="preprocessor"></span> <span class="comment">// transmit data byte</span>
559 00552 outb(TWDR, I2cSendData[I2cSendDataIndex++]);
560 00553 <span class="keywordflow">if</span>(I2cSendDataIndex &lt; I2cSendDataLength)
561 00554 <span class="comment">// expect ACK to data byte</span>
562 00555 outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
563 00556 <span class="keywordflow">else</span>
564 00557 <span class="comment">// expect NACK to data byte</span>
565 00558 outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT));
566 00559 <span class="keywordflow">break</span>;
567 00560 <span class="keywordflow">case</span> TW_ST_DATA_NACK: <span class="comment">// 0xC0: data byte has been transmitted, NACK has been received</span>
568 00561 <span class="keywordflow">case</span> TW_ST_LAST_DATA: <span class="comment">// 0xC8:</span>
569 00562 <span class="preprocessor"> #ifdef I2C_DEBUG</span>
570 00563 <span class="preprocessor"></span> <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
571 00564 rprintf(<span class="stringliteral">"I2C: ST-&gt;DATA_NACK or LAST_DATA\r\n"</span>);
572 00565 <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
573 00566 <span class="preprocessor"> #endif</span>
574 00567 <span class="preprocessor"></span> <span class="comment">// all done</span>
575 00568 <span class="comment">// switch to open slave</span>
576 00569 outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
577 00570 <span class="comment">// set state</span>
578 00571 I2cState = I2C_IDLE;
579 00572 <span class="keywordflow">break</span>;
580 00573
581 00574 <span class="comment">// Misc</span>
582 00575 <span class="keywordflow">case</span> TW_NO_INFO: <span class="comment">// 0xF8: No relevant state information</span>
583 00576 <span class="comment">// do nothing</span>
584 00577 <span class="preprocessor"> #ifdef I2C_DEBUG</span>
585 00578 <span class="preprocessor"></span> <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
586 00579 rprintf(<span class="stringliteral">"I2C: NO_INFO\r\n"</span>);
587 00580 <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
588 00581 <span class="preprocessor"> #endif</span>
589 00582 <span class="preprocessor"></span> <span class="keywordflow">break</span>;
590 00583 <span class="keywordflow">case</span> TW_BUS_ERROR: <span class="comment">// 0x00: Bus error due to illegal start or stop condition</span>
591 00584 <span class="preprocessor"> #ifdef I2C_DEBUG</span>
592 00585 <span class="preprocessor"></span> <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
593 00586 rprintf(<span class="stringliteral">"I2C: BUS_ERROR\r\n"</span>);
594 00587 <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
595 00588 <span class="preprocessor"> #endif</span>
596 00589 <span class="preprocessor"></span> <span class="comment">// reset internal hardware and release bus</span>
597 00590 outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTO)|BV(TWEA));
598 00591 <span class="comment">// set state</span>
599 00592 I2cState = I2C_IDLE;
600 00593 <span class="keywordflow">break</span>;
601 00594 }
602 00595 }
603 00596
604 <a name="l00597"></a><a class="code" href="i2c_8h.html#a54">00597</a> eI2cStateType <a class="code" href="i2c_8c.html#a27">i2cGetState</a>(<span class="keywordtype">void</span>)
605 00598 {
606 00599 <span class="keywordflow">return</span> I2cState;
607 00600 }
608 </pre></div><hr size="1"><address style="align: right;"><small>Generated on Sun Oct 29 03:41:06 2006 for Procyon AVRlib by&nbsp;
609 <a href="http://www.doxygen.org/index.html">
610 <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.2 </small></address>
611 </body>
612 </html>
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3