I found a header file to test a i2c eeprom 24LC256, but I used this to test my eeprom CAT24C32.The test sketch works fine. I modified the line BLOCKSIZE 8 because my eeprom have 32byte page write only.
I have also a FRAM MB85RC256V, I am wondering if can I use the same header to test the FRAM. I saw the command byte write are same like eeprom, but the page write have a different side of buffer, it says have 32Kbytes. Can I use it?
If I made a mistake please help me. Thanks very much!
Here the .h
#ifndef EEPROM_ROUTINES
#define EEPROM_ROUTINES
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include <Wire.h>
#define BLOCKSIZE 8
#define I2CADDR 0x57
#define BLOCKSIZE_READ 30
template <class T>
uint16_t writeObjectSimple(uint8_t i2cAddr, uint16_t addr, const T& value){
const uint8_t* p = (const uint8_t*)(const void*)&value;
uint16_t i;
for (i = 0; i < sizeof(value); i++){
Wire.beginTransmission(i2cAddr);
Wire.write((uint16_t)(addr >> 8)); // MSB
Wire.write((uint16_t)(addr & 0xFF));// LSB
Wire.write(*p++);
Wire.endTransmission();
addr++;
delay(5); //max time for writing in 24LC256
}
return i;
}
template <class T>
uint16_t readObjectSimple(uint8_t i2cAddr, uint16_t addr, T& value){
uint8_t* p = (uint8_t*)(void*)&value;
uint8_t objSize = sizeof(value);
uint16_t i;
for (i = 0; i < objSize; i++){
Wire.beginTransmission (i2cAddr);
Wire.write((uint16_t)(addr >> 8)); // MSB
Wire.write((uint16_t)(addr & 0xFF));// LSB
Wire.endTransmission();
Wire.requestFrom(i2cAddr, (uint8_t)1);
if(Wire.available()){
*p++ = Wire.read();
}
addr++;
}
return i;
}
template <class T>
uint16_t writeObject(uint16_t addr, const T& value){
const uint8_t* p = (const uint8_t*)(const void*)&value;
Wire.beginTransmission(I2CADDR);
Wire.write((uint16_t)(addr >> 8)); // MSB
Wire.write((uint16_t)(addr & 0xFF)); // LSB
//in the loop: counts the bytes we may send before
//our block becomes full
//but initialise it to the number of bytes up to the
//next 16-byte aligned address
uint8_t blockBytes = (addr/BLOCKSIZE + 1)*BLOCKSIZE - addr;
uint16_t i;
for (i = 0; i < sizeof(value); i++){
if (blockBytes == 0){
//block is full;
Wire.endTransmission(); //dispatch the buffer
delay(5);
//restart new block
addr = (addr/BLOCKSIZE + 1)*BLOCKSIZE;
blockBytes = BLOCKSIZE;
Wire.beginTransmission(I2CADDR);
Wire.write((uint16_t)(addr >> 8)); // MSB
Wire.write((uint16_t)(addr & 0xFF));// LSB
}
Wire.write(*p++); //dispatch the data byte
blockBytes--; //decrement the block space
}
Wire.endTransmission();
delay(5); //required write delay 5ms
return i;
}
template <class T>
uint16_t readObject(uint16_t addr, T& value){
uint8_t* p = (uint8_t*)(void*)&value;
Wire.beginTransmission(I2CADDR);
Wire.write((uint16_t)(addr >> 8)); // MSB
Wire.write((uint16_t)(addr & 0xFF)); // LSB
Wire.endTransmission();
//counts the bytes we may read before buffer is depleted
uint8_t blockBytes = 0;
uint16_t objSize = sizeof(value);
uint16_t i;
for (i = 0; i < objSize; i++){
if (blockBytes==0){
//we need a new block
blockBytes = BLOCKSIZE_READ;
if (objSize < blockBytes) blockBytes = objSize;
//get the new block
Wire.requestFrom((uint8_t)I2CADDR, blockBytes);
}
if(Wire.available()){
//read a byte from buffer
*p++ = Wire.read();
blockBytes--;
}
}
return i;
}
#endif
Here the skecth to test eeprom
#include <Wire.h>
#include "eeprom_routines.h" //definitions of the functions:
//writeObject, readObject,
//writeObjectSimple, readObjectSimple
#define BLOCK_OPERATIONS 0
#if BLOCK_OPERATIONS>0
#define __WRITE__(ad, obj) writeObject(ad,(obj))
#define __READ__(ad, obj) readObject(ad,(obj))
#else
#define __WRITE__(ad, obj) writeObjectSimple(0x57,ad,(obj))
#define __READ__(ad, obj) readObjectSimple(0x57,ad,(obj))
#endif
#define MEM_ADDR_MULTI 3458
//This is the structure we write and read from EEPROM
class MyData{
long result;
public:
float f1;
float f2;
double f3;
int i1;
long i2;
long i3;
bool negative;
long getResult(){
return result;
}
long calcResult(){
//makes a calculation with its data
//and stores the result to a private variable
long i = (i2+i3)/i1;
double f = f3/(f1+f2);
result = f/i;
//round off
result += result>0 ? 0.5 : -0.5;
if (negative) result=-result;
return result;
}
MyData() : result(0){ }
};
void setup(){
Serial.begin(9600);
Wire.begin();
MyData data[5];
//data[0] - result should be 20
data[0].i1 = 10;
data[0].i2 = 150000;
data[0].i3 = 350000;
data[0].f1 = 0.5;
data[0].f2 = 2.5;
data[0].f3 = 3.0E+6;
data[0].negative = false;
//data[1] - result should be -40
data[1].i1 = data[0].i1;
data[1].i2 = data[0].i2;
data[1].i3 = data[0].i3;
data[1].f1 = data[0].f1;
data[1].f2 = data[0].f2;
data[1].f3 = 2*data[0].f3;
data[1].negative = true;
//data[2] - result should be 80
data[2].i1 = data[0].i1;
data[2].i2 = data[0].i2;
data[2].i3 = data[0].i3;
data[2].f1 = data[0].f1;
data[2].f2 = data[0].f2;
data[2].f3 = 4*data[0].f3;
data[2].negative = false;
//data[3] - result should be -20
data[3].i1 = data[0].i1;
data[3].i2 = -data[0].i2;
data[3].i3 = -data[0].i3;
data[3].f1 = data[0].f1;
data[3].f2 = data[0].f2;
data[3].f3 = data[0].f3;
data[3].negative = false;
//data[4] - result should be -2
data[4].i1 = data[0].i1;
data[4].i2 = -data[0].i2;
data[4].i3 = -data[0].i3;
data[4].f1 = data[0].f1*10;
data[4].f2 = data[0].f2*10;
data[4].f3 = -data[0].f3;
data[4].negative = true;
Serial.println ("Data before writing to eeprom");
for (int i=0; i<5; i++){
data[i].calcResult();
Serial.print("data-"); Serial.print(i);
Serial.print(": result = ");
Serial.println(data[i].getResult());
}
Serial.print("Size of each object: ");
Serial.println(sizeof(MyData)) ;
Serial.println ("Writing data to eeprom");
int memaddr = MEM_ADDR_MULTI;
long t0 = millis();
for (int i=0; i<5; i++){
memaddr += __WRITE__(memaddr, data[i]);
}
long t1 = millis();
Serial.print ("...writing finished. Elapsed time: ");
Serial.println(t1-t0);
delay(1000);
Serial.println ("Reading data from eeprom");
MyData read[5];
t0 = millis();
memaddr = MEM_ADDR_MULTI;
for (int i=0; i<5; i++){
memaddr += __READ__(memaddr, read[i]);
}
t1 = millis();
Serial.print ("Time to read: "); Serial.println(t1-t0);
for (int i=0; i<5; i++){
Serial.print ("Read object: #");
Serial.println(i);
long storedResult = read[i].getResult();
Serial.print (" >stored result = ");
Serial.println(storedResult);
long newResult = read[i].calcResult();
Serial.print (" >recalculated result = ");
Serial.println(newResult);
if (storedResult== newResult &&
storedResult==data[i].getResult() )
Serial.println ("SUCCESS");
else Serial.println ("FAIL");
}
}
void loop() {
}
Here the serial output of eeprom CAT24C32 test
Data before writing to eeprom
data-0: result = 20
data-1: result = -40
data-2: result = 80
data-3: result = -20
data-4: result = -2
Size of each object: 27
Writing data to eeprom
...writing finished. Elapsed time: 126
Reading data from eeprom
Time to read: 15
Read object: #0
>stored result = 20
>recalculated result = 20
SUCCESS
Read object: #1
>stored result = -40
>recalculated result = -40
SUCCESS
Read object: #2
>stored result = 80
>recalculated result = 80
SUCCESS
Read object: #3
>stored result = -20
>recalculated result = -20
SUCCESS
Read object: #4
>stored result = -2
>recalculated result = -2
SUCCESS
1 Answer 1
At Fujitsu's site is said
Furthermore, applications that have used other products with I2C interfaces, such as EEPROMs and microcontrollers, can now replace EEPROMs, with the new FRAM products
So you can use it without any modifications in your code.