1. 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.
    Dismiss Notice

I2c in arm(LPC2124)

Discussion in 'ARM' started by Nagarathna, Jan 14, 2009.

  1. Nagarathna

    Nagarathna New Member

    Joined:
    Jan 14, 2009
    Messages:
    20
    Likes:
    0
    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 (text):



    #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: Jan 14, 2009
  2. Ubergeek63

    Ubergeek63 Well-Known Member

    Joined:
    Apr 16, 2008
    Messages:
    1,886
    Likes:
    37
    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: Jan 14, 2009
  3. Nagarathna

    Nagarathna New Member

    Joined:
    Jan 14, 2009
    Messages:
    20
    Likes:
    0
    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: Jan 16, 2009
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Ubergeek63

    Ubergeek63 Well-Known Member

    Joined:
    Apr 16, 2008
    Messages:
    1,886
    Likes:
    37

    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
     

Share This Page