Tag Archives: lpc2148

ARM7 to ARM7 (LPC2148) communication using I2C

1 Apr

     Board to board communication using I2C protocol, is simple once you’ve done any other program using this protocol with arm7. Since I have interfaced arm7 with eeprom. The same code used to send data to the eeprom is been used,except for the change in slave address,in this case it’s (0x00);

SEND

Master transmit mode

#include<lpc214x.h>
#include<stdio.h>
#include”appdef.h”
#include”armlcd.h”
#define led_port BIT0+BIT1+BIT8+BIT9+BIT25+BIT15+BIT12+BIT28
int c=1;
int r=0;
static int i=0;
unsigned char buf[12]=”YES YAMAHA”;
__irq void led(void)
{
     IOSET0=led_port;
     switch(I2C0STAT)
     {
         case 0x08 : lcd(‘s’); //start
                             I2C0CONCLR=BIT3+BIT5;

                             I2C0DAT=0x00;  //slave address of the other board

                             break;
          case 0x18 : lcd(‘a’);
                             I2C0CONCLR=BIT3;
                             break;
         case 0x28 : lcd(‘k’);
                            I2C0CONCLR=BIT3;
                            switch(c)
                            {
                               case 1 : I2C0DAT=buf[i];
                                             i++;
                                            if(i==10)
                                            {
                                                c++;
                                             }
                                             break;
                              case 2: I2C0CONSET=BIT4;
                                           lcd(‘p’);
                                           break;
                            }
                              break;
       case 0x30 : lcd(‘n’);
                          I2C0CONCLR=BIT3+BIT5;
                          break;
       default:      lcd(‘f’);
                         break;
}

VICVectAddr=0x00;
}

int main()
{

rs_clr();
en_clr();
lcd_init();
rs_set();
en_clr();
lcd(‘i’);
PINSEL0=BIT4+BIT6;

VICVectCntl0=0x29;
VICVectAddr0=(unsigned) led;
VICIntEnable=BIT9;

I2C0CONSET=BIT6;
I2C0CONCLR=BIT3+BIT2+BIT4;
I2C0SCLH=0x4B;
I2C0SCLL=0x4B;

I2C0CONSET|=BIT5;
while(1);

}
void lcd_init()
{
unsigned int i;
PINSEL0 = 0x00000000;

lcd_dir_write(); // output port
for (i=0;i<1000;i++);
lcd(0x33);
lcd(0x32);
lcd(0x28);
lcd(0x0e);
lcd(0x01);
lcd(0x06);
lcd(0x80);

for (i=0;i<1000000;i++);
}

void lcd(unsigned char val)
{
lcd1(val>>4);
lcd1(val);
}

void lcd1(unsigned char c)
{
unsigned int i;
IOCLR0 = 0x00f00000;
IOSET0 = (c<<20); // d4 connected to 20th port pin
en_set();
for (i=0;i<1000000;i++);
en_clr();
}

RECEIVE

Slight changes at the code at the slave side.You have to choose the arm controller to be in slave mode.

Slave receiver mode.

I2C0ADR=0X01; // general call address.Only when you set bit0 of this register can the master board send address as 0x00 to the slave board.

Enable bit & AA bit of the I2CCONSET register has to set to 1 during initialization. 

Remember no start bit required.

status codes are 0x70,0x90. go through the user manual

#include<lpc214x.h>
#include<stdio.h>
#include”appdef.h”
#include”armlcd.h”
#define led_port BIT0+BIT1+BIT8+BIT9+BIT25+BIT15+BIT12+BIT28
int c=0;
int r=0,dw=1,ss=0,rs=0,j;
char ch;
__irq void led(void)
{
        switch(I2C0STAT)
       {
           case 0x70 : lcd(‘g’);  
                              I2C0CONSET|=BIT2;  //AA bit set
                              I2C0CONCLR=BIT3;
                              break;
           case 0x90 :ch=I2C0DAT;  //data received and stored safely
                             I2C0CONCLR=BIT3;
                             lcd(ch);
                             break;
           case 0xa0 :lcd(‘p’);
                             I2C0CONCLR=BIT3;
                             break;
           default:lcd(‘f’);
                       I2C0CONCLR=BIT3;
                       break;
}

VICVectAddr=0x00;
}

int main()
{

rs_clr();
en_clr();
lcd_init();
rs_set();
en_clr();
PINSEL0=BIT4+BIT6;
VICVectCntl0=0x29;
VICVectAddr0=(unsigned) led;
VICIntEnable=BIT9;

I2C0ADR=0X01;  // general call addr
I2C0CONSET=BIT6+BIT2; // SLAVE MODE
I2C0CONCLR=BIT3;
I2C0SCLH=0x4B;
I2C0SCLL=0x4B;

lcd(‘v’);
while(1);
}
void lcd_init()
{
unsigned int i;
PINSEL0 = 0x00000000;

lcd_dir_write(); // output port
for (i=0;i<1000;i++);
lcd(0x33);
lcd(0x32);
lcd(0x28);
lcd(0x0e);
lcd(0x01);
lcd(0x06);
lcd(0x80);

for (i=0;i<1000000;i++);
}

void lcd(unsigned char val)
{
lcd1(val>>4);
lcd1(val);
}

void lcd1(unsigned char c)
{
unsigned int i;
IOCLR0 = 0x00f00000;
IOSET0 = (c<<20); // d4 connected to 20th port pin
en_set();
for (i=0;i<1000000;i++);
en_clr();
}

Interfacing external memory with LPC2148 using I2C Protocol (PART 2)

14 Mar

Dummy write operation

So once your done with writing data into the EEPROM,you would want to read from the location where you have written into.Image

The diagram above clearly shows the steps how it needs to be done. 

CODE:

#include<lpc214x.h> // standard header file
#include”appdef.h” // defining bits,example:#define BIT0 0x01<<0
#include”armlcd.h” // initialisations for lcd
#define led_port BIT0+BIT1+BIT8+BIT9+BIT25+BIT15+BIT12+BIT28
int c=0;
int r=0,dw=1,ss=0,rs=0,j;
char ch;
__irq void led(void)
{
switch(I2C0STAT)
{
case 0x08 : //lcd(‘s’); // 1.start
                  I2C0CONCLR=BIT3; 
                  I2C0DAT=0xa0; // dummy write
                  break;
case 0x10 :// lcd(‘b’); // 4. repeated start condition status
                   I2C0CONCLR=BIT3+BIT5;
                  I2C0DAT=0xa1; // read
                  break;
case 0x18 : //lcd(‘a’); // 2. write  ack
                   I2C0CONCLR=BIT3+BIT5;
                   I2C0DAT=0x00; // memory address
                   break;
case 0x28 : //lcd(‘k’); // 3. ack
                   I2C0CONCLR=BIT3;
                   I2C0CONSET|=BIT5; // repeated start bit
                   break;
case 0x40 : //lcd(‘r’);  // 5.read ack
                   I2C0CONCLR=BIT3;
                   I2C0CONSET=BIT2; // aa flag
                   break;
case 0x48 : lcd(‘l’);
                   I2C0CONCLR=BIT3;
                   break;
case 0x50 : I2C0CONCLR=BIT3; // 6.start receiving data
                   ch=I2C0DAT;
                   lcd(ch);
                  if(dw==9)
                  {
                       I2C0CONCLR=BIT2;  // sending a no ack after reading 10 bytes
                  }
                  dw++;
                  break;
case 0x58 ://lcd(‘n’);   // 7.stop bit
                   I2C0CONCLR=BIT3;
                   I2C0CONSET=BIT4;
                   break;
default:lcd(‘f’);
             I2C0CONCLR=BIT3;
              break;
}

VICVectAddr=0x00;
}

int main()
{

rs_clr();
en_clr();
lcd_init();
rs_set();
en_clr();
//lcd(‘i’);
PINSEL0=BIT4+BIT6;
VICVectCntl0=0x29;
VICVectAddr0=(unsigned) led;
VICIntEnable=BIT9;

I2C0CONSET=BIT6;
I2C0CONCLR=BIT3;
I2C0SCLH=0x4B;
I2C0SCLL=0x4B;

I2C0CONSET|=BIT5; //start
while(1);
}
void lcd_init()
{
unsigned int i;
PINSEL0 = 0x00000000;

lcd_dir_write(); // output port
for (i=0;i<1000;i++);
lcd(0x33);
lcd(0x32);
lcd(0x28);
lcd(0x0e);
lcd(0x01);
lcd(0x06);
lcd(0x80);

for (i=0;i<1000000;i++);
}

void lcd(unsigned char val)
{
lcd1(val>>4);
lcd1(val);
}

void lcd1(unsigned char c)
{
unsigned int i;
IOCLR0 = 0x00f00000;
IOSET0 = (c<<20); // d4 connected to 20th port pin
en_set();
for (i=0;i<1000000;i++);
en_clr();

}

Interfacing external memory with LPC2148 using I2C Protocol

10 Mar

I am using a LPC2148 development board from NSK Electronics. It has a slot for inserting external memory,I’ve used 24C02 chip.

LPC2148 has an inbuilt module for i2c protocol. All we need to know is how to use these registers.But before you dive into i2c of arm7,you need to learn to program for lpc2148 interrupts.Any interrupt as a matter of fact,because the i2c interrupt generation is very crucial.

Check out the below link  to learn more on interrupts in lpc2148

LPC2148 Interrupt Tutorial

The registers used for i2c are

I2C0CONSET,I2C0CONCLR,I2C0STAT,I2C0DAT

I2C0SCLH & I2C0SCLL used to set the bit frequency. The Pclk clock value I’ve taken is 15MHz.

LPC2148 is the master when writing into EEPROM and when it is reading.

Therefore Master transmit & receive mode.

The I2C0STAT register will tell you the status of the i2c module in arm,on when the interrupt flag SI is set. otherwise it will give you a value 0xf8. Therefore you can read the status only in the ISR which you have written for i2c interrupt.The SI flag gets SET automatically each time and it’s very important to clear the flag each time you enter the ISR.

Don not set all the bits in I2C0CONSET,I2C0CONCLR at one short.Go according to the steps required for i2c communication.

write-i2c

Writing into EEPROM

#include<lpc214x.h>
#include<stdio.h>
#include”appdef.h”
#include”armlcd.h”

int c=1;

static int i=0;
unsigned char buf[12]=”YES YAMAHA”;
__irq void led(void)
{
switch(I2C0STAT)
{
case 0x08 : lcd(‘s’); //start
I2C0CONCLR=BIT3+BIT5;  // clr start & SI bit
I2C0DAT=0xa0;  //device address
break;

case 0x10 : lcd(‘b’);
I2C0CONCLR=BIT3;  // clearing SIbit
break;

case 0x18 : lcd(‘a’);
I2C0CONCLR=BIT3;
I2C0DAT=0x00; // memory address
break;
case 0x28 : lcd(‘k’);
I2C0CONCLR=BIT3;
switch(c)
{
case 1 :
I2C0DAT=buf[i];  // writing data into EEPROM
lcd(‘m’);
i++;
if(i==10) //10 characters
{
c++;
}
break;

case 2: I2C0CONSET=BIT4; // stop bit
lcd(‘p’);
break;

}

break;
case 0x30 : lcd(‘n’);
I2C0CONCLR=BIT3+BIT5;
break;

default: lcd(‘f’);
break;
}

VICVectAddr=0x00;
}

int main()
{
rs_clr();
en_clr();
lcd_init();
rs_set();
en_clr();
lcd(‘i’);
PINSEL0=BIT4+BIT6;  // scl & sda pin
VICVectCntl0=0x29;
VICVectAddr0=(unsigned) led;
VICIntEnable=BIT9;

I2C0CONSET=BIT6;
I2C0CONCLR=BIT3+BIT2+BIT4;
I2C0SCLH=0x4B;   //100 MHz bit freq
I2C0SCLL=0x4B;

I2C0CONSET|=BIT5;  //start bit

}
void lcd_init()
{
unsigned int i;
PINSEL0 = 0x00000000;

lcd_dir_write(); // output port
for (i=0;i<1000;i++);
lcd(0x33);
lcd(0x32);
lcd(0x28);
lcd(0x0e);
lcd(0x01);
lcd(0x06);
lcd(0x80);

for (i=0;i<1000000;i++);
}

void lcd(unsigned char val)
{
lcd1(val>>4);
lcd1(val);
}

void lcd1(unsigned char c)
{
unsigned int i;
IOCLR0 = 0x00f00000;
IOSET0 = (c<<20); // d4 connected to 20th port pin
en_set();
for (i=0;i<1000000;i++);
en_clr();
}

I’ve used lcd in 4bit mode to display my output. At certain places I have passed character to lcd function,just to check for the proper functioning.Helps in debugging.You can take it off,if you want.

Software used:keil and philips utility