SparkFun Forums 

Where electronics enthusiasts find answers.

Everything ARM and LPC
By ICAC210
#73100
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 ****
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

}
}
By ICAC210
#73282
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?
By Cannibal
#73298
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.