This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

I2C between 2 lpc 2129 boards not initializing

I've tried to setup I2C communication between two LPC 2129 boards where one is the master and the other board is the slave. The code follows the following flow.
1.Initialize the output pins.
2.Initialize the interrupts.
3.Setup the I2C with proper symbol rate and Master/Slave config.
4.Start communication.

The simulation of these programs work properly on keil. All the registers initialize properly but in the hardware the communication doesn't happen. I've used a pull up resistor of 2.7K for the line with a 3.3V supply and the line remains high throughout. The start never bit never gets initialized and the controllers go into a loop waiting for the communication to interrupt the system.

Is there anything I have missed in the program ??

  • Have you looked at NXP's examples, and compared to your code?

    Rather than try to do both master & slave at the same time, can you get just a simple master to work with some "standard" I2C peripheral...?

  • Yes Andrew i have compared my code to the NXP examples.
    I also have a Humidicon sensor which uses the I2C bus for communication that also behaves the same when i connect the bus it just remains high. I have my doubts on the hardware. Are the values for the pull up resistors and the Vcc ok ? The I2C primer says the bus needs a minimum of 3mA to run does that have any thing to do with why the bus is behaving such ?
    If I connect just the SCK pin with a pull up resistor the pin starts clocking the start pulse but if both SCK and SDA are connected the bus gets held high.

  • While debugging the bus i have noticed that there is a start pulse being sent by the Master but this start pulse never causes the interrupt to set off. Even on the oscilloscope the low signal needed to establish a start condition is not achieved. I've programmed the board to send a continuous start signal in case the start is not acknowledged and this produces repeated start pulses the system does not get interrupted for either conditions of :-
    1. Start has been transmitted.

    or

    2. Repeat start has been transmitted.

    Cld really use some help i'm completely stuck.

  • a not too uncommon problem is that the master get ready some milliseconds before the slave and what you see could be a result of that.

    a simple way to check is to set a breakpoint in the master before it start communicating, if that makes the thingy work, Voila!

    Erik

  • Thanks erik

    I tried the solution you proposed. I even tried starting the master much after the slave, also added a 0.5 msec delay but this has yielded the same results. I've attached the code for the master for your reference

    # include <LPC21xx.h>
    
    int measurementrq(void);
    int datafetch(void);
    void uart(void);
    void i2cirq(void)__irq;
    void startbit (void);
    void restart (void);
    void datarcv (void);
    void lastdat(void);
    
    /*global variables*/
    unsigned int datcnt,count,SA = 0x27,datbuf,temp,hum,tempi,tempi1,dati;
    unsigned char data[4],dir,si,tempc,humc;
    
    
    
    int main(void)
    {
            si = 0; //initialise the SI register to keep track of the activity of the i2c bus
            IODIR1 = 0x00010000;
    
    
            /* setup the vector for I2C interrupt*/
            VICVectAddr2 = (unsigned)i2cirq;                //Set the timer ISR vector address
            VICVectCntl2 = 0x00000029;
            PINSEL0 = 0x00000055;
            VICIntEnable =0x00000200;
    
            /* setup the I2C bus for Master operation*/
    
            I2CONCLR = 0x6C;
            I2SCLL =  0x0c;
            I2SCLH = 0x0d;
    
            IOCLR1 = 0x00010000;
    
    
            /*setup the UART 2400*/
    
            U0LCR = 0X0000008B;
            U0DLL = 0X00000004;
            U0DLM = 0X00000001;
            U0LCR = 0X0000000B;
    
            while (!(U0LSR & 0x20));
    
                                            U0THR = 0x43;
    
            while (!(U0LSR & 0x20));
    
            while(1)
            {
                    int cnt;
                    I2CONSET = 0x40;
                    for (cnt = 0;cnt<0xFFFF;cnt++)
                    {
                            IOCLR1 = 0x00010000;
                    }
    
                    for (cnt = 0;cnt<0xFFFF;cnt++)
                    {
                    IOSET1 =        0x00010000;
                    }
    
                    measurementrq();
                    IOSET1 = 0x00010000;
                    datafetch();
                    IOSET1 = 0x00010000;
                    uart();
            }
    }
    
    
    /*interrupt subroutine for various condition handling */
    void i2cirq(void)__irq
    
    {
            IOSET1 = 0x00010000;
            /*transmit byte conditions*/
            switch(I2STAT)
    
            {
                    case (0x08):                                                            //Start bit tramsmitted
                    startbit();
                    break;
    
                    case(0x10) :                                                                    //repeat start condition
                    restart();
                    break;
    
    
                    case (0x18):                                                            //Slave address+W, ACK
                    I2CONSET        = 0x50;                                 //change more to a read mode to read the data from the memory operation send STOP  [clear the SI flag ]
                    si = 0;                                                                         //release the I2C loop wait mode and process data
                    break;
    
    
    
                    //Receive byte conditions
    
                    case (0x40) :                                                           //Slave Address +R, ACK
                    I2CONSET        = 0x04;                                                 //data bit will be recvd ack will be returned
    
    
                    break;
    
    
                    case (0x50) :                                                           //Data Received, ACK finally NACK
                    datarcv();
                    break;
    
                    case(0X58) :                                                    //last data recieved
                    lastdat();
                    break;
    
                    default :
                    break;
    
    }
    
            I2CONCLR |=0x08;
            VICVectAddr = 0x00000000;
            return  ;
    }
    
    int measurementrq(void)
    {
            //int cnt;
            si = 1;
            dir = 0;
            I2CONSET = 0x20;
            while(si == 1 )
            {
            //;for (cnt = 0;cnt<0xFFFF;cnt++)
                    {
                            IOCLR1 = 0x00010000;
                    }
    
                    /*for (cnt = 0;cnt<0xFFFF;cnt++)
                    {
                            IOSET1 = 0x00010000;
            }*/
    }
    
            return dir;
    
    }
    
    int datafetch(void)
    {
            si = 1; //bus is busy hence forth all the action will be handled by the ISR only data processing will be done in the end
            dir = 1;
            I2CONSET |= 0x60;
            while(si == 1 )
            {
                    ;
            }
            I2CONCLR = 0x40;
            //data[0] = 0x00;
    
            //un comment this part in case for operation with the sensor
            /*
            if (data[0] & 0xC0)
            {
                    datafetch();
            }
            else
            {
                    uart();
            }
            */
            return dir;
    }
    
    void uart(void)
    {
    
            dati = data[0] & 0x3F;
            hum  = ((dati<<8)+data[1]);
            tempi = data[2];
            tempi1 = (data[3] & 0xFC);
            temp = (((tempi<<8)+tempi1)>>2);
    
            /* calculations */
            datbuf = ((hum*0x64)/0x3FFE);
            humc = datbuf;
            datbuf = ((temp/0x3FFE)*0xA5)-0x28;
            tempc = datbuf;
    
            while (!(U0LSR & 0x20));
    
                                            U0THR = humc;
    
            while (!(U0LSR & 0x20));
                                            U0THR = tempc;
            while (!(U0LSR & 0x20));
                                            return;
    }
    
    void startbit (void)
    {
                    I2CONCLR        = 0x20;                                                 //Clear start bit
                    I2DAT           = ((SA<<1)|dir);                                  //Send address and  appropriate read/write bit
                    count = 0;
                    IOSET1 = 0x00010000;
                    //si = 0;
    }
    
    void restart (void)
    {
                    I2CONCLR        |= 0x20;                                                        //Clear start bit
                    I2DAT           = ((SA<<1)|dir);                                  //Send address and  appropriate read/write bit
                    count = 0;
    }
    
    void datarcv (void)
    {
                            if(count<=2)
                    {
                    data[count]     = I2DAT;
                    I2CONSET = 0x04;//assert an ack to the signal when the count reaches When the final count asser a nak on the bus as well as a stop on the bus
                    count++;
                    }
                    else
                    {
                    data[count]     = I2DAT;
                    I2CONCLR        = 0x04;                                                 //Stop condition
                    count++;
                    }
    }
    
    void lastdat(void)
    {
                            data[count]     = I2DAT;
                    I2CONSET        = 0x50;                                 //data BYTE AND NACK STOP  [clear the SI flag ]
                    IOCLR1 = 0x00010000;
                    si = 0;                                                                         //release the I2C loop wait mode and process data
    }
    

    I wld be grateful for the help
    Thank You