Sunteți pe pagina 1din 7

25-04-2011 /i2c.

c Source File
Main Page 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 "uart.h" // include uart function library
00060 #include "rprintf.h" // include printf function library
00061
00062
00063 // Standard I2C bit rates are:
00064 // 100KHz for slow speed
00065 // 400KHz for high speed
00066
00067 // I2C state and address variables
00068 static volatile eI2cStateType I2cState;
00069 static u08 I2cDeviceAddrRW;
00070 // send/transmit buffer (outgoing data)
00071 static u08 I2cSendData[I2C_SEND_DATA_BUFFER_SIZE];
00072 static u08 I2cSendDataIndex;
00073 static u08 I2cSendDataLength;
00074 // receive buffer (incoming data)
00075 static u08 I2cReceiveData[I2C_RECEIVE_DATA_BUFFER_SIZE];
00076 static u08 I2cReceiveDataIndex;
00077 static u08 I2cReceiveDataLength;
00078
00079 // function pointer to i2c receive routine

ccrma.stanford.edu/…/i2c_8c-source.html 1/7
25-04-2011 /i2c.c Source File
00080 //! I2cSlaveReceive is called when this processor
00081 // is addressed as a slave for writing
00082 static void (*i2cSlaveReceive)(u08 receiveDataLength, u08* recieveData);
00083 //! I2cSlaveTransmit is called when this processor
00084 // is addressed as a slave for reading
00085 static u08 (*i2cSlaveTransmit)(u08 transmitDataLengthMax, u08* transmitData);
00086
00087 // functions
00088 void i2cInit(void)
00089 {
00090 // set pull-up resistors on I2C bus pins
00091 sbi(PORTC, 0); // i2c SCL on ATmega163,323,16,32,etc
00092 sbi(PORTC, 1); // i2c SDA on ATmega163,323,16,32,etc
00093 sbi(PORTD, 0); // i2c SCL on ATmega128,64
00094 sbi(PORTD, 1); // i2c SDA on ATmega128,64
00095
00096 // clear SlaveReceive and SlaveTransmit handler to null
00097 i2cSlaveReceive = 0;
00098 i2cSlaveTransmit = 0;
00099 // set i2c bit rate to 100KHz
00100 i2cSetBitrate(100);
00101 // enable TWI (two-wire interface)
00102 sbi(TWCR, TWEN);
00103 // set state
00104 I2cState = I2C_IDLE;
00105 // enable TWI interrupt and slave address ACK
00106 sbi(TWCR, TWIE);
00107 sbi(TWCR, TWEA);
00108 //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00109 // enable interrupts
00110 sei();
00111 }
00112
00113 void i2cSetBitrate(u16 bitrateKHz)
00114 {
00115 u08 bitrate_div;
00116 // set i2c bitrate
00117 // SCL freq = F_CPU/(16+2*TWBR))
00118 #ifdef TWPS0
00119 // for processors with additional bitrate division (mega128)
00120 // SCL freq = F_CPU/(16+2*TWBR*4^TWPS)
00121 // set TWPS to zero
00122 cbi(TWSR, TWPS0);
00123 cbi(TWSR, TWPS1);
00124 #endif
00125 // calculate bitrate division
00126 bitrate_div = ((F_CPU/1000l)/bitrateKHz);
00127 if(bitrate_div >= 16)
00128 bitrate_div = (bitrate_div-16)/2;
00129 outb(TWBR, bitrate_div);
00130 }
00131
00132 void i2cSetLocalDeviceAddr(u08 deviceAddr, u08 genCallEn)
00133 {
00134 // set local device address (used in slave mode only)
00135 outb(TWAR, ((deviceAddr&0xFE) | (genCallEn?1:0)) );
00136 }
00137
00138 void i2cSetSlaveReceiveHandler(void (*i2cSlaveRx_func)(u08 receiveDataLength, u08* recieveData))
00139 {
00140 i2cSlaveReceive = i2cSlaveRx_func;
00141 }
00142
00143 void i2cSetSlaveTransmitHandler(u08 (*i2cSlaveTx_func)(u08 transmitDataLengthMax, u08* transmitData))
00144 {
00145 i2cSlaveTransmit = i2cSlaveTx_func;
00146 }
00147
00148 inline void i2cSendStart(void)
00149 {
00150 // send start condition
00151 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
00152 }
00153
00154 inline void i2cSendStop(void)
00155 {
00156 // transmit stop condition
00157 // leave with TWEA on for slave receiving
00158 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)|BV(TWSTO));
00159 }
00160
00161 inline void i2cWaitForComplete(void)
00162 {
00163 // wait for i2c interface to complete operation
00164 while( !(inb(TWCR) & BV(TWINT)) );
00165 }
00166
00167 inline void i2cSendByte(u08 data)

ccrma.stanford.edu/…/i2c_8c-source.html 2/7
25-04-2011 /i2c.c Source File
00168 {
00169 // save data to the TWDR
00170 outb(TWDR, data);
00171 // begin send
00172 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00173 }
00174
00175 inline void i2cReceiveByte(u08 ackFlag)
00176 {
00177 // begin receive over i2c
00178 if( ackFlag )
00179 {
00180 // ackFlag = TRUE: ACK the recevied data
00181 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00182 }
00183 else
00184 {
00185 // ackFlag = FALSE: NACK the recevied data
00186 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00187 }
00188 }
00189
00190 inline u08 i2cGetReceivedByte(void)
00191 {
00192 // retieve received data byte from i2c TWDR
00193 return( inb(TWDR) );
00194 }
00195
00196 inline u08 i2cGetStatus(void)
00197 {
00198 // retieve current i2c status from i2c TWSR
00199 return( inb(TWSR) );
00200 }
00201
00202 void i2cMasterSend(u08 deviceAddr, u08 length, u08* data)
00203 {
00204 u08 i;
00205 // wait for interface to be ready
00206 while(I2cState);
00207 // set state
00208 I2cState = I2C_MASTER_TX;
00209 // save data
00210 I2cDeviceAddrRW = (deviceAddr & 0xFE); // RW cleared: write operation
00211 for(i=0; i<length; i++)
00212 I2cSendData[i] = *data++;
00213 I2cSendDataIndex = 0;
00214 I2cSendDataLength = length;
00215 // send start condition
00216 i2cSendStart();
00217 }
00218
00219 void i2cMasterReceive(u08 deviceAddr, u08 length, u08* data)
00220 {
00221 u08 i;
00222 // wait for interface to be ready
00223 while(I2cState);
00224 // set state
00225 I2cState = I2C_MASTER_RX;
00226 // save data
00227 I2cDeviceAddrRW = (deviceAddr|0x01); // RW set: read operation
00228 I2cReceiveDataIndex = 0;
00229 I2cReceiveDataLength = length;
00230 // send start condition
00231 i2cSendStart();
00232 // wait for data
00233 while(I2cState);
00234 // return data
00235 for(i=0; i<length; i++)
00236 *data++ = I2cReceiveData[i];
00237 }
00238
00239 void i2cMasterSendNI(u08 deviceAddr, u08 length, u08* data)
00240 {
00241 // disable TWI interrupt
00242 cbi(TWCR, TWIE);
00243
00244 // send start condition
00245 i2cSendStart();
00246 i2cWaitForComplete();
00247
00248 // send device address with write
00249 i2cSendByte( deviceAddr & 0xFE );
00250 i2cWaitForComplete();
00251
00252 // send data
00253 while(length)
00254 {
00255 i2cSendByte( *data++ );

ccrma.stanford.edu/…/i2c_8c-source.html 3/7
25-04-2011 /i2c.c Source File
00256 i2cWaitForComplete();
00257 length--;
00258 }
00259
00260 // transmit stop condition
00261 // leave with TWEA on for slave receiving
00262 i2cSendStop();
00263 while( !(inb(TWCR) & BV(TWSTO)) );
00264
00265 // enable TWI interrupt
00266 sbi(TWCR, TWIE);
00267 }
00268
00269 void i2cMasterReceiveNI(u08 deviceAddr, u08 length, u08 *data)
00270 {
00271 // disable TWI interrupt
00272 cbi(TWCR, TWIE);
00273
00274 // send start condition
00275 i2cSendStart();
00276 i2cWaitForComplete();
00277
00278 // send device address with read
00279 i2cSendByte( deviceAddr | 0x01 );
00280 i2cWaitForComplete();
00281
00282 // accept receive data and ack it
00283 while(length > 1)
00284 {
00285 i2cReceiveByte(TRUE);
00286 i2cWaitForComplete();
00287 *data++ = i2cGetReceivedByte();
00288 // decrement length
00289 length--;
00290 }
00291
00292 // accept receive data and nack it (last-byte signal)
00293 i2cReceiveByte(TRUE);
00294 i2cWaitForComplete();
00295 *data++ = i2cGetReceivedByte();
00296
00297 // transmit stop condition
00298 // leave with TWEA on for slave receiving
00299 i2cSendStop();
00300
00301 // enable TWI interrupt
00302 sbi(TWCR, TWIE);
00303 }
00304
00305 void i2cMasterTransferNI(u08 deviceAddr, u08 sendlength, u08* senddata, u08 receivelength, u08* receivedata)
00306 {
00307 // disable TWI interrupt
00308 cbi(TWCR, TWIE);
00309
00310 // send start condition
00311 i2cSendStart();
00312 i2cWaitForComplete();
00313
00314 // if there's data to be sent, do it
00315 if(sendlength)
00316 {
00317 // send device address with write
00318 i2cSendByte( deviceAddr & 0xFE );
00319 i2cWaitForComplete();
00320
00321 // send data
00322 while(sendlength)
00323 {
00324 i2cSendByte( *senddata++ );
00325 i2cWaitForComplete();
00326 sendlength--;
00327 }
00328 }
00329
00330 // if there's data to be received, do it
00331 if(receivelength)
00332 {
00333 // send repeated start condition
00334 i2cSendStart();
00335 i2cWaitForComplete();
00336
00337 // send device address with read
00338 i2cSendByte( deviceAddr | 0x01 );
00339 i2cWaitForComplete();
00340
00341 // accept receive data and ack it
00342 while(receivelength > 1)
00343 {

ccrma.stanford.edu/…/i2c_8c-source.html 4/7
25-04-2011 /i2c.c Source File
00344 i2cReceiveByte(TRUE);
00345 i2cWaitForComplete();
00346 *receivedata++ = i2cGetReceivedByte();
00347 // decrement length
00348 receivelength--;
00349 }
00350
00351 // accept receive data and nack it (last-byte signal)
00352 i2cReceiveByte(TRUE);
00353 i2cWaitForComplete();
00354 *receivedata++ = i2cGetReceivedByte();
00355 }
00356
00357 // transmit stop condition
00358 // leave with TWEA on for slave receiving
00359 i2cSendStop();
00360 while( !(inb(TWCR) & BV(TWSTO)) );
00361
00362 // enable TWI interrupt
00363 sbi(TWCR, TWIE);
00364 }
00365
00366 //! I2C (TWI) interrupt service routine
00367 SIGNAL(SIG_2WIRE_SERIAL)
00368 {
00369 // read status bits
00370 u08 status = inb(TWSR) & TWSR_STATUS_MASK;
00371
00372 switch(status)
00373 {
00374 // Master General
00375 case TW_START: // 0x08: Sent start condition
00376 case TW_REP_START: // 0x10: Sent repeated start condition
00377 // send device address
00378 i2cSendByte(I2cDeviceAddrRW);
00379 //outb(TWDR, I2cDeviceAddrRW);
00380 //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
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 if(I2cSendDataIndex < I2cSendDataLength)
00387 {
00388 // send data
00389 i2cSendByte( I2cSendData[I2cSendDataIndex++] );
00390 //outb(TWDR, I2cSendData[I2cSendDataIndex++]);
00391 //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00392 }
00393 else
00394 {
00395 // transmit stop condition, enable SLA ACK
00396 i2cSendStop();
00397 //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTO)|BV(TWEA));
00398 // set state
00399 I2cState = I2C_IDLE;
00400 }
00401 break;
00402 case TW_MR_DATA_NACK: // 0x58: Data received, NACK reply issued
00403 // store final received data byte
00404 I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
00405 // continue to transmit STOP condition
00406 case TW_MR_SLA_NACK: // 0x48: Slave address not acknowledged
00407 case TW_MT_SLA_NACK: // 0x20: Slave address not acknowledged
00408 case TW_MT_DATA_NACK: // 0x30: Data not acknowledged
00409 // transmit stop condition, enable SLA ACK
00410 i2cSendStop();
00411 //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTO)|BV(TWEA));
00412 // set state
00413 I2cState = I2C_IDLE;
00414 break;
00415 case TW_MT_ARB_LOST: // 0x38: Bus arbitration lost
00416 //case TW_MR_ARB_LOST: // 0x38: Bus arbitration lost
00417 // release bus
00418 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00419 // set state
00420 I2cState = I2C_IDLE;
00421 // release bus and transmit start when bus is free
00422 //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
00423 break;
00424 case TW_MR_DATA_ACK: // 0x50: Data acknowledged
00425 // store received data byte
00426 I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
00427 // fall-through to see if more bytes will be received
00428 case TW_MR_SLA_ACK: // 0x40: Slave address acknowledged
00429 if(I2cReceiveDataIndex < (I2cReceiveDataLength-1))
00430 // data byte will be received, reply with ACK (more bytes in transfer)
00431 i2cReceiveByte(TRUE);

ccrma.stanford.edu/…/i2c_8c-source.html 5/7
25-04-2011 /i2c.c Source File
00432 //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00433 else
00434 // data byte will be received, reply with NACK (final byte in transfer)
00435 i2cReceiveByte(FALSE);
00436 //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00437 break;
00438
00439 // Slave Receiver status codes
00440 case TW_SR_SLA_ACK: // 0x60: own SLA+W has been received, ACK has been returned
00441 case TW_SR_ARB_LOST_SLA_ACK: // 0x68: own SLA+W has been received, ACK has been returned
00442 case TW_SR_GCALL_ACK: // 0x70: GCA+W has been received, ACK has been returned
00443 case TW_SR_ARB_LOST_GCALL_ACK: // 0x78: GCA+W has been received, ACK has been returned
00444 // we are being addressed as slave for writing (data will be received from master)
00445 // set state
00446 I2cState = I2C_SLAVE_RX;
00447 // prepare buffer
00448 I2cReceiveDataIndex = 0;
00449 // receive data byte and return ACK
00450 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00451 break;
00452 case TW_SR_DATA_ACK: // 0x80: data byte has been received, ACK has been returned
00453 case TW_SR_GCALL_DATA_ACK: // 0x90: data byte has been received, ACK has been returned
00454 // get previously received data byte
00455 I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
00456 // check receive buffer status
00457 if(I2cReceiveDataIndex < I2C_RECEIVE_DATA_BUFFER_SIZE)
00458 {
00459 // receive data byte and return ACK
00460 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00461 }
00462 else
00463 {
00464 // receive data byte and return NACK
00465 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00466 }
00467 break;
00468 case TW_SR_DATA_NACK: // 0x88: data byte has been received, NACK has been returned
00469 case TW_SR_GCALL_DATA_NACK: // 0x98: data byte has been received, NACK has been returned
00470 // receive data byte and return NACK
00471 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00472 break;
00473 case TW_SR_STOP: // 0xA0: STOP or REPEATED START has been received while addressed as slave
00474 // switch to SR mode with SLA ACK
00475 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00476 // i2c receive is complete, call i2cSlaveReceive
00477 if(i2cSlaveReceive) i2cSlaveReceive(I2cReceiveDataIndex, I2cReceiveData);
00478 // set state
00479 I2cState = I2C_IDLE;
00480 break;
00481
00482 // Slave Transmitter
00483 case TW_ST_SLA_ACK: // 0xA8: own SLA+R has been received, ACK has been returned
00484 case TW_ST_ARB_LOST_SLA_ACK: // 0xB0: GCA+R has been received, ACK has been returned
00485 // we are being addressed as slave for reading (data must be transmitted back to master)
00486 // set state
00487 I2cState = I2C_SLAVE_TX;
00488 // request data from application
00489 if(i2cSlaveTransmit) I2cSendDataLength = i2cSlaveTransmit(I2C_SEND_DATA_BUFFER_SIZE, I2cSendData);
00490 // reset data index
00491 I2cSendDataIndex = 0;
00492 // fall-through to transmit first data byte
00493 case TW_ST_DATA_ACK: // 0xB8: data byte has been transmitted, ACK has been received
00494 // transmit data byte
00495 outb(TWDR, I2cSendData[I2cSendDataIndex++]);
00496 if(I2cSendDataIndex < I2cSendDataLength)
00497 // expect ACK to data byte
00498 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00499 else
00500 // expect NACK to data byte
00501 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00502 break;
00503 case TW_ST_DATA_NACK: // 0xC0: data byte has been transmitted, NACK has been received
00504 case TW_ST_LAST_DATA: // 0xC8:
00505 // all done
00506 // switch to open slave
00507 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00508 // set state
00509 I2cState = I2C_IDLE;
00510 break;
00511
00512 // Misc
00513 case TW_NO_INFO: // 0xF8: No relevant state information
00514 // do nothing
00515 break;
00516 case TW_BUS_ERROR: // 0x00: Bus error due to illegal start or stop condition
00517 // reset internal hardware and release bus
00518 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTO)|BV(TWEA));
00519 // set state

ccrma.stanford.edu/…/i2c_8c-source.html 6/7
25-04-2011 /i2c.c Source File
00520 I2cState = I2C_IDLE;
00521 break;
00522 }
00523 //outb(PORTB, ~I2cState);
00524 }
00525
00526 /*
00527 void i2cSendNI(u08 deviceAddr, u08 length, u08* data)
00528 {
00529 // disable TWI interrupt
00530 cbi(TWCR, TWIE);
00531
00532 // send start condition
00533 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
00534 while( !(inb(TWCR) & BV(TWINT)) );
00535
00536 // send device address with write
00537 outb(TWDR, (deviceAddr&0xFE) );
00538 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00539 while( !(inb(TWCR) & BV(TWINT)) );
00540
00541 // send data
00542 while(length)
00543 {
00544 outb(TWDR, *data++);
00545 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00546 while( !(inb(TWCR) & BV(TWINT)) );
00547 length--;
00548 }
00549
00550 // transmit stop condition
00551 // leave with TWEA on for slave receiving
00552 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)|BV(TWSTO));
00553 // enable TWI interrupt
00554 sbi(TWCR, TWIE);
00555 }
00556
00557 void i2cReceiveNI(u08 deviceAddr, u08 length, u08 *data)
00558 {
00559 // disable TWI interrupt
00560 cbi(TWCR, TWIE);
00561
00562 // send start condition
00563 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
00564 while( !(inb(TWCR) & BV(TWINT)) );
00565
00566 // send device address with read
00567 outb(TWDR, (deviceAddr&0xFE) | 0x01);
00568 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00569 while( !(inb(TWCR) & BV(TWINT)) );
00570
00571 // accept receive data and ack it
00572 while(length > 1)
00573 {
00574 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00575 while( !(inb(TWCR) & BV(TWINT)) );
00576 *data++ = inb(TWDR);
00577 length--;
00578 }
00579
00580 // accept receive data and nack it (last-byte signal)
00581 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00582 while( !(inb(TWCR) & BV(TWINT)) );
00583 *data++ = inb(TWDR);
00584
00585 // transmit stop condition
00586 // leave with TWEA on for slave receiving
00587 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)|BV(TWSTO));
00588 // enable TWI interrupt
00589 sbi(TWCR, TWIE);
00590 }
00591 */

Generated on Fri Aug 1 10:42:41 2003 for Procyon AVRlib by 1.2.18

ccrma.stanford.edu/…/i2c_8c-source.html 7/7

S-ar putea să vă placă și