Trying to read accelerometer with LPC1115 via I2C

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

Trying to read accelerometer with LPC1115 via I2C

1,048 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by audriusmerfeldas on Wed Jan 06 04:17:00 MST 2016
Hi,

I am trying to read accelerometer MMA8652FC (http://www.farnell.com/datasheets/1908998.pdf) with LPC1115 LPCxpresso board, but I can't get any results.

Default device address (accelerometer): 0x1D

I have checked with scope and thats what I am getting on SDA and SCL:
[img]http://s9.postimg.org/5kr4d96bz/bendrasgeras.png[/img]

As I have checked all data need to be send to accelerometer is send from LPC1115, but it looks that LPC do not wait for 8 bits from accelerometer..

Please help.

Here is me code:

#include "LPC11xx.h"                        /* LPC11xx definitions */
#include "gpio.h"
#include <cr_section_macros.h>
#include <NXP/crp.h>

// Variable to store CRP value in. Will be placed automatically
// by the linker when "Enable Code Read Protect" selected.
// See crp.h header for more information
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;

#define I2C_I2CONSET_AA                         ((0x04))
#define I2C_I2CONSET_SI                         ((0x08))
#define I2C_I2CONSET_STO                        ((0x10))
#define I2C_I2CONSET_STA                        ((0x20))
#define I2C_I2CONSET_I2EN                       ((0x40))

#define I2C_I2CONCLR_AAC                        ((1<<2))
#define I2C_I2CONCLR_SIC                        ((1<<3))
#define I2C_I2CONCLR_STOC                       ((1<<4))
#define I2C_I2CONCLR_STAC                       ((1<<5))
#define I2C_I2CONCLR_I2ENC                      ((1<<6))

#define I2C_STAT_CODE_BITMASK                                   ((0xF8))

#define I2C_I2STAT_M_TX_START                                   ((0x08))
#define I2C_I2STAT_M_TX_RESTART                                 ((0x10))
#define I2C_I2STAT_M_TX_SLAW_ACK                                ((0x18))
#define I2C_I2STAT_M_TX_SLAW_NACK                               ((0x20))
#define I2C_I2STAT_M_TX_DAT_ACK                                 ((0x28))
#define I2C_I2STAT_M_TX_DAT_NACK                                ((0x30))
#define I2C_I2STAT_M_TX_ARB_LOST                                ((0x38))

#define I2C_I2STAT_M_RX_START                                   ((0x08))
#define I2C_I2STAT_M_RX_RESTART                                 ((0x10))
#define I2C_I2STAT_M_RX_SLAR_ACK                                ((0x40))
#define I2C_I2STAT_M_RX_SLAR_NACK                               ((0x48))
#define I2C_I2STAT_M_RX_DAT_ACK                                 ((0x50))
#define I2C_I2STAT_M_RX_DAT_NACK                                ((0x58))

#define I2C_I2DAT_BITMASK                       ((0xFF))


int delay;

//void I2C_Init( LPC_I2C_TypeDef *I2Cx, uint32_t clockrate );
void I2C_Init(void)
{
        LPC_SYSCON->PRESETCTRL |= (1<<1);      //De-Asserts Reset Signal to I2C
        LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5);   //Enable I2C Clock

        LPC_IOCON->PIO0_4 &= ~0x3F;
        LPC_IOCON->PIO0_4 |= 0x01;   //SCL

        LPC_IOCON->PIO0_5 &= ~0x3F;
        LPC_IOCON->PIO0_5 |= 0x01;   //SDA

        LPC_I2C->SCLH = 360;         //I2PCLK is 72MHz
        LPC_I2C->SCLL = 360;         //I2PCLK is 72MHz

        LPC_I2C->CONCLR = 0xFF;        //Clear All Flags
        LPC_I2C->CONSET = (1<<6);      //I2C Interface Enable
}

uint32_t I2C_Start(void)
{
    LPC_I2C->CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;
    LPC_I2C->CONSET = I2C_I2CONSET_STA;
    while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI));
    return (LPC_I2C->STAT & I2C_STAT_CODE_BITMASK);
}
void I2C_Stop(void)
{
    LPC_I2C->CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;
    LPC_I2C->CONSET = I2C_I2CONSET_STO;
    while (LPC_I2C->CONSET & I2C_I2CONSET_STO);
}
uint32_t I2C_Write(unsigned char data)
{
    LPC_I2C->DAT = data;
    LPC_I2C->CONCLR = I2C_I2CONCLR_SIC;
    while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI));
    return (LPC_I2C->STAT & I2C_STAT_CODE_BITMASK);
}
unsigned char Slave_Read(void)
{
    uint8_t result;

    if ( I2C_Start() == I2C_I2STAT_M_TX_START )
    {
        LPC_I2C->CONCLR = I2C_I2CONCLR_STAC;
      //  if ( I2C_Write(Address) == I2C_I2STAT_M_TX_SLAW_ACK )
       // {
        //    if ( I2C_Start() == I2C_I2STAT_M_TX_RESTART )
        //    {
                if ( I2C_Write( 0x3A ) == I2C_I2STAT_M_RX_SLAR_ACK ) //device address with write bit
                {
                    LPC_I2C->CONCLR = I2C_I2CONCLR_AAC;
                    LPC_I2C->CONCLR = I2C_I2CONCLR_SIC;
                    while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI));
                }
                if ( I2C_Write( 0x01 ) == I2C_I2STAT_M_RX_SLAR_ACK ) //register address
                {
                    LPC_I2C->CONCLR = I2C_I2CONCLR_AAC;
                    LPC_I2C->CONCLR = I2C_I2CONCLR_SIC;
                    while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI));
                }
                I2C_Start();
                if ( I2C_Write( 0x3B ) == I2C_I2STAT_M_RX_SLAR_ACK ) //device address with read bit
                {
                LPC_I2C->CONCLR = I2C_I2CONCLR_AAC;
                LPC_I2C->CONCLR = I2C_I2CONCLR_SIC;
                while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI));
                result = (uint8_t)(LPC_I2C->DAT & I2C_I2DAT_BITMASK);

                I2C_Stop();
                return result;
            //    }



           // }
        }
    }

    I2C_Stop();
    return 0xE8;
}


int main(void)
{
    volatile uint8_t result;

    //I2C_Init( LPC_I2C, 100000 );
    I2C_Init();

    while(1)
    {
        result = Slave_Read();
        /* Check result */
        for (delay=1000; delay>0 ; delay--)
                              {

                              }
    }
}
Labels (1)
0 Kudos
Reply
2 Replies

838 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by audriusmerfeldas on Mon Jan 11 23:07:55 MST 2016
Finally got it working. There were problems with I2C states
0 Kudos
Reply

838 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by audriusmerfeldas on Sat Jan 09 12:52:24 MST 2016
After debugging I have change me code a little bit, now looks like lpc gets ACK from sensor, but now I am facing problem when I am sendingslave address with read bit after line " LPC_I2C->CONCLR = I2C_I2CONCLR_SIC;" I2C state changes to 0x08 (A START condition has been transmitted), while it should be 0x48 (Slave address + read has been transmitted, NOT ACK has been received.)

Any ideas?

#include "LPC11xx.h"                        /* LPC11xx definitions */
#include "gpio.h"
#include <cr_section_macros.h>
#include <NXP/crp.h>

// Variable to store CRP value in. Will be placed automatically
// by the linker when "Enable Code Read Protect" selected.
// See crp.h header for more information
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;

#define I2C_I2CONSET_AA                         ((0x04))
#define I2C_I2CONSET_SI                         ((0x08))
#define I2C_I2CONSET_STO                        ((0x10))
#define I2C_I2CONSET_STA                        ((0x20))
#define I2C_I2CONSET_I2EN                       ((0x40))

#define I2C_I2CONCLR_AAC                        ((1<<2))
#define I2C_I2CONCLR_SIC                        ((1<<3))
#define I2C_I2CONCLR_STOC                       ((1<<4))
#define I2C_I2CONCLR_STAC                       ((1<<5))
#define I2C_I2CONCLR_I2ENC                      ((1<<6))

#define I2C_STAT_CODE_BITMASK                                   ((0xF8))

#define I2C_I2STAT_M_TX_START                                   ((0x08))
#define I2C_I2STAT_M_TX_RESTART                                 ((0x10))
#define I2C_I2STAT_M_TX_SLAW_ACK                                ((0x18))
#define I2C_I2STAT_M_TX_SLAW_NACK                               ((0x20))
#define I2C_I2STAT_M_TX_DAT_ACK                                 ((0x28))
#define I2C_I2STAT_M_TX_DAT_NACK                                ((0x30))
#define I2C_I2STAT_M_TX_ARB_LOST                                ((0x38))

#define I2C_I2STAT_M_RX_START                                   ((0x08))
#define I2C_I2STAT_M_RX_RESTART                                 ((0x10))
#define I2C_I2STAT_M_RX_SLAR_ACK                                ((0x40))
#define I2C_I2STAT_M_RX_SLAR_NACK                               ((0x48))
#define I2C_I2STAT_M_RX_DAT_ACK                                 ((0x50))
#define I2C_I2STAT_M_RX_DAT_NACK                                ((0x58))

#define I2C_I2DAT_BITMASK                       ((0xFF))


int delay;

//void I2C_Init( LPC_I2C_TypeDef *I2Cx, uint32_t clockrate );
void I2C_Init(void)
{
        LPC_SYSCON->PRESETCTRL |= (1<<1);      //De-Asserts Reset Signal to I2C
        LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5);   //Enable I2C Clock

        LPC_IOCON->PIO0_4 &= ~0x3F;
        LPC_IOCON->PIO0_4 |= 0x01;   //SCL

        LPC_IOCON->PIO0_5 &= ~0x3F;
        LPC_IOCON->PIO0_5 |= 0x01;   //SDA

        LPC_I2C->SCLH = 360;         //I2PCLK is 72MHz
        LPC_I2C->SCLL = 360;         //I2PCLK is 72MHz

        LPC_I2C->CONCLR = 0xFF;        //Clear All Flags
        LPC_I2C->CONSET = (1<<6);      //I2C Interface Enable
}

uint32_t I2C_Start(void)
{
    LPC_I2C->CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;
    LPC_I2C->CONSET = I2C_I2CONSET_STA;
    while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI));
    return (LPC_I2C->STAT & I2C_STAT_CODE_BITMASK);
}
void I2C_Stop(void)
{
    LPC_I2C->CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;
    LPC_I2C->CONSET = I2C_I2CONSET_STO;
    while (LPC_I2C->CONSET & I2C_I2CONSET_STO);
}
uint32_t I2C_Write(unsigned char data)
{
    LPC_I2C->DAT = data;
    LPC_I2C->CONCLR = I2C_I2CONCLR_SIC;
    while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI));
    return (LPC_I2C->STAT & I2C_STAT_CODE_BITMASK);
}
unsigned char Slave_Read(void)
{
    uint8_t result,res1,res2,res3,res4,res5;
res1=0; res2=0; res3=0; res4=0; res5=0;
    if ( I2C_Start() == I2C_I2STAT_M_TX_START )
    {
    res1=(LPC_I2C->STAT & I2C_STAT_CODE_BITMASK);
        LPC_I2C->CONCLR = I2C_I2CONCLR_STAC;


                if ( I2C_Write( 0x3A ) == 0x18 ) //device address with write bit
                {
                res2=(LPC_I2C->STAT & I2C_STAT_CODE_BITMASK);
                    LPC_I2C->CONCLR = I2C_I2CONCLR_AAC;
                    LPC_I2C->CONCLR = I2C_I2CONCLR_SIC;
                    while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI));
                }
                if ( I2C_Write( 0x0D ) == 0x28 ) //register address
                {

                res3=(LPC_I2C->STAT & I2C_STAT_CODE_BITMASK);
                LPC_I2C->CONCLR = I2C_I2CONCLR_AAC;
                    LPC_I2C->CONCLR = I2C_I2CONCLR_SIC;
                    while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI));
                }
                if ( I2C_Start() == 0x10 ) {
                
                if ( I2C_Write( 0x3B ) == 0x40 ) //SLA+R has been transmitted; ACK has been received
                {
                LPC_I2C->CONSET = 0x04;//I2C_I2CONCLR_AAC;
                LPC_I2C->CONCLR = I2C_I2CONCLR_SIC;

                while (!(LPC_I2C->CONSET & I2C_I2CONSET_SI));
                result = (uint8_t)(LPC_I2C->DAT & I2C_I2DAT_BITMASK);

                I2C_Stop();
                return result;
                }



           // }
        }
    }

    I2C_Stop();
    return 0xE8;
}


int main(void)
{
    volatile uint8_t result;

    //I2C_Init( LPC_I2C, 100000 );
    I2C_Init();

    while(1)
    {
        result = Slave_Read();
        /* Check result */
        for (delay=1000; delay>0 ; delay--)
                              {

                              }
    }
}
0 Kudos
Reply