0.7.0 FRAM_I2C

This commit is contained in:
Rob Tillaart 2023-10-30 17:08:58 +01:00
parent e09e9a6316
commit b61abd20e7
12 changed files with 609 additions and 93 deletions

View File

@ -5,11 +5,20 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.7.0] - 2023-10-30
- refactor / simplify begin() =>
- User has to call Wire.begin() explicitly.
- improves support for RP2040 (setSDA/SetSCL).
- add example for ESP32 => use Wire1 and set pins (SDA/SCL).
- Add example for RP2040 => setSDA() + setSCL()
- update badges in some document.md files.
----
## [0.6.1] - 2023-09-16
- add Wire1 support for ESP32
- fix changelog.md
## [0.6.0] - 2023-09-16
- fix #42 ReadObject, WriteObject for FRAM32
- add examples

View File

@ -1,7 +1,7 @@
//
// FILE: FRAM.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.6.1
// VERSION: 0.7.0
// DATE: 2018-01-24
// PURPOSE: Arduino library for I2C FRAM
// URL: https://github.com/RobTillaart/FRAM_I2C
@ -36,40 +36,12 @@ FRAM::FRAM(TwoWire *wire)
}
#if defined (ESP8266) || defined(ESP32)
int FRAM::begin(int sda, int scl, const uint8_t address,
const int8_t writeProtectPin)
{
if ((address < 0x50) || (address > 0x57)) return FRAM_ERROR_ADDR;
_address = address;
if ((sda < 255) && (scl < 255))
{
_wire->begin(sda, scl);
} else {
_wire->begin();
}
if (writeProtectPin > -1)
{
_writeProtectPin = writeProtectPin;
pinMode(_writeProtectPin, OUTPUT);
}
if (! isConnected()) return FRAM_ERROR_CONNECT;
getSize();
return FRAM_OK;
}
#endif
int FRAM::begin(const uint8_t address,
const int8_t writeProtectPin)
{
if ((address < 0x50) || (address > 0x57)) return FRAM_ERROR_ADDR;
_address = address;
_wire->begin();
if (writeProtectPin > -1)
{
_writeProtectPin = writeProtectPin;
@ -652,17 +624,6 @@ FRAM11::FRAM11(TwoWire *wire) : FRAM(wire)
}
#if defined (ESP8266) || defined(ESP32)
int FRAM11::begin(int sda, int scl, const uint8_t address,
const int8_t writeProtectPin)
{
int rv = FRAM::begin(sda, scl, address, writeProtectPin);
_sizeBytes = 2048;
return rv;
}
#endif
int FRAM11::begin(const uint8_t address, const int8_t writeProtectPin)
{
int rv = FRAM::begin(address, writeProtectPin);
@ -726,17 +687,6 @@ FRAM9::FRAM9(TwoWire *wire) : FRAM(wire)
}
#if defined (ESP8266) || defined(ESP32)
int FRAM9::begin(int sda, int scl, const uint8_t address,
const int8_t writeProtectPin)
{
int rv = FRAM::begin(sda, scl, address, writeProtectPin);
_sizeBytes = 512;
return rv;
}
#endif
int FRAM9::begin(const uint8_t address, const int8_t writeProtectPin)
{
int rv = FRAM::begin(address, writeProtectPin);

View File

@ -2,7 +2,7 @@
//
// FILE: FRAM.h
// AUTHOR: Rob Tillaart
// VERSION: 0.6.1
// VERSION: 0.7.0
// DATE: 2018-01-24
// PURPOSE: Arduino library for I2C FRAM
// URL: https://github.com/RobTillaart/FRAM_I2C
@ -12,7 +12,7 @@
#include "Wire.h"
#define FRAM_LIB_VERSION (F("0.6.1"))
#define FRAM_LIB_VERSION (F("0.7.0"))
#define FRAM_OK 0
@ -36,12 +36,8 @@ class FRAM
public:
FRAM(TwoWire *wire = &Wire);
#if defined (ESP8266) || defined(ESP32)
// address and writeProtectPin is optional
int begin(int sda, int scl, const uint8_t address = 0x50,
const int8_t writeProtectPin = -1);
#endif
// address and writeProtectPin is optional
// user has to call Wire.begin() before FRAM.begin().
int begin(const uint8_t address = 0x50,
const int8_t writeProtectPin = -1);
bool isConnected();
@ -206,11 +202,6 @@ class FRAM11 : public FRAM
public:
FRAM11(TwoWire *wire = &Wire);
#if defined (ESP8266) || defined(ESP32)
// address and writeProtectPin is optional
int begin(int sda, int scl, const uint8_t address = 0x50,
const int8_t writeProtectPin = -1);
#endif
// address and writeProtectPin is optional
int begin(const uint8_t address = 0x50,
const int8_t writeProtectPin = -1);
@ -234,11 +225,6 @@ class FRAM9 : public FRAM
public:
FRAM9(TwoWire *wire = &Wire);
#if defined (ESP8266) || defined(ESP32)
// address and writeProtectPin is optional
int begin(int sda, int scl, const uint8_t address = 0x50,
const int8_t writeProtectPin = -1);
#endif
// address and writeProtectPin is optional
int begin(const uint8_t address = 0x50,
const int8_t writeProtectPin = -1);

View File

@ -2,8 +2,11 @@
[![Arduino CI](https://github.com/RobTillaart/FRAM_I2C/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
[![Arduino-lint](https://github.com/RobTillaart/FRAM_I2C/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/FRAM_I2C/actions/workflows/arduino-lint.yml)
[![JSON check](https://github.com/RobTillaart/FRAM_I2C/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/FRAM_I2C/actions/workflows/jsoncheck.yml)
[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/FRAM_I2C.svg)](https://github.com/RobTillaart/FRAM_I2C/issues)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/FRAM_I2C/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/FRAM_I2C.svg?maxAge=3600)](https://github.com/RobTillaart/FRAM_I2C/releases)
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/FRAM_I2C.svg)](https://registry.platformio.org/libraries/robtillaart/FRAM_I2C)
# FRAM_MULTILANGUAGE

View File

@ -2,8 +2,11 @@
[![Arduino CI](https://github.com/RobTillaart/FRAM_I2C/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
[![Arduino-lint](https://github.com/RobTillaart/FRAM_I2C/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/FRAM_I2C/actions/workflows/arduino-lint.yml)
[![JSON check](https://github.com/RobTillaart/FRAM_I2C/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/FRAM_I2C/actions/workflows/jsoncheck.yml)
[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/FRAM_I2C.svg)](https://github.com/RobTillaart/FRAM_I2C/issues)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/FRAM_I2C/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/FRAM_I2C.svg?maxAge=3600)](https://github.com/RobTillaart/FRAM_I2C/releases)
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/FRAM_I2C.svg)](https://registry.platformio.org/libraries/robtillaart/FRAM_I2C)
# FRAM_RINGBUFFER

View File

@ -33,7 +33,14 @@ Another important feature FRAM has in common with EEPROM is that FRAM keeps
its content after a reboot as it is non-volatile, even for years.
That makes it ideal to store configuration or logging data in a project.
Types of FRAM that should work with this library:
Last but not least FRAM allows much more write cycles than any EEPROM.
Typical FRAM allows 10^12 write cycles (see datasheet) where an ATMEGA328 (UNO)
supports 10^5 write cycles (https://docs.arduino.cc/learn/built-in-libraries/eeprom). That is a factor of 10 million more write cycles.
#### Fujitsu
Types of FRAM tested with this library:
| TYPE | SIZE | TESTED | NOTES | uses | ref |
|:------------:|---------:|:--------:|:-----------------------|:---------|:-----:|
@ -46,13 +53,21 @@ Types of FRAM that should work with this library:
| MB85RC512T | 64 KB | Y | | FRAM | |
| MB85RC1MT | 128 KB | Y | | FRAM32 | #19 |
MB85RC128A and MB85RC64V have no size / deviceID, **clear()** will not work correctly, unless
one calls **setSizeBytes(16 \* 1024)** or **setSizeBytes(8 \* 1024)** to set the size manually.
For the FRAM9 and FRAM11 the size problem is solved (hard coded) in their class.
#### Ramtron
Types of FRAM tested with this library:
| TYPE | SIZE | TESTED | NOTES | uses | ref | Notes |
|:------------:|---------:|:--------:|:-----------------------|:---------|:-----:|:--------|
| FM24C256-G | 32 KB | Y | no deviceID register | FRAM | #45 | test with ESP32
#### Notes
- Not all types of FRAM are tested. Please let me know if you have verified one that is not in the list.
@ -92,10 +107,10 @@ specific for devices with 9 bit address e.g. **MB85RC04**.
### Begin
The user has to call **Wire.begin()** before **FRAM.begin()**!
- **int begin(uint8_t address = 0x50, int8_t writeProtectPin = -1)** address and writeProtectPin is optional.
Note the **MB85RC1MT** only uses even addresses.
- **int begin(int sda, int scl, uint8_t address = 0x50, int8_t writeProtectPin = -1)** idem for ESP32 a.o.
- **bool isConnected()** checks if the address set by begin() is visible on the I2C bus.
### Write & read
@ -228,15 +243,16 @@ Returns true if connected after the call.
According to the data sheets there are only three FRAM devices support the sleep command.
So use with care.
| TYPE | SIZE | SLEEP (datasheet) | CURRENT | CONFIRMED | NOTES |
|:------------:|-------:|:------------------:|:---------:|:-----------:|:----------|
| MB85RC04 | 512 | not supported | - | N | |
| MB85RC16 | 2 KB | not supported | - | N | |
| MB85RC64T | 8 KB | Y Page 11 | 4.0 uA* | N | |
| MB85RC128A | 16 KB | not supported | - | N | |
| MB85RC256V | 32 KB | not supported | - | Y | |
| MB85RC512T | 64 KB | Y Page 12 | 4.0 uA* | N | |
| MB85RC1MT | 128 KB | Y Page 12 | 3.6 uA | Y | See #17 |
| TYPE | SIZE | SLEEP (datasheet) | CURRENT | CONFIRMED | NOTES |
|:------------:|--------:|:------------------:|:---------:|:-----------:|:----------|
| MB85RC04 | 512 | not supported | - | N |
| MB85RC16 | 2 KB | not supported | - | N |
| MB85RC64T | 8 KB | Y Page 11 | 4.0 uA\* | N |
| MB85RC128A | 16 KB | not supported | - | N |
| MB85RC256V | 32 KB | not supported | - | Y |
| MB85RC512T | 64 KB | Y Page 12 | 4.0 uA\* | N |
| MB85RC1MT | 128 KB | Y Page 12 | 3.6 uA | Y | See #17
| FM24C256-G | 32 KB | not supported | | Y | See #45
_current with \* are from datasheet_
@ -246,15 +262,17 @@ _current with \* are from datasheet_
Indicative power usage in uA in three modi (if supported).
| TYPE | SIZE | STANDBY | WRITE | SLEEP | NOTES |
|:----------:|-------:|:--------:|:---------:|:---------:|:--------|
| MB85RC04 | 512 | | | - | |
| MB85RC16 | 2 KB | | | - | |
| MB85RC64T | 8 KB | | | 4.0 uA | |
| MB85RC128A | 16 KB | | | - | |
| MB85RC256V | 32 KB | 10.22 uA | 93.48 uA | - | |
| MB85RC512T | 64 KB | | | 4.0 uA | |
| MB85RC1MT | 128 KB | 11.7 uA | 46-721 uA | 3.6 uA | See #17 |
| TYPE | SIZE | STANDBY | WRITE | SLEEP | NOTES |
|:----------:|-------:|:---------:|:---------:|:---------:|:--------|
| MB85RC04 | 512 | | | - |
| MB85RC16 | 2 KB | | | - |
| MB85RC64T | 8 KB | | | 4.0 uA |
| MB85RC128A | 16 KB | | | - |
| MB85RC256V | 32 KB | 10.22 uA | 93.48 uA | - |
| MB85RC512T | 64 KB | | | 4.0 uA |
| MB85RC1MT | 128 KB | 11.7 uA | 46-721 uA | 3.6 uA | See #17
| FM24C256-G | 32 KB | 100 uA | | | See #45
_TODO: fill the table_
@ -325,6 +343,8 @@ Use **getSizeBytes()** to get 512.
- fill power usage table (documentation)
- is in data sheet.
- improve comments where needed.
- move the device address parameter to the constructor so it becomes "unmutable"?
would break the interface (even more).
#### Wont

View File

@ -0,0 +1,29 @@
platforms:
rpipico:
board: rp2040:rp2040:rpipico
package: rp2040:rp2040
gcc:
features:
defines:
- ARDUINO_ARCH_RP2040
warnings:
flags:
packages:
rp2040:rp2040:
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
# - uno
# - due
# - zero
# - leonardo
# - m4
- esp32
# - esp8266
# - mega2560
# - rpipico
# - nano_every

View File

@ -0,0 +1,242 @@
//
// FILE: FRAM_ESP32_Wire1.ino
// AUTHOR: Rob Tillaart
// PURPOSE: test for FRAM library for Arduino
// URL: https://github.com/RobTillaart/FRAM_I2C
#include "FRAM.h"
FRAM fram(&Wire1);
uint32_t start;
uint32_t stop;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("FRAM_LIB_VERSION: ");
Serial.println(FRAM_LIB_VERSION);
Wire1.begin(25, 26); // optional adjust pins.
int rv = fram.begin(0x50);
if (rv != 0)
{
Serial.println(rv);
}
else
{
testID();
testFRAMmemory();
testReadWriteSmall();
testReadWriteLarge();
testWriteText();
testReadText1();
testReadText2();
}
Serial.println("done...");
}
void loop()
{
}
void testID()
{
Serial.println();
Serial.println(__FUNCTION__);
Serial.print("ManufacturerID: ");
Serial.println(fram.getManufacturerID());
Serial.print(" ProductID: ");
Serial.println(fram.getProductID());
Serial.print(" memory KB: ");
Serial.println(fram.getSize());
Serial.println();
}
void testFRAMmemory()
{
Serial.println();
Serial.println(__FUNCTION__);
Serial.println("takes ~32 seconds");
start = millis();
uint8_t val = 0x55;
for (uint16_t addr = 0; addr < 32768; addr++)
{
fram.write8(addr, val);
if (fram.read8(addr) != 0x55)
{
Serial.print("FAIL: \t");
Serial.println(addr);
}
if (addr % 1000 == 0)
{
Serial.print(".");
}
}
stop = millis();
Serial.println();
Serial.print("TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
Serial.println();
}
void testReadWriteSmall()
{
Serial.println();
Serial.println(__FUNCTION__);
Serial.print("test8:\t");
uint8_t t8 = 0xFE;
fram.write8(1000, t8);
if (fram.read8(1000) != 0xFE)
{
Serial.println("failed.");
}
else
{
Serial.println("ok.");
}
Serial.print("test16:\t");
uint16_t t16 = 0xFADE;
fram.write16(1000, t16);
if (fram.read16(1000) != 0xFADE)
{
Serial.println("failed.");
}
else
{
Serial.println("ok.");
}
Serial.print("test32:\t");
uint32_t t32 = 0xFADEFACE;
fram.write32(1000, t32);
if (fram.read32(1000) != 0xFADEFACE)
{
Serial.println("failed.");
}
else
{
Serial.println("ok.");
}
Serial.println();
}
void testReadWriteLarge()
{
Serial.println();
Serial.println(__FUNCTION__);
uint8_t ar[100];
for (int i = 0; i < 100; i++) ar[i] = i;
start = millis();
fram.write(1000, ar, 100);
stop = millis();
Serial.print("WRITE 100 bytes TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
for (int i = 0; i < 100; i++) ar[i] = 0;
start = millis();
fram.read(1000, ar, 100);
stop = millis();
Serial.print("READ 100 bytes TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
for (int i = 0; i < 100; i++)
{
if (ar[i] != i)
{
Serial.print("FAIL: \t");
Serial.println(i);
}
}
Serial.println();
}
void testWriteText()
{
char str[10][20] =
{
"Hello world 0",
"Hello world 1",
"Hello world 2",
"Hello world 3",
"Hello world 4",
"Hello world 5",
"Hello world 6",
"Hello world 7",
"Hello world 8",
"Hello world 9",
};
Serial.println();
Serial.println(__FUNCTION__);
start = millis();
fram.write(2000, (uint8_t *)str, 200);
stop = millis();
Serial.print("WRITE 200 bytes TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
Serial.println();
}
void testReadText1()
{
char str[10][20];
Serial.println();
Serial.println(__FUNCTION__);
start = millis();
fram.read(2000, (uint8_t *)str, 200);
stop = millis();
Serial.print("READ 200 bytes TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
Serial.println();
for (int i = 0; i < 10; i++)
{
Serial.println(str[i]);
}
Serial.println();
}
void testReadText2()
{
char str[20];
Serial.println();
Serial.println(__FUNCTION__);
for (int i = 0; i < 10; i++)
{
fram.read(2000 + 20 * i, (uint8_t *)str, 20);
Serial.println(str);
}
Serial.println();
}
// -- END OF FILE --

View File

@ -0,0 +1,29 @@
platforms:
rpipico:
board: rp2040:rp2040:rpipico
package: rp2040:rp2040
gcc:
features:
defines:
- ARDUINO_ARCH_RP2040
warnings:
flags:
packages:
rp2040:rp2040:
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
# - uno
# - due
# - zero
# - leonardo
# - m4
# - esp32
# - esp8266
# - mega2560
- rpipico
# - nano_every

View File

@ -0,0 +1,245 @@
//
// FILE: FRAM_RP2040.ino
// AUTHOR: Rob Tillaart
// PURPOSE: test for FRAM library for Arduino
// URL: https://github.com/RobTillaart/FRAM_I2C
#include "FRAM.h"
FRAM fram;
uint32_t start;
uint32_t stop;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("FRAM_LIB_VERSION: ");
Serial.println(FRAM_LIB_VERSION);
Wire.begin();
// optional adjust pins.
Wire.setSDA(12);
Wire.setSCL(14);
int rv = fram.begin(0x50);
if (rv != 0)
{
Serial.println(rv);
}
else
{
testID();
testFRAMmemory();
testReadWriteSmall();
testReadWriteLarge();
testWriteText();
testReadText1();
testReadText2();
}
Serial.println("done...");
}
void loop()
{
}
void testID()
{
Serial.println();
Serial.println(__FUNCTION__);
Serial.print("ManufacturerID: ");
Serial.println(fram.getManufacturerID());
Serial.print(" ProductID: ");
Serial.println(fram.getProductID());
Serial.print(" memory KB: ");
Serial.println(fram.getSize());
Serial.println();
}
void testFRAMmemory()
{
Serial.println();
Serial.println(__FUNCTION__);
Serial.println("takes ~32 seconds");
start = millis();
uint8_t val = 0x55;
for (uint16_t addr = 0; addr < 32768; addr++)
{
fram.write8(addr, val);
if (fram.read8(addr) != 0x55)
{
Serial.print("FAIL: \t");
Serial.println(addr);
}
if (addr % 1000 == 0)
{
Serial.print(".");
}
}
stop = millis();
Serial.println();
Serial.print("TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
Serial.println();
}
void testReadWriteSmall()
{
Serial.println();
Serial.println(__FUNCTION__);
Serial.print("test8:\t");
uint8_t t8 = 0xFE;
fram.write8(1000, t8);
if (fram.read8(1000) != 0xFE)
{
Serial.println("failed.");
}
else
{
Serial.println("ok.");
}
Serial.print("test16:\t");
uint16_t t16 = 0xFADE;
fram.write16(1000, t16);
if (fram.read16(1000) != 0xFADE)
{
Serial.println("failed.");
}
else
{
Serial.println("ok.");
}
Serial.print("test32:\t");
uint32_t t32 = 0xFADEFACE;
fram.write32(1000, t32);
if (fram.read32(1000) != 0xFADEFACE)
{
Serial.println("failed.");
}
else
{
Serial.println("ok.");
}
Serial.println();
}
void testReadWriteLarge()
{
Serial.println();
Serial.println(__FUNCTION__);
uint8_t ar[100];
for (int i = 0; i < 100; i++) ar[i] = i;
start = millis();
fram.write(1000, ar, 100);
stop = millis();
Serial.print("WRITE 100 bytes TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
for (int i = 0; i < 100; i++) ar[i] = 0;
start = millis();
fram.read(1000, ar, 100);
stop = millis();
Serial.print("READ 100 bytes TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
for (int i = 0; i < 100; i++)
{
if (ar[i] != i)
{
Serial.print("FAIL: \t");
Serial.println(i);
}
}
Serial.println();
}
void testWriteText()
{
char str[10][20] =
{
"Hello world 0",
"Hello world 1",
"Hello world 2",
"Hello world 3",
"Hello world 4",
"Hello world 5",
"Hello world 6",
"Hello world 7",
"Hello world 8",
"Hello world 9",
};
Serial.println();
Serial.println(__FUNCTION__);
start = millis();
fram.write(2000, (uint8_t *)str, 200);
stop = millis();
Serial.print("WRITE 200 bytes TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
Serial.println();
}
void testReadText1()
{
char str[10][20];
Serial.println();
Serial.println(__FUNCTION__);
start = millis();
fram.read(2000, (uint8_t *)str, 200);
stop = millis();
Serial.print("READ 200 bytes TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
Serial.println();
for (int i = 0; i < 10; i++)
{
Serial.println(str[i]);
}
Serial.println();
}
void testReadText2()
{
char str[20];
Serial.println();
Serial.println(__FUNCTION__);
for (int i = 0; i < 10; i++)
{
fram.read(2000 + 20 * i, (uint8_t *)str, 20);
Serial.println(str);
}
Serial.println();
}
// -- END OF FILE --

View File

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

View File

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