Yahoo Groups archive

Lpc2000

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

Message

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
	}
}

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.