pb with i2c interrupt with GCC
2006-01-24 by sebfr74
Hi,
I modify actually an existing 8051 project to a LPC2138. I've quite
finish to reprogram my product but I've got a problem with i2c
interrupt in order to use a FRAM.
It's the only interrupt I use on this project, and when I try to
write to the FRAM the LPC2138 reboot ??
I use GCC with Keil editor, and I use the exemple from the "insider
guide" book for the i2c.
This is my source code : (it's the call to i2c_transfer_byte() in
main() who reboot....)
Thanks,
Sebastien
////////////////////////////////////////
#include <LPC22xx.H>
void I2CISR (void) __attribute__ ((interrupt));
void init_i2c()
{
lock = 0;
PINSEL0 |= 0x50;
I2SCLH = 0x08;
I2SCLL = 0x08;
}
//////////////////////////////
void I2CTransferByte(uint I2CAddr,uchar MemAddr,uchar count,uchar
*data)
{
while(lock == 1) watchdog();
lock = 1;
I2CAddress = I2CAddr;
if(count >0) I2CData = data;
I2Counter = count;
MemAddress = MemAddr;
I2CONCLR = 0x000000FF;
I2CONSET = 0x00000040;
I2CONSET = 0x00000020;
}
/////////////////////////////////
void init_interrupt()
{
VICVectCntl0 = 0x00000029;
VICVectAddr0 = (unsigned long)I2CISR;
VICIntEnable = 0x00000200;
}
////////////////////////////////
void watchdog()
{
WDFEED = 0x000000AA; //Feed sequence pour relancer le watchdog
WDFEED = 0x00000055;
}
///////////////////////////////////
void I2CISR (void) //I2C interrupt routine
{
switch (I2STAT)
//Read result code and switch to next action
{
// Start and Send byte conditions
case ( 0x08):
//Start bit
I2CONCLR = 0x20;
//Clear start bit
I2DAT = I2CAddress; //Send
address and write bit
break;
case (0x18):
//Slave address+W, ACK
I2DAT = MemAddress; //Write
Mem,ory start address to tx register
break;
case (0x20):
//Salve address +W, Not ACK
I2DAT = I2CAddress; //Resend
address and write bi
break;
case (0x28):
if(I2Counter-->0)
//Data sent, Ack
{
I2DAT = *I2CData;
//Write data to tx register
I2CData++;
}
else
{
I2CONSET = 0x10;
//Stop condition
lock = 0; //Signal end
of I2C activity
}
break;
case (0x30) :
//Data sent, NOT Ack
I2DAT = *I2CData;
//Write data to tx register
break;
//Receive byte conditions
case (0x40) :
//Slave Address +R, ACK
I2CONSET = 0x04;
//Enable ACK for data byte
break;
case (0x48) :
//Slave Address +R, Not Ack
I2CONSET = 0x20;
//Resend Start condition
break;
case (0x50) :
//Data Received, ACK
if(--I2Counter>0)
{
*I2CData = I2DAT;
I2CData++;
}
else
{
I2CONSET = 0x10;
//Stop condition
lock = 0; //Signal
end of I2C activity
}
break;
case (0x58):
//Data Received, Not Ack
I2CONSET = 0x20; //
Resend Start condition
break;
default :
break;
}
I2CONCLR = 0x08;
//Clear I2C interrupt flag
VICVectAddr = 0x00000000; //Clear
interrupt in
}
/////////////////////
void main(void)
{
init_interrupt();
init_i2c();
while(1){
watchdog();
I2CTransferByte(0xA0,0,4,message);
//write data to the I2C Memory
}
}