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
00007 // Created      : 2002.06.25
00008 // Revised      : 2002.08.22
00009 // Version      : 0.7
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 // Standard I2C bit rates are:
00060 // 100KHz for slow speed
00061 // 400KHz for high speed
00062 
00063 #define I2C_IDLE                0
00064 #define I2C_BUSY                1
00065 #define I2C_SENT_START          2
00066 #define I2C_SENT_DEVICEADDR     3
00067 #define I2C_SENT_REGADDR        4
00068 #define I2C_SENT_DATA           5
00069 
00070 static volatile u08 I2cState;
00071 static u08 I2cDeviceAddrRW;
00072 static u08 I2cData[0x10];
00073 static u08 I2cDataIndex;
00074 static u08 I2cDataLength;
00075 
00076 // function pointer to i2c byte receive routine
00077 static void (*i2cSlaveReceive)(u08 data);
00078 
00079 // functions
00080 void i2cInit(void)
00081 {
00082     // set pull-up resistors on I2C bus pins
00083     sbi(PORTC, 0);  // i2c SCL on ATmega163,323,16,32,etc
00084     sbi(PORTC, 1);  // i2c SDA on ATmega163,323,16,32,etc
00085     sbi(PORTD, 0);  // i2c SCL on ATmega128,103,64
00086     sbi(PORTD, 1);  // i2c SDA on ATmega128,103,64
00087 
00088     // clear SlaveReceive handler to null
00089     i2cSlaveReceive = 0;
00090     // set i2c bit rate to 100KHz
00091     i2cSetBitrate(100);
00092     // enable TWI (two-wire interface)
00093     sbi(TWCR, TWEN);
00094     // set state
00095     I2cState = I2C_IDLE;
00096     // enable TWI interrupt and slave address ACK
00097     sbi(TWCR, TWIE);
00098     sbi(TWCR, TWEA);
00099     // enable interrupts
00100     sei();
00101 }
00102 
00103 void i2cSetBitrate(u16 bitrateKHz)
00104 {
00105     u08 bitrate_div;
00106     // set i2c bitrate
00107     // SCL freq = F_CPU/(16+2*TWBR))
00108     #ifdef TWPS0
00109         // for processors with additional bitrate division (mega128)
00110         // SCL freq = F_CPU/(16+2*TWBR*4^TWPS)
00111         // set TWPS to zero
00112         cbi(TWSR, TWPS0);
00113         cbi(TWSR, TWPS1);
00114     #endif
00115     // calculate bitrate division   
00116     bitrate_div = (((F_CPU/1000l)/bitrateKHz)-16)/2;
00117     //outb(TWBR, bitrate_div);
00118     outb(TWBR, 0xFF);
00119 }
00120 
00121 void i2cSetLocalDeviceAddr(u08 deviceAddr, u08 genCallEn)
00122 {
00123     // set local device address (used in slave mode only)
00124     outb(TWAR, ((deviceAddr&0xFE) | (genCallEn?1:0)) );
00125 }
00126 
00127 void i2cSetReceiveHandler(void (*i2cRx_func)(u08 data))
00128 {
00129     i2cSlaveReceive = i2cRx_func;
00130 }
00131 
00132 void i2cSend(u08 deviceAddr, u08 length, u08* data)
00133 {
00134     u08 i;
00135     // wait for interface to be ready
00136     while(I2cState);
00137     // save data
00138     I2cDeviceAddrRW = (deviceAddr&0xFE);    // RW cleared: write operation
00139     for(i=0; i<length; i++)
00140         I2cData[i] = *data++;
00141     I2cDataIndex = 0;
00142     I2cDataLength = length;
00143     // set state
00144     I2cState = I2C_BUSY;
00145     // send start condition
00146     outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
00147 }
00148 
00149 void i2cReceive(u08 deviceAddr, u08 length, u08* data)
00150 {
00151     u08 i;
00152     // wait for interface to be ready
00153     while(I2cState);
00154     // save data
00155     I2cDeviceAddrRW = (deviceAddr&0xFE);    // RW set: read operation
00156     I2cDataIndex = 0;
00157     I2cDataLength = length;
00158     // set state
00159     I2cState = I2C_BUSY;
00160     // send start condition
00161     outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
00162     // wait for data
00163     while(I2cState);
00164     // return data
00165     for(i=0; i<length; i++)
00166         *data++ = I2cData[i];
00167 }
00168 
00169 //! TWI interrupt service routine
00170 SIGNAL(SIG_2WIRE_SERIAL)
00171 {
00172     u08 data=0;
00173     // read status bits
00174     u08 status = inb(TWSR) & TWSR_STATUS_MASK;
00175 
00176     switch(status)
00177     {
00178 
00179     // Master General
00180     case TW_START:                          // 0x08: Sent start condition
00181         // send device address
00182         outb(TWDR, I2cDeviceAddrRW);
00183         outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00184         break;
00185     case TW_REP_START:                  // 0x10: Sent repeated start condition
00186         break;
00187     
00188     // Master Transmitter & Receiver status codes
00189     case TW_MT_SLA_ACK:                 // 0x18: Slave address acknowledged
00190     case TW_MT_DATA_ACK:                    // 0x28: Data acknowledged
00191         if(I2cDataIndex < I2cDataLength)
00192         {
00193             // send data
00194             outb(TWDR, I2cData[I2cDataIndex++]);
00195             outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00196         }
00197         else
00198         {
00199             // transmit stop condition, enable SLA ACK
00200             outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTO)|BV(TWEA));
00201             // set state
00202             I2cState = I2C_IDLE;
00203         }
00204         break;
00205     case TW_MR_DATA_NACK:               // 0x58: Data received, NACK reply issued
00206         // store final received data byte
00207         I2cData[I2cDataIndex++] = inb(TWDR);
00208         // continue to transmit STOP condition
00209     case TW_MR_SLA_NACK:                    // 0x48: Slave address not acknowledged
00210     case TW_MT_SLA_NACK:                    // 0x20: Slave address not acknowledged
00211     case TW_MT_DATA_NACK:               // 0x30: Data not acknowledged
00212         // transmit stop condition, enable SLA ACK
00213         outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTO)|BV(TWEA));
00214         // set state
00215         I2cState = I2C_IDLE;
00216         break;
00217     case TW_MT_ARB_LOST:                    // 0x38: Bus arbitration lost
00218     //case TW_MR_ARB_LOST:              // 0x38: Bus arbitration lost
00219         // release bus
00220         outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00221         // set state
00222         I2cState = I2C_IDLE;
00223         // release bus and transmit start when bus is free
00224         //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
00225         break;
00226     case TW_MR_DATA_ACK:                    // 0x50: Data acknowledged
00227         // store received data byte
00228         I2cData[I2cDataIndex++] = inb(TWDR);
00229         // continue to see if more bytes will be received
00230     case TW_MR_SLA_ACK:                 // 0x40: Slave address acknowledged
00231         if(I2cDataIndex < (I2cDataLength-1))
00232             // data byte will be received, reply with ACK (more bytes in transfer)
00233             outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00234         else
00235             // data byte will be received, reply with NACK (final byte in transfer)
00236             outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00237         break;
00238 
00239     // Slave Receiver status codes
00240     case TW_SR_SLA_ACK:                 // 0x60:
00241     case TW_SR_ARB_LOST_SLA_ACK:        // 0x68:
00242     case TW_SR_GCALL_ACK:               // 0x70:
00243     case TW_SR_ARB_LOST_GCALL_ACK:  // 0x78:
00244         // receive data byte and return ACK
00245         outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00246         break;
00247     case TW_SR_DATA_ACK:                    // 0x80:
00248     case TW_SR_GCALL_DATA_ACK:          // 0x90:
00249         // get received data byte
00250         data = inb(TWDR);
00251         if(i2cSlaveReceive) i2cSlaveReceive(data);
00252         // receive data byte and return ACK
00253         outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00254         break;
00255     case TW_SR_DATA_NACK:               // 0x88:
00256     case TW_SR_GCALL_DATA_NACK:     // 0x98:
00257         break;
00258     case TW_SR_STOP:                        // 0xA0:
00259         // switch to SR mode with SLA ACK
00260         outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00261         // set state
00262         I2cState = I2C_IDLE;
00263         break;
00264 
00265     // Slave Transmitter
00266     case TW_ST_SLA_ACK:                 // 0xA8:
00267     case TW_ST_ARB_LOST_SLA_ACK:        // 0xB0:
00268     case TW_ST_DATA_ACK:                    // 0xB8:
00269     case TW_ST_DATA_NACK:               // 0xC0:
00270     case TW_ST_LAST_DATA:               // 0xC8:
00271     // Misc
00272     case TW_NO_INFO:                        // 0xF8:
00273     case TW_BUS_ERROR:                  // 0x00:
00274         break;
00275     }
00276 }
00277 
00278 void i2cSendNI(u08 deviceAddr, u08 length, u08* data)
00279 {
00280     // disable TWI interrupt
00281     cbi(TWCR, TWIE);
00282 
00283     // send start condition
00284     outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
00285     while( !(inb(TWCR) & BV(TWINT)) );
00286 
00287     // send device address with write
00288     outb(TWDR, (deviceAddr&0xFE) );
00289     outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00290     while( !(inb(TWCR) & BV(TWINT)) );
00291     
00292     // send data
00293     while(length)
00294     {
00295         outb(TWDR, *data++);
00296         outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00297         while( !(inb(TWCR) & BV(TWINT)) );
00298         length--;
00299     }
00300     
00301     // transmit stop condition
00302     // leave with TWEA on for slave receiving
00303     outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)|BV(TWSTO));
00304     // enable TWI interrupt
00305     sbi(TWCR, TWIE);
00306 }
00307 
00308 void i2cReceiveNI(u08 deviceAddr, u08 length, u08 *data)
00309 {
00310     // disable TWI interrupt
00311     cbi(TWCR, TWIE);
00312 
00313     // send start condition
00314     outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
00315     while( !(inb(TWCR) & BV(TWINT)) );
00316 
00317     // send device address with read
00318     outb(TWDR, (deviceAddr&0xFE) | 0x01);
00319     outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00320     while( !(inb(TWCR) & BV(TWINT)) );
00321 
00322     // accept receive data and ack it
00323     while(length > 1)
00324     {
00325         outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00326         while( !(inb(TWCR) & BV(TWINT)) );
00327         *data++ = inb(TWDR);
00328         length--;
00329     }
00330 
00331     // accept receive data and nack it (last-byte signal)
00332     outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00333     while( !(inb(TWCR) & BV(TWINT)) );
00334     *data++ = inb(TWDR);
00335 
00336     // transmit stop condition
00337     // leave with TWEA on for slave receiving
00338     outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)|BV(TWSTO));
00339     // enable TWI interrupt
00340     sbi(TWCR, TWIE);
00341 }

Generated on Tue Feb 4 20:18:37 2003 for Procyon AVRlib by doxygen1.3-rc2