m24C64 i2c eeprom

Has anybody used this? I've found example code for the AT24C256 in the playground but i'm failing to find anything for the chips I have.

Anybody used it? Any tips on getting something out of it?

Hi, I've read now your question. Please, try to see if the project Bank 1.2 may help you, I think the question is the same es explained there.

http://www.contesti.eu/opensource/bank

Enrico

Thanks for the link. Found out I wasn’t using any pull-up resistors. Still no change.

I am using the library you linked to as the 24c64 datasheet seems to ask for what the lib says sometimes

For write: start condition (Wire.beginTransmission i assume) → MSB → LSB → BYTE → No ack.

The same cannot be said for reading. There seems to be no way to read a single byte :’( → http://i.imgur.com/MvHzT.png

Any ideas?

Hi I’m sure that the read and write procedure must be the same, because the only thing that do at24c library is the evaluation of the address. Then, the process is delivered to the wire library that do the low level work to manage I2C bus. Can you send me a little piece of code for reading and writing and a link to the datasheet of your device ?

Here’s the link to the d/s http://www.datasheetcatalog.org/datasheet/stmicroelectronics/4578.pdf

I’ve wired a0/1/2 and WC to Gnd.

About the library. It turns out I can’t even write to the eeprom. It hangs at the write. Here’s the code I have

//m24C64-WP eeprom

#include <Wire.h>
#define DEV_ADDR 80

// SDA == pin a4
// SCL == pin a5

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();
}

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;
}

void setup() {
  Serial.begin(9600);
  Wire.begin();
}

int main() {
  byte meh = 0xFF;
  setup();
  
  Serial.println("INIT");
  i2c_eeprom_write_byte(DEV_ADDR, 0, meh);
  //delay(100);
  meh = i2c_eeprom_read_byte(DEV_ADDR, 10);
  Serial.println(meh, BYTE);
  
  Serial.println("FIN");
  
  return 0;
}

Hi. About the fact you can’t read by byte: I see in the datasheet that the way so STOP the reading sequence (in your case after the first byte read) is
“master does acknowledge the data byte output,
and sends additional clock pulses so that the de-
vice continues to output the next byte in sequence.
To terminate the stream of bytes, the bus master
must not acknowledge the last byte, and must
generate a Stop condition, as shown in Figure 9.
The output data comes from consecutive address-
es, with the internal address counter automatically
incremented after each byte output. After the last
memory address, the address counter ‘rolls-over’,
and the device continues to output data from
memory address 00h.” (from datasheet)

About the code: I see that you work with data address directly, but this must be ORed with 0x500000 (corresponding to the bits 1010) for I2C addressing. This is the fixed part of the addressing.
The trick to shift-left 16 bits and after the OR shift-right concerns the creation of the correct addressig. Read the datasheet of Atmel AT24C1024, that’s clearly explained in the chapter “device addressing”. Anyway your chip doesn’t differ by the others I’ve used.
What is that define of 80 in your code? I don’t find referrals to this value after the #define.

The addressing of eeprom is not so simple, I saw, and I needed a lot of works to understand exactly the method.

My sensation is that you can’t read simly because you have addressed somewere else were you are thinking…
Tell me after trying with the library.

Enrico

Thanks for the help conTESTI.eu. I did see the sequential read mode but I thought it wasn't possible as i'm a bit confused about the term 'current' in "sequential current read". How do you find out the current address? All I see is byte after byte after the start condition with the address++.

DEV_ADDR is the device select code as shown in Table 2: 1010000/ 0x50/ 80. It's used later on in i2c_eeprom_write_byte as __deviceaddress. I'm assuming that's what it means as there's no documentation.

Which library should I use? The one I am currently using or the at24c library? I'll have a look at that d/s you recommend. Cheers

I’ve found where i’m getting issues. For some reason if I use “void loop()” things work, if I use “int main ()” things don’t. Strange.

Here’s what works (I include the non-working main()):

//m24C64-WP eeprom

#include <Wire.h>
#define DEV_ADDR 0x50

// SDA == pin a4
// SCL == pin a5

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();
}

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;
}

void setup() {
  Serial.begin(9600);
  Wire.begin();  
}


void loop() {
  i2c_eeprom_write_byte(DEV_ADDR, 0 , '!');
  delay(5);
  byte b = i2c_eeprom_read_byte(DEV_ADDR, 0);
  Serial.println(b);
  delay(1000);
}

//int main () {
//  setup();
//  Serial.println("INIT");
//  delay(10);
//  i2c_eeprom_write_byte(DEV_ADDR, 0 , '!');
//  delay(5);
//  byte b = i2c_eeprom_read_byte(DEV_ADDR, 0);
//  Serial.println(b);
//}

:exclamation Hi

I'm happy... The difference seems that an int value declared in main should be used only (I think) in a command line program. And you in your main() haven't a return value.

Very good conclusion. And if you want to connect more than one eeprom, you can buy the pcb of Bank.

cheers. Enrico

Thanks. I actually moved commented code (my experiments) into that main(). When a return(0) was there it made no difference.

I don't really have a need for more than one eeprom. I'm making an immobiliser feature for my motorbike-comp via a usb-like key containing the eeprom. The eeprom is going to hold a hash that my code is going to look for on startup.

Interfacing to my motorbike will be trivial as I already have a hidden toggle-switch that does the same thing. In fact i'm 75% there. Already have a hash check that works, just need to figure out how to turn off the arduino if the hash-check fails.

Thanks for your help.