0.3.4 FRAM_I2C

This commit is contained in:
rob tillaart 2022-03-18 13:37:57 +01:00
parent 7b3b31c4ad
commit fc44f40eb2
17 changed files with 572 additions and 85 deletions

View File

@ -2,10 +2,10 @@ compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
- uno
# - due
# - zero
# - leonardo
- due
- zero
- leonardo
- m4
- esp32
# - esp8266
# - mega2560
- esp8266
- mega2560

View File

@ -0,0 +1,61 @@
# Change Log
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.3.3] - 2022-03-16
### Added
- add **uint16_t writeObject(memaddr, &obj)** see #13
- add **uint16_t readObject(memaddr, &obj)** see #13
- add examples for write- and readObject()
### Changed
- renamed releaseNotes.md => CHANGELOG.md
- some edits in readme.md
### Fixed
## [0.3.3] - 2022-02-08
- added **getSizeBytes()**
- created releaseNotes.md
- updated readme.md
- add example FRAM_logging.ino
## [0.3.2] - 2021-12-18
- update Arduino-CI,
- add badges in readme.md
- update library.json,
- update license,
- minor edits
## [0.3.1] - 2021-02-05
- fix #7 typo in .cpp
## [0.3.0] - 2021-01-13
- fix #2 ESP32
- add WireN support
## [0.2.3] - 2021-01-11
- fix getMetaData (kudos to PraxisSoft)
## [0.2.2] - 2020-12-23
- add Arduino-CI + unit test
- add **getWriteProtect()**
## [0.2.1] - 2020-06-10
- fix library.json
## [0.2.0] - 2020-04-30
- refactor,
- add writeProtectPin code
## [0.1.1] - 2019-07-31
- added support for Fujitsu 64Kbit MB85RC64T (kudos to ysoyipek)
## [0.1.0] - 2018-01-24
- initial version

View File

@ -1,12 +1,12 @@
//
// FILE: FRAM.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.3.3
// VERSION: 0.3.4
// DATE: 2018-01-24
// PURPOSE: Arduino library for I2C FRAM
// URL: https://github.com/RobTillaart/FRAM_I2C
//
// HISTORY: see releaseNotes.md
// HISTORY: see CHANGELOG.md
#include "FRAM.h"

View File

@ -2,7 +2,7 @@
//
// FILE: FRAM.h
// AUTHOR: Rob Tillaart
// VERSION: 0.3.3
// VERSION: 0.3.4
// DATE: 2018-01-24
// PURPOSE: Arduino library for I2C FRAM
// URL: https://github.com/RobTillaart/FRAM_I2C
@ -13,7 +13,7 @@
#include "Wire.h"
#define FRAM_LIB_VERSION (F("0.3.3"))
#define FRAM_LIB_VERSION (F("0.3.4"))
#define FRAM_OK 0
@ -45,6 +45,17 @@ public:
uint32_t read32(uint16_t memaddr);
void read(uint16_t memaddr, uint8_t * obj, uint16_t size);
template <class T> uint16_t writeObject(uint16_t memaddr, T &obj)
{
write(memaddr, (uint8_t *) &obj, sizeof(obj));
return memaddr + sizeof(obj);
};
template <class T> uint16_t readObject(uint16_t memaddr, T &obj)
{
read(memaddr, (uint8_t *) &obj, sizeof(obj));
return memaddr + sizeof(obj);
}
// works only if pin is defined in begin.
bool setWriteProtect(bool b);
bool getWriteProtect();

View File

@ -14,9 +14,11 @@ Arduino library for I2C FRAM.
## Description
FRAM is a library to read from and write to (over I2C) an FRAM module.
FRAM is much faster than EEPROM and almost as fast as Arduino UNO RAM.
FRAM is much faster than EEPROM and almost as fast as (Arduino UNO) RAM.
Another important feature it has in common with EEPROM is that FRAM keeps
its content after a reboot (non-volatile).
its content after a reboot as it is non-volatile.
That makes it ideal to store configuration or logging
data in a project.
FRAM stands for Ferroelectric RAM - https://en.wikipedia.org/wiki/Ferroelectric_RAM
@ -30,10 +32,10 @@ Types of FRAM the library should work with
| MB85RC128A | 16 KB | | no deviceID register |
| MB85RC256V | 32 KB | |
| MB85RC512T | 64 KB | Y |
| MB85RC1MT | 128 KB | |
| MB85RC1MT | 128 KB | | 16 bit address problem? to be tested |
Notes
- Not all types are tested. Pleas let me know if you have verified one.
- Not all types of FRAM are tested. Please let me know if you have verified one.
- If there is no deviceID **getSize()** will not work correctly.
Address = 0x50 (default) .. 0x57, depends on the lines A0..A2.
@ -64,20 +66,25 @@ Support for basic types and 2 calls for generic object, use casting if needed.
- **void read(uint16_t memaddr, uint8_t uint8_t \* obj, uint16_t size)**
One needs to allocate memory as the function won't.
(0.3.4 added template functions, see issue #13 )
- **uint16_t writeObject(uint16_t memaddr, T &obj)** writes an object to memaddr (and following bytes). Returns memaddr + sizeof(obj) to get the next address to write to.
- **uint16_t readObject(uint16_t memaddr, T &obj)** reads an object from memaddr and next bytes. Returns memaddr + sizeof(obj) to get the next address to read from.
### Miscellaneous
- **bool setWriteProtect(bool b)** make the FRAM write-protected by pulling line HIGH / LOW.
Returns true if a writeProtectPin was defined.
Otherwise the FRAM cannot be write protected.
- **bool getWriteProtect()** get current status.
Otherwise the FRAM cannot be write protected.
Note the pin should be defined in **begin()**.
- **bool getWriteProtect()** get current write protect status.
- **uint16_t getManufacturerID()** idem. Fujitsu = 0x00A.
- **uint16_t getProductID()** idem. Proprietary.
- **uint16_t getSize()** returns size in kiloBYTE.
If the FRAM has no device ID, the size cannot be read.
- **uint32_t getSizeBytes()** returns size in BYTES.
Convenience wrapper, useful for iterating over the whole memory,
or testing upper boundary.
or testing the upper boundary.
## Operational
@ -87,14 +94,13 @@ or testing upper boundary.
## Future
- test more types
- new functionality
- **clear(begin, end)** or complete clear / format only?
- **dump(stream)** or printable interface?
- Print interface? expensive in performance per char..
- **getSize()** scanning FRAM like EEPROM library?
- **write(addr obj size)** should return end + 1 == next address.
- remember last written address? why?
### high
### medium
- **write()** and **writeBlock()** might write beyond the end of FRAM
- now it is responsibility user.
- testing would degrade performance?
- error flag ?
- extend examples
- FRAM for multi language string storage
- FRAM as linear buffer for a slow stream?
@ -102,4 +108,16 @@ or testing upper boundary.
- FRAM logging, unequal length strings.
- FRAM (8x) concatenated as one continuous memory.
### low
- test more types of FRAM
- **clear(begin, end)** or complete clear / format only?
- loop with write is slow
- loop with writeBlock().
- **dump(stream)** or printable interface?
- Print interface? expensive in performance per char..
- **getSize()** scanning FRAM like EEPROM library?
- remember last written address? why?

View File

@ -0,0 +1,136 @@
//
// FILE: FRAM_clear.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo clear FRAM
// URL: https://github.com/RobTillaart/FRAM_I2C
//
// experimental performance test "clear" function.
#include "FRAM.h"
FRAM fram;
uint32_t start;
uint32_t stop;
uint32_t sizeInBytes = 0;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("FRAM_LIB_VERSION: ");
Serial.println(FRAM_LIB_VERSION);
Wire.begin();
int rv = fram.begin(0x50);
if (rv != 0)
{
Serial.print("INIT ERROR: ");
Serial.println(rv);
}
// get size in bytes
sizeInBytes = fram.getSize() * 1024;
Serial.print("BYTES :\t");
Serial.println(sizeInBytes);
delay(100);
Serial.println("\nSPEED :\t100000");
Wire.setClock(100000);
test();
Serial.println("\nSPEED :\t200000");
Wire.setClock(200000);
test();
Serial.println("\nSPEED :\t400000");
Wire.setClock(400000);
test();
Serial.println("done...");
}
void loop()
{
}
void test()
{
start = micros();
for (uint32_t addr = 0; addr < sizeInBytes; addr++)
{
fram.write8(addr, 0x00);
}
stop = micros();
Serial.print("BYTES 1:\t");
Serial.print(stop - start);
Serial.print(" ==> \t");
Serial.print((stop - start) * 1.0 / 32768.0);
Serial.println(" us/byte");
delay(100);
start = micros();
for (uint32_t addr = 0; addr < sizeInBytes; addr += 2)
{
fram.write16(addr, 0x0000);
}
stop = micros();
Serial.print("BYTES 2:\t");
Serial.print(stop - start);
Serial.print(" ==> \t");
Serial.print((stop - start) * 1.0 / 32768.0);
Serial.println(" us/byte");
delay(100);
start = micros();
for (uint32_t addr = 0; addr < sizeInBytes; addr += 4)
{
fram.write32(addr, 0x00000000);
}
stop = micros();
Serial.print("BYTES 4:\t");
Serial.print(stop - start);
Serial.print(" ==> \t");
Serial.print((stop - start) * 1.0 / 32768.0);
Serial.println(" us/byte");
delay(100);
uint8_t buf[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
start = micros();
for (uint32_t addr = 0; addr < sizeInBytes; addr += 8)
{
fram.write(addr, buf, 8);
}
stop = micros();
Serial.print("BYTES 8:\t");
Serial.print(stop - start);
Serial.print(" ==> \t");
Serial.print((stop - start) * 1.0 / 32768.0);
Serial.println(" us/byte");
delay(100);
start = micros();
for (uint32_t addr = 0; addr < sizeInBytes; addr += 16)
{
fram.write(addr, buf, 16);
}
stop = micros();
Serial.print("BYTES 16:\t");
Serial.print(stop - start);
Serial.print(" ==> \t");
Serial.print((stop - start) * 1.0 / 32768.0);
Serial.println(" us/byte");
delay(100);
}
// -- END OF FILE --

View File

@ -0,0 +1,25 @@
FRAM_LIB_VERSION: 0.3.4
BYTES : 32768
SPEED : 100000
BYTES 1: 14233452 ==> 434.37 us/byte
BYTES 2: 8763436 ==> 267.44 us/byte
BYTES 4: 6033312 ==> 184.12 us/byte
BYTES 8: 4652880 ==> 141.99 us/byte
BYTES 16: 3961276 ==> 120.89 us/byte
SPEED : 200000
BYTES 1: 8116408 ==> 247.69 us/byte
BYTES 2: 4961196 ==> 151.40 us/byte
BYTES 4: 3383204 ==> 103.25 us/byte
BYTES 8: 2589084 ==> 79.01 us/byte
BYTES 16: 2197032 ==> 67.05 us/byte
SPEED : 400000
BYTES 1: 5033228 ==> 153.60 us/byte
BYTES 2: 3050420 ==> 93.09 us/byte
BYTES 4: 2055052 ==> 62.72 us/byte
BYTES 8: 1557596 ==> 47.53 us/byte
BYTES 16: 1307132 ==> 39.89 us/byte
done...

View File

@ -54,7 +54,7 @@ void loop()
{
char buffer[24];
sprintf(buffer, "%ld\t%ld\n", millis(), random());
sprintf(buffer, "%ld\t%ld\n", millis(), random(1000000000UL));
Serial.print(buffer);
log2fram(buffer);
delay(1000);

View File

@ -0,0 +1,73 @@
//
// FILE: FRAM_readObject.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo reading objects
// URL: https://github.com/RobTillaart/FRAM_I2C
//
// experimental
#include "FRAM.h"
FRAM fram;
uint32_t start;
uint32_t stop;
uint32_t sizeInBytes = 0;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("FRAM_LIB_VERSION: ");
Serial.println(FRAM_LIB_VERSION);
Serial.println("\n run writeObject Demo first!\n");
Wire.begin();
int rv = fram.begin(0x50);
if (rv != 0)
{
Serial.print("INIT ERROR: ");
Serial.println(rv);
}
test_float();
test_struct();
}
void loop()
{
}
void test_float()
{
float x = 0;
Serial.println(x, 6);
fram.readObject(100, x);
Serial.println(x, 6);
}
struct point
{
float x;
float y;
float z;
} Q;
void test_struct()
{
fram.readObject(50, Q);
Serial.println(Q.x);
Serial.println(Q.y);
Serial.println(Q.z);
}
// -- END OF FILE --

View File

@ -0,0 +1,90 @@
//
// FILE: FRAM_writeObject.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo writing reading objects
// URL: https://github.com/RobTillaart/FRAM_I2C
//
// experimental
#include "FRAM.h"
FRAM fram;
uint32_t start;
uint32_t stop;
uint32_t sizeInBytes = 0;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("FRAM_LIB_VERSION: ");
Serial.println(FRAM_LIB_VERSION);
Wire.begin();
int rv = fram.begin(0x50);
if (rv != 0)
{
Serial.print("INIT ERROR: ");
Serial.println(rv);
}
// get size in bytes
sizeInBytes = fram.getSize() * 1024;
// clear FRAM
for (uint32_t addr = 0; addr < sizeInBytes; addr++)
{
fram.write8(addr, 0x00);
}
test_float();
test_struct();
}
void loop()
{
}
void test_float()
{
float x = 3.14159265;
Serial.println(x, 6);
fram.writeObject(100, x);
x = 1.0/x;
Serial.println(x, 6);
fram.readObject(100, x);
Serial.println(x, 6);
}
struct point
{
float x;
float y;
float z;
} P = {3.91, 5.24, 7.58};
void test_struct()
{
Serial.println(P.x);
Serial.println(P.y);
Serial.println(P.z);
fram.writeObject(50, P);
struct point Q;
fram.readObject(50, Q);
Serial.println(Q.x);
Serial.println(Q.y);
Serial.println(Q.z);
}
// -- END OF FILE --

View File

@ -0,0 +1,71 @@
//
// FILE: FRAM_writeObject.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo writing reading objects
// URL: https://github.com/RobTillaart/FRAM_I2C
//
// experimental
#include "FRAM.h"
FRAM fram;
uint32_t start;
uint32_t stop;
uint32_t sizeInBytes = 0;
float x[10];
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("FRAM_LIB_VERSION: ");
Serial.println(FRAM_LIB_VERSION);
Wire.begin();
int rv = fram.begin(0x50);
if (rv != 0)
{
Serial.print("INIT ERROR: ");
Serial.println(rv);
}
// FILL AND WRITE 10 FLOATS
uint16_t address = 100;
for (int i = 0; i < 10; i++)
{
x[i] = random(1000) / 3.14159265;
Serial.println(x[i], 5);
address = fram.writeObject(address, x[i]);
}
Serial.println();
// CLEAR THE ARRAY
for (int i = 0; i < 10; i++)
{
x[i] = 0;
Serial.println(x[i], 5);
}
Serial.println();
// READ BACK 10 FLOATS
address = 100;
for (int i = 0; i < 10; i++)
{
address = fram.readObject(address, x[i]);
Serial.println(x[i], 5);
}
Serial.println();
Serial.println("done...");
}
void loop()
{
}
// -- END OF FILE --

View File

@ -0,0 +1,42 @@
Sketch: testFRAMPerformance.ino
Platform: UNO
IDE: 1.18.19
FRAM_LIB_VERSION: 0.3.4
CLOCK: 100000
WRITE 1200 bytes TIME: 136704 us ==> 113.92 us/byte.
READ 1200 bytes TIME: 141708 us ==> 118.09 us/byte.
CLOCK: 200000
WRITE 1200 bytes TIME: 75420 us ==> 62.85 us/byte.
READ 1200 bytes TIME: 78016 us ==> 65.01 us/byte.
CLOCK: 300000
WRITE 1200 bytes TIME: 53976 us ==> 44.98 us/byte.
READ 1200 bytes TIME: 55540 us ==> 46.28 us/byte.
CLOCK: 400000
WRITE 1200 bytes TIME: 44856 us ==> 37.38 us/byte.
READ 1200 bytes TIME: 46044 us ==> 38.37 us/byte.
CLOCK: 500000
WRITE 1200 bytes TIME: 38708 us ==> 32.26 us/byte.
READ 1200 bytes TIME: 39572 us ==> 32.98 us/byte.
CLOCK: 600000
WRITE 1200 bytes TIME: 34920 us ==> 29.10 us/byte.
READ 1200 bytes TIME: 35740 us ==> 29.78 us/byte.
CLOCK: 700000
WRITE 1200 bytes TIME: 32576 us ==> 27.15 us/byte.
READ 1200 bytes TIME: 33228 us ==> 27.69 us/byte.
CLOCK: 800000
WRITE 1200 bytes TIME: 30992 us ==> 25.83 us/byte.
READ 1200 bytes TIME: 31560 us ==> 26.30 us/byte.
done...

View File

@ -14,7 +14,7 @@ FRAM fram;
uint32_t start;
uint32_t stop;
int ar[600];
int ar[600]; // 1200 bytes
void setup()
@ -56,26 +56,29 @@ void loop()
void testReadWriteLarge()
{
Serial.println();
Serial.println(__FUNCTION__);
for (int i = 0; i < 600; i++) ar[i] = i;
start = millis();
start = micros();
fram.write(1000, (uint8_t*)ar, 1200);
stop = millis();
Serial.print("WRITE 1200 bytes TIME:\t");
stop = micros();
Serial.print("WRITE 1200 bytes TIME: \t");
Serial.print(stop - start);
Serial.println(" ms");
Serial.print(" us ==> \t");
Serial.print((stop - start) / 1200.0, 2);
Serial.println(" us/byte.");
delay(100);
for (int i = 0; i < 600; i++) ar[i] = 0;
start = millis();
start = micros();
fram.read(1000, (uint8_t*)ar, 1200);
stop = millis();
Serial.print("READ 1200 bytes TIME:\t");
stop = micros();
Serial.print("READ 1200 bytes TIME: \t");
Serial.print(stop - start);
Serial.println(" ms");
Serial.print(" us ==> \t");
Serial.print((stop - start) / 1200.0, 2);
Serial.println(" us/byte.");
delay(100);
for (int i = 0; i < 600; i++)
{

View File

@ -18,6 +18,9 @@ read16 KEYWORD2
read32 KEYWORD2
read KEYWORD2
writeObject KEYWORD2
readObject KEYWORD2
setWriteProtect KEYWORD2
getWriteProtect KEYWORD2

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/FRAM_I2C.git"
},
"version": "0.3.3",
"version": "0.3.4",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",

View File

@ -1,5 +1,5 @@
name=FRAM_I2C
version=0.3.3
version=0.3.4
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for I2C FRAM.

View File

@ -1,46 +0,0 @@
# FRAM I2C library
## Release notes
## 0.3.3 2022-02-08
- added **getSizeBytes()**
- created releaseNotes.md
- updated readme.md
- add example FRAM_logging.ino
## 0.3.2 2021-12-18
- update Arduino-CI,
- add badges in readme.md
- update library.json,
- update license,
- minor edits
## 0.3.1 2021-02-05
- fix #7 typo in .cpp
## 0.3.0 2021-01-13
- fix #2 ESP32
- add WireN support
## 0.2.3 2021-01-11
- fix getMetaData (kudos to PraxisSoft)
## 0.2.2 2020-12-23
- add Arduino-CI + unit test
- add **getWriteProtect()**
## 0.2.1 2020-06-10
- fix library.json
## 0.2.0 2020-04-30
- refactor,
- add writeProtectPin code
## 0.1.1 2019-07-31
- added support for Fujitsu 64Kbit MB85RC64T (kudos to ysoyipek)
## 0.1.0 2018-01-24
- initial version