mirror of
https://github.com/RobTillaart/I2C_EEPROM.git
synced 2026-10-26 22:10:15 +00:00
1.4.2 add updateBlock() (#23)
This commit is contained in:
1 parent
692f1a3004
commit
d0f8385bc4
7 files changed
+264
-5
No files matched your search
+26
-1
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// FILE: I2C_eeprom.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 1.4.1
|
||||
// VERSION: 1.4.2
|
||||
// PURPOSE: Arduino Library for external I2C EEPROM 24LC256 et al.
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM.git
|
||||
//
|
||||
@@ -36,6 +36,7 @@
|
||||
// See determineSize for all tested.
|
||||
// 1.4.1 2021-01-28 fixed addressing bug 24LC04/08/16 equivalents from ST e.g. m24c08w
|
||||
// add Wire1..WireN;
|
||||
// 1.4.2 2021-01-31 add updateBlock()
|
||||
|
||||
|
||||
#include <I2C_eeprom.h>
|
||||
@@ -169,6 +170,30 @@ int I2C_eeprom::updateByte(const uint16_t memoryAddress, const uint8_t data)
|
||||
return writeByte(memoryAddress, data);
|
||||
}
|
||||
|
||||
int I2C_eeprom::updateBlock(const uint16_t memoryAddress, const uint8_t* buffer, const uint16_t length)
|
||||
{
|
||||
uint16_t addr = memoryAddress;
|
||||
uint16_t len = length;
|
||||
uint16_t rv = 0;
|
||||
while (len > 0)
|
||||
{
|
||||
uint8_t buf[I2C_TWIBUFFERSIZE];
|
||||
uint8_t cnt = I2C_TWIBUFFERSIZE;
|
||||
|
||||
if (cnt > len) cnt = len;
|
||||
rv += _ReadBlock(addr, buf, cnt);
|
||||
if (memcmp(buffer, buf, cnt) != 0)
|
||||
{
|
||||
_pageBlock(addr, buffer, cnt, true);
|
||||
}
|
||||
addr += cnt;
|
||||
buffer += cnt;
|
||||
len -= cnt;
|
||||
yield(); // For OS scheduling etc
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
// returns size in bytes
|
||||
// returns 0 if not connected
|
||||
|
||||
+6
-2
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// FILE: I2C_eeprom.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 1.4.1
|
||||
// VERSION: 1.4.2
|
||||
// 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.1"))
|
||||
#define I2C_EEPROM_VERSION (F("1.4.2"))
|
||||
|
||||
|
||||
#define I2C_DEVICESIZE_24LC512 65536
|
||||
@@ -76,6 +76,10 @@ public:
|
||||
// updates a byte at memory address, 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.
|
||||
// only to be used when you expect to write same buffer multiple times.
|
||||
// test your performance gains!
|
||||
int updateBlock(const uint16_t memoryAddress, const uint8_t* buffer, const uint16_t length);
|
||||
|
||||
uint32_t determineSize(const bool debug = false);
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ The **I2C_eeprom_cyclic_store** interface is documented [here](README_cyclic_sto
|
||||
- **int writeByte(uint16_t memoryAddress, uint8_t value)** write a single byte to the specified memory address.
|
||||
- **int updateByte(uint16_t memoryAddress, uint8_t value)** write a single byte, but only if changed. Returns 0 if value was same or write succeeded.
|
||||
- **int writeBlock(uint16_t memoryAddress, uint8_t \* buffer, uint16_t length)** write a buffer starting at the specified memory address.
|
||||
- **int updateBlock(uint16_t memoryAddress, uint8_t \* buffer, uint16_t length)** write a buffer starting at the specified memory address, but only if changed
|
||||
- **int setBlock(uint16_t memoryAddress, uint8_t value, uint16_t length)** writes the same byte to length places starting at the specified memory address. Returns 0 if OK.
|
||||
- **uint8_t readByte(uint16_t memoryAddress)** read a single byte from a given address
|
||||
- **uint16_t readBlock(uint16_t memoryAddress, uint8_t \* buffer, uint16_t length)** read length bytes into buffer starting at specified memory address. Returns the number of bytes read, which should be length.
|
||||
@@ -69,6 +70,18 @@ Testresults
|
||||
The function cannot detect smaller than 128 bit EEPROMS.
|
||||
|
||||
|
||||
#### UpdateBlock()
|
||||
|
||||
(new since 1.4.2)
|
||||
|
||||
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.
|
||||
|
||||
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()**
|
||||
|
||||
|
||||
## Limitation
|
||||
|
||||
The library does not offer multiple EEPROMS as one continuous storage device.
|
||||
@@ -79,6 +92,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.
|
||||
|
||||
|
||||
## Operational
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
D:\Rob\WORK\Arduino\libraries\I2C_EEPROM\examples\I2C_eeprom_updateBlock\I2C_eeprom_updateBlock.ino
|
||||
VERSION: 1.4.1
|
||||
|
||||
1
|
||||
TEST: writeBlock() 32840
|
||||
TEST: readBlock() 11792
|
||||
TEST: updateBlock() 44672
|
||||
|
||||
2
|
||||
TEST: writeBlock() 65720
|
||||
TEST: readBlock() 23588
|
||||
TEST: updateBlock() 60764
|
||||
|
||||
3
|
||||
TEST: writeBlock() 98544
|
||||
TEST: readBlock() 35384
|
||||
TEST: updateBlock() 72628
|
||||
|
||||
4
|
||||
TEST: writeBlock() 131348
|
||||
TEST: readBlock() 47172
|
||||
TEST: updateBlock() 84464
|
||||
|
||||
5
|
||||
TEST: writeBlock() 164200
|
||||
TEST: readBlock() 58976
|
||||
TEST: updateBlock() 96340
|
||||
|
||||
6
|
||||
TEST: writeBlock() 197068
|
||||
TEST: readBlock() 70756
|
||||
TEST: updateBlock() 108236
|
||||
|
||||
7
|
||||
TEST: writeBlock() 229872
|
||||
TEST: readBlock() 82576
|
||||
TEST: updateBlock() 120072
|
||||
|
||||
8
|
||||
TEST: writeBlock() 262684
|
||||
TEST: readBlock() 94352
|
||||
TEST: updateBlock() 131952
|
||||
|
||||
9
|
||||
TEST: writeBlock() 295568
|
||||
TEST: readBlock() 106144
|
||||
TEST: updateBlock() 143808
|
||||
|
||||
10
|
||||
TEST: writeBlock() 328388
|
||||
TEST: readBlock() 117928
|
||||
TEST: updateBlock() 155688
|
||||
|
||||
|
||||
TEST: 100x writeBlock()
|
||||
DUR1: 3284020
|
||||
|
||||
00000000 64 63 62 61 60 5F 5E 5D 5C 5B 5A 59 58 57 56 55
|
||||
00000010 54 53 52 51 50 4F 4E 4D 4C 4B 4A 49 48 47 46 45
|
||||
00000020 44 43 42 41 40 3F 3E 3D 3C 3B 3A 39 38 37 36 35
|
||||
00000030 34 33 32 31 30 2F 2E 2D 2C 2B 2A 29 28 27 26 25
|
||||
00000040 24 23 22 21 20 1F 1E 1D 1C 1B 1A 19 18 17 16 15
|
||||
00000050 14 13 12 11 10 0F 0E 0D 0C 0B 0A 09 08 07 06 05
|
||||
00000060 04 03 02 01
|
||||
|
||||
TEST: 100x updateBlock()
|
||||
DUR2: 1223896
|
||||
|
||||
00000000 64 63 62 61 60 5F 5E 5D 5C 5B 5A 59 58 57 56 55
|
||||
00000010 54 53 52 51 50 4F 4E 4D 4C 4B 4A 49 48 47 46 45
|
||||
00000020 44 43 42 41 40 3F 3E 3D 3C 3B 3A 39 38 37 36 35
|
||||
00000030 34 33 32 31 30 2F 2E 2D 2C 2B 2A 29 28 27 26 25
|
||||
00000040 24 23 22 21 20 1F 1E 1D 1C 1B 1A 19 18 17 16 15
|
||||
00000050 14 13 12 11 10 0F 0E 0D 0C 0B 0A 09 08 07 06 05
|
||||
00000060 04 03 02 01
|
||||
|
||||
done...
|
||||
@@ -0,0 +1,139 @@
|
||||
//
|
||||
// FILE: I2C_eeprom_updateBlock.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo I2C_EEPROM library - performance gain updateBlock
|
||||
//
|
||||
|
||||
// uses a 24LC256 (32KB) EEPROM
|
||||
// as this test writes a lot it might wear out EEPROMs eventually.
|
||||
//
|
||||
|
||||
#include "Wire.h"
|
||||
#include "I2C_eeprom.h"
|
||||
|
||||
|
||||
I2C_eeprom ee(0x50, I2C_DEVICESIZE_24LC256);
|
||||
|
||||
uint32_t start, dur1, dur2;
|
||||
|
||||
uint8_t ar[100];
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); // wait for SERIAL_OUT port to connect. Needed for Leonardo only
|
||||
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("VERSION: ");
|
||||
Serial.println(I2C_EEPROM_VERSION);
|
||||
Serial.println();
|
||||
|
||||
ee.begin();
|
||||
if (! ee.isConnected())
|
||||
{
|
||||
Serial.println("ERROR: Can't find eeprom\nstopped...");
|
||||
while (1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 100; i++) ar[i] = 100 - i;
|
||||
|
||||
for (int i = 1; i < 11; i++)
|
||||
{
|
||||
test_1(i);
|
||||
}
|
||||
|
||||
test_2();
|
||||
|
||||
Serial.println("\ndone...");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
void test_1(int n)
|
||||
{
|
||||
Serial.println(n);
|
||||
Serial.print("TEST:\twriteBlock()");
|
||||
delay(10);
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
start = micros();
|
||||
for (int i = 0; i < n; i++) ee.writeBlock(0, ar, 100);
|
||||
dur1 = micros() - start;
|
||||
Serial.print("\t");
|
||||
Serial.println(dur1);
|
||||
delay(10);
|
||||
|
||||
Serial.print("TEST:\treadBlock()");
|
||||
delay(10);
|
||||
start = micros();
|
||||
for (int i = 0; i < n; i++) ee.readBlock(0, ar, 100);
|
||||
dur1 = micros() - start;
|
||||
Serial.print("\t");
|
||||
Serial.println(dur1);
|
||||
delay(10);
|
||||
|
||||
Serial.print("TEST:\tupdateBlock()");
|
||||
delay(10);
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
start = micros();
|
||||
for (int i = 0; i < n; i++) ee.updateBlock(0, ar, 100);
|
||||
dur1 = micros() - start;
|
||||
Serial.print("\t");
|
||||
Serial.println(dur1);
|
||||
delay(10);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void test_2()
|
||||
{
|
||||
Serial.println("\nTEST: 100x writeBlock()");
|
||||
delay(10);
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
start = micros();
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
ee.writeBlock(0, ar, 100);
|
||||
}
|
||||
dur1 = micros() - start;
|
||||
Serial.print("DUR1: ");
|
||||
Serial.println(dur1);
|
||||
dump(0, 100);
|
||||
delay(100);
|
||||
|
||||
|
||||
Serial.println("\nTEST: 100x updateBlock()");
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
start = micros();
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
ee.updateBlock(0, ar, 100);
|
||||
}
|
||||
dur2 = micros() - start;
|
||||
Serial.print("DUR2: ");
|
||||
Serial.println(dur2);
|
||||
dump(0, 100);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
|
||||
void dump(uint32_t from, uint32_t to)
|
||||
{
|
||||
for (uint32_t i = from; i < to; i++) // I2C_DEVICESIZE_24LC512
|
||||
{
|
||||
char buffer[24];
|
||||
if (i % 16 == 0)
|
||||
{
|
||||
char buffer[24];
|
||||
Serial.print('\n');
|
||||
sprintf(buffer, "%08lX\t", i);
|
||||
Serial.print(buffer);
|
||||
}
|
||||
sprintf(buffer, "%02X\t", ee.readByte(i));
|
||||
Serial.print(buffer);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/I2C_EEPROM.git"
|
||||
},
|
||||
"version":"1.4.1",
|
||||
"version":"1.4.2",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*"
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
name=I2C_EEPROM
|
||||
version=1.4.1
|
||||
version=1.4.2
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Library for I2C EEPROMS
|
||||
|
||||
Reference in new issue
Block a user