LPC1769 I2C1 + EEPROM 24LC64 - LPCXpresso LPC1769 Rev.D board

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi all,
I need to use EEPROM memory Microchip 24LC64 (64 kb/8 kB) built-in in LPCXpresso LPC17659 Rev. D PC board for storage some settings data when power is turned off.
This EEPROM memory is connected to the I2C number 1 (I2C1) of the LPC1769 microcontroller on the LPCXpresso Rev. D PC board. Memory is not Write Protected (WP pin is connected to the GND) and the EEPROM device address is 0 (binary 000 - pins A2, A1 and A0 are connected to the GND).
I wrote some start C code to run I2C1 interface but there is no response from the EEPROM memory.
I read the I2STAT of I2C1 interface and it gave me 0xF8 value - it means some miscellaneous state: no revelant information is available because the serial interrupt flag, SI, is not yet set.
I connected oscilloscopes' probes to theEEPROM pins SCL and SDA and I run my simpy C code but thereare no changes on the lines - all the time both are in high level.
Below I send my simply C code for I2C1:
void I2C1_Init_100kHz (void)
{
LPC_SC->PCONP |= (1<<19); // Turn on power for I2C1LPC_PINCON->PINSEL1 |= (1<<6); // Set pin P0.19 as SDA1 I2C1
LPC_PINCON->PINSEL1 |= (1<<7); // Set pin P0.19 as SDA1 I2C1
LPC_PINCON->PINSEL1 |= (1<<8); // Set pin P0.20 as SCL1 I2C1
LPC_PINCON->PINSEL1 |= (1<<9); // Set pin P0.20 as SCL1 I2C1LPC_SC->PCLKSEL1 |= (1<<6); // Turn on clock signal for I2C1; bits 6 i 7
LPC_SC->PCLKSEL1 &=~(1<<7); // Turn on clock signal for I2C1; bits 6 i 7
/* values: 00 - PCLK I2C1 = CCLK/4
* 01 - PCLK I2C1 = CCLK
* 10 - PCLK I2C1 = CCLK/2
* 11 - PCLK I2C1 = CCLK/8
* where: x - MSb (e.g. PCLK_I2C1 it bit 7)
* x - LSb (e.g. PCLK_I2C1 is bit 6)
* CCLK - Core CLK = 100 MHz -> PCLK I2C1 = 100 MHz/1 = 100 MHz
*/// Set 100 kHz I2C1 frequency with 50 % of Duty Cycle
LPC_I2C1->I2SCLH = 500; // High register of Duty Cycles number
LPC_I2C1->I2SCLL = 500; // Low register of Duty Cycles numberLPC_I2C1->I2CONCLR |= ( (1<<2) | (1<<5) | (1<<6) ); // Clear all bits: 2 - (AAC) Assert Acknowledge bit
// 3 - (SIC) I2C Interrupt bit
// 4 - bit is reserved (do not write to this bit)
// 5 - (STAC) Start Flag bit
// 6 - (I2CENC) I2C Interface Disable bit// Do a dummy byte transmit - just for test the I2C1 signals (SCL1 and SDA1) with oscilloscope
LPC_I2C1->I2CONSET |= (1<<6); // Turn on the I2C1 interface; set bit 6 - I2C1 Enable bit to 1
Timer0_MicroSeconds (10000); // Time delay - 100 usLPC_I2C1->I2CONSET |= (1<<5); // START condition is send; set bit 5 - I2C1 STA bit to 1
LPC_I2C1->I2CONCLR |= (1<<3); // Clear the I2C Interrupt bit; clear bit 3 - I2C1 SICLPC_I2C1->I2DAT = 0xA0; // Send control byte: 0xA0 = 1010 0000 => 1010 - Control Code
// 000 - Chip Select bits (Device Address)
// 0 - Read or notWrite (1: Read; 0: Write)
// Wait for complete data sending
while ( !( LPC_I2C0->I2CONSET & (1<<3) ) );
LPC_I2C0->I2CONCLR |= (1<<5); // Clear the STAC bit - clear START condition bit
}
Do you have any idea what is wrong with my code?
I will be very helpful for help.


- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Please check the below thread and let me know if this helps,
Onboard I2C 24LC64 EEPROM on LPCXpresso1769 | www.LPCware.com
Have a great day,
Sol
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi there,
I studied the LPC1769 User Manual (UM 10360), Microchip 24LC64 datasheet and LPCXpresso LPC1769 Rev.D schematic.
I wrote C code to make a simply transmission with EEPROM memory (write one byte and read one byte).
For write one byte value to the EEPROM memory I send bytes via I2C as follows:
1. I2C START CONDITION (it is not a byte)
2. 0xA0 (Control Byte + Write bit: 1010 0000)
3. 0x00 (Byte Address High Byte - MSB: 0000 0000)
4. 0x00 (Byte Address Low Byte - LSB: 0000 0000)
5. 0xAA (Data byte value: 1010 1010)
6. I2C STOP CONDITION (it is not a byte)
and I get I2C Status Register values after each byte:
1. 0x08 (START CONDITION has been sent)
2. 0x18 (Slave Address and Write bit has been sent - Control Byte + Write bit)
3. 0x28 (Data in I2DAT has been transmitted - Byte Address High Byte - MSB)
4. 0x28 (Data in I2DAT has been transmitted - Byte Address Low Byte - LSB)
5. 0x28 (Data in I2DAT has been transmitted - Data byte value)
The oscilloscope screen shows that the signals SDA and SCL and their values in time are proper.
For read one byte value from the EEPROM memory I send bytes via I2C as follows:
1. I2C START CONDITION (it is not a byte)
2. 0xA0 (Control Byte + Write bit: 1010 0000)
3. 0x00 (Byte Address High Byte - MSB: 0000 0000)
4. 0x00 (Byte Address Low Byte - LSB: 0000 0000)
5. I2C START CONDITION (it is not a byte)
5. 0xA1 (Control Byte + Read bit: 1010 0001)
-- Here I get/read byte from I2DAT register
6. I2C STOP CONDITION (it is not a byte)
and I get I2C Status Register values after each byte:
1. 0x08 (START CONDITION has been sent)
2. 0x18 (Data in I2DAT has been transmitted - Byte Address High Byte - MSB)
3. 0x28 (Data in I2DAT has been transmitted - Byte Address High Byte - LSB)
4. 0x08 (START CONDITION has been sent)
5. 0x40 (Slave Addres and Read bit has been sent - Control Byte + Read bit)
6. 0x58 (Data byte value has been received)
The oscilloscope screens show that there is some problem with signals SDA and SCL and their values in time are unproper
and the read data byte value from I2DAT register is 0xFF - one step before I wrote there data byte value 0xAA.
So something is wrong.
Below I send the oscilloscope screens (first write one byte, second read one byte).
Write data byte value to the EEPROM memory - oscilloscope screen:
Read data byte value from the EEPROM memory - oscilloscope screen:
Read data byte value from the EEPROM memory - oscilloscope screen and small analyze:
It seems that LSB memory address byte is lost or something... and then the read sequence is broken.
But the I2C Status Register values reding is proper - wondering thing.
Below I send my C code:
// Header files to internal CMSIS libraries
#include "LPC17xx.h"
#include <cr_section_macros.h>
#include <NXP/crp.h>
#include "timerbasic.h" // Header file for Timers and time delays
#include "uartbasic.h" // Header file for UARTs
void I2C1_Init_100kHz (void); // Initialize I2C1 interface
void I2C1_StartCondition (void); // Send START condition
void I2C1_StopCondition (void); // Send STOP condition
void I2C1_IRQHandler (void); // I2C1 interrupt routine for I2C service routine
#define I2C_Clear_AllBitsDisableI2C 0x6C // LPC_I2C1->I2CONCLR -> 0110 1100; clear bits: AAC (Acknowledge), SIC (I2C Interrupt), STAC (Start Flag), I2ENC (I2C Interface Disable)
#define I2C_Clear_I2CInterrupt 0x08 // LPC_I2C1->I2CONCLR -> 0000 1000; clear bit: SIC (I2C Interrupt)
#define I2C_Clear_StartCondition 0x20 // LPC_I2C1->I2CONCLR -> 0010 0000; clear bit: STAC (Start Flag)
#define I2C_Set_EnableI2C 0x40 // LPC_I2C1->I2CONSET -> 0100 0000; set bits: I2EN (I2C Interface Enable )
#define I2C_Set_StartCondition 0x20 // LPC_I2C1->I2CONSET -> 0010 0000; set bit: STA (Start Flag)
#define I2C_Set_StopCondition 0x10 // LPC_I2C1->I2CONSET -> 0001 0000; set bits: AAC (Assert Acknowledge), STO (Stop Flag)
__CRP const unsigned int CRP_WORD = CRP_NO_CRP; // CRP - Code Read Protection
uint8_t i = 0; // Auxilary variable for counting bytes in the IC21 Interrupt routine
uint8_t I2C_CountOfDataBytesToWrite = 4; // I2C count of sent bytes
uint8_t I2C_CountOfDataBytesToRead = 4; // I2C count of received bytes
uint8_t Tab_I2CDataWrite [32]; // I2C write data byte table
uint8_t Tab_I2CDataRead [32]; // I2C read data byte table
uint8_t ControlByteConstant = 0xA0; // I2C EEPROM constant Control Byte
uint16_t EEPROM_ByteAddress = 0x00; // EEPROM byte (to write or or read) address
uint8_t EEPROM_ByteValue = 0xAA; // EEPROM byte (to write) address
uint8_t EEPROM_ControlByte_Write = 0x00; // EEPROM 24LC64 first byte - control byte: with WRITE bit flag
uint8_t EEPROM_ControlByte_Read = 0x00; // EEPROM 24LC64 first byte - control byte: with READ bit flag
uint8_t I2C_EEPROM_Address = 0x00; // Hardware EEPROM I2C address from 0 to 7
uint8_t I2C_RW_Bit_Write = 0x00; // Write to the EEPROM memory bit flag
uint8_t I2C_RW_Bit_Read = 0x01; // Read from the EEPROM memory bit flag
uint8_t EEPROM_Write_notRead_Mode = 0x00; // Settings flag - EEPROM Write or Read data byte value
uint8_t EEPROM_WriteDoneFlag = 0x00; // Global flag - EEPROM Write done
uint8_t EEPROM_ReadDoneFlag = 0x00; // Global flag - EEPROM Read done
// Main program
int main (void)
{
UART0_Init (); // UART0 init - PC communication via USB-UART converter FTDI FT232RL chip
UART0_Bitrate (115200); // UART0 bitrate 115200 bps - PC communication
Timer0_Init (); // Timer0 init - void, Timer for forced time delays
I2C1_Init_100kHz (); // Initialize I2C1 interface with 100 kbps bitrate
// Create the I2C EEPROM Control bytes - for write and for read byte value
EEPROM_ControlByte_Write = (ControlByteConstant | ((I2C_EEPROM_Address & 0x07) << 1) | (I2C_RW_Bit_Write) ); // Create EEPROM Control byte with WRITE bit flag
EEPROM_ControlByte_Read = (ControlByteConstant | ((I2C_EEPROM_Address & 0x07) << 1) | (I2C_RW_Bit_Read ) ); // Create EEPROM Control byte with READ bit flag
// Creating table with data for I2C transmission - WRITE BYTE INTO EEPROM MEMORY
Tab_I2CDataWrite [0] = EEPROM_ControlByte_Write; // EEPROM Control byte (1010 0000) - for EEPROM write mode
Tab_I2CDataWrite [1] = (EEPROM_ByteAddress & 0xFF00) >> 8; // EEPROM MSB Address value
Tab_I2CDataWrite [2] = (EEPROM_ByteAddress & 0x00FF) >> 0; // EEPROM LSB Address value
Tab_I2CDataWrite [3] = EEPROM_ByteValue; // EEPROM Data Byte value
// Creating table with data for I2C transmission - READ BYTE FROM EEPROM MEMORY
Tab_I2CDataRead [0] = EEPROM_ControlByte_Write; // EEPROM Control byte (1010 0000)
Tab_I2CDataRead [1] = (EEPROM_ByteAddress & 0xFF00) >> 8; // EEPROM MSB Address value
Tab_I2CDataRead [2] = (EEPROM_ByteAddress & 0x00FF) >> 0; // EEPROM LSB Address value
Tab_I2CDataRead [3] = EEPROM_ControlByte_Read; // EEPROM Control byte (1010 0001) - for EEPROM read mode
// EEPROM_Write_notRead_Mode = 0x01;
// Send the START CONDITION to I2C1 interface
// I2C1_StartCondition (); // START condition is send; set bit 5 - I2C1 STA bit to 1; Read and Write register
// while (EEPROM_WriteDoneFlag != 0x01)
// EEPROM_WriteDoneFlag = 0x00;
EEPROM_Write_notRead_Mode = 0x00;
// Send the START CONDITION to I2C1 interface
I2C1_StartCondition (); // START condition is send; set bit 5 - I2C1 STA bit to 1; Read and Write register
while (EEPROM_ReadDoneFlag != 0x01)
EEPROM_ReadDoneFlag = 0x00;
//Main "for" loop
for (;;)
{
// do nothing here
// ...
}
return (0);
}
// Initialize I2C1 interface
void I2C1_Init_100kHz (void)
{
LPC_SC->PCONP |= (1<<19); // Turn on power for I2C1
LPC_PINCON->PINSEL1 |= (1<<6); // Set pin P0.19 as SDA1 I2C1
LPC_PINCON->PINSEL1 |= (1<<7); // Set pin P0.19 as SDA1 I2C1
LPC_PINCON->PINSEL1 |= (1<<8); // Set pin P0.20 as SCL1 I2C1
LPC_PINCON->PINSEL1 |= (1<<9); // Set pin P0.20 as SCL1 I2C1
LPC_SC->PCLKSEL1 |= (1<<6); // Turn on clock signal for I2C1; bits 6 i 7
LPC_SC->PCLKSEL1 &=~(1<<7); // Turn on clock signal for I2C1; bits 6 i 7
/* values: 00 - PCLK I2C1 = CCLK/4
* 01 - PCLK I2C1 = CCLK
* 10 - PCLK I2C1 = CCLK/2
* 11 - PCLK I2C1 = CCLK/8
* where: x - MSb (e.g. PCLK_I2C1 it bit 7)
* x - LSb (e.g. PCLK_I2C1 is bit 6)
* CCLK - Core CLK = 100 MHz -> PCLK I2C1 = 100 MHz/1 = 100 MHz
*/
// Set 100 kHz I2C1 frequency with 50 % of Duty Cycle
LPC_I2C1->I2SCLH = 500; // High register of Duty Cycles number; Read and Write register
LPC_I2C1->I2SCLL = 500; // Low register of Duty Cycles number; Read and Write register
LPC_I2C1->I2CONCLR = I2C_Clear_AllBitsDisableI2C; // Write Only register - musn't read this register - do not use "|="
// Clear all bits: 2 - (AAC) Assert Acknowledge bit
// 3 - (SIC) I2C Interrupt bit
// 4 - bit is reserved (do not write to this bit)
// 5 - (STAC) Start Flag bit
// 6 - (I2CENC) I2C Interface Disable bit
NVIC_EnableIRQ (I2C1_IRQn); // Set I2C1 Global Interrupts
LPC_I2C1->I2CONSET = I2C_Set_EnableI2C; // Turn on the I2C1 interface; set bit 6 - I2C1 Enable bit to 1; Read and Write register
Timer0_MicroSeconds (100); // Time delay - 100 us
}
void I2C1_StartCondition (void)
{
LPC_I2C1->I2CONSET = I2C_Set_StartCondition; // START condition is send; set bit 5 - I2C1 STA bit to 1; Read and Write register
LPC_I2C1->I2CONCLR = I2C_Clear_I2CInterrupt; // Write Only register - musn't read this register - do not use "|="
// Clear the I2C Interrupt bit; clear bit 3 - I2C1 SIC;
}
void I2C1_StopCondition (void)
{
LPC_I2C1->I2CONSET = I2C_Set_StopCondition; // STOP condition is send; set bit 4 - I2C STO bit to 1; Read and Write register
}
void I2C1_IRQHandler (void)
{
// Send I2C Status Register value - check and control
UART0_SendByte (LPC_I2C1->I2STAT);
switch (LPC_I2C1->I2STAT)
{
// Transmit START condition
case 0x08: // Now: A START condition has been transmitted
// Next: Slave Address and Write bit will be transmitted; ACK will be received - > next I2STAT value = 0x18
if (i == 0) { LPC_I2C1->I2DAT = Tab_I2CDataWrite [i]; }
if (i != 0) { LPC_I2C1->I2DAT = Tab_I2CDataRead [i]; }
LPC_I2C1->I2CONCLR = I2C_Clear_StartCondition; // Reset the STA bit
LPC_I2C1->I2CONCLR = I2C_Clear_I2CInterrupt; // Reset the SI bit
i++;
break;
// EEPROM Write mode - The first byte
case 0x18: // Now: Slave Address and Write bit (0 value) has been transmitted; ACK has been received
// Next: Data byte will be transmitted; ACK bit will be received - > next I2STAT value = 0x28
LPC_I2C1->I2DAT = 0x00; // Tab_I2CDataWrite [i];
LPC_I2C1->I2CONCLR = I2C_Clear_I2CInterrupt; // Reset the SI bit
i++;
break;
// EEPROM Write mode - Other bytes
case 0x28: // Now: Data byte in I2DAT has been transmitted; ACK has been received
// Next: Data byte will be transmitted; ACK bit will be received
// or: NO I2DAT Action - Repeated START will be transmitted
// or: NO I2DAT Action - STOP condition will be transmitted; STO flag will be reset
LPC_I2C1->I2DAT = 0x00; // Tab_I2CDataWrite [i];
LPC_I2C1->I2CONCLR = I2C_Clear_I2CInterrupt; // Reset the SI bit
// EEPROM Write mode
if (EEPROM_Write_notRead_Mode == 1)
{
if (i >= I2C_CountOfDataBytesToWrite) { i = 0; I2C1_StopCondition (); EEPROM_WriteDoneFlag = 0x01; }
// Send STOP CONDITION when all bytes are sent
i++;
}
// EEPROM Read mode
if (EEPROM_Write_notRead_Mode == 0)
{
i++;
I2C1_StartCondition ();
}
break;
// EEPROM Read mode
// Now: SLA+R has been transmitted; ACK has been received
// Next: Data byte will be received; NOT ACK bit will be returned
// or: Data byte will be received; ACK bit will be returned
case 0x40:
LPC_I2C1->I2DAT = Tab_I2CDataRead [i];
LPC_I2C1->I2CONCLR = I2C_Clear_I2CInterrupt; // Reset the SI bit
i++;
break;
// EEPROM Read mode
// Data byte has been received; NOT ACK has been returned
case 0x58:
UART0_SendByte (LPC_I2C1->I2DAT); // Read EEPROM data byte value and send thru UART0
LPC_I2C1->I2CONCLR = I2C_Clear_I2CInterrupt; // Reset the SI bit
i = 0;
I2C1_StopCondition (); // Transmit STOP condition
EEPROM_ReadDoneFlag = 0x01; // Send global Read Done flag
break;
}
}
Additionaly I send this C code in C file for better reading of C code (than in unformatted lines).
