i2c in LPC810

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i2c in LPC810

1,258 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by HammingBird on Mon Apr 04 09:33:43 MST 2016
Hallo,
I am doing a project with LPC810, i2c communication.  I need to configure LPC810 as a Master.  . trying to send 1byte to slave. But cound not get nothing.

even, I did not see any signal(scl,sda) in oscilloscope.

can anyone help me out ?

here is the prog(Although this prog is from internet, almost everything make sence):







#include "LPC8xx.h"

#define I2C_CFG_MSTEN (0x1)
#define I2C_STAT_MSTPENDING (0x1)
#define I2C_STAT_MSTSTATE (0xe)
#define I2C_STAT_MSTST_IDLE (0x0)
#define I2C_STAT_MSTST_RX (0x2)
#define I2C_STAT_MSTST_TX (0x4) // STAT registor
#define I2C_MSTCTL_MSTCONTINUE (0x1)
#define I2C_MSTCTL_MSTSTART (0x2)
#define I2C_WSTCTL_MSTSTOP (0x4)

int main ()
{
        //Set clock for SWM (file:SWM.c)
// normal addr of SYSAHBCLKCTRL = 0x080 = 1<<7
        LPC_SYSCON->SYSAHBCLKCTRL |= 1<<7; ///Set clock for i2c


      //Disable special functions (file:SWM.c)
        LPC_SWM->PINENABLE0 |= 0xFF0FFFFFFUL;

//Set pins for i2c by SWM (file:SWM.c)
        LPC_SWM->PINASSIGN7 |= 0x03FFFFFFUL; //* I2C0_SDA */Pin PIO0_3= pin3
        LPC_SWM->PINASSIGN8 |= 0xFFFFFF04UL; //* I2C0_SCL */Pin PIO0_4= pin2


        //Set clock for IOCON by SWM (file:iocon.c)
        LPC_SYSCON->SYSAHBCLKCTRL |= 1<<18;

//Disable Pullups for PIO0_2 and PIO0_3 (file:iocon.c) 
        LPC_IOCON->PIO0_2 = 0x80; //PIO0_2 (pin 4)
        LPC_IOCON->PIO0_3 = 0x80; //PIO0_3 (pin 3)


//Set clock for i2c (file:swm.c)
// SYSAHBCLKCTRL= 0x0A0- 0x080 =  0x020 -->1<<5
        LPC_SYSCON->SYSAHBCLKCTRL |= 1<<5;

//Set preset for i2c
//PRESETCTRL =0x044-0x004=0x040--> 0x040= 1<<6
LPC_SYSCON->PRESETCTRL &= ~1<<6;  // ~1<<6 = 0111111 = 3f
LPC_SYSCON->PRESETCTRL |= 1<<6;


//NVIC enable
        NVIC_EnableIRQ(I2C_IRQn);


//Set i2c clock DIV--> CLKDIV
        LPC_I2C->DIV = 0x1;
//CLKDIV= 0x0001 --> PCLK is divided by 2 before use by the I2C  function.




//Example Code:Master write one byte to slave

// Configure I2C Master = CFG = 0x001  
        //Enable i2c master
        LPC_I2C->CFG = I2C_CFG_MSTEN; // Master Enable


// Write to the Slave Address 
        while(!(LPC_I2C->STAT & I2C_STAT_MSTPENDING));
        if((LPC_I2C->STAT & I2C_STAT_MSTSTATE) == I2C_STAT_MSTST_IDLE){
               
//Set address(Display/Slave address 0x3c for OLED  )
                LPC_I2C->MSTDAT = (0x3C << 1) | 0;
               

// MSTCTL = 0x22--> 0x2 
//Send start bit
                LPC_I2C->MSTCTL = 0x2; //ex:code= 0x2
        }

//waiting for pending status
        while(!(LPC_I2C->STAT & I2C_STAT_MSTPENDING));
        if((LPC_I2C->STAT & I2C_STAT_MSTSTATE) == I2C_STAT_MSTST_TX) {
               
// Write 8 bit data
//Send sub address //in ex:sub addr = 0xaa 
                LPC_I2C->MSTDAT = 0x00; // sub address 0x00
              
       // Continue Transmission
//  Send continue
                LPC_I2C->MSTCTL = 0x1; //0x21--> 0x1
        }

// Waiting for Pending Status
        while(!(LPC_I2C->STAT & I2C_STAT_MSTPENDING));
        if((LPC_I2C->STAT & I2C_STAT_MSTSTATE) == I2C_STAT_MSTST_TX){
  //I2C_STAT_MSTSTATE (0xe) //I2C_STAT_MSTST_TX =STAT(0x4)

                //Send value to Display
                LPC_I2C->MSTDAT = 0xAF; //Writing “0xAF” to Display
               
//  Continue Transmission
//Send continue
                LPC_I2C->MSTCTL = 0x1; //0x21-> 0x1
        }

while(!(LPC_I2C->STAT & I2C_STAT_MSTPENDING));
        if((LPC_I2C->STAT & I2C_STAT_MSTSTATE) == I2C_STAT_MSTST_TX){
                     //I2C_STAT_MSTSTATE (0xe)//I2C_STAT_MSTST_TX =STAT(0x4)
               

// stop Transmission
//Send stop bit
                LPC_I2C->MSTCTL = 0x4; //0x24 -->0x4 
        }

        while(!(LPC_I2C->STAT & I2C_STAT_MSTPENDING));
        if((LPC_I2C->STAT & I2C_STAT_MSTSTATE) == I2C_STAT_MSTST_IDLE);

}












Labels (1)
0 Kudos
Reply
4 Replies

967 Views
lpcware
NXP Employee
NXP Employee
bump
0 Kudos
Reply

967 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by IanB on Thu Apr 07 02:29:14 MST 2016
Here it is. It's just the program lifted straight from the manual, translated into assembler
            #define I2C_CFG_MSTEN (0x1)
            #define I2C_CFG_SLVEN (0x2)
            #define I2C_STAT_MSTPENDING (0x1)
            #define I2C_STAT_MSTSTATE (0xe)
            #define I2C_STAT_MSTST_IDLE (0x0)
            #define I2C_STAT_MSTST_RX (0x2)
            #define I2C_STAT_MSTST_TX (0x4)
            #define I2C_STAT_MSTST_NACK_ADDR (0x6)
            #define I2C_STAT_MSTST_NACK_TX (0x8)
            #define I2C_STAT_SLVPENDING (0x100)
            #define I2C_STAT_SLVSTATE (0x600)
            #define I2C_STAT_SLVST_ADDR (0x000)
            #define I2C_STAT_SLVST_RX (0x200)
            #define I2C_STAT_SLVST_TX (0x400)
            #define I2C_MSTCTL_MSTCONTINUE (0x1)
            #define I2C_MSTCTL_MSTSTART (0x2)
            #define I2C_MSTCTL_MSTSTOP (0x4)
            #define I2C_SLVCTL_SLVCONTINUE (0x1)
            #define I2C_SLVCTL_SLVNACK (0x2)
@ ------------------------------------------------------------------------------------
waiti2c:        LDR R0,[R3,IICSTAT]
                LSRS R1,R0,#1
                BCC.n waiti2c
                BX LR
@ ------------------------------------------------------------------------------------
writei2c:       PUSH {R2-R5,LR}                             @ address in R1
                MOVS R4,R0                                  @ data in R0
                MOVS R5,R1
                LDR R3,=LPC_I2C_BASE
                MOVS R0,I2C_CFG_MSTEN
                STR R0,[R3,IICCFG]
                BL waiti2c                                  @ wait for idle
                ANDS R0,R0,#I2C_STAT_MSTSTATE
                BNE.n i2cabort
                LSLS R0,R5,#1                               @ address with RW=0
                STR R0,[R3,IICMSTDAT]
                MOVS R0,#I2C_MSTCTL_MSTSTART                @ send start
                STR R0,[R3,IICMSTCTL]
                BL waiti2c                                  @ wait for idle
                ANDS R0,R0,#I2C_STAT_MSTSTATE
                CMP R0,#I2C_STAT_MSTST_TX
                BNE.N i2cabort
                ANDS R0,R0,#I2C_STAT_MSTSTATE
                STR R4,[R3,IICMSTDAT]                           @ send data
                MOVS R0,#I2C_MSTCTL_MSTCONTINUE             @ continue
                STR R0,[R3,IICMSTCTL]
                BL waiti2c                                  @ wait for completion
                ANDS R0,R0,#I2C_STAT_MSTSTATE
                CMP R0,#I2C_STAT_MSTST_TX
                BNE.N i2cabort
                MOVS R0,#I2C_MSTCTL_MSTSTOP                 @ send STOP
                STR R0,[R3,IICMSTCTL]
                BL waiti2c                                  @ wait for completion
                ANDS R0,R0,#I2C_STAT_MSTSTATE
                BNE.n i2cabort
                POP {R2-R5,PC}

i2cabort:       MVNS R0,#0
                POP {R2-R5,PC}
@ ------------------------------------------------------------------------------------
readi2c:        PUSH {R2-R5,LR}                             @ address in R1
                MOVS R4,R1                                  @ returns 16 bits of data in R0
                LDR R3,=LPC_I2C_BASE
                MOVS R0,I2C_CFG_MSTEN
                STR R0,[R3,IICCFG]
                BL waiti2c
                ANDS R0,R0,#I2C_STAT_MSTSTATE
                BNE.n i2cabort
                LSLS R0,R4,#1
                ADDS R0,R0,#1                               @ RW set for read
                STR R0,[R3,IICMSTDAT]
                MOVS R0,#I2C_MSTCTL_MSTSTART
                STR R0,[R3,IICMSTCTL]                           @ send START
                BL waiti2c                                  @ wait for completion
                ANDS R0,R0,#I2C_STAT_MSTSTATE
                CMP R0,#I2C_STAT_MSTST_RX
                BNE.N i2cabort
                LDR R4,[R3,IICMSTDAT]                           @ read data
                MOVS R0,#I2C_MSTCTL_MSTCONTINUE             @ continue
                STR R0,[R3,IICMSTCTL]
                BL waiti2c                                  @ wait for completion
                ANDS R0,R0,#I2C_STAT_MSTSTATE
                CMP R0,#I2C_STAT_MSTST_RX
                BNE.N i2cabort
                LDR R0,[R3,IICMSTDAT]                           @ load data
                ADDS R4,R0,R4,LSL #8
                MOVS R0,#I2C_MSTCTL_MSTSTOP                 @ send STOP
                STR R0,[R3,IICMSTCTL]
                BL waiti2c                                  @ wait for completion
                ANDS R0,R0,#I2C_STAT_MSTSTATE
                BNE.n i2cabort
                MOVS R0,R4
                POP {R2-R5,PC}
@ ------------------------------------------------------------------------------------


Which pins are you using for your I2C outputs? I think that that may be your problem,
0 Kudos
Reply

967 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by HammingBird on Tue Apr 05 05:01:59 MST 2016
Hallo lanB,
Yes, the program from the user manual (table 309).  if possible,  I would like to see your prog in details explanation.

Could you please upload your prog ?


Thanks
0 Kudos
Reply

967 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by IanB on Mon Apr 04 13:57:55 MST 2016
Did you try the program from the user manual (table 309)? I've just used I2C on the LPC15xx (and the 15xx shares its peripherals with the 8xx) and it worked.

Your program assigns the I2C functions to pins PIO0_3 and PIO0_4 whereas they are conventionally on pins PIO0_10 and PIO0_11 which have proper open-drain structures.
0 Kudos
Reply