Hey there!
I'm currently working on emulating the Atmel AT24C01 I2C EEPROM using an Arduino Pro (3.3v, ATMEGA 328 @ 8MHz). The reason for doing so is that I am working with a device that uses proprietary chip, and that chip reads data from the aforementioned EEPROM upon boot. In my application I need to change those values periodically and cannot store them. The proprietary chip acts as an I2C master clocking at 400kHz (according to the docs) and looks for I2C devices upon boot on the 0x50 address. The proprietary chip reads reads data perfectly from the EEPROM, as can be seen in the logic analyzer snapshots following this post. Additionally, I personally programmed the EEPROM.
The activity on the I2C data lines between the chip and the EEPROM is as follows (can be confirmed from the logic analyzer snapshot):
- Write Bytes {0x50, 0x00} //Detect I2C devices
- Read Byte {0x50, 0x87, 0x50, data_byte} //Read first byte of data (memory address 0x87, response should be 0x00)
- Various other read/write requests... //Read various other bytes of data
Now I attempted to replace the EEPROM chip with the Arduino...
To emulate the chip, I've done the following steps:
- Modified the I2C speed in twi.h to 400kHz: "#define TWI_FREQ 400000L"
- Added 1.5k pull up resistors on SDA <-> Pin 4 and SCL <-> Pin 5
- Created slave device in the code on address 0x50
- The code at the end of this post is what I am using to test replying to the first requested byte.
When the proprietary chip writes data to the I2C line, the onReceive() interrupt gets called fine. The problem lies when the proprietary chip reads data as onRequest() never gets called. The logic analyzer output is also attached below.
I've looked into various causations and stumbled upon the following post by el_supremo on this thread: http://arduino.cc/forum/index.php/topic,109335.0.html
AFAIK, When you specify an address to the I2C library it has to be the 7-bit address. Internally, the library shifts this up one bit which sets the low order bit to zero (which is good for a write). If you have asked for a read, the library sets the low order bit to one.
So, specifying 0x40 to the library means that internally this will be shifted to become 0x80 and when writing it will use 0x80. For reading it will use 0x81. [...]
Could this be the cause of my issue? That the Arduino is waiting for read requests on a different address than 0x50? If so, I'm not sure how to address this (pun intended)!
Any help would be much appreciated!
Best,
Aakash
Logic analyzer output for I2C connection from AT24C01 <-> Proprietary chip
Logic analyzer output for I2C connection from Arduino <-> Proprietary chip
Logic analyzer output for I2C connection from Arduino <-> Proprietary chip [Zoomed into actual read request]:
Code (currently only attempts to handle first read request):
#include <Wire.h>
volatile byte rQ;
void setup()
{
Wire.begin(0x50);
Wire.onRequest(requestEvent);
Wire.onReceive(receiveEvent);
}
void loop()
{
}
void requestEvent()
{
if(rQ == 0x87){
Wire.write(0);
}
}
void receiveEvent(int iData){
rQ = Wire.read();
}