I2C Ferroelectric Random Access Memory (FRAM). Read/write endurance for each memory slot : 10^12 cycles and more. 9~16 bit adresses, 8 bits data slots.
Supports 4K, 16K, 64K, 128K, 256K & 512K devices. Works for 1M devices when considering each device as 2 differents 512K devices
For SPI chips, please have a look on Christophe Persoz's repo
- Device settings detection (if Device ID feature is available)
- Device manual setting
- Manage single bit (read, set, clear, toggle) from a byte
- Write one 8-bits, 16-bits or 32-bits value
- Write one array of bytes
- Read one 8-bits, 16-bits or 32-bits value
- Read one array of bytes (up to 256 per call - maximum supported by Arduino's Wire lib)
- Move a byte from an address to another
- Get device information
- 1: Manufacturer ID
- 2: Product ID
- 3: Density code
- 4: Density human readable
- Manage write protect pin
- Erase memory (set all chip to 0x00)
- Prevent cycling through memory map to avoid unwanted overwrites
- Debug mode manageable from header file
v1.0 - First release
v1.0.1 - Robustness enhancement
v1.0.2 - fix constructor, introducing byte move in memory
v1.0.3 - fix writeLong() function
v1.0.4 - fix constructor call error
v1.0.4.1 - Add example to help @porcao
v1.0.5 - Enlarge density chip support by making check more flexible, Error codes not anymore hardcoded, add connect example, add Cypress FM24 & CY15B series comment.
v1.1.0b - Adding support for devices without device IDs + 4K & 16 K devices support
v1.1.0b1 - Fixing checkDevice() + end of range memory map check + better manual mode example
v1.2.0 - Uses reinterpret_cast instead of bit shift / masking for performance. Breaks backward compatibility with previous code - See PR#6
Fujitsu FRAM - manufacturer code 0x00A - Fujitsu page
Model | Density (kB) | Device addressing | Device ID feature | Density code | Memory addressing | Tested |
---|---|---|---|---|---|---|
MB85RC04V | 4 | 6 bits | Yes | 0x00 | 9 bits (1) | No |
MB85RC16V | 16 | 4 bits | No | - | 11 bits (2) | Yes |
MB85RC16 | 16 | 4 bits | No | - | 11 bits (2) | No |
MB85RC64V | 64 | 7 bits | No | - | 13 bits | No |
MB85RC64A | 64 | 7 bits | No | - | 13 bits | Yes |
MB85RC64TA | 64 | 7 bits | Yes | 0x03 | 13 bits | No |
MB85RC128A | 128 | 7 bits | No | - | 14 bits | No |
MB85RC256V | 256 | 7 bits | Yes | 0x05 | 15 bits | Yes |
MB85RC512T | 512 | 7 bits | Yes | 0x06 | 16 bits | No |
MB85RC1MT | 1024 | 6 bits | Yes | 0x07 | 17 bits (3) | No |
Cypress FRAM - manufacturer code 0x004 - Cypress page
Model | Density (kB) | Device addressing | Device ID feature | Density code | Memory addressing | Tested |
---|---|---|---|---|---|---|
FM24CL04B | 4 | 6 bits | No | - | 9 bits (1) | No |
FM24C04B | 4 | 6 bits | No | - | 9 bits (1) | No |
FM24C16B | 16 | 4 bits | No | - | 11 bits (2) | No |
FM24C64B | 64 | 7 bits | No | - | 13 bits | Yes |
FM24CL64B | 64 | 7 bits | No | - | 13 bits | No |
CY15B128J | 128 | 7 bits | Yes | 0x01 | 14 bits | No |
FM24W256 | 256 | 7 bits | No | - | 15 bits | No |
CY15B256J | 256 | 7 bits | Yes | 0x02 | 15 bits | No |
FM24V05 | 512 | 7 bits | Yes | 0x03 | 16 bits | No |
FM24V10 | 1024 | 6 bits | Yes | 0x04 | 17 bits (3) | No |
Note 1 : 4K devices have a 9 bits adressing memory map. The 9th bit is set in the device address byte
Note 2 : 16K devices a 11 bits adressing memory map. The 3 MSB are set in the device address byte in place of A2~A0
Note 3 : 1M a 17 bits adressing memory map. To manage this device, you need to consider it as 2 512K devices with 2 distincts adresses : 1010+A2+A1+0 and 1010+A2+A1+1. The library is set that way.
Devices address : b1010 + A2 + A1 + A0.
All devices are pulling down internaly A2, A1 & A0. Default address is b1010000 (0x50) - exception 1M chips which seems to be a double 512K devices in a single package. Please use 2 objects instances to deal with them.
4K devices have only A2 & A1 support. A0 is used for memory addressing. i2c_addr = 0b1010xx0
16K devices does not have A2, A1 nor A0 support. This is used for memory addressing i2c_addr = 0b1010000
An interesting document from Fujitsu describes it quite well.
The error management is eased by returning a byte value for almost each method. Most of the time, this is the status code from Wire.endTransmission() function.
- 0: success
- 1: data too long to fit in transmit buffer
- 2: received NACK on transmit of address
- 3: received NACK on transmit of data
- 4: Serial not accessible
- 5: Not referenced device ID
- 7: Fram chip unidentified
- 8: number of bytes asked to read null
- 9: bit position out of range
- 10: Not permitted operation
- 11: Out of memory range operation
-
Tested against MB85RC256V - breakout board from Adafruit http://www.adafruit.com/product/1895
-
Tested on Arduino Mega with Arduino IDE 1.0.5 & 1.6.11
-
Please comment about other devices (Memory & Arduino Boards) - A specific thread has been opened.
-
@Porcao reports on issue #2 a 16k labelled MB85RC chip behaving like a 64K+ device with no device ID feature. This chip has been bought from China (Aliexpress). Seems to be a mislabelled device or anything else. If the tests fails with your chip, feel free to test other densities using the "Manual Mode" example.
- Test all devices - Testing thread
- Create a more robust error management (function to handle that with higher layer)
- Rework the debug mode
Here some quick answers to some interesting questions:
-
Does this lib suitable for some others devices not listed here ? It can. To understand the way the lib works, just have a look on the datasheets of MB85RC256V & MB85RC16V. They will let you know about the details. Some other chips, FRAM or not, may use the same logic : MB85RC series, FM24 series, CY15B series or even some 24LC memory chips
-
What if I run manual mode declaring another density than the one really embeded ? There are several options :
- You have a 128K chip and declaring 64K. There is no issue and you'll only use the first half of the memory map
- You have a 128K chip and declaring 16K or 4K. The memory address mamangement is not done the same way. This cannot work
- You have a 128K chip and declaring 256K. You'll be able to loop through the whole memory map and overwritting some data. The worst bugs ever
- You have a 16K chip and declaring 256K. The memory address mamangement is not done the same way. This cannot work
-
Your chip or the lib does not behave as expected First check the datasheet to check either this is a lib bug or not. Using the various exmaples and playing around with settings would help. Have a look on issue #2 to have ideas about some possible misbehavior's origins.
-
My devices is not recognized automatically Please run the
ReadIDs.ino
example andmanual_mode.ino
example to find out your real chip capabilities. -
Your chip has device's IDs but not recognized by the lib Please open an issue to add it in the lib. Provide also all required data such as device's manufacturer, name, IDs and the tests done.
-
Sleep mode & High speed mode are not supported Those features are not supported at the moment as they require a huge rework of the lib. At this time they seem to be out of scope.
- Kevin Townsend wrote the very first Adafruit Lib of which this one is forked.
- All testers who helped to improve this library