Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

I2c in arm(LPC2124)

Status
Not open for further replies.

Nagarathna

New Member
Hi,

Below is code for inbuilt I2C cofiguration in ARM (LPC2124)

When i run the code the control goes to ISR but the execution doess not come out of ISR and cannot find where the control is going.

I have posted the code if there is any changes to be made please infom

thanks for any reply in advance





Code:
#define START  				I2CONSET=0x60;	 /* Send start bit */
#define ENABLE_I2C			I2CONSET=0x60;	 /* ENABLE I2C bit */
#define SI_START_DISABLE   	I2CONSET=0x28;	 /* START AND SI DISABLE */
#define SLAVE_ADDR  		I2ADR=0xA0;	 	 /* MEMORY IC ADDRESS    */
#define SLAVE_MEM_LOCATION	I2ADR=0x00;	 	 /* MEMORY LOCATION ADDRESS */
#define SLAVE_DATA	  		I2DAT='A';	 	 /* DATA TO BE TRANSMITTED  */



void main()
 {
	unsigned char c;

	VPBDIV=2;					   // cclk=pclk/4;	   cclk=crystal*5=(11.0592M*5);	 vpbdiv 00=1/4 * pclk, 01=pclk,10=1/2 *	pclk
	PINSEL0=0X00050000;		  	   //ENABLE RX0(21),TX0(19)
	U1LCR=0X83;					   //LINE CONTROL REGISTER WORD LENTH 8 BIT, 1 STOP BIT
	U1DLL=0xb4;                    //0x1e;//90;	//0x5A //0x1e
	U1LCR=0X03;				 	   //disable divisor access latch bit
	send_string("WELCOME EMBED INNOVATION,JAYA NAGAR");
	sendchar(0x0d);
	sendchar(0x0a);
	Initialize ();	 	
		while(1)
		{
					               		
			ENABLE_I2C;
			START;						//transmit a character
		}
}	



void Initialize()
{

	PINSEL0	=0x50;   	 	/* Initialize Pin Connect Block */
	I2CONCLR=0x6c;   		/* clearing all flags */
	I2SCLH	=0x0039;   	/* 100 KHz */
	I2SCLL	=0x0039;
	VICIntSelect  = 0x00000000; /* selecting IRQ 0=IRQ 1=FIQ */
	VICVectAddr0    =(unsigned long) I2C_ISR;
	VICVectCntl0    = 0x20 | 9; 	/ * highest priority and enabled */
	VICIntEnable    = 0x00000200; /* enabling I2C 9TH IS ASSIGNDE TO I2C REFER PERIPHERALS IN DEBUG MODE*/


}


 void I2C_ISR(void)
{
	int temp=0;
	   	temp=I2STAT;


		switch(temp)
			{
				case 8:
					ISR_8();
					break;
				case 24:
					ISR_18();
					break;
				case 40:
					ISR_28();
					break;
				default :
					break;
			}
	VICVectAddr0=0xFF;
 }
 
Last edited:
Are you telling the compiler it is an interrupt service routine? I do not see it in the code, all I see is you telling the hardware to go to the interrupt routine. Unless you tell the compiler it is an interrupt service routine, it will not include return code in the compile.

Also, you do not say which compiler you are using. I am not sure how standardized the compilers are. I do know vendors did not used to be consistent. While the code itself was standardized, the compiler commands were not.

Dan
 
Last edited:
The code written below is for hard I2C in arm LPC2124(Master mode).

Problem -
Step1 - when a start condition is transmitted i get an expected response 08h in status register from slave.
Step2 - when slave address and r/w bit is sent i dont get the expected response 18h but i get 20h form slave i.e. not acknowledged.




#include <LPC21xx.H>
#include<stdio.h>
#include<string.h>


void sendchar(unsigned char );
unsigned char readchar();
void send_string(unsigned char *);
void Initialize();
void ISR_8();
void ISR_18();
void ISR_28();
void ISR_20();
void I2C_ISR(void);
void serial_init();



#define START I2CONSET= 0x20; /* Send start bit */
#define START_DISABLE I2CONCLR= 0x20; /* Send start bit */
#define ENABLE_I2C I2CONSET= 0x40; /* ENABLE I2C bit*/
#define SI_START_ENABLE I2CONSET= 0x28; /* START AND SI DISABLE */
#define SI_START_DISABLE I2CONCLR= 0x28; /* START AND SI DISABLE */
#define SI_DISABLE I2CONCLR= 0x08; /* START AND SI DISABLE */
#define SLAVE_ADDR I2ADR = 0xA0; /* MEMORY IC ADDRESS */
#define SLAVE_DATA I2DAT = 0x00 ; /*DATA TO BE TRANSMITTED*/
#define SLAVE_MEM_LOCATION I2ADR = 0x00;/*EMORYlOCATIONADDRESS*/





int main()
{
serial_init();
send_string("WELCOME EMBED INNOVATION,JAYA NAGAR");
sendchar(0x0d);
sendchar(0x0a);
Initialize ();
ENABLE_I2C;
START;
while((I2CONSET&0X08)!=0X08);
sendchar(temp|0x30);
START_DISABLE;


}



void Initialize()
{

PINSEL0 = 0x55; /* Initialize Pin Connect Block */
I2CONCLR = 0x6c; /* clearing all flags */
I2SCLH = 0x0089; /* 100 KHz */
I2SCLL = 0x0089;
VICIntSelect = 0x00000000; /* selecting IRQ 0=IRQ 1=FIQ */
VICVectAddr0 = (unsigned long) I2C_ISR;
VICVectCntl0 = 0x20 | 9; /* highest priority and enabled */
VICIntEnable = 0x00000200; /* enabling I2C 9TH IS ASSIGNDE */


}

void serial_init()
{
VPBDIV=2; // cclk=crystal*5=(11.0592M*5);vpbdiv 10=1/2 * pclk
PINSEL0=0X00000005; // ENABLE RX0(21),TX0(19)
U0LCR=0X83; // LINE CONTROL REGISTER WORD LENTH 8 BIT, 1 STOP BIT
U0DLL=0xb4;
U0LCR=0X03; // disable divisor access latch bit

}


void I2C_ISR() __irq
{
unsigned int temp=0,i;


temp=I2STAT;
switch(temp)
{
case 0X08: //8h
ISR_8();
break;
case 0x18: //18h
ISR_18();
break;
case 0x28: //28h
ISR_28();
break;
case 0X20: //20h
ISR_20();
break;
case 0x38: //38h
ISR_18();
break;
default :
break;
}
}



/* I2C states*/
/* Start condition transmitted */
void ISR_8()
{
START_DISABLE;
SI_DISABLE;
SLAVE_ADDR; /* Slave address + write */
while((I2CONSET&0X08)!=0X08);

}


/* Acknowledgement received from slave for slave address */
void ISR_18()
{
SI_DISABLE; /* clear SI */
SLAVE_MEM_LOCATION; /* Data to be transmitted */

}


/* Acknowledgement received from slave for byte transmitted from master. Stop
condition is transmitted in this state signaling the end of transmission */
void ISR_28()
{
SI_DISABLE; /* clear SI */
SLAVE_DATA;

}
void ISR_20()
{
SI_DISABLE; /* clear SI */
I2CONSET=0x10; /* Transmit stop condition */

}

void sendchar(unsigned char a)
{
while(!(U0LSR&0X20));//LINE STATUS REGISTER transmiter holding register empty,5 th bit of LSR
U0THR=a; //U0THR IS EMPTY ,READY TO ACCCEPT
}



unsigned char readchar()
{
unsigned char buff; //temparary variable
while(!(U0LSR & 0X01)); //Checking for Receive data ready
buff=U0RBR;
return(buff); // receive buffer register
}





void send_string(unsigned char *str)
{
unsigned char i;
i=*str;
while(i!='\0') //CONTINUE UPTO NULL CHARACTER
{
sendchar(*str++);
i=*str;
}
}
 
Last edited:
that sounds like your original problem, not returning from the interrupt routine, has been solved.

As to your current problem, it would be helpful if you had a scope. I2C is quite finicky since it is an open collector system. You need to make sure that the pull ups are strong enough. A good place to start is the maximum current the weakest component can pull down.

Dan
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top