0.3.6 FRAM_I2C

This commit is contained in:
rob tillaart 2022-05-02 16:06:10 +02:00
parent 3d8ebd4dfc
commit 5f418397a8
8 changed files with 265 additions and 24 deletions

View File

@ -5,20 +5,34 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/). and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.3.6] - 2022-05-02
### Added
- add **void sleep()** experimental.
- add **bool wakeup(trec = 400)** experimental. wakeup time of 400us. returns true if connected after call.
- add example **FRAM_sleep.ino**
### Changed
- updated readme.md
- updated keywords.txt
### Fixed
- minor edits
## [0.3.5] - 2022-03-23 ## [0.3.5] - 2022-03-23
### Added ### Added
- add **uint32_t clear(uint8_t value = 0)** - add **uint32_t clear(uint8_t value = 0)**
- add **void setSizeBytes(uint32_t value)** - add **void setSizeBytes(uint32_t value)**
- added defines for size of known types for e.g. **void setSizeBytes(uint32_t value)** - added defines for size of known types for e.g. **void setSizeBytes(uint32_t value)**
- add _sizeinBytes private var. Needed in clear a.o. - add \_sizeinBytes private var. Needed in clear a.o.
### Changed ### Changed
- **getSize()** automatically called in **begin()** - **getSize()** automatically called in **begin()**
- updated example **FRAM_clear.ino** - updated example **FRAM_clear.ino**
- renamed private functions with _ - renamed private functions with \_
- updated readme.md - updated readme.md
-
### Fixed ### Fixed

View File

@ -1,7 +1,7 @@
// //
// FILE: FRAM.cpp // FILE: FRAM.cpp
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.3.5 // VERSION: 0.3.6
// DATE: 2018-01-24 // DATE: 2018-01-24
// PURPOSE: Arduino library for I2C FRAM // PURPOSE: Arduino library for I2C FRAM
// URL: https://github.com/RobTillaart/FRAM_I2C // URL: https://github.com/RobTillaart/FRAM_I2C
@ -20,8 +20,9 @@
#define FRAM_MB85RC1M 0x07 #define FRAM_MB85RC1M 0x07
// used for metadata // used for metadata and sleep
const uint8_t FRAM_SLAVE_ID_= 0x7C; const uint8_t FRAM_SLAVE_ID_ = 0x7C; // == 0xF8
const uint8_t FRAM_SLEEP_CMD = 0x86; //
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
@ -230,6 +231,30 @@ uint32_t FRAM::clear(uint8_t value)
} }
// EXPERIMENTAL - to be confirmed
// page 12 datasheet
// command = S 0xF8 A address A S 86 A P (A = Ack from slave )
void FRAM::sleep()
{
_wire->beginTransmission(FRAM_SLAVE_ID_); // S 0xF8
_wire->write(_address << 1); // address << 1
_wire->endTransmission(false); // no stoP
_wire->beginTransmission(FRAM_SLEEP_CMD >> 1); // S 0x86
_wire->endTransmission(true); // stoP
}
// page 12 datasheet trec <= 400us
bool FRAM::wakeup(uint32_t trec)
{
bool b = isConnected(); // wakeup
if (trec == 0) return b;
// wait recovery time
delayMicroseconds(trec);
return isConnected(); // check recovery OK
}
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// //
// PRIVATE // PRIVATE

View File

@ -2,7 +2,7 @@
// //
// FILE: FRAM.h // FILE: FRAM.h
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.3.5 // VERSION: 0.3.6
// DATE: 2018-01-24 // DATE: 2018-01-24
// PURPOSE: Arduino library for I2C FRAM // PURPOSE: Arduino library for I2C FRAM
// URL: https://github.com/RobTillaart/FRAM_I2C // URL: https://github.com/RobTillaart/FRAM_I2C
@ -13,7 +13,7 @@
#include "Wire.h" #include "Wire.h"
#define FRAM_LIB_VERSION (F("0.3.5")) #define FRAM_LIB_VERSION (F("0.3.6"))
#define FRAM_OK 0 #define FRAM_OK 0
@ -76,8 +76,11 @@ public:
uint32_t getSizeBytes() { return _sizeBytes; }; // Returns size in BYTE uint32_t getSizeBytes() { return _sizeBytes; }; // Returns size in BYTE
void setSizeBytes(uint32_t value); // override when getSize() fails == 0 void setSizeBytes(uint32_t value); // override when getSize() fails == 0
// 0.3.5 uint32_t clear(uint8_t value = 0); // fills FRAM with value
uint32_t clear(uint8_t value = 0);
// 0.3.6
void sleep();
bool wakeup(uint32_t trec = 400); // trec <= 400us P12
private: private:

View File

@ -17,28 +17,27 @@ 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 Another important feature it has in common with EEPROM is that FRAM keeps
its content after a reboot as it is non-volatile. its content after a reboot as it is non-volatile.
That makes it ideal to store configuration or logging That makes it ideal to store configuration or logging data in a project.
data in a project.
FRAM stands for Ferroelectric RAM - https://en.wikipedia.org/wiki/Ferroelectric_RAM FRAM stands for Ferroelectric RAM - https://en.wikipedia.org/wiki/Ferroelectric_RAM
Types of FRAM the library should work with Types of FRAM the library should work with the library:
| TYPE | SIZE | TESTED | NOTES | | TYPE | SIZE | TESTED | NOTES |
|:----------:|-------:|:------:|:---------------------| |:----------:|-------:|:------:|:---------------------|
| MB85RC04 | 512 | | no deviceID register | | MB85RC04 | 512 | | no deviceID register |
| MB85RC16 | 2 KB | | no deviceID register | | MB85RC16 | 2 KB | | no deviceID register |
| MB85RC64T | 8 KB | Y | | MB85RC64T | 8 KB | Y | |
| MB85RC128A | 16 KB | | no deviceID register | | MB85RC128A | 16 KB | | no deviceID register |
| MB85RC256V | 32 KB | | | MB85RC256V | 32 KB | Y | |
| MB85RC512T | 64 KB | Y | | MB85RC512T | 64 KB | Y | |
| MB85RC1MT | 128 KB | | 16 bit address problem? to be tested | | MB85RC1MT | 128 KB | | 16 bit address problem? to be tested |
Notes
#### Notes
- Not all types of FRAM are tested. Please 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. - If there is no deviceID **getSize()** will not work correctly.
- Address = 0x50 (default) .. 0x57, depends on the lines A0..A2.
Address = 0x50 (default) .. 0x57, depends on the lines A0..A2.
## Interface ## Interface
@ -67,8 +66,10 @@ Support for basic types and 2 calls for generic object, use casting if needed.
One needs to allocate memory as the function won't. One needs to allocate memory as the function won't.
(0.3.4 added template functions, see issue #13 ) (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 writeObject(uint16_t memaddr, T &obj)** writes an object to memaddr (and following bytes).
- **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. 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.
(0.3.5 added) (0.3.5 added)
- **uint32_t clear(uint8_t value = 0)** clears the whole FRAM by writing value to all addresses - default zero's. - **uint32_t clear(uint8_t value = 0)** clears the whole FRAM by writing value to all addresses - default zero's.
@ -94,6 +95,47 @@ To be used only if **getSize()** cannot determine the size.
See also remark in Future section below. See also remark in Future section below.
### Sleep
(0.3.6 added - experimental)
- **void sleep()** puts the FRAM in sleep mode so it uses less power.
Still needs a power test for 2 types of FRAM.
- **bool wakeup(uint32_t trec = 400)** tries to wake up the device with a default recovery time of 400 microseconds.
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 | N | - | N | |
| MB85RC16 | 2 KB | N | - | N | |
| MB85RC64T | 8 KB | Y Page 11 | 4.0 uA* | N | |
| MB85RC128A | 16 KB | N | - | N | |
| MB85RC256V | 32 KB | N | - | N | |
| MB85RC512T | 64 KB | Y Page 12 | 4.0 uA* | N | |
| MB85RC1MT | 128 KB | Y Page 12 | 3.6 uA | Y | See #17 |
_current with \* are from datasheet_
### Current
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 |
_TODO fill the table_
## Operational ## Operational
@ -103,7 +145,7 @@ See also remark in Future section below.
## Future ## Future
### high ### high
- 32 bits addresses to support MB85RC1MT. - 32 bits addresses to support MB85RC1MT (to be verified if needed).
- no explicit request yet (0.4.0) - no explicit request yet (0.4.0)
### medium ### medium
@ -122,6 +164,7 @@ See also remark in Future section below.
- test more types of FRAM - test more types of FRAM
- **getSize()** scanning FRAM like EEPROM library? - **getSize()** scanning FRAM like EEPROM library?
- remember last written address? why? - remember last written address? why?
- fill power usage table
### wont ### wont
- extend current **clear()** with partial **clear(begin, end, value)**? - extend current **clear()** with partial **clear(begin, end, value)**?

View File

@ -0,0 +1,154 @@
//
// FILE: FRAM_sleep.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo sleep FRAM
// URL: https://github.com/RobTillaart/FRAM_I2C
#include "FRAM.h"
FRAM fram;
uint32_t start;
uint32_t stop;
uint32_t sizeInBytes = 0;
const int LED = 13; // adjust if needed
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("FRAM_LIB_VERSION: ");
Serial.println(FRAM_LIB_VERSION);
pinMode(LED, OUTPUT);
digitalWrite(LED, LOW);
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);
}
void loop()
{
fram.sleep();
digitalWrite(LED, LOW);
delay(3000);
fram.wakeup();
digitalWrite(LED, HIGH);
fram.clear();
delay(1000);
}
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);
start = micros();
fram.clear();
stop = micros();
Serial.print("CLEAR():\t");
Serial.print(stop - start);
Serial.print(" ==> \t");
Serial.print((stop - start) * 1.0 / 32768.0);
Serial.println(" us/byte");
delay(100);
start = micros();
fram.clear(0xFF);
stop = micros();
Serial.print("CLEAR(0xFF):\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

@ -31,6 +31,8 @@ getSizeBytes KEYWORD2
setSizeBytes KEYWORD2 setSizeBytes KEYWORD2
clear KEYWORD2 clear KEYWORD2
sleep KEYWORD2
wakeup KEYWORD2
# Constants (LITERAL1) # Constants (LITERAL1)

View File

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

View File

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