Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addressing problems #2

Closed
porcao opened this issue Nov 1, 2016 · 37 comments
Closed

Addressing problems #2

porcao opened this issue Nov 1, 2016 · 37 comments

Comments

@porcao
Copy link

porcao commented Nov 1, 2016

I'm doing some tests using MB85RC16.
I have managed to make the examples work perfectly.
But if I include a new recording at another address he always writes at the beginning where the previous recording was made. This seeming it uses not the last address, and always use the same address for any recording I do.
I tried now record two numbers in two memory locations. But every recording is made and read from the same address.
If we try to read one byte, for example, a completely different place it always returns me first byte that is written at the beginning of the memory.
Ex.: fram.readByte (0x50, & readValue);
Tks

@porcao
Copy link
Author

porcao commented Nov 1, 2016

Example:

#include < Wire.h >
#include < math.h >
#include < FRAM_MB85RC_I2C.h >

uint16_t writeaddress = 0x10;
uint16_t testaddress = 0x50;
uint16_t testaddress2 = 0x70;

//Creating object for FRAM chip
FRAM_MB85RC_I2C fram;

void setup() {
uint8_t readvalue = 0xFF;

Serial.begin(115200);
Serial.println("Starting...");
while (!Serial) ;
Wire.begin();

fram.begin();
byte result;

result = fram.readByte(writeaddress, &readvalue);
if (result == 0) Serial.println("Read Done");
if (result != 0) Serial.println("Read failed");
Serial.print("Leitura:"); Serial.println(readvalue, DEC);

result = fram.writeByte(writeaddress, 77);
if (result == 0) Serial.println("Write Done");
if (result != 0) Serial.println("Write failed");

result = fram.writeByte(testaddress, 44);
if (result == 0) Serial.println("Write Done");
if (result != 0) Serial.println("Write failed");

result = fram.readByte(writeaddress, &readvalue);
if (result == 0) Serial.println("Read Done");
if (result != 0) Serial.println("Read failed");
Serial.print("Leitura:"); Serial.println(readvalue, DEC);

result = fram.readByte(testaddress2, &readvalue);
if (result == 0) Serial.println("Read Done");
if (result != 0) Serial.println("Read failed");
Serial.print("Leitura:"); Serial.println(readvalue, DEC);
}

void loop() {
// nothing to do
}

@sosandroid
Copy link
Owner

Hi,
Thanks for sharing your issue. However, this is not an issue.
The source of this behavior comes from the device itself.

I designed the lib for devices with 3 bits salve address and 16 bits memory address.

MB85RC16 has no slave adresses and 11 bits memory addresses. The 3 upper bits of the memory address are used as the "salve address" to match the I2C protocol. The lib is not compatible with this device.

To address this device, this lib has to be modified widely. I do not have the time nor testing devices to do it right now (not even in the coming months) but if you want to try, I can help you a bit.

To better understand the difference between the lib behavior and what the device expects, please have a look on page 8 of datasheets for MB85RC256V and MB85RC16.

http://edevice.fujitsu.com/fj/DATASHEET/e-ds/MB85RC256V-DS501-00017-5v1-E.pdf
http://edevice.fujitsu.com/fj/DATASHEET/e-ds/MB85RC16-DS501-00001-11v0-E.pdf

@sosandroid
Copy link
Owner

To make it easier, the things to modify are :

  • Make i2c_addr calculated for each read or write instruction
  • Modify the FRAM_MB85RC_I2C::readArray and FRAM_MB85RC_I2C::writeArray methods to set i2c_addr with 1010 + 3MSB of the memory address and send memory address LSB as address.

This should be enougth

@porcao
Copy link
Author

porcao commented Nov 2, 2016

My friend! Thank you very much! I managed to work perfectly.
Congratulations for the great work!
And again: thank you!

@sosandroid
Copy link
Owner

Fell free to share your code in order to improve the whole lib. This can be usefull to others :)

@porcao
Copy link
Author

porcao commented Nov 3, 2016

In fact I rushed a little.
Apparently still have a problem. I need to set up a new code to perform further tests.
But I ended up not changing your lib and made this way:

  Wire.beginTransmission(0x50);
  Wire.write(writeaddress);
  if ( Wire.endTransmission() > 0) Serial.print("Erro da Fram");
  Wire.requestFrom(0x50, 1);
  Serial.print("Leitura 1:"); Serial.println(Wire.read(), DEC);

  Wire.beginTransmission(0x50);
  Wire.write(writeaddress);
  Wire.write(77);
  if ( Wire.endTransmission() > 0) Serial.print("Erro da Fram");

@sosandroid
Copy link
Owner

By the way, can you share the device IDs sent to serial when you have the SERiAL_DEBUG enabled ?

@porcao
Copy link
Author

porcao commented Nov 4, 2016

Starting...
FRAM_MB85RC_I2C object created
I2C device address 0x50
WP pin number 13
Write protect management: false
Memory Chip NOT FOUND

I gave up.
I set up a program to list me all I2C devices. I obtained a list ranging from 0x50 to 0x57.
Are memory banks. Each with 256 bytes.
I'll buy another memory module that will be easier.
Thank you for your patience and help.

@sosandroid
Copy link
Owner

Ok,, this is because the the checkDevice method has a lower limit when outputing the results. At the time I wrote the Lib, 4K & 16K devices were not available.

I just added a new example which tries to identify the device for you and get its IDs

@porcao
Copy link
Author

porcao commented Nov 4, 2016

The Result:
Starting...
....... .......
FRAM Device IDs
Manufacturer 0xFFF
ProductID 0xFFF
Density code 0xF
...... ...... ......

@sosandroid
Copy link
Owner

sosandroid commented Nov 4, 2016

Very strange as we do not have the manufacturer ID = 0x00A.
I may come from the weird way of mixing device address & memory address of the chip.

I would recommend to switch the memory chip with a 256K. The lib has been heavily tested against this one (MB85RC256V). https://www.adafruit.com/product/1895

If easy with solder station, you can get the chip alone with a DIP to SOIC adapter for cheaper on ebay or equiv.

@porcao
Copy link
Author

porcao commented Nov 4, 2016

Thank you.
That's what I'll do, I'll use this other memory.

@sosandroid
Copy link
Owner

Just had a mail from Fujitsu's marketing manager. The 16K devices does not have Device IDs implemented. From there, I'll try to add support for the chip in the LIB.

@porcao
Copy link
Author

porcao commented Nov 7, 2016

That good news.
Once you're done can do the tests you want. Just send me the test code that I am sending you the results.
Want my email to facilitate communication?

@sosandroid
Copy link
Owner

1.1.0b is ready for testing.
A new example has been added to show how to address 16K devices

If you can deeply test the lib against your device It would be appreciated as I do not have one.

@porcao
Copy link
Author

porcao commented Nov 10, 2016

I testing the FRAM_MB85RC_I2C_manual_mode_simple_write_read example.
Result:
Starting...
FRAM_MB85RC_I2C object created
I2C device address 0x50
WP pin number 13
Write protect management: false
Memory Chip NOT FOUND
...... ...... ......
Written value 0xCC
Read value 0xCC
DensityCode 0xF00

@porcao
Copy link
Author

porcao commented Nov 10, 2016

I ran some tests by changing the address where writing and reading are made.
This chip is 16Kbits then are 2k bytes.
The larger address would be 0x800.
I did some tests and above 0x0ff it returns me a wrong value.
Do you have any test in particular that I can do for you?

@sosandroid
Copy link
Owner

1.1.0b1 is available for testing.
Bug fixing on the lib + better example for 16K device

The example now test a byte & a word writing at 0x25 and 0x750 memory slots.
Let me know about the results

@porcao
Copy link
Author

porcao commented Nov 11, 2016

writeaddress2 = 0x0FA ==OK
writeaddress2 = 0x0FF ==OK
writeaddress2 = 0x100 == NOT OK

Starting...
FRAM_MB85RC_I2C object created
I2C device address 0x50
WP pin number 13
Write protect management: false
Memory Chip initialized
FRAM Device IDs
Manufacturer 0xF00
ProductID 0xF00
Density code 0xF00
Density 16K
Device properties set
...... ...... ......
...... ...... ......
i2c_addr 0x50
i2c_addr 0x50
Written value 0xCC
Read value 0xCC
Write Byte test : OK
.... ....
i2c_addr 0x50
i2c_addr 0x50
Written value 0xBEEF
Read value 0x1
Write word test : NOT OK
.... ....
Manufacturer 0xF00
DensityCode 0xF00
Density 16

@sosandroid
Copy link
Owner

OK, there was an issue with I2CAddressAdapt() to know about the address translation. The issue seems coming from there ...
Another test is welcome to find out the write issue

@sosandroid sosandroid reopened this Nov 11, 2016
@sosandroid
Copy link
Owner

Library modified to find out more :)

@porcao
Copy link
Author

porcao commented Nov 12, 2016

:(

Starting...
FRAM_MB85RC_I2C object created
I2C device address 0x50
WP pin number 13
Write protect management: false
Memory Chip initialized
FRAM Device IDs
Manufacturer 0xF00
ProductID 0xF00
Density code 0xF00
Density 16K
Device properties set
...... ...... ......
...... ...... ......
Writing at location 0x25
Calculated addr 0x50
Calculated addr 0x50
Written value 0xCC
Read value 0xCC
Write Byte test : OK
.... ....
Writing at location 0x750
Calculated addr 0x57
Calculated addr 0x57
Written value 0xBEEF
Read value 0x5051
Write word test : NOT OK
.... ....
Manufacturer 0xF00
DensityCode 0xF00
Density 16

@porcao
Copy link
Author

porcao commented Nov 12, 2016

This works!!!

`#include <Wire.h>

#define disk1 0x50 //Address of 24LC256 eeprom chip

void setup(void)
{
Serial.begin(115200);
Wire.begin();

unsigned int address = 0x7FF;

writeEEPROM(disk1, address, 56);
Serial.print(readEEPROM(disk1, address), DEC);
}

void loop(){}

void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data )
{
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.write(data);
Wire.endTransmission();
}

byte readEEPROM(int deviceaddress, unsigned int eeaddress )
{
byte rdata = 0xFF;

Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();

Wire.requestFrom(deviceaddress,1);

if (Wire.available()) rdata = Wire.read();

return rdata;
}`

@sosandroid
Copy link
Owner

sosandroid commented Nov 12, 2016

The working example let me thing your have a 64K device. The working process is not compliant with 16K device's datasheet. Can you change the chipDensity to 64 and run the test ?
If this works, you have a 64K devivce ...

Despite the KO test at 0x750 memory slot, here below the detailed explanation for a 16K device :

write address 0x25 =>  0b 000 00100101
write address 0x750 => 0b 111 01010000

According to 16K device's datasheet, the I2C protocol is used the following way :
7 bits device address + R/W bit. Device address is 1010xxx where xxx are the 3 MSB of the memory slot (out of 11 bits)
After that device address, the 8 LSB of the memory slot are send to the bus.

To read or write at 0x025 memory slot, the IC2 device address is 0b 1010 000 x. Which means 0x050
To read or write at 0x750 memory slot, the IC2 device address is 0b 1010 111 x. Which means 0x057

The second bit send is
    To read or write at 0x025 memory slot, (0b 000 00100101 & 0x000 11111111) => 0b 000 00100101 => 0x025
    To read or write at 0x750 memory slot, (0b 111 01010000 & 0x000 11111111) => 0b 000 01010000 => 0x010

The process (0x025 memory slot)
    wire.beginTranmission(0x50);
    Wire.write(0x25);
    ...

The process (0x750 memory slot)
    wire.beginTranmission(0x57);
    Wire.write(0x10);
    ...

@porcao
Copy link
Author

porcao commented Nov 14, 2016

I ran a program to list all i2c devices.
Response got the numbers from 0x50 to 0x57.

@sosandroid
Copy link
Owner

I agree this is weird.
But if the program for 24LC256 works, this means the memory mapping is not the one of the MB85RC16.

Can you just change one line in the "Manual Mode" example ?

uint16_t chipDensity = 16; changed to uint16_t chipDensity = 64;.

Modifying this wil change the way the memory adressing is done by the library. This will be exactly the same as the 24LC256 example you gave 2 days ago. Let me know if this works or not :)

@porcao
Copy link
Author

porcao commented Nov 15, 2016

It worked! But I still do not understand why. Because the chip is 16 not 64.
Can you imagine an address test to check the limits and make sure it's 64 but sold as 16?

Starting...
FRAM_MB85RC_I2C object created
I2C device address 0x50
WP pin number 13
Write protect management: false
Memory Chip initialized
FRAM Device IDs
Manufacturer 0xF00
ProductID 0xF00
Density code 0xF00
Density 64K
Device properties set
...... ...... ......
...... ...... ......
Writing at location 0x25
Calculated addr 0x50
Calculated addr 0x50
Written value 0xCC
Read value 0xCC
Write Byte test : OK
.... ....
Writing at location 0x750
Calculated addr 0x50
Calculated addr 0x50
Written value 0xBEEF
Read value 0xBEEF
Write word test : OK
.... ....
Manufacturer 0xF00
DensityCode 0xF00
Density 64

@sosandroid
Copy link
Owner

sosandroid commented Nov 15, 2016

Ok, that sounds better and I'm not falling dummy. Thanks for that.

To fully test either this is a 64K or higher chip or not, you just have to run the reworked example. I added a calculation of the second test address according to the chip density.
The second test address will be (chipDensity * 128) - 80
For a 64K chip, you will hit the address 1FB0

@porcao
Copy link
Author

porcao commented Nov 15, 2016

It worked.
But now I've been thinking about something. Could it be that by using a very high memory value it did not go back to the beginning? And overwritten something that might be in the beginning?

Starting...
FRAM_MB85RC_I2C object created
I2C device address 0x50
WP pin number 13
Write protect management: false
Memory Chip initialized
FRAM Device IDs
Manufacturer 0xF00
ProductID 0xF00
Density code 0xF00
Density 64K
Device properties set
...... ...... ......
...... ...... ......
Writing at location 0x25
Calculated addr 0x50
Calculated addr 0x50
Written value 0xCC
Read value 0xCC
Write Byte test : OK
.... ....
Writing at location 0x1FB0
Calculated addr 0x50
Calculated addr 0x50
Written value 0xBEEF
Read value 0xBEEF
Write word test : OK
.... ....
Manufacturer 0xF00
DensityCode 0xF00
Density 64

@sosandroid
Copy link
Owner

sosandroid commented Nov 15, 2016

The standard behavior of the chips, according to Datasheet, is last memory slot +1 = first memory slot.
You can of course overwrite the 0x780 slot of a 16K device. To be sure, you should modify the example to add a read at that location to be sure you're not looping through the memory map.

If you're not looping, just test some other densities that do not support the Device IDs as mentionned in the readme tables.

One thing is clear now : you do not have a MB85RC16 chip but something else.
After checking the MB85RC16 datasheet, the chip marking is different from what you have.
RC16
E11050
300

@sosandroid
Copy link
Owner

Closed

@dsk1990
Copy link

dsk1990 commented Mar 27, 2017

With MB85RC16 I have exactly same problem as porcao.
And replace MB85RC16 with FM24C16B , I got the same result!
Maybe there is some unknown bug with this lib about r/w address.
thank you~

@porcao
Copy link
Author

porcao commented Mar 27, 2017

I buy 20 MB85RC16 from USA.
Same errors.
I stopped my tests and for my use this code work fine:

void writeEEPROM(uint16_t eeaddress, byte data )
{
Wire.beginTransmission(0x50 + (eeaddress >> 8));
Wire.write(eeaddress & 0xFF); // LSB
Wire.write(data);
Wire.endTransmission();
}

byte readEEPROM(uint16_t eeaddress )
{
byte rdata = 0x0;
Wire.beginTransmission(0x50 + (eeaddress >> 8));
Wire.write(eeaddress & 0xFF); // LSB
Wire.endTransmission();
Wire.requestFrom(0x50 + (eeaddress >> 8), 1);
if (Wire.available()) rdata = Wire.read();
return rdata;
}

@sosandroid
Copy link
Owner

A fix has been provided by @Palatis. A few weeks ago.
@dsk1990, Which version did you test ?

@dsk1990
Copy link

dsk1990 commented Mar 28, 2017

i test 4k and 16k fram; latest version; following results:

if define chipDensity = 4 or 16; when wr addr <= 255;
=> Calculated address = 0x50; Write word test : OK

if define chipDensity = 4 or 16; when wr addr > 255;
=> Calculated address != 0x50; Write word test : NOT OK

if define chipDensity = 64 or 256;
=> always Calculated address = 0x50; Write word test : OK

may difference is in function FRAM_MB85RC_I2C::I2CAddressAdapt

@dsk1990
Copy link

dsk1990 commented Mar 29, 2017

aha, i got it~~

following graph show when read at address 0x1b0
1
Id2 addr should be 51 but it is 50 .

the mistake is in FRAM_MB85RC_I2C::readArray :
Wire.requestFrom(i2c_addr, (uint8_t)items);

Changed to:

switch(density) {
			case 4:
				chipaddress = (i2c_addr | ((framAddr >> 8) & 0x1));
				break;
			case 16:
				chipaddress = (i2c_addr | ((framAddr >> 8) & 0x7));
				break;
			default:
				chipaddress = i2c_addr;
				break;
		}

Wire.requestFrom(chipaddress, (uint8_t)items);

enjoy it, thank you~~
@porcao @sosandroid

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants