initializing I2C problem
2005-04-12 by neptunus1000
Hello,
I use an olimex evaboard (LPC2129) and crossStudio.
I would like to use the I2C interface but it won't work.
ARM should be the master. First I tried to code it on my own with the
datasheet. Then I found some example code on the group.
The methode InitI2C() is working fine. Only the methode
SendSlaveAdress(unsigned char Addr_S) is working not well. At "while
(I2STAT != 0x08); // Wait for start to be completed" my code stops
and is waiting for de SI bit to set. This is never happening. I don't
understand why it is already stopping here.
I have nothing connected to the I2C bus, I mean that there is only
the EEPROM. Which is standard on the evaboard. I'm using 0xA0 address
for writing and 0xA1 for reading. But it can only by a matter if the
code can past this line of code "while(I2STAT != 0x08);"
For who have an interest this is the link the de pcb plan.
http://microcontrollershop.com/Images/lpc-e2124-sch.gif?
osCsid=3e8281154ae1883323bdf695bf87d276
can anybody help?
Roy
#define STA 0x20
#define SIC 0x08
#define SI 0x08
#define STO 0x10
#define STAC 0x20
#define AA 0x04
#include <__cross_studio_io.h>
class I2C{
private:
public:
I2C(void);
void delay(int);
void InitI2C(void);
void SendSlaveAdress(unsigned char);
unsigned char ReadOnI2C(void);
void WriteOnI2C(unsigned char);
void StopI2C(void);
};
I2C::I2C(void){
}
void I2C::delay(int d){
for(; d; --d){
asm volatile ("nop");
}
}
void I2C::InitI2C(void) {
I2CONCLR = 0xFF;
PINSEL0 |= 0x50; // Set pinouts as scl and sda
I2SCLL =60; //19 speed at 100Khz for a VPB Clock Divider =
4 at 14 MHz
I2SCLH =60;
// I2SCLL=60; //speed at 375Khz for a VPB Clock Divider = 1
// I2SCLH=70; // Pierre Seguin's origional values.
I2CONSET = 0x40; //Active Master Mode on I2C bus
}
void I2C::SendSlaveAdress(unsigned char Addr_S){
unsigned char r;
I2CONCLR = 0xFF; // clear I2C - included if User
forgot to "StopI2C()"
// else this function would hang.
I2CONSET = 0x40; // Active Master Mode on I2C bus
if((Addr_S & 0x01)) // test if it's reading
I2CONSET = STA | AA; // set STA - allow master to
acknowlege slave;
else
I2CONSET = STA; // set STA dont allow acknowledges;
r = I2STAT;
while(I2STAT != 0x08) ; // Wait for start to be completed
I2DAT = Addr_S; // Charge slave Address
I2CONCLR = SIC | STAC; // Clear i2c interrupt bit to send
the data
r = I2STAT;
while( ! ( I2CONSET & SI)) ; // wait till status available
r = I2STAT; // read Status. See standard error
codes pdf (link in manual).
if(!(Addr_S & 0x01)) { // if we are doing a write
if (r != 0x18) { // look for "SLA+W has been
transmitted; ACK has been received"
if ( r==0x20 ) // check for "SLA+W has been
transmitted; NOT ACK has been received"
debug_printf("no acknowlege - probably no device
there.\n"); // no acknowlege - probably no device there. Return a 1
in longjmp
debug_printf("error code: %x\n", r); // other
error - return status code in longjmp
}
} else {
if (r != 0x40) { // look for "SLA+R has been
transmitted; ACK has been received"
if ( r==0x48 ) // check for "SLA+R has been
transmitted; NOT ACK has been received"
debug_printf("no acknowlege - probably no device
there.\n"); // no acknowlege - probably no device there. Return a 1
in longjmp
debug_printf("error code: %x\n", r); // other
error - return status code in longjmp
}
}
debug_printf("I2STAT OKÉ: %x\n", r);
}
unsigned char I2C::ReadOnI2C(void) {
unsigned char r;
I2CONCLR = SIC; // clear SIC;
while( ! (I2CONSET & 0x8)); // wait till status available
r=I2STAT; // check for error
if (r != 0x50){ // look for "Data byte has been
received; ACK has been returned"
debug_printf("Read fail error code: %x\n", r); //
read fail
}
return I2DAT;
}
void I2C::WriteOnI2C(unsigned char Data) {
unsigned char r;
I2DAT = Data; // Charge Data
I2CONCLR = 0x8; // SIC; Clear i2c interrupt bit
to send the data
while( ! (I2CONSET & 0x8)); // wait till status available
r = I2STAT;
if (r != 0x28){ // look for "Data byte in S1DAT
has been transmitted; ACK has been received"
debug_printf("Write fail error code: %x\n", r); //
write fail
}
}
void I2C::StopI2C(void){
I2CONCLR = SIC;
I2CONSET = STO;
while((I2CONSET&STO)) ; // wait for Stopped bus I2C
}