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

library

?curdirlinks? - Rev 6

?prevdifflink? - Blame - ?getfile?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>Procyon AVRlib: i2c.c Source File</title>
<link href="dox.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.4.2 -->
<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>
<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>
00002 <span class="comment">//*****************************************************************************</span>
00003 <span class="comment">//</span>
00004 <span class="comment">// File Name    : 'i2c.c'</span>
00005 <span class="comment">// Title        : I2C interface using AVR Two-Wire Interface (TWI) hardware</span>
00006 <span class="comment">// Author       : Pascal Stang - Copyright (C) 2002-2003</span>
00007 <span class="comment">// Created      : 2002.06.25</span>
00008 <span class="comment">// Revised      : 2003.03.02</span>
00009 <span class="comment">// Version      : 0.9</span>
00010 <span class="comment">// Target MCU   : Atmel AVR series</span>
00011 <span class="comment">// Editor Tabs  : 4</span>
00012 <span class="comment">//</span>
00013 <span class="comment">// This code is distributed under the GNU Public License</span>
00014 <span class="comment">//      which can be found at http://www.gnu.org/licenses/gpl.txt</span>
00015 <span class="comment">//</span>
00016 <span class="comment">//*****************************************************************************</span>
00017 
00018 <span class="preprocessor">#include &lt;avr/io.h&gt;</span>
00019 <span class="preprocessor">#include &lt;avr/interrupt.h&gt;</span>
00020 
00021 <span class="preprocessor">#include "<a class="code" href="i2c_8h.html">i2c.h</a>"</span>
00022 
00023 <span class="preprocessor">#include "<a class="code" href="rprintf_8h.html">rprintf.h</a>"</span>    <span class="comment">// include printf function library</span>
00024 <span class="preprocessor">#include "<a class="code" href="uart2_8h.html">uart2.h</a>"</span>
00025 
00026 <span class="comment">// Standard I2C bit rates are:</span>
00027 <span class="comment">// 100KHz for slow speed</span>
00028 <span class="comment">// 400KHz for high speed</span>
00029 
00030 <span class="comment">//#define I2C_DEBUG</span>
00031 
00032 <span class="comment">// I2C state and address variables</span>
00033 <span class="keyword">static</span> <span class="keyword">volatile</span> eI2cStateType I2cState;
00034 <span class="keyword">static</span> u08 I2cDeviceAddrRW;
00035 <span class="comment">// send/transmit buffer (outgoing data)</span>
00036 <span class="keyword">static</span> u08 I2cSendData[I2C_SEND_DATA_BUFFER_SIZE];
00037 <span class="keyword">static</span> u08 I2cSendDataIndex;
00038 <span class="keyword">static</span> u08 I2cSendDataLength;
00039 <span class="comment">// receive buffer (incoming data)</span>
00040 <span class="keyword">static</span> u08 I2cReceiveData[I2C_RECEIVE_DATA_BUFFER_SIZE];
00041 <span class="keyword">static</span> u08 I2cReceiveDataIndex;
00042 <span class="keyword">static</span> u08 I2cReceiveDataLength;
00043 
00044 <span class="comment">// function pointer to i2c receive routine</span><span class="comment"></span>
00045 <span class="comment">//! I2cSlaveReceive is called when this processor</span>
00046 <span class="comment"></span><span class="comment">// is addressed as a slave for writing</span>
00047 <span class="keyword">static</span> void (*i2cSlaveReceive)(u08 receiveDataLength, u08* recieveData);<span class="comment"></span>
00048 <span class="comment">//! I2cSlaveTransmit is called when this processor</span>
00049 <span class="comment"></span><span class="comment">// is addressed as a slave for reading</span>
00050 <span class="keyword">static</span> u08 (*i2cSlaveTransmit)(u08 transmitDataLengthMax, u08* transmitData);
00051 
00052 <span class="comment">// functions</span>
<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>)
00054 {
00055     <span class="comment">// set pull-up resistors on I2C bus pins</span>
00056     <span class="comment">// TODO: should #ifdef these</span>
00057     sbi(PORTC, 0);  <span class="comment">// i2c SCL on ATmega163,323,16,32,etc</span>
00058     sbi(PORTC, 1);  <span class="comment">// i2c SDA on ATmega163,323,16,32,etc</span>
00059     sbi(PORTD, 0);  <span class="comment">// i2c SCL on ATmega128,64</span>
00060     sbi(PORTD, 1);  <span class="comment">// i2c SDA on ATmega128,64</span>
00061 
00062     <span class="comment">// clear SlaveReceive and SlaveTransmit handler to null</span>
00063     i2cSlaveReceive = 0;
00064     i2cSlaveTransmit = 0;
00065     <span class="comment">// set i2c bit rate to 100KHz</span>
00066     <a class="code" href="i2c_8c.html#a11">i2cSetBitrate</a>(100);
00067     <span class="comment">// enable TWI (two-wire interface)</span>
00068     sbi(TWCR, TWEN);
00069     <span class="comment">// set state</span>
00070     I2cState = I2C_IDLE;
00071     <span class="comment">// enable TWI interrupt and slave address ACK</span>
00072     sbi(TWCR, TWIE);
00073     sbi(TWCR, TWEA);
00074     <span class="comment">//outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));</span>
00075     <span class="comment">// enable interrupts</span>
00076     sei();
00077 }
00078 
<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)
00080 {
00081     u08 bitrate_div;
00082     <span class="comment">// set i2c bitrate</span>
00083     <span class="comment">// SCL freq = F_CPU/(16+2*TWBR))</span>
00084 <span class="preprocessor">    #ifdef TWPS0</span>
00085 <span class="preprocessor"></span>        <span class="comment">// for processors with additional bitrate division (mega128)</span>
00086         <span class="comment">// SCL freq = F_CPU/(16+2*TWBR*4^TWPS)</span>
00087         <span class="comment">// set TWPS to zero</span>
00088         cbi(TWSR, TWPS0);
00089         cbi(TWSR, TWPS1);
00090 <span class="preprocessor">    #endif</span>
00091 <span class="preprocessor"></span>    <span class="comment">// calculate bitrate division   </span>
00092     bitrate_div = ((F_CPU/1000l)/bitrateKHz);
00093     <span class="keywordflow">if</span>(bitrate_div &gt;= 16)
00094         bitrate_div = (bitrate_div-16)/2;
00095     outb(TWBR, bitrate_div);
00096 }
00097 
<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)
00099 {
00100     <span class="comment">// set local device address (used in slave mode only)</span>
00101     outb(TWAR, ((deviceAddr&amp;0xFE) | (genCallEn?1:0)) );
00102 }
00103 
<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))
00105 {
00106     i2cSlaveReceive = i2cSlaveRx_func;
00107 }
00108 
<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))
00110 {
00111     i2cSlaveTransmit = i2cSlaveTx_func;
00112 }
00113 
<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>)
00115 {
00116     <span class="comment">// send start condition</span>
00117     outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
00118 }
00119 
<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>)
00121 {
00122     <span class="comment">// transmit stop condition</span>
00123     <span class="comment">// leave with TWEA on for slave receiving</span>
00124     outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)|BV(TWSTO));
00125 }
00126 
<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>)
00128 {
00129     <span class="comment">// wait for i2c interface to complete operation</span>
00130     <span class="keywordflow">while</span>( !(inb(TWCR) &amp; BV(TWINT)) );
00131 }
00132 
<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)
00134 {
00135     <span class="comment">// save data to the TWDR</span>
00136     outb(TWDR, data);
00137     <span class="comment">// begin send</span>
00138     outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT));
00139 }
00140 
<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)
00142 {
00143     <span class="comment">// begin receive over i2c</span>
00144     <span class="keywordflow">if</span>( ackFlag )
00145     {
00146         <span class="comment">// ackFlag = TRUE: ACK the recevied data</span>
00147         outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00148     }
00149     <span class="keywordflow">else</span>
00150     {
00151         <span class="comment">// ackFlag = FALSE: NACK the recevied data</span>
00152         outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT));
00153     }
00154 }
00155 
<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>)
00157 {
00158     <span class="comment">// retieve received data byte from i2c TWDR</span>
00159     <span class="keywordflow">return</span>( inb(TWDR) );
00160 }
00161 
<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>)
00163 {
00164     <span class="comment">// retieve current i2c status from i2c TWSR</span>
00165     <span class="keywordflow">return</span>( inb(TWSR) );
00166 }
00167 
<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)
00169 {
00170     u08 i;
00171     <span class="comment">// wait for interface to be ready</span>
00172     <span class="keywordflow">while</span>(I2cState);
00173     <span class="comment">// set state</span>
00174     I2cState = I2C_MASTER_TX;
00175     <span class="comment">// save data</span>
00176     I2cDeviceAddrRW = (deviceAddr &amp; 0xFE);  <span class="comment">// RW cleared: write operation</span>
00177     <span class="keywordflow">for</span>(i=0; i&lt;length; i++)
00178         I2cSendData[i] = *data++;
00179     I2cSendDataIndex = 0;
00180     I2cSendDataLength = length;
00181     <span class="comment">// send start condition</span>
00182     <a class="code" href="i2c_8c.html#a15">i2cSendStart</a>();
00183 }
00184 
<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)
00186 {
00187     u08 i;
00188     <span class="comment">// wait for interface to be ready</span>
00189     <span class="keywordflow">while</span>(I2cState);
00190     <span class="comment">// set state</span>
00191     I2cState = I2C_MASTER_RX;
00192     <span class="comment">// save data</span>
00193     I2cDeviceAddrRW = (deviceAddr|0x01);    <span class="comment">// RW set: read operation</span>
00194     I2cReceiveDataIndex = 0;
00195     I2cReceiveDataLength = length;
00196     <span class="comment">// send start condition</span>
00197     <a class="code" href="i2c_8c.html#a15">i2cSendStart</a>();
00198     <span class="comment">// wait for data</span>
00199     <span class="keywordflow">while</span>(I2cState);
00200     <span class="comment">// return data</span>
00201     <span class="keywordflow">for</span>(i=0; i&lt;length; i++)
00202         *data++ = I2cReceiveData[i];
00203 }
00204 
<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)
00206 {
00207     u08 retval = I2C_OK;
00208 
00209     <span class="comment">// disable TWI interrupt</span>
00210     cbi(TWCR, TWIE);
00211 
00212     <span class="comment">// send start condition</span>
00213     <a class="code" href="i2c_8c.html#a15">i2cSendStart</a>();
00214     <a class="code" href="i2c_8c.html#a17">i2cWaitForComplete</a>();
00215 
00216     <span class="comment">// send device address with write</span>
00217     <a class="code" href="i2c_8c.html#a18">i2cSendByte</a>( deviceAddr &amp; 0xFE );
00218     <a class="code" href="i2c_8c.html#a17">i2cWaitForComplete</a>();
00219 
00220     <span class="comment">// check if device is present and live</span>
00221     <span class="keywordflow">if</span>( inb(TWSR) == TW_MT_SLA_ACK)
00222     {
00223         <span class="comment">// send data</span>
00224         <span class="keywordflow">while</span>(length)
00225         {
00226             <a class="code" href="i2c_8c.html#a18">i2cSendByte</a>( *data++ );
00227             <a class="code" href="i2c_8c.html#a17">i2cWaitForComplete</a>();
00228             length--;
00229         }
00230     }
00231     <span class="keywordflow">else</span>
00232     {
00233         <span class="comment">// device did not ACK it's address,</span>
00234         <span class="comment">// data will not be transferred</span>
00235         <span class="comment">// return error</span>
00236         retval = I2C_ERROR_NODEV;
00237     }
00238 
00239     <span class="comment">// transmit stop condition</span>
00240     <span class="comment">// leave with TWEA on for slave receiving</span>
00241     <a class="code" href="i2c_8c.html#a16">i2cSendStop</a>();
00242     <span class="keywordflow">while</span>( !(inb(TWCR) &amp; BV(TWSTO)) );
00243 
00244     <span class="comment">// enable TWI interrupt</span>
00245     sbi(TWCR, TWIE);
00246 
00247     <span class="keywordflow">return</span> retval;
00248 }
00249 
<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)
00251 {
00252     u08 retval = I2C_OK;
00253 
00254     <span class="comment">// disable TWI interrupt</span>
00255     cbi(TWCR, TWIE);
00256 
00257     <span class="comment">// send start condition</span>
00258     <a class="code" href="i2c_8c.html#a15">i2cSendStart</a>();
00259     <a class="code" href="i2c_8c.html#a17">i2cWaitForComplete</a>();
00260 
00261     <span class="comment">// send device address with read</span>
00262     <a class="code" href="i2c_8c.html#a18">i2cSendByte</a>( deviceAddr | 0x01 );
00263     <a class="code" href="i2c_8c.html#a17">i2cWaitForComplete</a>();
00264 
00265     <span class="comment">// check if device is present and live</span>
00266     <span class="keywordflow">if</span>( inb(TWSR) == TW_MR_SLA_ACK)
00267     {
00268         <span class="comment">// accept receive data and ack it</span>
00269         <span class="keywordflow">while</span>(length &gt; 1)
00270         {
00271             <a class="code" href="i2c_8c.html#a19">i2cReceiveByte</a>(TRUE);
00272             <a class="code" href="i2c_8c.html#a17">i2cWaitForComplete</a>();
00273             *data++ = <a class="code" href="i2c_8c.html#a20">i2cGetReceivedByte</a>();
00274             <span class="comment">// decrement length</span>
00275             length--;
00276         }
00277 
00278         <span class="comment">// accept receive data and nack it (last-byte signal)</span>
00279         <a class="code" href="i2c_8c.html#a19">i2cReceiveByte</a>(FALSE);
00280         <a class="code" href="i2c_8c.html#a17">i2cWaitForComplete</a>();
00281         *data++ = <a class="code" href="i2c_8c.html#a20">i2cGetReceivedByte</a>();
00282     }
00283     <span class="keywordflow">else</span>
00284     {
00285         <span class="comment">// device did not ACK it's address,</span>
00286         <span class="comment">// data will not be transferred</span>
00287         <span class="comment">// return error</span>
00288         retval = I2C_ERROR_NODEV;
00289     }
00290 
00291     <span class="comment">// transmit stop condition</span>
00292     <span class="comment">// leave with TWEA on for slave receiving</span>
00293     <a class="code" href="i2c_8c.html#a16">i2cSendStop</a>();
00294 
00295     <span class="comment">// enable TWI interrupt</span>
00296     sbi(TWCR, TWIE);
00297 
00298     <span class="keywordflow">return</span> retval;
00299 }
00300 <span class="comment">/*</span>
00301 <span class="comment">void i2cMasterTransferNI(u08 deviceAddr, u08 sendlength, u08* senddata, u08 receivelength, u08* receivedata)</span>
00302 <span class="comment">{</span>
00303 <span class="comment">    // disable TWI interrupt</span>
00304 <span class="comment">    cbi(TWCR, TWIE);</span>
00305 <span class="comment"></span>
00306 <span class="comment">    // send start condition</span>
00307 <span class="comment">    i2cSendStart();</span>
00308 <span class="comment">    i2cWaitForComplete();</span>
00309 <span class="comment"></span>
00310 <span class="comment">    // if there's data to be sent, do it</span>
00311 <span class="comment">    if(sendlength)</span>
00312 <span class="comment">    {</span>
00313 <span class="comment">        // send device address with write</span>
00314 <span class="comment">        i2cSendByte( deviceAddr &amp; 0xFE );</span>
00315 <span class="comment">        i2cWaitForComplete();</span>
00316 <span class="comment">        </span>
00317 <span class="comment">        // send data</span>
00318 <span class="comment">        while(sendlength)</span>
00319 <span class="comment">        {</span>
00320 <span class="comment">            i2cSendByte( *senddata++ );</span>
00321 <span class="comment">            i2cWaitForComplete();</span>
00322 <span class="comment">            sendlength--;</span>
00323 <span class="comment">        }</span>
00324 <span class="comment">    }</span>
00325 <span class="comment"></span>
00326 <span class="comment">    // if there's data to be received, do it</span>
00327 <span class="comment">    if(receivelength)</span>
00328 <span class="comment">    {</span>
00329 <span class="comment">        // send repeated start condition</span>
00330 <span class="comment">        i2cSendStart();</span>
00331 <span class="comment">        i2cWaitForComplete();</span>
00332 <span class="comment"></span>
00333 <span class="comment">        // send device address with read</span>
00334 <span class="comment">        i2cSendByte( deviceAddr | 0x01 );</span>
00335 <span class="comment">        i2cWaitForComplete();</span>
00336 <span class="comment"></span>
00337 <span class="comment">        // accept receive data and ack it</span>
00338 <span class="comment">        while(receivelength &gt; 1)</span>
00339 <span class="comment">        {</span>
00340 <span class="comment">            i2cReceiveByte(TRUE);</span>
00341 <span class="comment">            i2cWaitForComplete();</span>
00342 <span class="comment">            *receivedata++ = i2cGetReceivedByte();</span>
00343 <span class="comment">            // decrement length</span>
00344 <span class="comment">            receivelength--;</span>
00345 <span class="comment">        }</span>
00346 <span class="comment"></span>
00347 <span class="comment">        // accept receive data and nack it (last-byte signal)</span>
00348 <span class="comment">        i2cReceiveByte(TRUE);</span>
00349 <span class="comment">        i2cWaitForComplete();</span>
00350 <span class="comment">        *receivedata++ = i2cGetReceivedByte();</span>
00351 <span class="comment">    }</span>
00352 <span class="comment">    </span>
00353 <span class="comment">    // transmit stop condition</span>
00354 <span class="comment">    // leave with TWEA on for slave receiving</span>
00355 <span class="comment">    i2cSendStop();</span>
00356 <span class="comment">    while( !(inb(TWCR) &amp; BV(TWSTO)) );</span>
00357 <span class="comment"></span>
00358 <span class="comment">    // enable TWI interrupt</span>
00359 <span class="comment">    sbi(TWCR, TWIE);</span>
00360 <span class="comment">}</span>
00361 <span class="comment">*/</span>
00362 <span class="comment"></span>
00363 <span class="comment">//! I2C (TWI) interrupt service routine</span>
<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)
00365 {
00366     <span class="comment">// read status bits</span>
00367     u08 status = inb(TWSR) &amp; TWSR_STATUS_MASK;
00368 
00369     <span class="keywordflow">switch</span>(status)
00370     {
00371     <span class="comment">// Master General</span>
00372     <span class="keywordflow">case</span> TW_START:                      <span class="comment">// 0x08: Sent start condition</span>
00373     <span class="keywordflow">case</span> TW_REP_START:                  <span class="comment">// 0x10: Sent repeated start condition</span>
00374 <span class="preprocessor">        #ifdef I2C_DEBUG</span>
00375 <span class="preprocessor"></span>        <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
00376         rprintf(<span class="stringliteral">"I2C: M-&gt;START\r\n"</span>);
00377         <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
00378 <span class="preprocessor">        #endif</span>
00379 <span class="preprocessor"></span>        <span class="comment">// send device address</span>
00380         <a class="code" href="i2c_8c.html#a18">i2cSendByte</a>(I2cDeviceAddrRW);
00381         <span class="keywordflow">break</span>;
00382     
00383     <span class="comment">// Master Transmitter &amp; Receiver status codes</span>
00384     <span class="keywordflow">case</span> TW_MT_SLA_ACK:                 <span class="comment">// 0x18: Slave address acknowledged</span>
00385     <span class="keywordflow">case</span> TW_MT_DATA_ACK:                <span class="comment">// 0x28: Data acknowledged</span>
00386 <span class="preprocessor">        #ifdef I2C_DEBUG</span>
00387 <span class="preprocessor"></span>        <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
00388         rprintf(<span class="stringliteral">"I2C: MT-&gt;SLA_ACK or DATA_ACK\r\n"</span>);
00389         <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
00390 <span class="preprocessor">        #endif</span>
00391 <span class="preprocessor"></span>        <span class="keywordflow">if</span>(I2cSendDataIndex &lt; I2cSendDataLength)
00392         {
00393             <span class="comment">// send data</span>
00394             <a class="code" href="i2c_8c.html#a18">i2cSendByte</a>( I2cSendData[I2cSendDataIndex++] );
00395         }
00396         <span class="keywordflow">else</span>
00397         {
00398             <span class="comment">// transmit stop condition, enable SLA ACK</span>
00399             <a class="code" href="i2c_8c.html#a16">i2cSendStop</a>();
00400             <span class="comment">// set state</span>
00401             I2cState = I2C_IDLE;
00402         }
00403         <span class="keywordflow">break</span>;
00404     <span class="keywordflow">case</span> TW_MR_DATA_NACK:               <span class="comment">// 0x58: Data received, NACK reply issued</span>
00405 <span class="preprocessor">        #ifdef I2C_DEBUG</span>
00406 <span class="preprocessor"></span>        <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
00407         rprintf(<span class="stringliteral">"I2C: MR-&gt;DATA_NACK\r\n"</span>);
00408         <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
00409 <span class="preprocessor">        #endif</span>
00410 <span class="preprocessor"></span>        <span class="comment">// store final received data byte</span>
00411         I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
00412         <span class="comment">// continue to transmit STOP condition</span>
00413     <span class="keywordflow">case</span> TW_MR_SLA_NACK:                <span class="comment">// 0x48: Slave address not acknowledged</span>
00414     <span class="keywordflow">case</span> TW_MT_SLA_NACK:                <span class="comment">// 0x20: Slave address not acknowledged</span>
00415     <span class="keywordflow">case</span> TW_MT_DATA_NACK:               <span class="comment">// 0x30: Data not acknowledged</span>
00416 <span class="preprocessor">        #ifdef I2C_DEBUG</span>
00417 <span class="preprocessor"></span>        <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
00418         rprintf(<span class="stringliteral">"I2C: MTR-&gt;SLA_NACK or MT-&gt;DATA_NACK\r\n"</span>);
00419         <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
00420 <span class="preprocessor">        #endif</span>
00421 <span class="preprocessor"></span>        <span class="comment">// transmit stop condition, enable SLA ACK</span>
00422         <a class="code" href="i2c_8c.html#a16">i2cSendStop</a>();
00423         <span class="comment">// set state</span>
00424         I2cState = I2C_IDLE;
00425         <span class="keywordflow">break</span>;
00426     <span class="keywordflow">case</span> TW_MT_ARB_LOST:                <span class="comment">// 0x38: Bus arbitration lost</span>
00427     <span class="comment">//case TW_MR_ARB_LOST:              // 0x38: Bus arbitration lost</span>
00428 <span class="preprocessor">        #ifdef I2C_DEBUG</span>
00429 <span class="preprocessor"></span>        <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
00430         rprintf(<span class="stringliteral">"I2C: MT-&gt;ARB_LOST\r\n"</span>);
00431         <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
00432 <span class="preprocessor">        #endif</span>
00433 <span class="preprocessor"></span>        <span class="comment">// release bus</span>
00434         outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT));
00435         <span class="comment">// set state</span>
00436         I2cState = I2C_IDLE;
00437         <span class="comment">// release bus and transmit start when bus is free</span>
00438         <span class="comment">//outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));</span>
00439         <span class="keywordflow">break</span>;
00440     <span class="keywordflow">case</span> TW_MR_DATA_ACK:                <span class="comment">// 0x50: Data acknowledged</span>
00441 <span class="preprocessor">        #ifdef I2C_DEBUG</span>
00442 <span class="preprocessor"></span>        <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
00443         rprintf(<span class="stringliteral">"I2C: MR-&gt;DATA_ACK\r\n"</span>);
00444         <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
00445 <span class="preprocessor">        #endif</span>
00446 <span class="preprocessor"></span>        <span class="comment">// store received data byte</span>
00447         I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
00448         <span class="comment">// fall-through to see if more bytes will be received</span>
00449     <span class="keywordflow">case</span> TW_MR_SLA_ACK:                 <span class="comment">// 0x40: Slave address acknowledged</span>
00450 <span class="preprocessor">        #ifdef I2C_DEBUG</span>
00451 <span class="preprocessor"></span>        <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
00452         rprintf(<span class="stringliteral">"I2C: MR-&gt;SLA_ACK\r\n"</span>);
00453         <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
00454 <span class="preprocessor">        #endif</span>
00455 <span class="preprocessor"></span>        <span class="keywordflow">if</span>(I2cReceiveDataIndex &lt; (I2cReceiveDataLength-1))
00456             <span class="comment">// data byte will be received, reply with ACK (more bytes in transfer)</span>
00457             <a class="code" href="i2c_8c.html#a19">i2cReceiveByte</a>(TRUE);
00458         <span class="keywordflow">else</span>
00459             <span class="comment">// data byte will be received, reply with NACK (final byte in transfer)</span>
00460             <a class="code" href="i2c_8c.html#a19">i2cReceiveByte</a>(FALSE);
00461         <span class="keywordflow">break</span>;
00462 
00463     <span class="comment">// Slave Receiver status codes</span>
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>
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>
00466     <span class="keywordflow">case</span> TW_SR_GCALL_ACK:               <span class="comment">// 0x70:     GCA+W has been received, ACK has been returned</span>
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>
00468 <span class="preprocessor">        #ifdef I2C_DEBUG</span>
00469 <span class="preprocessor"></span>        <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
00470         rprintf(<span class="stringliteral">"I2C: SR-&gt;SLA_ACK\r\n"</span>);
00471         <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
00472 <span class="preprocessor">        #endif</span>
00473 <span class="preprocessor"></span>        <span class="comment">// we are being addressed as slave for writing (data will be received from master)</span>
00474         <span class="comment">// set state</span>
00475         I2cState = I2C_SLAVE_RX;
00476         <span class="comment">// prepare buffer</span>
00477         I2cReceiveDataIndex = 0;
00478         <span class="comment">// receive data byte and return ACK</span>
00479         outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00480         <span class="keywordflow">break</span>;
00481     <span class="keywordflow">case</span> TW_SR_DATA_ACK:                <span class="comment">// 0x80: data byte has been received, ACK has been returned</span>
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>
00483 <span class="preprocessor">        #ifdef I2C_DEBUG</span>
00484 <span class="preprocessor"></span>        <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
00485         rprintf(<span class="stringliteral">"I2C: SR-&gt;DATA_ACK\r\n"</span>);
00486         <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
00487 <span class="preprocessor">        #endif</span>
00488 <span class="preprocessor"></span>        <span class="comment">// get previously received data byte</span>
00489         I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
00490         <span class="comment">// check receive buffer status</span>
00491         <span class="keywordflow">if</span>(I2cReceiveDataIndex &lt; I2C_RECEIVE_DATA_BUFFER_SIZE)
00492         {
00493             <span class="comment">// receive data byte and return ACK</span>
00494             <a class="code" href="i2c_8c.html#a19">i2cReceiveByte</a>(TRUE);
00495             <span class="comment">//outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));</span>
00496         }
00497         <span class="keywordflow">else</span>
00498         {
00499             <span class="comment">// receive data byte and return NACK</span>
00500             <a class="code" href="i2c_8c.html#a19">i2cReceiveByte</a>(FALSE);
00501             <span class="comment">//outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT));</span>
00502         }
00503         <span class="keywordflow">break</span>;
00504     <span class="keywordflow">case</span> TW_SR_DATA_NACK:               <span class="comment">// 0x88: data byte has been received, NACK has been returned</span>
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>
00506 <span class="preprocessor">        #ifdef I2C_DEBUG</span>
00507 <span class="preprocessor"></span>        <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
00508         rprintf(<span class="stringliteral">"I2C: SR-&gt;DATA_NACK\r\n"</span>);
00509         <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
00510 <span class="preprocessor">        #endif</span>
00511 <span class="preprocessor"></span>        <span class="comment">// receive data byte and return NACK</span>
00512         <a class="code" href="i2c_8c.html#a19">i2cReceiveByte</a>(FALSE);
00513         <span class="comment">//outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT));</span>
00514         <span class="keywordflow">break</span>;
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>
00516 <span class="preprocessor">        #ifdef I2C_DEBUG</span>
00517 <span class="preprocessor"></span>        <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
00518         rprintf(<span class="stringliteral">"I2C: SR-&gt;SR_STOP\r\n"</span>);
00519         <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
00520 <span class="preprocessor">        #endif</span>
00521 <span class="preprocessor"></span>        <span class="comment">// switch to SR mode with SLA ACK</span>
00522         outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00523         <span class="comment">// i2c receive is complete, call i2cSlaveReceive</span>
00524         <span class="keywordflow">if</span>(i2cSlaveReceive) i2cSlaveReceive(I2cReceiveDataIndex, I2cReceiveData);
00525         <span class="comment">// set state</span>
00526         I2cState = I2C_IDLE;
00527         <span class="keywordflow">break</span>;
00528 
00529     <span class="comment">// Slave Transmitter</span>
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>
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>
00532 <span class="preprocessor">        #ifdef I2C_DEBUG</span>
00533 <span class="preprocessor"></span>        <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
00534         rprintf(<span class="stringliteral">"I2C: ST-&gt;SLA_ACK\r\n"</span>);
00535         <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
00536 <span class="preprocessor">        #endif</span>
00537 <span class="preprocessor"></span>        <span class="comment">// we are being addressed as slave for reading (data must be transmitted back to master)</span>
00538         <span class="comment">// set state</span>
00539         I2cState = I2C_SLAVE_TX;
00540         <span class="comment">// request data from application</span>
00541         <span class="keywordflow">if</span>(i2cSlaveTransmit) I2cSendDataLength = i2cSlaveTransmit(I2C_SEND_DATA_BUFFER_SIZE, I2cSendData);
00542         <span class="comment">// reset data index</span>
00543         I2cSendDataIndex = 0;
00544         <span class="comment">// fall-through to transmit first data byte</span>
00545     <span class="keywordflow">case</span> TW_ST_DATA_ACK:                <span class="comment">// 0xB8: data byte has been transmitted, ACK has been received</span>
00546 <span class="preprocessor">        #ifdef I2C_DEBUG</span>
00547 <span class="preprocessor"></span>        <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
00548         rprintf(<span class="stringliteral">"I2C: ST-&gt;DATA_ACK\r\n"</span>);
00549         <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
00550 <span class="preprocessor">        #endif</span>
00551 <span class="preprocessor"></span>        <span class="comment">// transmit data byte</span>
00552         outb(TWDR, I2cSendData[I2cSendDataIndex++]);
00553         <span class="keywordflow">if</span>(I2cSendDataIndex &lt; I2cSendDataLength)
00554             <span class="comment">// expect ACK to data byte</span>
00555             outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00556         <span class="keywordflow">else</span>
00557             <span class="comment">// expect NACK to data byte</span>
00558             outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT));
00559         <span class="keywordflow">break</span>;
00560     <span class="keywordflow">case</span> TW_ST_DATA_NACK:               <span class="comment">// 0xC0: data byte has been transmitted, NACK has been received</span>
00561     <span class="keywordflow">case</span> TW_ST_LAST_DATA:               <span class="comment">// 0xC8:</span>
00562 <span class="preprocessor">        #ifdef I2C_DEBUG</span>
00563 <span class="preprocessor"></span>        <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
00564         rprintf(<span class="stringliteral">"I2C: ST-&gt;DATA_NACK or LAST_DATA\r\n"</span>);
00565         <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
00566 <span class="preprocessor">        #endif</span>
00567 <span class="preprocessor"></span>        <span class="comment">// all done</span>
00568         <span class="comment">// switch to open slave</span>
00569         outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00570         <span class="comment">// set state</span>
00571         I2cState = I2C_IDLE;
00572         <span class="keywordflow">break</span>;
00573 
00574     <span class="comment">// Misc</span>
00575     <span class="keywordflow">case</span> TW_NO_INFO:                    <span class="comment">// 0xF8: No relevant state information</span>
00576         <span class="comment">// do nothing</span>
00577 <span class="preprocessor">        #ifdef I2C_DEBUG</span>
00578 <span class="preprocessor"></span>        <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
00579         rprintf(<span class="stringliteral">"I2C: NO_INFO\r\n"</span>);
00580         <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
00581 <span class="preprocessor">        #endif</span>
00582 <span class="preprocessor"></span>        <span class="keywordflow">break</span>;
00583     <span class="keywordflow">case</span> TW_BUS_ERROR:                  <span class="comment">// 0x00: Bus error due to illegal start or stop condition</span>
00584 <span class="preprocessor">        #ifdef I2C_DEBUG</span>
00585 <span class="preprocessor"></span>        <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1AddToTxBuffer);
00586         rprintf(<span class="stringliteral">"I2C: BUS_ERROR\r\n"</span>);
00587         <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(uart1SendByte);
00588 <span class="preprocessor">        #endif</span>
00589 <span class="preprocessor"></span>        <span class="comment">// reset internal hardware and release bus</span>
00590         outb(TWCR, (inb(TWCR)&amp;TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTO)|BV(TWEA));
00591         <span class="comment">// set state</span>
00592         I2cState = I2C_IDLE;
00593         <span class="keywordflow">break</span>;
00594     }
00595 }
00596 
<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>)
00598 {
00599     <span class="keywordflow">return</span> I2cState;
00600 }
</pre></div><hr size="1"><address style="align: right;"><small>Generated on Sun Oct 29 03:41:06 2006 for Procyon AVRlib by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.2 </small></address>
</body>
</html>
{FILE END}
{FOOTER START}

Powered by WebSVN v2.8.3