mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
1.5.0 I2C_EEPROM
This commit is contained in:
parent
814134abcf
commit
5885b36187
@ -1,7 +1,7 @@
|
||||
//
|
||||
// FILE: I2C_eeprom.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 1.4.3
|
||||
// VERSION: 1.5.0
|
||||
// PURPOSE: Arduino Library for external I2C EEPROM 24LC256 et al.
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM.git
|
||||
//
|
||||
@ -30,7 +30,7 @@
|
||||
// 1.2.6 2019-02-01 fix issue #121
|
||||
// 1.2.7 2019-09-03 fix issue #113 and #128
|
||||
// 1.3.0 2020-06-19 refactor; removed pre 1.0 support; added ESP32 support.
|
||||
// 1.3.1 2020-12-22 arduino-ci + unit tests + updateByte()
|
||||
// 1.3.1 2020-12-22 Arduino-CI + unit tests + updateByte()
|
||||
// 1.3.2 2021-01-18 cyclic store functionality (Thanks to Tomas Hübner)
|
||||
// 1.4.0 2021-01-27 rewritten addressing scheme + determineSize
|
||||
// See determineSize for all tested.
|
||||
@ -38,7 +38,8 @@
|
||||
// add Wire1..WireN;
|
||||
// 1.4.2 2021-01-31 add updateBlock()
|
||||
// 1.4.3 2021-05-05 adjust buffer size AVR / ESP +rename
|
||||
|
||||
// 1.5.0 2021-06-30 #28 fix addressing 24LC04/08/16
|
||||
|
||||
|
||||
#include <I2C_eeprom.h>
|
||||
|
||||
@ -55,8 +56,8 @@
|
||||
#define I2C_PAGESIZE_24LC01 8
|
||||
|
||||
|
||||
// TWI buffer needs max 2 bytes for eeprom address
|
||||
// 1 byte for eeprom register address is available in txbuffer
|
||||
// I2C buffer needs max 2 bytes for EEPROM address
|
||||
// 1 byte for EEPROM register address is available in transmit buffer
|
||||
#if defined(ESP32) || defined(ESP8266)
|
||||
#define I2C_BUFFERSIZE 128
|
||||
#else
|
||||
@ -78,7 +79,7 @@ I2C_eeprom::I2C_eeprom(const uint8_t deviceAddress, const uint32_t deviceSize, T
|
||||
_wire = wire;
|
||||
|
||||
// Chips 16Kbit (2048 Bytes) or smaller only have one-word addresses.
|
||||
this->_isAddressSizeTwoWords = (deviceSize <= I2C_DEVICESIZE_24LC16) ? false : true;
|
||||
this->_isAddressSizeTwoWords = deviceSize > I2C_DEVICESIZE_24LC16;
|
||||
}
|
||||
|
||||
|
||||
@ -161,7 +162,7 @@ uint16_t I2C_eeprom::readBlock(const uint16_t memoryAddress, uint8_t* buffer, co
|
||||
addr += cnt;
|
||||
buffer += cnt;
|
||||
len -= cnt;
|
||||
yield(); // For OS scheduling etc
|
||||
yield(); // For OS scheduling
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@ -192,7 +193,7 @@ int I2C_eeprom::updateBlock(const uint16_t memoryAddress, const uint8_t* buffer,
|
||||
addr += cnt;
|
||||
buffer += cnt;
|
||||
len -= cnt;
|
||||
yield(); // For OS scheduling etc
|
||||
yield(); // For OS scheduling
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@ -229,7 +230,7 @@ uint32_t I2C_eeprom::determineSize(const bool debug)
|
||||
|
||||
// store old values
|
||||
bool addressSize = _isAddressSizeTwoWords;
|
||||
_isAddressSizeTwoWords = (size <= 2048) ? false : true;
|
||||
_isAddressSizeTwoWords = size > I2C_DEVICESIZE_24LC16; // 2048
|
||||
uint8_t buf = readByte(size);
|
||||
|
||||
// test folding
|
||||
@ -258,7 +259,7 @@ uint32_t I2C_eeprom::determineSize(const bool debug)
|
||||
|
||||
uint8_t I2C_eeprom::getPageSize(uint32_t deviceSize)
|
||||
{
|
||||
// determine page size from device size - based on Microchip 24LCXX datasheets.
|
||||
// determine page size from device size - based on Microchip 24LCXX data sheets.
|
||||
if (deviceSize <= I2C_DEVICESIZE_24LC02) return 8;
|
||||
if (deviceSize <= I2C_DEVICESIZE_24LC16) return 16;
|
||||
if (deviceSize <= I2C_DEVICESIZE_24LC64) return 32;
|
||||
@ -274,7 +275,7 @@ uint8_t I2C_eeprom::getPageSize(uint32_t deviceSize)
|
||||
//
|
||||
|
||||
// _pageBlock aligns buffer to page boundaries for writing.
|
||||
// and to TWI buffer size
|
||||
// and to I2C buffer size
|
||||
// returns 0 = OK otherwise error
|
||||
int I2C_eeprom::_pageBlock(const uint16_t memoryAddress, const uint8_t* buffer, const uint16_t length, const bool incrBuffer)
|
||||
{
|
||||
@ -299,7 +300,7 @@ int I2C_eeprom::_pageBlock(const uint16_t memoryAddress, const uint8_t* buffer,
|
||||
}
|
||||
|
||||
|
||||
// supports one and 2 bytes addresses
|
||||
// supports one and two bytes addresses
|
||||
void I2C_eeprom::_beginTransmission(const uint16_t memoryAddress)
|
||||
{
|
||||
if (this->_isAddressSizeTwoWords)
|
||||
@ -314,7 +315,7 @@ void I2C_eeprom::_beginTransmission(const uint16_t memoryAddress)
|
||||
_wire->beginTransmission(addr);
|
||||
}
|
||||
|
||||
// Address Low Byte (or only byte for chips 16K or smaller that only have one-word addresses)
|
||||
// Address Low Byte (or single byte for chips 16K or smaller that have one-word addresses)
|
||||
_wire->write((memoryAddress & 0xFF));
|
||||
}
|
||||
|
||||
@ -345,8 +346,18 @@ uint8_t I2C_eeprom::_ReadBlock(const uint16_t memoryAddress, uint8_t* buffer, co
|
||||
int rv = _wire->endTransmission();
|
||||
if (rv != 0) return 0; // error
|
||||
|
||||
// readbytes will always be equal or smaller to length
|
||||
uint8_t readBytes = _wire->requestFrom(_deviceAddress, length);
|
||||
// readBytes will always be equal or smaller to length
|
||||
|
||||
uint8_t readBytes = 0;
|
||||
if (this->_isAddressSizeTwoWords)
|
||||
{
|
||||
readBytes = _wire->requestFrom(_deviceAddress, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t addr = _deviceAddress | ((memoryAddress >> 8) & 0x07);
|
||||
readBytes = _wire->requestFrom(addr, length);
|
||||
}
|
||||
uint8_t cnt = 0;
|
||||
while (cnt < readBytes)
|
||||
{
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// FILE: I2C_eeprom.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 1.4.3
|
||||
// VERSION: 1.5.0
|
||||
// PURPOSE: Arduino Library for external I2C EEPROM 24LC256 et al.
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM.git
|
||||
//
|
||||
@ -13,7 +13,7 @@
|
||||
#include "Wire.h"
|
||||
|
||||
|
||||
#define I2C_EEPROM_VERSION (F("1.4.3"))
|
||||
#define I2C_EEPROM_VERSION (F("1.5.0"))
|
||||
|
||||
|
||||
#define I2C_DEVICESIZE_24LC512 65536
|
||||
@ -59,7 +59,7 @@ public:
|
||||
|
||||
bool isConnected();
|
||||
|
||||
// writes a byte to memaddr
|
||||
// writes a byte to memoryAddress
|
||||
int writeByte(const uint16_t memoryAddress, const uint8_t value);
|
||||
// writes length bytes from buffer to EEPROM
|
||||
int writeBlock(const uint16_t memoryAddress, const uint8_t* buffer, const uint16_t length);
|
||||
@ -67,13 +67,13 @@ public:
|
||||
int setBlock(const uint16_t memoryAddress, const uint8_t value, const uint16_t length);
|
||||
|
||||
|
||||
// returns the value stored in memaddr
|
||||
// returns the value stored in memoryAddress
|
||||
uint8_t readByte(const uint16_t memoryAddress);
|
||||
// reads length bytes into buffer
|
||||
uint16_t readBlock(const uint16_t memoryAddress, uint8_t* buffer, const uint16_t length);
|
||||
|
||||
|
||||
// updates a byte at memory address, writes only if there is a new value.
|
||||
// updates a byte at memoryAddress, writes only if there is a new value.
|
||||
// return 0 if data is same or written OK, error code otherwise.
|
||||
int updateByte(const uint16_t memoryAddress, const uint8_t value);
|
||||
// updates a block in memory, writes only if there is a new value.
|
||||
|
@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/I2C_EEPROM.git"
|
||||
},
|
||||
"version": "1.4.3",
|
||||
"version": "1.5.0",
|
||||
"license": "MIT",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*"
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=I2C_EEPROM
|
||||
version=1.4.3
|
||||
version=1.5.0
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Library for I2C EEPROMS
|
||||
|
@ -24,7 +24,7 @@ The **I2C_eeprom_cyclic_store** interface is documented [here](README_cyclic_sto
|
||||
- **I2C_eeprom(uint8_t deviceAddress, uint32_t deviceSize, TwoWire \*wire = &Wire)** constructor, with optional Wire interface.
|
||||
- **bool begin()** initializes the I2C bus and checks if the device is available on the I2C bus.
|
||||
- **bool begin(uint8_t sda, uint8_t scl)** idem for ESP32 / ESP8266 and alike.
|
||||
- **bool isConnected()** test to see if device is on the bus.
|
||||
- **bool isConnected()** test to see if deviceAddress is found on the bus.
|
||||
|
||||
|
||||
### Core functions
|
||||
@ -45,13 +45,13 @@ The **I2C_eeprom_cyclic_store** interface is documented [here](README_cyclic_sto
|
||||
- **uint8_t getPageSize(uint32_t deviceSize)** idem
|
||||
- **uint32_t getLastWrite()** idem
|
||||
- **uint32_t determineSize(bool debug = false)**
|
||||
function that determins the size of the EEPROM by detecting when a memory address is folded upon memory address 0.
|
||||
function that determines the size of the EEPROM by detecting when a memory address is folded upon memory address 0.
|
||||
It is based upon the observation that memory wraps around.
|
||||
The debug flag gives some output to Serial.
|
||||
|
||||
**Warning**: this function has changed (again) in 1.4.0
|
||||
|
||||
Testresults
|
||||
Test results
|
||||
|
||||
| Type | returns | Memory | Page Size | Notes |
|
||||
|:--------|:--------|:---------|:-----:|:------|
|
||||
@ -76,7 +76,9 @@ The function cannot detect smaller than 128 bit EEPROMS.
|
||||
|
||||
The function **updateBlock()** reads the block of data and compares it with the new values to see if it needs rewriting.
|
||||
|
||||
As the function reads/writes the data in blocks with a maximum length of **I2C_TWIBUFFERSIZE** (== 30 AVR limitation) it does this comparison in chuncks if the length exceeds this number. The result is that an **updateBlock()** call can result e.g. in 4 reads and only 2 writes under the hood.
|
||||
As the function reads/writes the data in blocks with a maximum length of **I2C_BUFFERSIZE** (== 30 on AVR limitation).
|
||||
It does this comparison in chunks if the length exceeds this number.
|
||||
The result is that an **updateBlock()** call can result e.g. in 4 reads and only 2 writes under the hood.
|
||||
|
||||
If data is changed often between writes, **updateBlock()** is slower than **writeBlock()**.
|
||||
So you should verify if your sketch can make use of the advantages of **updateBlock()**
|
||||
@ -92,7 +94,7 @@ The library does not offer multiple EEPROMS as one continuous storage device.
|
||||
- improve error handling, write functions should return bytes written or so.
|
||||
- what can we do with the print interface? (investigate)
|
||||
- investigate multi-EEPROM storage,
|
||||
- investigate smarter strategy for updateBlock() => find first and last changed position would possibly result in less writes.
|
||||
- investigate smarter strategy for updateBlock() => find first and last changed position could possibly result in less writes.
|
||||
|
||||
|
||||
## Operational
|
||||
|
Loading…
Reference in New Issue
Block a user