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