Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

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
}

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.