Hi all,
I'm trying to interfacing the 24LC64 EEPROM to my FRDM KL25-Z. I'm using the MQX Lite and CW 10.6 (just for you know).
My first try was follow the code from Driver for Microchip 24xx Serial EEPROM | MCU on Eclipse , but unfortunately I'm unable to follow the code and build my own driver.
I'm trying to do this because I should have control about the blocking routines (like delays and waits), due to a lot of data processing at this same project, like PIT triggering a data logger (for example).
So, I've tried to write this:
byte buffer[3];
word sent;
byte data;
byte err;
//WRITE DATA
i2c_end = 0; //Variable is setting at CI2C1_OnReceiveData event
err = CI2C1_SelectSlave(0x50); //Select address of the EEPROM device (not required if only one device on the bus)
buffer[0] = 0; //most significant byte of storage address
buffer[1] = 0x12; //least significant byte of storage address
buffer[2] = 0xA8; //data
err = CI2C1_SendBlock(buffer, 3, &sent); //send storage address and data to the EEPROM
while(!i2c_end){} //wait for communication completition
err = CI2C1_SendStop(); //Send STOP condition
//10ms delay for EEPROM to complete write cycle - for more details see EEPROM datasheet
delay_ms(10); //#define delay_ms(x) _time_delay_ticks(((x)/SYST_TICK_TIME));
//READ DATA
i2c_end = 0;
buffer[0] = 0; //most significant byte of storage address
buffer[1] = 0x12; //least significant byte of storage address
err = CI2C1_SendBlock(buffer, 2, &sent); //send address to the EEPROM
while(!i2c_end){}
i2c_end = 0;
err = CI2C1_RecvChar(&data); //read data from EEPROM
while(!i2c_end){}
err = data;
But DATA is returning the value 0xFF (what I think is a error?).
Can anyone help?
Regards,
Solved! Go to Solution.
First byte of any communication with 24LC64 EEPROM contains fix part “1010” binary, I2C address and R/W bit.
When you used 0x50 as address, it means that A0, A1 and A2 pins of 24LC64 are connected to GND. Correct?
When you want read from EEPROM you must let it know to chip. So, you have to send address once again, but with R/W bit set to one. So, you have to use this command prior you send any byte from address:
err = CI2C1_SelectSlave(0x51); //Select address of the EEPROM device - read
Have a great day,
RadekS
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Oh I just realised that I had acknowledgement polling enabled when I tried read/write and so I disabled acknowledgement poll on the PE component and the read/write happens as expected.
Thank you for your help.
The readbyte, write byte and the block read and block write happens as expected.
Hi Saipriya,
I am glad that it works correctly on your side.
Have a great day,
Radek
First byte of any communication with 24LC64 EEPROM contains fix part “1010” binary, I2C address and R/W bit.
When you used 0x50 as address, it means that A0, A1 and A2 pins of 24LC64 are connected to GND. Correct?
When you want read from EEPROM you must let it know to chip. So, you have to send address once again, but with R/W bit set to one. So, you have to use this command prior you send any byte from address:
err = CI2C1_SelectSlave(0x51); //Select address of the EEPROM device - read
Have a great day,
RadekS
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
I am using the SKEAZ16NLC part and trying to interface it with an external EEPROM 24LC32A which communicates through I2C. I am using KDS and PE to make the write/read to work.There is a driver for EEPROm in Erich Styger's blog.
Driver for Microchip 24xx Serial EEPROM | MCU on Eclipse
I have a screengrab of the scope lines on SDA and SCL on the chip.
I see that the ACK bit is not set as a result of which write/read is not happening.
Scope image is attached. I am wondering what the issue is. I would like to know if there are any steps to debug this issues.
I stepped through the code and checked for PRIMASK register setting to check if interrupts are enabled and they are. Any help is much appreciated.
Thanks
I don't understand the issue. The scope DOES show ACK on each of the two bytes (write command, address byte 0xFF) showing as the zero in the 9th clock of each, made 'more visible' by being a slightly lower 'zero state' voltage, being driven from a different IC. In what way is the overall driver 'not working'?
Hi Earl,
You are fully right. I didn’t count all SCL edges and I missed that “detail”. I expected that “I see that the ACK bit is not set” is true.
So, memory behavior is correct and some potentieal issue may be probably in the code/settings.
Saipriya,
since 32Kbit presents 4096 bytes, the address for write commend must be transmitted in two bytes (0xX000~0xXFFF where X are “don’t care” bits).
The waveform at Scope image looks rather like acknowledge pooling action after a write command. This pooling may be used for checking whether data was already written or not (memory do not send acknowledge during a write operation). See ACKNOWLEDGE POLLING chapter in memory datasheet.
So, this waveform looks like the last execution of res = GI2C1_WriteBlock(block, 1, GI2C1_SEND_STOP);
command.
So, could you please specify reason why you think that write/read is not happening?
I hope it helps you.
Have a great day,
Radek
Hi Saipriya,
Are you sure that A0, A1 and A2 pins at your EEPROM are configured as low?
Are you sure that WP pins are connected to VSS for enabling write commands? However, this should not have any direct influence on acknowledging.
The highest four bits from Address High Byte should be “don’t care” bits, but I would try to configure them as 0 - just for sure.
I hope it helps you.
Have a great day,
Radek
If you are really 'trying to get other work done' while I2C/EEPROM access is 'blathering away' I am tempted to offer-up my adaptation of the Freescale Interrupt-driven I2C operations and a next-layer 'state machine' that by using a PIT can sequence thru a complicated process. I use it not only for 24LC64 access, but a Maxim one-wire 'master' DS2483. This is a 'bare-metal' code set I built for my real-time-sensor data device (4K samples/s into EtherCAT). But as you might imagine it is a 'little bit involved' and may take a little effort to adapt.