Hi,
I am working on MCB2300(LPC2387). I have used its sample code for Temperature sensing using I2C and its working fine. Now I have connected EEPROM (AT24C02) with microcontroller to store some data. For that I have used same code and did some changes to write and read data from EEPROM. But its not working properly. Below is changes which I have done.
int main (void) { DWORD i; if ( I2CInit( (DWORD)I2CMASTER ) == FALSE ) /* initialize I2c */ { while ( 1 ); /* Fatal error */ } /* Configure temp register before reading */ for ( i = 0; i < BUFSIZE; i++ ) /* clear buffer */ { I2CMasterBuffer[i] = 0; } I2CWriteLength = 3; I2CReadLength = 0; I2CMasterBuffer[0] = 0xA0; I2CMasterBuffer[1] = 0x00; I2CMasterBuffer[2] = 0x10; /* configuration value, no change from default */ I2CCmd = LM75_CONFIG; I2CEngine(); for ( i = 0; i < BUFSIZE; i++ ) /* clear buffer */ { I2CMasterBuffer[i] = 0; } I2CWriteLength = 2; I2CReadLength = 1; I2CMasterBuffer[0] = 0xA1; I2CMasterBuffer[1] = 0x00; I2CCmd = 0xA0; I2CEngine(); }
Suggest me where I have done mistake. any link of tutorial for R/W data using LPC2387 will be appreciated. Hope for best solution.
Thanks Dhaval
"But its not working properly."
I think if you change your code, it will work properly.
Based on my experience of LPC2368 with AT24LC64, you need to re-write the Interrupt Handler of I2C.
void I2C0MasterHandler(void) __irq { BYTE StatValue; /* this handler deals with master read and master write only */ StatValue = I20STAT; // App should clear buffer, not ISR. switch ( StatValue ) { case 0x08: // Master Transmitter mode; Master Receiver mode; // A START condition has been transmitted. break; case 0x10: // Master Transmitter mode; Master Receiver mode; // A repeated START condition has been transmitted. break; case 0x18: // Master Transmitter mode; // SLA+W has been transmitted; ACK has been received. break; case 0x28: // Master Transmitter mode; // Data byte in I2DAT has been transmitted; ACK has been received. if (!Dummy_Write) { if ( DatBuf_Idx < I2C_BUFSIZE ) { DatBuf_Idx++; } else { DatBuf_Idx = 0; } } else { } break; case 0x40: // Master Receiver mode; // SLA+R has been transmitted; ACK has been received. break; case 0x50: // Master Receiver mode; // Data byte has been received; ACK has been returned. DatBuf_Idx++; if ( DatBuf_Idx >= (I2C_BUFSIZE-1) ) { } break; case 0x58: // Master Receiver mode; // Data byte has been received; NOT ACK has been returned. break; /* Do NOT need-want to Handle. */ case 0x20: // Master Transmitter mode; case 0x30: // Master Transmitter mode; case 0x38: // Master Transmitter mode; Master Receiver mode; case 0x48: // Master Receiver mode; default: I2CMasterState = DATA_ERROR; I20CONCLR = I2CONCLR_SIC; break; } VICVectAddr = 0; /* Acknowledge Interrupt */ }
ics.nxp.com/.../lpc17xx.cmsis.driver.library.zip
Download the above driver library, it is for LPC17xx, but the I2C controller supposed to be similar.
Now, NXP provides more I2C examples, including:
/***********************************************************************//** * @file pca8581_test.c * @purpose An example of I2C using polling mode to test the I2C driver. * Using EEPROM PCA8581 to transfer a number of data byte. * @version 2.0 * @date 21. May. 2010 * @author NXP MCU SW Application Team *---------------------------------------------------------------------
The path: lpc17xx.cmsis.driver.library\LPC1700CMSIS\Examples\I2C\pca8581_polling
"void I2C0MasterHandler(void) __irq"
that's the worst aspect of the lpc i2c engine.
it runs off a series of "states", rather than a series of tasks (i2c_start, i2c_send, i2c_read, i2c_stop, etc.).
not sure why nxp decided to do it that way.
Sounds similar to the STM32's I2C...
"Sounds similar to the STM32's I2C..."
maybe you are looking at different stm32s, :)
here is from the st library for stm32:
void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct); void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState); void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState); void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState); void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction); void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data); uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);
does it look like they are even remotely similar to the lpc code?