Hi,
I am trying to read accelerometer MMA8652FC (www.farnell.com/.../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: s9.postimg.org/.../bendrasgeras.png
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 #include // 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--) { } } }
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 #include // 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--) { } } }
Your code looks quite familiar, I would suggest you to use the source code of 'John Linq, 11-Jul-2014 03:44 GMT' in the below thread as a beginning.
http://www.keil.com/forum/58249/
Thanks mate, helped a lot, finally got some data from me accelerometer. Superb