Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

# i2c.c

Go to the documentation of this file.

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