diff --git a/FRAM.cpp b/FRAM.cpp index 78d3421..ded02ee 100644 --- a/FRAM.cpp +++ b/FRAM.cpp @@ -10,7 +10,7 @@ #include "FRAM.h" -// DENSITY CODES +// DENSITY CODES #define FRAM_MB85RC64 0x03 #define FRAM_MB85RC256 0x05 @@ -18,7 +18,7 @@ #define FRAM_MB85RC1M 0x07 -// used for metadata and sleep +// used for metadata and sleep const uint8_t FRAM_SLAVE_ID_ = 0x7C; // == 0xF8 const uint8_t FRAM_SLEEP_CMD = 0x86; // @@ -180,7 +180,7 @@ void FRAM::read(uint16_t memAddr, uint8_t * obj, uint16_t size) p += blocksize; size -= blocksize; } - // remainder + // remainder if (size > 0) { _readBlock(memAddr, p, size); @@ -199,7 +199,8 @@ int32_t FRAM::readUntil(uint16_t memAddr, char * buffer, uint16_t bufferLength, { if (buffer[length] == separator) { - buffer[length] = 0; // replace separator => \0 EndChar + // replace separator => \0 EndChar + buffer[length] = 0; return length; } } @@ -216,7 +217,8 @@ int32_t FRAM::readLine(uint16_t memAddr, char * buffer, uint16_t bufferLength) { if (buffer[length] == '\n') { - buffer[length + 1] = 0; // add \0 EndChar after '\n' + // add \0 EndChar after '\n' + buffer[length + 1] = 0; return length + 1; } } @@ -279,7 +281,7 @@ uint16_t FRAM::getSize() { uint32_t value = _getMetaData(); if (value == 0xFFFFFFFF) return 0; - + uint16_t manufacturer = (value >> 12) & 0x0FFF; if (manufacturer == FRAM_MANU_CYPRESS) @@ -340,11 +342,13 @@ void FRAM::sleep() // page 12 datasheet trec <= 400us bool FRAM::wakeup(uint32_t timeRecover) { - bool b = isConnected(); // wakeup + // wakeup + bool b = isConnected(); if (timeRecover == 0) return b; // wait recovery time delayMicroseconds(timeRecover); - return isConnected(); // check recovery OK + // check recovery OK + return isConnected(); } @@ -410,7 +414,6 @@ void FRAM::_readBlock(uint16_t memAddr, uint8_t * obj, uint8_t size) // // FRAM32 PUBLIC // - FRAM32::FRAM32(TwoWire *wire) : FRAM(wire) { } @@ -469,7 +472,7 @@ void FRAM32::write(uint32_t memAddr, uint8_t * obj, uint16_t size) p += blocksize; size -= blocksize; } - // remaining + // remaining if (size > 0) { _writeBlock(memAddr, p, size); @@ -552,7 +555,8 @@ int32_t FRAM32::readUntil(uint32_t memAddr, char * buffer, uint16_t bufferLength { if (buffer[length] == separator) { - buffer[length] = 0; // replace separator => \0 EndChar + // replace separator => \0 EndChar + buffer[length] = 0; return length; } } @@ -569,7 +573,8 @@ int32_t FRAM32::readLine(uint32_t memAddr, char * buffer, uint16_t bufferLength) { if (buffer[length] == '\n') { - buffer[length + 1] = 0; // add \0 EndChar after '\n' + // add \0 EndChar after '\n' + buffer[length + 1] = 0; return length + 1; } } @@ -592,8 +597,6 @@ uint32_t FRAM32::clear(uint8_t value) } - - ///////////////////////////////////////////////////////////////////////////// // // FRAM32 PROTECTED @@ -633,8 +636,6 @@ void FRAM32::_readBlock(uint32_t memAddr, uint8_t * obj, uint8_t size) } - - ///////////////////////////////////////////////////////////////////////////// // // FRAM11 @@ -665,7 +666,7 @@ uint16_t FRAM11::getSize() // void FRAM11::_writeBlock(uint16_t memAddr, uint8_t * obj, uint8_t size) { - // Device uses Address Pages + // Device uses Address Pages uint8_t DeviceAddrWithPageBits = _address | ((memAddr & 0x0700) >> 8); _wire->beginTransmission(DeviceAddrWithPageBits); _wire->write((uint8_t) (memAddr & 0xFF)); @@ -681,7 +682,7 @@ void FRAM11::_writeBlock(uint16_t memAddr, uint8_t * obj, uint8_t size) void FRAM11::_readBlock(uint16_t memAddr, uint8_t * obj, uint8_t size) { - // Device uses Address Pages + // Device uses Address Pages uint8_t DeviceAddrWithPageBits = _address | ((memAddr & 0x0700) >> 8); _wire->beginTransmission(DeviceAddrWithPageBits); _wire->write((uint8_t) (memAddr & 0xFF)); @@ -696,8 +697,6 @@ void FRAM11::_readBlock(uint16_t memAddr, uint8_t * obj, uint8_t size) } - - ///////////////////////////////////////////////////////////////////////////// // // FRAM9 @@ -722,14 +721,13 @@ uint16_t FRAM9::getSize() } - ///////////////////////////////////////////////////////////////////////////// // // FRAM9 PROTECTED // void FRAM9::_writeBlock(uint16_t memAddr, uint8_t * obj, uint8_t size) { - // Device uses Address Pages + // Device uses Address Pages uint8_t DeviceAddrWithPageBits = _address | ((memAddr & 0x0100) >> 8); _wire->beginTransmission(DeviceAddrWithPageBits); _wire->write((uint8_t) (memAddr & 0xFF)); @@ -745,7 +743,7 @@ void FRAM9::_writeBlock(uint16_t memAddr, uint8_t * obj, uint8_t size) void FRAM9::_readBlock(uint16_t memAddr, uint8_t * obj, uint8_t size) { - // Device uses Address Pages + // Device uses Address Pages uint8_t DeviceAddrWithPageBits = _address | ((memAddr & 0x0100) >> 8); _wire->beginTransmission(DeviceAddrWithPageBits); _wire->write((uint8_t) (memAddr & 0xFF)); diff --git a/FRAM.h b/FRAM.h index 4f50be7..bdb6c8d 100644 --- a/FRAM.h +++ b/FRAM.h @@ -100,7 +100,7 @@ class FRAM // MEAT INFO // may not work for devices with no deviceID register. - // Fujitsu = 0x000A, Ramtron = 0x004 + // Fujitsu = 0x000A, Ramtron et al = 0x004 uint16_t getManufacturerID(); // Proprietary product ID uint16_t getProductID(); diff --git a/LICENSE b/LICENSE index c3b72e9..9a18ec2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018-2023 Rob Tillaart +Copyright (c) 2018-2024 Rob Tillaart Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 61b5330..df15ec3 100644 --- a/README.md +++ b/README.md @@ -17,11 +17,11 @@ Arduino library for I2C FRAM. ## Description FRAM is a library to read from and write to (over I2C) an FRAM module. -The library has (since 0.5.0) four classes -- **FRAM** 16 bit address. -- **FRAM32** 32 (17) bit address. -- **FRAM11** 11 bit address. -- **FRAM9** 9 bit address. +Since 0.5.0 the library provides four classes: +- **FRAM** for 16 bit address devices. +- **FRAM32** for 32 (17) bit address devices. +- **FRAM11** for 11 bit address devices. +- **FRAM9** for 9 bit address devices. Currently only the **MB85RC1MT** is known to use 32 bit. **FRAM32** can also address 16 bit devices although there is some overhead in footprint. @@ -30,7 +30,7 @@ FRAM stands for Ferroelectric RAM - https://en.wikipedia.org/wiki/Ferroelectric_ 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. +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. Last but not least FRAM allows much more write cycles than any EEPROM. @@ -66,6 +66,7 @@ Types of FRAM tested with this library: | TYPE | SIZE | TESTED | NOTES | uses | ref | Notes | |:------------:|---------:|:--------:|:-----------------------|:---------|:-----:|:--------| +| 24CL16B | 2 KB | N | no deviceID register | FRAM11 | #28 | | FM24C256-G | 32 KB | Y | no deviceID register | FRAM | #45 | test with ESP32 | FM24V10 | 128 KB | Y | | FRAM32 | #49 | @@ -74,7 +75,7 @@ Types of FRAM tested with this library: - Not all types of FRAM are tested. Please let me know if you have verified one that is not in the list. - If there is no deviceID **getSize()** will not work correctly. - - ==> fixed for FRAM9 and FRAM11 + - ==> fixed for FRAM9 and FRAM11 by hardcoding the size. - Address = 0x50 (default) .. 0x57, depends on the lines A0..A2. - **MB85RC1MT** uses even addresses only as it uses the next odd one internally. So 0x50 uses 0x51 internally for the upper 64 KB block. @@ -111,7 +112,8 @@ specific for devices with 9 bit address e.g. **MB85RC04**. 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. +- **int begin(uint8_t address = 0x50, int8_t writeProtectPin = -1)** +address and writeProtectPin is optional. Note the **MB85RC1MT** only uses even addresses. @@ -167,7 +169,7 @@ However the buffer does contain the data read, which might be useful. Handle with care as buffer has probably no '\0' end char. - **int32_t readLine(uint16_t memAddr, char \* buffer, uint16_t bufferLength)** Similar to **readUntil()**, reads a line from FRAM including the '\n'. -This '\n' is mandatory as end separator!. +This '\n' is mandatory as end separator!. Note: The buffer needs one extra char for the delimiting '\0' end char. To get the address of the next "field" one must add ```memAddr += length```. This is an minor but important difference with **readUntil()**. @@ -197,7 +199,8 @@ that uses a per byte fetching. Will work only if a writeProtectPin was defined in **begin()** -- **bool setWriteProtect(bool b)** make the FRAM write-protected by pulling the WP line HIGH or LOW. +- **bool setWriteProtect(bool b)** make the FRAM write-protected by pulling +the WP line HIGH or LOW. - Returns true if a writeProtectPin was defined in **begin()**. Otherwise the FRAM cannot be write protected. - **bool getWriteProtect()** get current write protect status. @@ -320,7 +323,7 @@ Use **getSizeBytes()** to get 512. #### Must - improve documentation -- test more types of FRAM +- test more types of FRAM (continuous action) - FRAM11 / FRAM9 - other people might provide input. @@ -352,7 +355,7 @@ 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"? +- move the device address parameter to the constructor so it becomes " "? would break the interface (even more).