I2C Problem!

Hi, I am working on I2C with LPC2138. The problem I have is I can not see anything on SCL and SDA on the scope. When I set the I20SCLL and I20SCLH, shouldn’t I see SCL running at least? I have troubleshooting to the point that I know it is entering and exiting I2Caddressing(), as well as writeI2C and readI2C, but there is simply nothing at the output pin. I am only using a development board with no slave device connected. Here is the code,

//Ryesat1 CD&H board software

// sdkfj

#include <stdio.h> /* prototype declarations for I/O functions */

#include <LPC213x.H>

#include <setjmp.h>

/* LPC21xx definitions */

#define MODEMTX 0x00300000 //after PCB level 2 this will key up

#define MODEMRX 0x00400000 //

#define RADIOKEY 0x00000080

#define BUFFER_LEN 256

#define flash1 0x00030000

jmp_buf i2cerror;

#define STA 0x20

#define SIC 0x08

#define SI 0x08

#define STO 0x10

#define STAC 0x20

#define AA 0x04

float PS1, PS2, PS3, PS4;

float SC1, SC2, SC3, SC4, SC5, SC6, SV;

float BStat, BV, BD;

int j;

void InitI2C(void) {

I20CONCLR = 0xFF;

PINSEL0 |= 0x50; // Set pinouts as scl and sda

//PINSEL0 = 0x00000050;

//PINSEL0 |= 0x00000050;

//PINSEL0 &= 0xFFFFFF5F;

I20SCLL =19; //speed at 100Khz for a VPB Clock Divider = 4 at 14 MHz

I20SCLH =19;

// I2SCLL=60; //speed at 375Khz for a VPB Clock Divider = 1

// I2SCLH=70; // Pierre Seguin’s origional values.

for(j=0;j<5000000;j++);

I20CONSET = 0x40; //Active Master Mode on I2C bus

}

void SendI2CAddress(unsigned char Addr_S){

unsigned char r;

//int i;

I20CONCLR = 0xFF; // clear I2C - included if User forgot to “StopI2C()”

// else this function would hang.

I20CONSET = 0x40; // Active Master Mode on I2C bus

if((Addr_S & 0x01)) // test if it’s reading

I20CONSET = STA | AA; // set STA - allow master to acknowlege slave;

else

I20CONSET = STA; // set STA dont allow acknowledges;

//while(I20STAT!=0x08) ; // Wait for start to be completed

I20DAT = Addr_S; // Charge slave Address

I20CONCLR = SIC | STAC; // Clear i2c interrupt bit to send the data

//while( ! ( I20CONSET & SI)) ; // wait till status available

r=I20STAT; // 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”

// longjmp(i2cerror,1); // no acknowlege - probably no device there. Return a 1 in longjmp

// longjmp(i2cerror,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”

// longjmp(i2cerror,1); // no acknowlege - probably no device there. Return a 1 in longjmp

// longjmp(i2cerror,r); // other error - return status code in longjmp

// }

//}

}

unsigned char ReadI2C(void) {

unsigned char r;

I20CONCLR = SIC; // clear SIC;

//while( ! (I20CONSET & 0x8)); // wait till status available

r=I20STAT; // check for error

//if (r != 0x50){ // look for “Data byte has been received; ACK has been returned”

// longjmp(i2cerror,r); // read fail

//}

return I20DAT;

}

void WriteI2C(unsigned char Data) {

unsigned char r;

I20DAT = Data; // Charge Data

I20CONCLR = 0x8; // SIC; Clear i2c interrupt bit to send the data

//while( ! (I20CONSET & 0x8)); // wait till status available

r=I20STAT;

//if (r != 0x28){ // look for “Data byte in S1DAT has been transmitted; ACK has been received”

// longjmp(i2cerror,r); // write fail

//}

}

void StopI2C(void){

I20CONCLR = SIC;

I20CONSET = STO;

//while((I20CONSET&STO)) ; // wait for Stopped bus I2C

}

void getPSUstates(void){

InitI2C();

SendI2CAddress(0x70);

WriteI2C(0x02);

WriteI2C(0x00);

WriteI2C(0x09);

WriteI2C(0x55);

WriteI2C(0x11);

WriteI2C(0x55);

WriteI2C(0x55);

WriteI2C(0x01);

WriteI2C(0x1B);

StopI2C();

SendI2CAddress(0x71);

ReadI2C();

ReadI2C();

ReadI2C();

PS1=ReadI2C();

PS2=ReadI2C();

PS3=ReadI2C();

PS4=ReadI2C(); // read the result

ReadI2C();

ReadI2C();

StopI2C();

//return r*12.15/118; // return the battery voltage

}

void getSolarData(void){

InitI2C();

SendI2CAddress(0x70);

WriteI2C(0x04);

WriteI2C(0x00);

WriteI2C(0x05);

WriteI2C(0x00);

WriteI2C(0x09);

StopI2C();

SendI2CAddress(0x71); // Start the read

ReadI2C();

ReadI2C();

ReadI2C();

SC1=ReadI2C();

SC2=ReadI2C();

SC3=ReadI2C();

SC4=ReadI2C();

SC5=ReadI2C();

SC6=ReadI2C(); // read the result

SV=ReadI2C();

ReadI2C();

ReadI2C();

StopI2C();

}

void getBatteryData(void){

InitI2C();

SendI2CAddress(0x70);

WriteI2C(0x08); // Set the control port value

WriteI2C(0x00); // and the D/A output

WriteI2C(0x05);

WriteI2C(0x00);

WriteI2C(0x11);

StopI2C();

SendI2CAddress(0x71); // Start the read

ReadI2C();

ReadI2C();

ReadI2C();

BStat=ReadI2C();

BV=ReadI2C();

BD=ReadI2C(); // read the result

SV=ReadI2C();

ReadI2C();

ReadI2C();

StopI2C();

//return r*12.15/118; // return the battery voltage

}

int main (void)

{

int i;

/* initialize the serial interface */

PINSEL0 = 0x00050005; // Enable RxD1,TxD1,RxD0,TxD0

PINSEL1 = 0x00000000; //disable all JTAG BS.

PINSEL2 = 0X00000000; //DISABLE MORE JTAG SHIT

IODIR0 = 0x0000008C; //p0.7 output

IODIR1 = 0x00FF0000; //p1.22;p1.21;p1.20 output

U0LCR = 0x83; // 8 bits, no Parity, 1 Stop bit

//U0DLL = 97; // 9600 Baud Rate @ 15MHz VPB Clock

U0DLM=3; //1200bps @ 15mhz vpb

U0DLL=13; //1200bps #2 (not used for 9600)

U0LCR = 0x03; //8-n-1

//setup GPIO pins

IOCLR1=MODEMTX; //disable TX mode (MX604)

IOSET1=MODEMRX;

IOSET0=RADIOKEY; //key off radio

while (1) {

IOCLR1=MODEMRX; //dont allow m0+m1=11

IOSET1=MODEMTX; //enable TX mode (MX604), key up radio

IOCLR0=RADIOKEY; //key up radio

//IOSET1=flash1;

for(i=0;i<5000000;i++); //short, but humanly short delay

IOSET1=flash1;

getPSUstates();

for(j=0;j<5000000;j++);

IOCLR1=flash1;

//getSolarData();

//getBatteryData();

printf (“VA3SPR TEST: %F %5.3F %5.3F %5.3F %5.3F\n”,PS1,PS2,PS3,PS4);

printf (“VA3SPR TEST: %F %5.3F %5.3F %5.3F %5.3F %5.3F\n”,SC1, SC2, SC3, SC4, SC5, SC6);

printf (“VA3SPR TEST: %F \n”,SV);

printf (“VA3SPR TEST: %F %5.3F\n”,BV, BD);

for(i=0;i<1000000;i++); //short, but humanly short delay

printf (“VA3SPR END TEST\n”);

//while((U0LSR&0x80)==0); //spin while transmitter finishes sending.

IOCLR1=MODEMTX; //disable TX mode (MX604)

IOSET1=MODEMRX;

IOSET0=RADIOKEY; //key off radio

for(i=0;i<5000000;i++); //slightly longer delay

}

}

I tried to set SCL and SDA as GPIO output pins and SDA works, but SCL does NOT? which would explain why the I2C doesn’t work i believe. One question, when SCL and SDA are initialized as I2C, do I still need to config the IODIR for those two pins as output? I am looking at some sample codes and they don’t do that?

This is a guess on my part, but I hope it helps.

Do you have pull-ups on your I2C lines?

The SCL line might be an open collector (?) configuration, so it can’t pull up, only down - therefore it needs a pull-up to show 1.

Please let me know, and sorry if this is wasted time.