That hollow clonking sound you've been hearing for the last couple of days has been me beating my head against the wall trying to get I2C working with a serial (I2C) EEPROM. I'm running Kubuntu 8.1, a Diecimila with a Lady Ada 328, and IDE v13.
I think I'm writing to it, but bugger-all if I'm getting anything reasonable back out of it; I can get a few (best so far has been 52 of 128) bytes to read back correctly, but that's it.
Here's the Sketch I've been using, in case someone can spot an otherwise obvious mistook I've made:
/******************************************************************************
* 20090313 -- I2C_DEVICE DEVICE writing
* by D.K.Merriman
*
* Arduino analog input 5 - I2C SCL
* Arduino analog input 4 - I2C SDA
*
******************************************************************************/
#include "Wire.h"
#define ChipSize 128 // size of EEPROM in bytes
#define PageSize 32 // bytes per page (from datasheet)
#define ChipAddress 0x50 // address of the EEPROM - pretending lowest bit doesn't exist: 1010 000x = 101 0000 = 0x50
void setup()
{
Wire.begin();
Serial.begin(9600);
}
void loop()
{
int x;
int y;
int z;
int PageCount= (ChipSize / PageSize); // number of pages in the EEPROM
byte SourceData[ChipSize]; // Source Data for testing
byte TestData[ChipSize]; // for reading EEPROM data back
byte t[PageSize]; // array for temp buffer (needed to write to eeprom in page-size chunks)
delay(2000); // just to give yourself time to switch over to the serial monitor before things start happening
Serial.println("Loading Source data array");
for (x = 0; x < ChipSize; x++) {
SourceData[x] = 0x38; // ASCII '8'
TestData[x] = 0x00; // make sure the test data array is "empty"
}
Serial.println();
Serial.println("Source data array Initialized - Writing to EEPROM");
for (x = 0; x < PageCount; x++) {
for (y = 0; y < PageSize; y++) {
t[y] = SourceData[(x * PageSize) + y];
}
i2c_eeprom_write_page(ChipAddress, x, t, PageSize);
delay(1); // a couple of examples have indicated that a delay is needed here. I've gone from 1-100 with no effect.
}
Serial.println();
Serial.println("EEPROM written");
delay(5000); // kill some time, just on general principles
Serial.println();
Serial.println("Reading data back from EEPROM");
for (x = 0; x < ChipSize; x++) {
TestData[x] = i2c_eeprom_read_byte(ChipAddress, x);
}
Serial.println("All EEPROM data read");
for (x = 0; x < ChipSize; x++) {
if (TestData[x] != SourceData[x]) {
Serial.print("Data mismatch at ");
Serial.print(x);
Serial.print(" Received: ");
Serial.print(TestData[x]);
Serial.print(" Should have been: ");
Serial.println(SourceData[x]);
}
}
}
// I2C Read/Write routines
void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
int rdata = data;
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddress >> 8)); // MSB
Wire.send((int)(eeaddress & 0xFF)); // LSB
Wire.send(rdata);
Wire.endTransmission();
}
// WARNING: address is a page address, 6-bit end will wrap around
// also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes
void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) {
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddresspage >> 8)); // MSB
Wire.send((int)(eeaddresspage & 0xFF)); // LSB
byte c;
for ( c = 0; c < length; c++)
Wire.send(data[c]);
Wire.endTransmission();
}
byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
byte rdata = 0xFF;
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddress >> 8)); // MSB
Wire.send((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
if (Wire.available()) rdata = Wire.receive();
return rdata;
}
// maybe let's not read more than 30 or 32 bytes at a time!
void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) {
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddress >> 8)); // MSB
Wire.send((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,length);
int c = 0;
for ( c = 0; c < length; c++ )
if (Wire.available()) buffer[c] = Wire.receive();
}
The specific EEPROM I've been using is a CAT24WC33 (32K-bit) from FunGizmos at: http://store.fungizmos.com/index.php?main_page=product_info&cPath=68&products_id=211
where you can also get the datasheet from: http://www.catsemi.com/documents/24WC33.pdf.
IF I'm understanding things I've read elsewhere, there may be some question as to the reliability of the Wire library, as regards I2C -- can anyone even vaguely authoritative confirm or deny that?
Any suggestions on where/why I can't seem to read the EEPROM would be appreciated.
/me