Main Page   Modules   Data Structures   File List   Data Fields   Globals  

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

Generated on Sun Feb 22 19:12:31 2004 for Procyon AVRlib by doxygen1.3-rc2