PDA

View Full Version : I2C on the 2138


RageKage
12-02-06, 08:41 PM
Back again new question. I've decided to move on from output to the screen and now I'm trying to use the built in I2C routines working. I'm using some modified code that I was able to get from NXP. Essentially it is supposed to act as the master transmitter and send a couple instructions. After all is said and done I expect the hardware I'm to which I am sending to do start outputting so that I can read it on an oscilloscope. If all was acting as expected I wouldn't be here with a question. Essentially I'm not sure my code is running as expected. Any comments and suggestions you have would be greatly appreciated.




#include <LPC213X.H>

void Initialize(void);
/* I2C ISR */
__irq void I2C_ISR(void);
/* Master Transmitter states */
void ISR_8(void);
void ISR_18(void);
void ISR_28(void);

const int masterbuffer[1] = {0x9};
const int mastercounter = 1;

int main(void)
{
Initialize();

I2C0CONSET = 0x40;

while(1){}
}

/*************** System Initialization ***************/
void Initialize()
{
/* Remap interrupt vectors to SRAM */
MEMMAP=0x2;

/* Initialize GPIO ports to be used as indicators */
IODIR0=0xF0;
IOSET0=0xF0;

/* Initialize Pin Connect Block */
PINSEL0=0x50;

/* Initialize I2C */
I2C0CONCLR=0x6c; /* clearing all flags */
I2C0CONSET=0x40; /* enabling I2C */
I2C0SCLH=0x50; /* 375 KHz */
I2C0SCLL=0x50;

/* Initialize VIC for I2C use */
VICIntSelect=0x0; /* selecting IRQ */
VICIntEnable= 0x200; /* enabling I2C */
VICVectCntl0= 0x29; /* highest priority and enabled */
VICVectAddr0=(unsigned long) I2C_ISR;
/* ISR address written to the respective address register*/
}

/********************** I2C ISR **************************/
__irq void I2C_ISR()
{
int temp=0;

temp=I2C0STAT;
switch(temp)
{
case 8:
ISR_8();
break;
case 24:
ISR_18();
break;
case 40:
ISR_28();
break;
default :
break;
}
VICVectAddr=0xFF;
}

/* I2C states*/
/* Start condition transmitted */
void ISR_8()
{
/* Port Indicator */
IOCLR0=0x10;
/* Slave address + write */
I2C0DAT=0xB8;
/* Clear SI and Start flag */
I2C0CONCLR=0x28;
/* Port Indicator */
IOSET0=0x10;
}

/* Acknowledgement received from slave for slave address */
void ISR_18()
{
/* Port Indicator */
IOCLR0=0x20;
/* Data to be transmitted */
I2C0DAT=0x03; //address where data will be written
/* clear SI */
I2C0CONCLR=0x8;
/* Port Indicator */
IOSET0=0x20;
}

/* Acknowledgement received from slave for byte transmitted from master. Stop
condition is transmitted in this state signaling the end of transmission */
void ISR_28()
{
static int counter = 0;
/* Port Indicator */
IOCLR0=0x80;
if(counter < mastercounter)
{
I2C0DAT=masterbuffer[counter];
counter++;
}
else
/* Transmit stop condition */
I2C0CONSET=0x10;
/* clear SI */
I2C0CONCLR=0x8;
/* Port Indicator */
IOSET0=0x80;
}

mckenney
12-03-06, 11:45 AM
The setup looks about right, but I don't see where you issue a STArt to get
things going. Did you rather intend main() to:
I2C0CONSET = 0x20; // initiate STArt condition
Unsolicited suggestion: Add something to the "default" case in your ISR to
tell you that something unexpected has happened. If you can contrive a way
to display the status (I2C state) bits on some GPIO lines (LEDs?) I think you'll
find it very useful over time.

RageKage
12-03-06, 07:49 PM
Nice catch, you are right I cant believe I didn't catch that.

RageKage
12-04-06, 12:30 PM
Thanks again for the pointer. Just to let you know, the code seems to be working. I know for a fact that all the data is getting sent across. I also know that I am receiving an acknowledge after that and the stop condition is being sent. I'm not positive the stop condition is working. However this could be an issue with the slave I am communicating with. Anyway thanks again for the assistance.