#define EEPROM_ADDR 0xA0 int main(void) { int f; I2CInit(I2CMASTER); // Write the byte 0xFD into location zero in the EEPROM I2CWriteLength = 4; I2CReadLength = 0; I2CMasterBuffer[0] = EEPROM_ADDR; I2CMasterBuffer[1] = 0x00;// 2 byte address zero I2CMasterBuffer[2] = 0x00; I2CMasterBuffer[3] = 0xFD; I2CEngine(); // And read it back, should appear at IC2MasterBuffer[3 + 2] ...? I2CWriteLength = 3; I2CReadLength = 1; I2CMasterBuffer[0] = EEPROM_ADDR; I2CMasterBuffer[1] = 0x00;// 2 byte address zero I2CMasterBuffer[2] = 0x00; I2CMasterBuffer[3] = EEPROM_ADDR | RD_BIT; I2CEngine(); return 0 ; } |
Hello everyone,
I'm migrating my project to ARM, LPC1343 and I'm having difficulties with I2C, I did the initialization but when it gets to the line LPC_I2C->CONSET = (1 << 5); // STA the MCU stops, I put a serial debug to check as follows
sprintf(string, "CONSET STA INIT - VALUE: %04X\r\nSTAT REG: %04X\r\n", LPC_I2C->CONSET, LPC_I2C->STAT);
uart_enviar(string);
LPC_I2C->CONSET = (1 << 5); // STA
sprintf(string, "CONSET STA OK - VALUE: %04X\r\nSTAT REG: %04X\r\n", LPC_I2C->CONSET, LPC_I2C->STAT);
uart_send(string);
the second uart is not executed
see the monitor
CONSET 0040
STAT 00F8
I2C START
CONSET STA INIT - VALUE: 0040
STAT REG: 00F8
should appear next CONSET STA OK
this is the I2C initialization
uint32_t I2CInit( uint32_t I2cMode ) {
test(16);
LPC_SYSCON->PRESETCTRL |= (0x1<<1);
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5);
LPC_IOCON->PIO0_4 &= ~0x3F; /* I2C I/O config */
LPC_IOCON->PIO0_4 |= 0x01; /* I2C SCL */
LPC_IOCON->PIO0_5 &= ~0x3F;
LPC_IOCON->PIO0_5 |= 0x01; /* I2C SDA */
/*--- Clear flags ---*/
test(17);
LPC_I2C->CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;
/*--- Reset registers ---*/
test(18);
#if FAST_MODE_PLUS
test(19);
LPC_IOCON->PIO0_4 |= (0x2<<8);
LPC_IOCON->PIO0_5 |= (0x2<<8);
LPC_I2C->SCLL = I2SCLL_HS_SCLL;
LPC_I2C->SCLH = I2SCLH_HS_SCLH;
test(20);
#else
test(21);
LPC_I2C->SCLL = I2SCLL_SCLL;
LPC_I2C->SCLH = I2SCLH_SCLH;
test(22);
#endif
The clock is at 72Mhz
What is missing?
uint8_t write_register(uint8_t i2cReg, uint8_t i2cData) { i2cWriteLength = 3; i2cReadLength = 0; i2cWriteBuffer[0] = i2cSlaveAddr; i2cWriteBuffer[1] = i2cReg; i2cWriteBuffer[2] = i2cData; return (I2CEngine(i2cWriteBuffer, &i2cWriteLength, i2cReadBuffer, &i2cReadLength) == I2CSTATE_ACK); } uint8_t read_registers(uint8_t i2cReg, uint8_t *buffer, uint8_t length) { i2cWriteLength = 2; i2cReadLength = length; i2cWriteBuffer[0] = i2cSlaveAddr; i2cWriteBuffer[1] = i2cReg; i2cWriteBuffer[2] = i2cSlaveAddr | RD_BIT; return I2CEngine(i2cWriteBuffer, &i2cWriteLength, buffer, &length); } |
write_register(0x2c, 0x00); write_register(0x2d, 0x01); write_register(0x2e, 0x01); write_register(0x2a, 0x11); /* 200 Hz sampling rate */ |
uint16_t sensorData[3]; for(i=0; i<3; i++) { read_registers(0, i2cReadBuffer, 7); if(i2cReadBuffer[0]) break; } if(i2cReadBuffer[0] & 1) sensorData[0] = (i2cReadBuffer[1] << 8) | i2cReadBuffer[2]; else sensorXErr++; if(i2cReadBuffer[0] & 2) sensorData[1] = (i2cReadBuffer[3] << 8) | i2cReadBuffer[4]; else sensorYErr++; if(i2cReadBuffer[0] & 4) sensorData[2] = (i2cReadBuffer[5] << 8) | i2cReadBuffer[6]; else sensorZErr++; |
The Master (or MCU) transmits a start condition (ST) to the MMA8453Q, slave address ($1D), with the R/W bit set to “0” for a write, and the MMA8453Q sends an acknowledgement. Then the Master (or MCU) transmits the address of the register to read and the MMA8453Q sends an acknowledgement. The Master (or MCU) transmits a [B]repeated start condition[/B] (SR) and then addresses the MMA8453Q ($1D) with the R/W bit set to “1” for a read from the previously selected register. The Slave then acknowledges and transmits the data from the requested register. The Master does not acknowledge (NAK) the transmitted data, but transmits a stop condition to end the data transfer. |