GY-63_MS5611/libraries/FRAM_I2C/README.md

346 lines
14 KiB
Markdown
Raw Normal View History

2021-01-29 06:31:58 -05:00
[![Arduino CI](https://github.com/RobTillaart/FRAM_I2C/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
2021-12-18 09:02:32 -05:00
[![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)
2023-09-07 08:07:49 -04:00
[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/FRAM_I2C.svg)](https://github.com/RobTillaart/FRAM_I2C/issues)
2021-01-29 06:31:58 -05:00
[![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)
2023-09-07 08:07:49 -04:00
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/FRAM_I2C.svg)](https://registry.platformio.org/libraries/robtillaart/FRAM_I2C)
2021-01-29 06:31:58 -05:00
# FRAM_I2C
2022-02-08 10:47:34 -05:00
Arduino library for I2C FRAM.
2021-01-29 06:31:58 -05:00
## Description
2022-02-08 10:47:34 -05:00
FRAM is a library to read from and write to (over I2C) an FRAM module.
2023-02-26 09:02:10 -05:00
The library has (since 0.5.0) four classes
- **FRAM** 16 bit address.
- **FRAM32** 32 (17) bit address.
2023-05-01 10:00:11 -04:00
- **FRAM11** 11 bit address.
- **FRAM9** 9 bit address.
2023-02-26 09:02:10 -05:00
Currently only the **MB85RC1MT** is known to use 32 bit.
2022-10-16 13:09:32 -04:00
**FRAM32** can also address 16 bit devices although there is some overhead in footprint.
2021-12-18 09:02:32 -05:00
FRAM stands for Ferroelectric RAM - https://en.wikipedia.org/wiki/Ferroelectric_RAM
2021-01-29 06:31:58 -05:00
2022-05-10 04:10:44 -04:00
FRAM memory is much faster than EEPROM and almost as fast as (Arduino UNO) RAM.
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:
2021-01-29 06:31:58 -05:00
2023-05-01 10:00:11 -04:00
| TYPE | SIZE | TESTED | NOTES | uses | ref |
|:------------:|---------:|:--------:|:-----------------------|:---------|:-----:|
| MB85RC04 | 512 | Y | no deviceID register | FRAM9 | #35 |
| MB85RC16 | 2 KB | Y | no deviceID register | FRAM11 | #28 |
| MB85RC64T | 8 KB | Y | | FRAM | |
2023-09-07 08:07:49 -04:00
| MB85RC64V | 8 KB | Y | no deviceID register | FRAM | #38 |
2023-05-01 10:00:11 -04:00
| MB85RC128A | 16 KB | N | no deviceID register | FRAM | |
| MB85RC256V | 32 KB | Y | | FRAM | |
| MB85RC512T | 64 KB | Y | | FRAM | |
| MB85RC1MT | 128 KB | Y | | FRAM32 | #19 |
2023-02-26 09:02:10 -05:00
2023-09-07 08:07:49 -04:00
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.
2023-05-01 10:00:11 -04:00
For the FRAM9 and FRAM11 the size problem is solved (hard coded) in their class.
2021-01-29 06:31:58 -05:00
2022-05-02 10:06:10 -04:00
#### Notes
2022-05-10 04:10:44 -04:00
- Not all types of FRAM are tested. Please let me know if you have verified one that is not in the list.
2022-02-08 10:47:34 -05:00
- If there is no deviceID **getSize()** will not work correctly.
2023-05-01 10:00:11 -04:00
- ==> fixed for FRAM9 and FRAM11
2022-05-02 10:06:10 -04:00
- Address = 0x50 (default) .. 0x57, depends on the lines A0..A2.
2023-02-26 09:02:10 -05:00
- **MB85RC1MT** uses even addresses only as it uses the next odd one internally.
So 0x50 uses 0x51 internally for the upper 64 KB block.
2023-05-01 10:00:11 -04:00
This latter will not be shown on an I2C scanner (to be tested).
2023-02-26 09:02:10 -05:00
Not tested: expect the **MB85RC1MT** can be addressed with 2 instances of **FRAM**
too with adjacent addresses.
2021-01-29 06:31:58 -05:00
## Interface
2023-02-26 09:02:10 -05:00
```cpp
#include "FRAM.h"
```
2022-02-08 10:47:34 -05:00
2023-02-26 09:02:10 -05:00
### Constructors
2021-01-29 06:31:58 -05:00
- **FRAM(TwoWire \*wire = &Wire)** Constructor with optional Wire interface.
2022-10-16 13:09:32 -04:00
- **FRAM32(TwoWire \*wire = &Wire)** Constructor with optional Wire interface,
2023-02-26 09:02:10 -05:00
specific for **MB85RC1MT** type of device, 17 bit address.
- **FRAM11(TwoWire \*wire = &Wire)** Constructor with optional Wire interface,
specific for devices with 11 bit address e.g. **Cypress/Infineon 24CL16B**.
- **FRAM9(TwoWire \*wire = &Wire)** Constructor with optional Wire interface,
specific for devices with 9 bit address e.g. **MB85RC04**.
### Begin
2021-12-18 09:02:32 -05:00
- **int begin(uint8_t address = 0x50, int8_t writeProtectPin = -1)** address and writeProtectPin is optional.
2022-10-16 13:09:32 -04:00
Note the **MB85RC1MT** only uses even addresses.
2022-09-25 04:04:25 -04:00
- **int begin(int sda, int scl, uint8_t address = 0x50, int8_t writeProtectPin = -1)** idem for ESP32 a.o.
2023-05-01 10:00:11 -04:00
- **bool isConnected()** checks if the address set by begin() is visible on the I2C bus.
2021-01-29 06:31:58 -05:00
### Write & read
2023-05-01 10:00:11 -04:00
Support for basic types and two calls for generic objects, use casting if needed.
2023-09-07 08:07:49 -04:00
In the **FRAM32** class these functions have an **uin32_t memAddr**.
- **void write8(uint16_t memAddr, uint8_t value)** uint8_t
- **void write16(uint16_t memAddr, uint16_t value)** uint16_t
- **void write32(uint16_t memAddr, uint32_t value)** uint32_t
- **void write64(uint16_t memAddr, uint64_t value)** uint64_t
- **void writeFloat(uint16_t memAddr, float value)** float
- **void writeDouble(uint16_t memAddr, double value)** double
2023-05-01 10:00:11 -04:00
- For boards that have an 8 byte double.
2023-09-07 08:07:49 -04:00
- **void write(uint16_t memAddr, uint8_t \* obj, uint16_t size)** other types / sizes.
- typical used for structs or text.
- **uint8_t read8(uint16_t memAddr)**
- **uint16_t read16(uint16_t memAddr)**
- **uint32_t read32(uint16_t memAddr)**
- **uint64_t read64(uint16_t memAddr)**
- **float readFloat(uint16_t memAddr)**
- **double readDouble(uint16_t memAddr)**
2023-05-01 10:00:11 -04:00
- For board that have 8 byte double.
2023-09-07 08:07:49 -04:00
- **void read(uint16_t memAddr, uint8_t uint8_t \* obj, uint16_t size)**
2023-05-01 10:00:11 -04:00
- One needs to allocate memory as the function won't.
- **uint32_t clear(uint8_t value = 0)** clears the whole FRAM by writing value to all addresses
- default value is all zero's.
- Returns the number of bytes written.
- **clear()** does not work for **MB85RC128A** unless **setSizeBytes()** is used.
2021-01-29 06:31:58 -05:00
2023-02-26 09:02:10 -05:00
2023-09-17 04:13:35 -04:00
(Template functions, see issue #13, #42)
2023-09-07 08:07:49 -04:00
- **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.
2022-03-18 08:37:57 -04:00
2023-02-26 09:02:10 -05:00
2023-05-01 10:00:11 -04:00
(Experimental 0.5.1, see issue #30)
2023-09-07 08:07:49 -04:00
- **int32_t readUntil(uint16_t memAddr, char \* buffer, uint16_t bufferLength, char separator)**
Reads FRAM from an address into **buffer** until separator is encountered.
2023-04-22 05:34:55 -04:00
The separator is replaced by an '\0' - end of char array.
**ReadUntil()** returns the length of the buffer.
2023-09-07 08:07:49 -04:00
To get the address of the next "field" one must add ```memAddr += (length + 1)```.
If the separator is not found after **bufferLength** characters the function returns -1.
2023-04-22 05:34:55 -04:00
However the buffer does contain the data read, which might be useful.
Handle with care as buffer has probably no '\0' end char.
2023-09-07 08:07:49 -04:00
- **int32_t readLine(uint16_t memAddr, char \* buffer, uint16_t bufferLength)**
2023-04-22 05:34:55 -04:00
Similar to **readUntil()**, reads a line from FRAM including the '\n'.
This '\n' is mandatory as end separator!.
Note: The buffer needs one extra char for the delimiting '\0' end char.
2023-09-07 08:07:49 -04:00
To get the address of the next "field" one must add ```memAddr += length```.
2023-04-22 05:34:55 -04:00
This is an minor but important difference with **readUntil()**.
Note: the returning buffer contains the '\n' so one need to take care when
printing the buffer.
### ReadUntil
2023-05-01 10:00:11 -04:00
**readUntil()** can be used to read lines and/or fields from an FRAM filled with text.
For example logging written with the FRAM_logging.ino example.
2023-09-07 08:07:49 -04:00
Note: if memAddr + bufferLength >= size of FRAM, memory wrapping may occur.
2023-04-22 05:34:55 -04:00
The library does not check, so the user should.
2023-09-07 08:07:49 -04:00
Note: internally **readUntil()** reads bufferLength bytes to fill the buffer.
2023-04-22 05:34:55 -04:00
Then it searches for the separator.
This is chosen to optimize performance for relative small buffers that are used most.
For large buffers this fetching of the whole buffer will take much time.
This can results in less responsiveness.
Increasing the I2C bus speed might compensate this a bit.
2023-05-01 10:00:11 -04:00
Finally the **FRAM_readUntil.ino** sketch has a **readUntil()** implementation
2023-04-22 05:34:55 -04:00
that uses a per byte fetching.
2022-03-25 05:04:48 -04:00
2021-01-29 06:31:58 -05:00
2023-05-01 10:00:11 -04:00
### Write-protect
Will work only if a writeProtectPin was defined in **begin()**
2021-01-29 06:31:58 -05:00
2023-04-22 05:34:55 -04:00
- **bool setWriteProtect(bool b)** make the FRAM write-protected by pulling the WP line HIGH or LOW.
2023-05-01 10:00:11 -04:00
- Returns true if a writeProtectPin was defined in **begin()**.
Otherwise the FRAM cannot be write protected.
2022-03-18 08:37:57 -04:00
- **bool getWriteProtect()** get current write protect status.
2023-05-01 10:00:11 -04:00
- returns status (true/false).
- Returns false if the writeProtectPin was not defined.
### Metadata
These may not work for devices that have no **deviceID** register.
So use with care.
- **uint16_t getManufacturerID()** see table below.
2023-09-07 08:07:49 -04:00
Returns 0x0FFF means **getMetaData()** had a read error.
2022-02-08 10:47:34 -05:00
- **uint16_t getProductID()** idem. Proprietary.
2023-09-07 08:07:49 -04:00
Returns 0x0FFF means **getMetaData()** had a read error.
2023-04-22 05:34:55 -04:00
- **uint16_t getSize()** returns the size in kiloBYTE.
2023-05-01 10:00:11 -04:00
If the FRAM has no device ID register, the size cannot be read.
- FRAM9 will return 0 as it is less than 1 KB. use GetSizeBytes() instead.
2023-04-22 05:34:55 -04:00
- **uint32_t getSizeBytes()** returns the size in BYTES.
2023-05-01 10:00:11 -04:00
- Useful for iterating over the whole memory,
2022-03-18 08:37:57 -04:00
or testing the upper boundary.
2023-04-22 05:34:55 -04:00
- **void setSizeBytes(uint32_t value)** sets the size in bytes for **getSizeBytes()**.
2022-03-25 05:04:48 -04:00
To be used only if **getSize()** cannot determine the size.
2023-09-07 08:07:49 -04:00
As far as known this is for the **MB85RC128A** and **MB85RC64V** only.
2022-10-16 13:09:32 -04:00
See also remark in Future section below.
2023-05-01 10:00:11 -04:00
Can also be used to "virtually" reduce the size, e.g. to speed up **clear()**
2023-04-22 05:34:55 -04:00
if the FRAM is used only partial.
2022-03-25 05:04:48 -04:00
2021-01-29 06:31:58 -05:00
2023-05-01 10:00:11 -04:00
### Manufacturers ID
2023-09-07 08:07:49 -04:00
| Name | ID | Notes |
|:-------------------------|:-------:|:--------|
| Fujitsu | 0x00A |
| Ramtron | 0x004 |
| getMetaData read error | 0xFFF | See #38
2023-05-01 10:00:11 -04:00
2023-09-07 08:07:49 -04:00
Additions for manufacturers ID's are welcome.
2023-05-01 10:00:11 -04:00
2022-05-02 10:06:10 -04:00
### Sleep
(0.3.6 added - experimental)
2022-10-16 13:09:32 -04:00
- **void sleep()** puts the FRAM in sleep mode so it uses less power.
Still needs a power test for several types of FRAM.
2022-05-02 10:06:10 -04:00
- **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.
2022-10-16 13:09:32 -04:00
So use with care.
2022-05-02 10:06:10 -04:00
2023-05-01 10:00:11 -04:00
| 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 |
2022-05-02 10:06:10 -04:00
_current with \* are from datasheet_
### Current
2022-10-16 13:09:32 -04:00
Indicative power usage in uA in three modi (if supported).
2022-05-02 10:06:10 -04:00
| 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 | |
2022-10-16 13:09:32 -04:00
| MB85RC1MT | 128 KB | 11.7 uA | 46-721 uA | 3.6 uA | See #17 |
2022-05-02 10:06:10 -04:00
2022-05-10 04:10:44 -04:00
_TODO: fill the table_
2022-05-02 10:06:10 -04:00
2021-01-29 06:31:58 -05:00
2022-10-16 13:09:32 -04:00
## FRAM_RINGBUFFER
2023-04-22 05:34:55 -04:00
Since version 0.4.2 a separate class **FRAM_RINGBUFFER** is added to this repo.
2023-05-01 10:00:11 -04:00
Its interface is straightforward and described in **FRAM_RINGBUFFER.md**.
2022-10-16 13:09:32 -04:00
The FRAM_ringbuffer.ino examples shows how the class can be used.
2022-02-08 10:47:34 -05:00
2023-04-23 13:32:07 -04:00
## FRAM_MULTILANGUAGE
Since version 0.5.2 the **FRAM_ML** class is added.
Its purpose is to store tables of strings in FRAM.
2023-05-01 10:00:11 -04:00
Its interface is described in **FRAM_MULTILANGUAGE.md**.
2023-04-23 13:32:07 -04:00
2023-05-01 10:00:11 -04:00
See examples.
2023-04-23 13:32:07 -04:00
2023-02-26 09:02:10 -05:00
2023-05-01 10:00:11 -04:00
## FRAM11 + FRAM9
2023-02-26 09:02:10 -05:00
2023-05-01 10:00:11 -04:00
- 0.5.0 added, see issue #28
- 0.5.3 redo FRAM9 and FRAM11, see #35
2023-02-26 09:02:10 -05:00
2023-05-01 10:00:11 -04:00
Experimental support for smaller FRAM's with 11 and 9 bits addresses.
2023-02-26 09:02:10 -05:00
2023-05-01 10:00:11 -04:00
- FRAM11 e.g. Cypress/Infineon 24CL16B (see #28)
- FRAM9 e.g. MB85RC04 (see #35)
Note **getSize()** will return 0 as it is only 0.5 KB and rounded down.
Use **getSizeBytes()** to get 512.
2023-02-26 09:02:10 -05:00
2021-12-18 09:02:32 -05:00
## Future
2023-02-26 09:02:10 -05:00
#### Must
2022-05-10 04:10:44 -04:00
2023-02-26 09:02:10 -05:00
- improve documentation
- test more types of FRAM
- FRAM11 / FRAM9
- other people might help.
#### Should
2023-05-01 10:00:11 -04:00
- Improve **getSize()** to have **clear()** working properly.
- **MB85RC128A** only (hard code fall back?).
2023-02-26 09:02:10 -05:00
- **getSize()** scanning FRAM like EEPROM library?
2023-05-01 10:00:11 -04:00
- investigate a faster strategy for **readUntil()**
2023-04-22 05:34:55 -04:00
- search for separator per block (e.g. 16 bytes) read.
2023-05-01 10:00:11 -04:00
- Investigate **getManufacturerID()** and **getProductID()** for FRAM9/11.
- need hardware + data sheets.
2023-04-22 05:34:55 -04:00
2022-05-10 04:10:44 -04:00
2023-02-26 09:02:10 -05:00
#### Could
2022-05-10 04:10:44 -04:00
2023-02-26 09:02:10 -05:00
- improve **FRAM32** that can write over the 64 KB border without problems.
- Would need extra checking ==> overhead.
- now it is responsibility of the user.
- do we want/need this?
2022-03-18 08:37:57 -04:00
- **write()** and **writeBlock()** might write beyond the end of FRAM
2023-02-26 09:02:10 -05:00
- now it is responsibility of the user.
- range check would degrade performance
2022-03-18 08:37:57 -04:00
- error flag ?
2021-12-18 09:02:32 -05:00
- extend examples
2022-02-08 10:47:34 -05:00
- FRAM (8x) concatenated as one continuous memory.
2023-02-26 09:02:10 -05:00
- a wrapper class?
2022-12-29 10:05:49 -05:00
- fill power usage table (documentation)
2023-02-26 09:02:10 -05:00
- is in data sheet.
2023-09-07 08:07:49 -04:00
- improve comments where needed.
2022-03-18 08:37:57 -04:00
2022-05-10 04:10:44 -04:00
2023-02-26 09:02:10 -05:00
#### Wont
2022-05-10 04:10:44 -04:00
2022-03-25 05:04:48 -04:00
- extend current **clear()** with partial **clear(begin, end, value)**?
- can be done by **writeBlock()** calls by user too
- would need more complex end checking
- ==> wont for now
- **dump(stream)** or printable interface?
- Print interface? expensive in performance per char..
2023-04-22 05:34:55 -04:00
- see example **FRAM_hexdump.ino**
2023-02-26 09:02:10 -05:00
- remember last written address? why?
2023-09-07 08:07:49 -04:00
- do we need a **write(memAddr, char \* buffer)** for completeness?
2023-04-22 05:34:55 -04:00
- it is just a wrapper
2021-12-18 09:02:32 -05:00
2023-09-07 08:07:49 -04:00
## Support
If you appreciate my libraries, you can support the development and maintenance.
Improve the quality of the libraries by providing issues and Pull Requests, or
donate through PayPal or GitHub sponsors.
Thank you,