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

i2c.c

00001 /*! \file i2c.c \brief I2C interface using Philips LPC internal I2C hardware. */
00002 //*****************************************************************************
00003 //
00004 // File Name    : 'i2c.c'
00005 // Title        : I2C interface using Philips LPC internal I2C hardware
00006 // Author       : Pascal Stang - Copyright (C) 2004
00007 // Created      : 2004.05.05
00008 // Revised      : 2004.07.12
00009 // Version      : 0.9
00010 // Target MCU   : ARM, Philips LPC2100-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 "lpc2000.h"
00053 #include "global.h"
00054 #include "timer.h"
00055 #include "i2c.h"
00056 
00057 void i2cInit(void)
00058 {
00059     // setup SCL pin P02
00060     PINSEL0 &= ~(3<<4);
00061     PINSEL0 |=   1<<4;
00062     // setup SDA pin P03
00063     PINSEL0 &= ~(3<<6);
00064     PINSEL0 |=   1<<6;
00065 
00066     // set default bitrate of 100KHz
00067     i2cSetBitrate(400);
00068 
00069     // disable and reset interface
00070     I2CONCLR = 0xFF;
00071     delay(10);
00072 
00073     // enable interface
00074     I2CONSET = BIT(I2CON_I2EN);
00075 }
00076 /*
00077 void InitialiseI2C(void)
00078 {
00079 
00080 REG(I2C_I2SCLL) = 0x18;
00081 
00082 REG(I2C_I2SCLH) = 0x18;
00083 
00084 REG(I2C_I2CONCLR) = 0xFF;
00085 
00086 // Set pinouts as scl and sda
00087 REG(PCB_PINSEL0) = 0x50;
00088 
00089 REG(I2C_I2CONSET) = 0x40;
00090 delay(10);
00091 REG(I2C_I2CONSET) = 0x64;
00092 
00093 REG(I2C_I2DAT) = 0x42;
00094 
00095 REG(I2C_I2CONCLR) = 0x08;
00096 
00097 REG(I2C_I2CONCLR) = 0x20;
00098 
00099 }
00100 */
00101 
00102 void i2cSetBitrate(u16 bitrateDiv)
00103 {
00104     // @60MHz and VPB=2, set to 75 for 400KHz
00105     // @60MHz and VPB=2, set to 400 for 75KHz
00106     // set equal high and low periods
00107     I2SCLL = bitrateDiv;
00108     I2SCLH = bitrateDiv;
00109 }
00110 
00111 void i2cSetLocalDeviceAddr(u08 deviceAddr, u08 genCallEn)
00112 {
00113     // set local device address (used in slave mode only)
00114     I2ADR = ((deviceAddr&0xFE) | (genCallEn?1:0));
00115 }
00116 
00117 void i2cSendStart(void)
00118 {
00119     I2CONSET = BIT(I2CON_STA);
00120     I2CONCLR = BIT(I2CON_SI);
00121 }
00122 
00123 void i2cSendStop(void)
00124 {
00125     I2CONSET = BIT(I2CON_STO);
00126     I2CONCLR = BIT(I2CON_SI);
00127 }
00128 
00129 void i2cWaitForComplete(void)
00130 {
00131     // wait for a valid status code
00132     while(I2STAT == TW_NO_INFO);
00133 }
00134 
00135 void i2cSendByte(u08 data)
00136 {
00137     // save data into data register
00138     I2DAT = data;
00139     // clear SI bit to begin transfer
00140     I2CONCLR = BIT(I2CON_SI);
00141 }
00142 
00143 void i2cReceiveByte(u08 ackFlag)
00144 {
00145     // begin receive over i2c
00146     if( ackFlag )
00147     {
00148         // ackFlag = TRUE: ACK the recevied data
00149         I2CONSET = BIT(I2CON_AA);
00150         //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00151     }
00152     else
00153     {
00154         // ackFlag = FALSE: NACK the recevied data
00155         I2CONCLR = BIT(I2CON_AA);
00156         //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00157     }
00158     // clear SI bit to begin transfer
00159     I2CONCLR = BIT(I2CON_SI);
00160 }
00161 
00162 u08 i2cGetReceivedByte(void)
00163 {
00164     return I2DAT;
00165 }
00166 
00167 u08 i2cGetStatus(void)
00168 {
00169     return I2STAT;
00170 }
00171 
00172 
00173 u08 i2cMasterSendNI(u08 deviceAddr, u08 length, u08* data)
00174 {
00175     u08 retval = I2C_OK;
00176 
00177     // disable TWI interrupt
00178     //cbi(TWCR, TWIE);
00179 
00180     // send start condition
00181     i2cSendStart();
00182     i2cWaitForComplete();
00183     I2CONCLR = BIT(I2CON_STA);
00184 
00185     // send device address with write
00186     i2cSendByte( deviceAddr & 0xFE );
00187     i2cWaitForComplete();
00188 
00189     // check if device is present and live
00190     if( I2STAT == TW_MT_SLA_ACK)
00191     {
00192         // send data
00193         while(length)
00194         {
00195             i2cSendByte( *data++ );
00196             i2cWaitForComplete();
00197             length--;
00198         }
00199     }
00200     else
00201     {
00202         // device did not ACK it's address,
00203         // data will not be transferred
00204         // return error
00205         retval = I2C_ERROR_NODEV;
00206     }
00207 
00208     // transmit stop condition
00209     // leave with TWEA on for slave receiving
00210 //  I2CONSET = BIT(I2CON_STA);
00211 //  delay(10);
00212 //  I2CONCLR = BIT(I2CON_STO);
00213     i2cSendStop();
00214     //while( !(inb(TWCR) & BV(TWSTO)) );
00215 
00216     // enable TWI interrupt
00217     //sbi(TWCR, TWIE);
00218 
00219     return retval;
00220 }
00221 
00222 u08 i2cMasterReceiveNI(u08 deviceAddr, u08 length, u08 *data)
00223 {
00224     u08 retval = I2C_OK;
00225 
00226     // disable TWI interrupt
00227     ///cbi(TWCR, TWIE);
00228 
00229     // send start condition
00230     i2cSendStart();
00231     i2cWaitForComplete();
00232     I2CONCLR = BIT(I2CON_STA);
00233 
00234     // send device address with read
00235     i2cSendByte( deviceAddr | 0x01 );
00236     i2cWaitForComplete();
00237 
00238     // check if device is present and live
00239     if( I2STAT == TW_MR_SLA_ACK)
00240     {
00241         // accept receive data and ack it
00242         while(length > 1)
00243         {
00244             i2cReceiveByte(TRUE);
00245             i2cWaitForComplete();
00246             *data++ = i2cGetReceivedByte();
00247             // decrement length
00248             length--;
00249         }
00250 
00251         // accept receive data and nack it (last-byte signal)
00252         i2cReceiveByte(FALSE);
00253         i2cWaitForComplete();
00254         *data++ = i2cGetReceivedByte();
00255     }
00256     else
00257     {
00258         // device did not ACK it's address,
00259         // data will not be transferred
00260         // return error
00261         retval = I2C_ERROR_NODEV;
00262     }
00263 
00264     // transmit stop condition
00265     // leave with TWEA on for slave receiving
00266     i2cSendStop();
00267 
00268     // enable TWI interrupt
00269     //sbi(TWCR, TWIE);
00270 
00271     return retval;
00272 }
00273 

Generated on Mon Nov 6 23:36:58 2006 for Procyon ARMlib by  doxygen 1.4.2