mirror of
https://github.com/RobTillaart/I2C_EEPROM.git
synced 2026-07-28 04:16:22 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86a5017fa9 | ||
|
|
86228c599f | ||
|
|
e57418ba44 | ||
|
|
bb84b19faf | ||
|
|
43f4886a91 | ||
|
|
8cb180d081 | ||
|
|
0de303ff95 | ||
|
|
6c3cb3081c | ||
|
|
d5ad5ce16d | ||
|
|
f3e70ff3cf | ||
|
|
af9448c770 | ||
|
|
ee4d38aac7 | ||
|
|
42cdf1a95e | ||
|
|
0248508109 | ||
|
|
ff21bd6cdc | ||
|
|
54cf6bee85 | ||
|
|
e7c5075c36 | ||
|
|
a13ec203ef | ||
|
|
c4400ea101 | ||
|
|
d26182c753 | ||
|
|
b61c5f9c0a | ||
|
|
8caac3eb91 | ||
|
|
8f530b6d8f | ||
|
|
4db0ca9815 | ||
|
|
9001ab38c7 | ||
|
|
803147a945 | ||
|
|
a39c7a1bc2 | ||
|
|
f80f4eea31 | ||
|
|
1a6461a7dd | ||
|
|
7eae2b7ba2 | ||
|
|
5adbe66a14 | ||
|
|
710e1d1fb1 | ||
|
|
1cd0bdaf07 | ||
|
|
23c86332ee | ||
|
|
acb263880a | ||
|
|
a0826324f9 | ||
|
|
8454c12512 |
+24
-3
@@ -1,7 +1,28 @@
|
||||
platforms:
|
||||
rpipico:
|
||||
board: rp2040:rp2040:rpipico
|
||||
package: rp2040:rp2040
|
||||
gcc:
|
||||
features:
|
||||
defines:
|
||||
- ARDUINO_ARCH_RP2040
|
||||
warnings:
|
||||
flags:
|
||||
|
||||
packages:
|
||||
rp2040:rp2040:
|
||||
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
|
||||
|
||||
compile:
|
||||
# Choosing to run compilation tests on 2 different Arduino platforms
|
||||
platforms:
|
||||
- uno
|
||||
- leonardo
|
||||
- due
|
||||
- zero
|
||||
# - due
|
||||
# - zero
|
||||
# - leonardo
|
||||
- m4
|
||||
- esp32
|
||||
- esp8266
|
||||
# - mega2560
|
||||
- rpipico
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: RobTillaart
|
||||
custom: "https://www.paypal.me/robtillaart"
|
||||
@@ -0,0 +1,13 @@
|
||||
name: Arduino-lint
|
||||
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: arduino/arduino-lint-action@v2
|
||||
with:
|
||||
library-manager: update
|
||||
compliance: strict
|
||||
@@ -1,13 +1,17 @@
|
||||
---
|
||||
name: Arduino CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
arduino_ci:
|
||||
runTest:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: Arduino-CI/action@master
|
||||
# Arduino-CI/action@v0.1.1
|
||||
- uses: actions/checkout@v5
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 2.6
|
||||
- run: |
|
||||
gem install arduino_ci
|
||||
arduino_ci.rb
|
||||
|
||||
@@ -5,14 +5,16 @@ on:
|
||||
paths:
|
||||
- '**.json'
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.json'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v5
|
||||
- name: json-syntax-check
|
||||
uses: limitusus/json-syntax-check@v1
|
||||
uses: limitusus/json-syntax-check@v2
|
||||
with:
|
||||
pattern: "\\.json$"
|
||||
|
||||
pattern: "\\.json$"
|
||||
+234
@@ -0,0 +1,234 @@
|
||||
# Change Log I2C_EEPROM
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
|
||||
## [1.9.4] - 2025-08-27
|
||||
- fix #83, update readme.md (thanks to TonyRiddiough)
|
||||
- add calculatePageSize(deviceSize) to replace getPageSize(deviceSize) prep.
|
||||
- update GitHub actions
|
||||
- minor update examples
|
||||
- minor edits
|
||||
|
||||
## [1.9.3] - 2025-08-01
|
||||
- update readme.md
|
||||
|
||||
## [1.9.2] - 2024-11-25
|
||||
- fix #79, wrong default in constructor - kudos to ekinohito
|
||||
|
||||
## [1.9.1] - 2024-10-26
|
||||
- fix #77, updateBlock() returns bytes actually written.
|
||||
- minor edits
|
||||
|
||||
## [1.9.0] - 2024-10-09
|
||||
- Fix #74, memory leak in setBlockVerify() - kudos to cmichailidis
|
||||
|
||||
----
|
||||
|
||||
## [1.8.5] - 2024-04-22
|
||||
- Fix #72, force requestFrom parameters to use int type
|
||||
|
||||
## [1.8.4] - 2024-04-20
|
||||
- Fix #70, increase length internal buffer.
|
||||
- add compile time flag **EN_AUTO_WRITE_PROTECT** (thanks to microfoundry)
|
||||
- improve readability: cnt => count addr => address
|
||||
- add URL to examples
|
||||
- minor edits.
|
||||
|
||||
## [1.8.3] - 2024-03-28
|
||||
- Fix #64, compiler warning.
|
||||
- add **verifyBlock(memoryAddress, buffer, length)**
|
||||
- add example **I2C_eeprom_verifyBlock.ino**
|
||||
- update GitHub actions
|
||||
- update keywords.txt
|
||||
- update examples
|
||||
- update readme.md
|
||||
|
||||
## [1.8.2] - 2024-01-02
|
||||
- updated **uint32_t determineSizeNoWrite()**, kudos to roelandkluit
|
||||
- minor edits
|
||||
|
||||
## [1.8.1] - 2023-12-14
|
||||
- add **uint32_t determineSizeNoWrite()**, kudos to roelandkluit
|
||||
- add example
|
||||
- minor edits
|
||||
|
||||
## [1.8.0] - 2023-11-24 (breaking change)
|
||||
- simplify **begin()**, remove setting Wire pins from library.
|
||||
- add **getAddress()**
|
||||
- update readme.md
|
||||
- update examples
|
||||
|
||||
----
|
||||
|
||||
## [1.7.4] - 2023-09-06
|
||||
- solve #57 add support for WriteProtectPin
|
||||
- add writeProtectPin as optional parameter in **begin()**
|
||||
- add **bool hasWriteProtectPin()**
|
||||
- add **void allowWrite()**
|
||||
- add **void preventWrite()**
|
||||
- add **void setAutoWriteProtect(bool b)**
|
||||
- add **bool getAutoWriteProtect()**
|
||||
- optimized **waitEEReady()**
|
||||
- update keywords.txt
|
||||
- update readme.md
|
||||
|
||||
## [1.7.3] - 2023-05-10
|
||||
- fix #55 ==> redo fix #53
|
||||
- add test to detect **MBED** and **RP2040**
|
||||
- adjust **I2C_BUFFERSIZE** for RP2040 to 128.
|
||||
- update readme.md
|
||||
|
||||
## [1.7.2] - 2023-05-02
|
||||
- fix #53 support RP2040 (kudos to jotamachuca)
|
||||
- move code from .h to .cpp
|
||||
- make I2C_WRITEDELAY overridable
|
||||
- minor edits
|
||||
|
||||
## [1.7.1] - 2023-01-12
|
||||
- add setDeviceSize()
|
||||
- add setPageSize()
|
||||
- use setDeviceSize() in constructor to force power of 2.
|
||||
- update unit test
|
||||
- update GitHub actions
|
||||
- update license
|
||||
- update readme.md
|
||||
- minor edits
|
||||
|
||||
## [1.7.0] - 2022-12-02
|
||||
- fix #48 rewrote constructor.
|
||||
|
||||
----
|
||||
|
||||
## [1.6.2] - 2022-10-30
|
||||
- Add RP2040 support to build-CI.
|
||||
- Add CHANGELOG.md
|
||||
- remove **yield()** calls in writeBlock(), readBlock() and updateBlock()
|
||||
as these are already handled on a lower level. See #46
|
||||
- better explain **begin()** in readme.md
|
||||
|
||||
## [1.6.1] - 2022-06-11
|
||||
- update documentation
|
||||
- minor edits
|
||||
- minor improvements / bug fixes
|
||||
|
||||
## [1.6.0] - 2022-06-02
|
||||
- add verify functions.
|
||||
|
||||
----
|
||||
|
||||
## [1.5.2] - 2021-12-19
|
||||
- update library.json
|
||||
- update license
|
||||
- minor edits
|
||||
|
||||
## [1.5.1] - 2021-10-14
|
||||
- function to add extra for write cycle (experimental)
|
||||
|
||||
## [1.5.0] - 2021-06-30
|
||||
- #28 fix addressing 24LC04/08/16
|
||||
|
||||
----
|
||||
|
||||
## [1.4.3] - 2021-05-05
|
||||
- adjust buffer size AVR / ESP
|
||||
- rename ?
|
||||
|
||||
## [1.4.2] - 2021-01-31
|
||||
- add updateBlock()
|
||||
|
||||
## [1.4.1] - 2021-01-28
|
||||
- fix addressing bug 24LC04/08/16 equivalents from ST e.g. m24c08w
|
||||
- add Wire1..WireN;
|
||||
|
||||
## [1.4.0] - 2021-01-27
|
||||
- rewrite addressing scheme
|
||||
- fix determineSize() - See determineSize for all tested.
|
||||
|
||||
----
|
||||
|
||||
## [1.3.2] - 2021-01-18
|
||||
- add cyclic store functionality (Thanks to Tomas Hübner)
|
||||
|
||||
## [1.3.1] - 2020-12-22
|
||||
- add Arduino-CI + unit tests
|
||||
- add updateByte()
|
||||
|
||||
## [1.3.0] - 2020-06-19
|
||||
- refactor
|
||||
- remove pre 1.0 support
|
||||
- add ESP32 support.
|
||||
|
||||
----
|
||||
|
||||
## [1.2.7] - 2019-09-03
|
||||
- fix issue #113 and #128
|
||||
|
||||
## [1.2.6] - 2019-02-01
|
||||
- fix issue #121
|
||||
|
||||
## [1.2.5] - 2017-04-20
|
||||
- refactor the removed timeout (Thanks to Koepel)
|
||||
|
||||
## [1.2.4] - 2017-04-19
|
||||
- remove timeout - issue #63
|
||||
|
||||
## [1.2.03] - 2015-05-15
|
||||
- fix in \_pageBlock & example (thanks ifreislich )
|
||||
|
||||
## [1.2.02] - 2015-03-06
|
||||
- stricter interface
|
||||
|
||||
## [1.2.01] - 2014-05-21
|
||||
- Refactoring
|
||||
|
||||
## [1.2.00] - 2014-05-21
|
||||
- Add support for Arduino DUE ( thanks to Tyler F.)
|
||||
|
||||
----
|
||||
|
||||
## [1.1.00] - 2013-11-13
|
||||
- added begin() function (Note breaking interface)
|
||||
- use faster block Wire.write()
|
||||
- int casting removed
|
||||
|
||||
----
|
||||
|
||||
## [1.0.05] - 2013-11-06
|
||||
- improved waitEEReady(),
|
||||
- add determineSize()
|
||||
|
||||
## [1.0.04] - 2013-11-03
|
||||
- fix bug in readBlock
|
||||
- moved waitEEReady() -> more efficient.
|
||||
|
||||
## [1.0.03] - 2013-11-03
|
||||
- refactor 5 millis() write-latency
|
||||
|
||||
## [1.0.02] - 2013-11-03
|
||||
- optimize internal buffers
|
||||
- refactor
|
||||
## [1.0.01] - 2013-11-01
|
||||
- fixed writeBlock bug
|
||||
- refactor
|
||||
## [1.0.00] - 2013-06-09
|
||||
- support for Arduino 1.0.x
|
||||
|
||||
----
|
||||
|
||||
## [0.2.01] - 2011-08-13
|
||||
- \_readBlock made more robust + return value
|
||||
|
||||
## [0.2.00] - 2011-02-11
|
||||
- fix 64 bit boundary bug
|
||||
|
||||
----
|
||||
|
||||
## [0.1.01] - 2011-02-07
|
||||
- add setBlock function
|
||||
|
||||
## [0.1.00] - 2011-01-21
|
||||
- initial version
|
||||
+530
-158
@@ -1,48 +1,15 @@
|
||||
//
|
||||
// FILE: I2C_eeprom.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 1.4.3
|
||||
// VERSION: 1.9.3
|
||||
// PURPOSE: Arduino Library for external I2C EEPROM 24LC256 et al.
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM.git
|
||||
//
|
||||
// HISTORY:
|
||||
// 0.1.00 2011-01-21 initial version
|
||||
// 0.1.01 2011-02-07 added setBlock function
|
||||
// 0.2.00 2011-02-11 fixed 64 bit boundary bug
|
||||
// 0.2.01 2011-08-13 _readBlock made more robust + return value
|
||||
// 1.0.00 2013-06-09 support for Arduino 1.0.x
|
||||
// 1.0.01 2013-11-01 fixed writeBlock bug, refactor
|
||||
// 1.0.02 2013-11-03 optimize internal buffers, refactor
|
||||
// 1.0.03 2013-11-03 refactor 5 millis() write-latency
|
||||
// 1.0.04 2013-11-03 fix bug in readBlock, moved waitEEReady()
|
||||
// -> more efficient.
|
||||
// 1.0.05 2013-11-06 improved waitEEReady(),
|
||||
// added determineSize()
|
||||
// 1.1.00 2013-11-13 added begin() function (Note breaking interface)
|
||||
// use faster block Wire.write()
|
||||
// int casting removed
|
||||
// 1.2.00 2014-05-21 Added support for Arduino DUE ( thanks to Tyler F.)
|
||||
// 1.2.01 2014-05-21 Refactoring
|
||||
// 1.2.02 2015-03-06 stricter interface
|
||||
// 1.2.03 2015-05-15 bugfix in _pageBlock & example (thanks ifreislich )
|
||||
// 1.2.4 2017-04-19 remove timeout - issue #63
|
||||
// 1.2.5 2017-04-20 refactor the removed timeout (Thanks to Koepel)
|
||||
// 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.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.
|
||||
// 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()
|
||||
// 1.4.3 2021-05-05 adjust buffer size AVR / ESP +rename
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM
|
||||
|
||||
|
||||
#include <I2C_eeprom.h>
|
||||
#include "I2C_eeprom.h"
|
||||
|
||||
// Not used directly
|
||||
|
||||
// Not used directly
|
||||
#define I2C_PAGESIZE_24LC512 128
|
||||
#define I2C_PAGESIZE_24LC256 64
|
||||
#define I2C_PAGESIZE_24LC128 64
|
||||
@@ -55,54 +22,48 @@
|
||||
#define I2C_PAGESIZE_24LC01 8
|
||||
|
||||
|
||||
// TWI buffer needs max 2 bytes for eeprom address
|
||||
// 1 byte for eeprom register address is available in txbuffer
|
||||
#if defined(ESP32) || defined(ESP8266)
|
||||
// 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) || defined(PICO_RP2040)
|
||||
#define I2C_BUFFERSIZE 128
|
||||
#else
|
||||
#define I2C_BUFFERSIZE 30 // AVR, STM
|
||||
#define I2C_BUFFERSIZE 30 // AVR, STM
|
||||
#endif
|
||||
|
||||
|
||||
I2C_eeprom::I2C_eeprom(const uint8_t deviceAddress, TwoWire *wire)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
I2C_eeprom::I2C_eeprom(const uint8_t deviceAddress, TwoWire * wire) :
|
||||
I2C_eeprom(deviceAddress, I2C_DEVICESIZE_24LC256, wire)
|
||||
{
|
||||
I2C_eeprom(deviceAddress, I2C_PAGESIZE_24LC256, wire);
|
||||
}
|
||||
|
||||
|
||||
I2C_eeprom::I2C_eeprom(const uint8_t deviceAddress, const uint32_t deviceSize, TwoWire *wire)
|
||||
I2C_eeprom::I2C_eeprom(const uint8_t deviceAddress, const uint32_t deviceSize, TwoWire * wire)
|
||||
{
|
||||
_deviceAddress = deviceAddress;
|
||||
_deviceSize = deviceSize;
|
||||
_pageSize = getPageSize(_deviceSize);
|
||||
_wire = wire;
|
||||
_deviceAddress = deviceAddress;
|
||||
_deviceSize = setDeviceSize(deviceSize);
|
||||
_pageSize = calculatePageSize(_deviceSize);
|
||||
_wire = wire;
|
||||
|
||||
// Chips 16Kbit (2048 Bytes) or smaller only have one-word addresses.
|
||||
this->_isAddressSizeTwoWords = (deviceSize <= I2C_DEVICESIZE_24LC16) ? false : true;
|
||||
// Chips 16 Kbit (2048 Bytes) or smaller only have one-word addresses.
|
||||
this->_isAddressSizeTwoWords = deviceSize > I2C_DEVICESIZE_24LC16;
|
||||
}
|
||||
|
||||
|
||||
#if defined (ESP8266) || defined(ESP32)
|
||||
bool I2C_eeprom::begin(uint8_t sda, uint8_t scl)
|
||||
bool I2C_eeprom::begin(int8_t writeProtectPin)
|
||||
{
|
||||
if ((sda < 255) && (scl < 255))
|
||||
{
|
||||
_wire->begin(sda, scl);
|
||||
}
|
||||
else
|
||||
{
|
||||
_wire->begin();
|
||||
}
|
||||
_lastWrite = 0;
|
||||
return isConnected();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool I2C_eeprom::begin()
|
||||
{
|
||||
_wire->begin();
|
||||
// if (_wire == 0) SPRNL("zero"); // test #48
|
||||
_lastWrite = 0;
|
||||
_writeProtectPin = writeProtectPin;
|
||||
if (_writeProtectPin >= 0)
|
||||
{
|
||||
_autoWriteProtect = EN_AUTO_WRITE_PROTECT;
|
||||
pinMode(_writeProtectPin, OUTPUT);
|
||||
preventWrite();
|
||||
}
|
||||
return isConnected();
|
||||
}
|
||||
|
||||
@@ -114,6 +75,18 @@ bool I2C_eeprom::isConnected()
|
||||
}
|
||||
|
||||
|
||||
uint8_t I2C_eeprom::getAddress()
|
||||
{
|
||||
return _deviceAddress;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// WRITE SECTION
|
||||
//
|
||||
|
||||
// returns I2C status, 0 = OK
|
||||
int I2C_eeprom::writeByte(const uint16_t memoryAddress, const uint8_t data)
|
||||
{
|
||||
int rv = _WriteBlock(memoryAddress, &data, 1);
|
||||
@@ -121,6 +94,7 @@ int I2C_eeprom::writeByte(const uint16_t memoryAddress, const uint8_t data)
|
||||
}
|
||||
|
||||
|
||||
// returns I2C status, 0 = OK
|
||||
int I2C_eeprom::setBlock(const uint16_t memoryAddress, const uint8_t data, const uint16_t length)
|
||||
{
|
||||
uint8_t buffer[I2C_BUFFERSIZE];
|
||||
@@ -133,13 +107,20 @@ int I2C_eeprom::setBlock(const uint16_t memoryAddress, const uint8_t data, const
|
||||
}
|
||||
|
||||
|
||||
int I2C_eeprom::writeBlock(const uint16_t memoryAddress, const uint8_t* buffer, const uint16_t length)
|
||||
// returns I2C status, 0 = OK
|
||||
int I2C_eeprom::writeBlock(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length)
|
||||
{
|
||||
int rv = _pageBlock(memoryAddress, buffer, length, true);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// READ SECTION
|
||||
//
|
||||
|
||||
// returns the value stored in memoryAddress
|
||||
uint8_t I2C_eeprom::readByte(const uint16_t memoryAddress)
|
||||
{
|
||||
uint8_t rdata;
|
||||
@@ -148,58 +129,156 @@ uint8_t I2C_eeprom::readByte(const uint16_t memoryAddress)
|
||||
}
|
||||
|
||||
|
||||
uint16_t I2C_eeprom::readBlock(const uint16_t memoryAddress, uint8_t* buffer, const uint16_t length)
|
||||
// returns bytes read.
|
||||
uint16_t I2C_eeprom::readBlock(const uint16_t memoryAddress, uint8_t * buffer, const uint16_t length)
|
||||
{
|
||||
uint16_t addr = memoryAddress;
|
||||
uint16_t address = memoryAddress;
|
||||
uint16_t len = length;
|
||||
uint16_t rv = 0;
|
||||
uint16_t bytes = 0;
|
||||
while (len > 0)
|
||||
{
|
||||
uint8_t cnt = I2C_BUFFERSIZE;
|
||||
if (cnt > len) cnt = len;
|
||||
rv += _ReadBlock(addr, buffer, cnt);
|
||||
addr += cnt;
|
||||
buffer += cnt;
|
||||
len -= cnt;
|
||||
yield(); // For OS scheduling etc
|
||||
uint8_t count = I2C_BUFFERSIZE;
|
||||
if (count > len) count = len;
|
||||
bytes += _ReadBlock(address, buffer, count);
|
||||
address += count;
|
||||
buffer += count;
|
||||
len -= count;
|
||||
}
|
||||
return rv;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
// returns true or false.
|
||||
bool I2C_eeprom::verifyBlock(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length)
|
||||
{
|
||||
uint16_t address = memoryAddress;
|
||||
uint16_t len = length;
|
||||
while (len > 0)
|
||||
{
|
||||
uint8_t count = I2C_BUFFERSIZE;
|
||||
if (count > len) count = len;
|
||||
if (_verifyBlock(address, buffer, count) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
address += count;
|
||||
buffer += count;
|
||||
len -= count;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// UPDATE SECTION
|
||||
//
|
||||
|
||||
// returns 0 == OK
|
||||
int I2C_eeprom::updateByte(const uint16_t memoryAddress, const uint8_t data)
|
||||
{
|
||||
if (data == readByte(memoryAddress)) return 0;
|
||||
return writeByte(memoryAddress, data);
|
||||
}
|
||||
|
||||
int I2C_eeprom::updateBlock(const uint16_t memoryAddress, const uint8_t* buffer, const uint16_t length)
|
||||
|
||||
// returns bytes actually written <= length
|
||||
uint16_t I2C_eeprom::updateBlock(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length)
|
||||
{
|
||||
uint16_t addr = memoryAddress;
|
||||
uint16_t address = memoryAddress;
|
||||
uint16_t len = length;
|
||||
uint16_t rv = 0;
|
||||
uint16_t bytes = 0;
|
||||
while (len > 0)
|
||||
{
|
||||
uint8_t buf[I2C_BUFFERSIZE];
|
||||
uint8_t cnt = I2C_BUFFERSIZE;
|
||||
|
||||
if (cnt > len) cnt = len;
|
||||
rv += _ReadBlock(addr, buf, cnt);
|
||||
if (memcmp(buffer, buf, cnt) != 0)
|
||||
uint8_t count = I2C_BUFFERSIZE;
|
||||
|
||||
if (count > len) count = len;
|
||||
_ReadBlock(address, buf, count);
|
||||
if (memcmp(buffer, buf, count) != 0)
|
||||
{
|
||||
_pageBlock(addr, buffer, cnt, true);
|
||||
_pageBlock(address, buffer, count, true);
|
||||
bytes += count;
|
||||
}
|
||||
addr += cnt;
|
||||
buffer += cnt;
|
||||
len -= cnt;
|
||||
yield(); // For OS scheduling etc
|
||||
address += count;
|
||||
buffer += count;
|
||||
len -= count;
|
||||
}
|
||||
return rv;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
// returns size in bytes
|
||||
// returns 0 if not connected
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// VERIFY SECTION
|
||||
//
|
||||
|
||||
// return false if write or verify failed.
|
||||
bool I2C_eeprom::writeByteVerify(const uint16_t memoryAddress, const uint8_t value)
|
||||
{
|
||||
if (writeByte(memoryAddress, value) != 0 ) return false;
|
||||
uint8_t data = readByte(memoryAddress);
|
||||
return (data == value);
|
||||
}
|
||||
|
||||
|
||||
// return false if write or verify failed.
|
||||
bool I2C_eeprom::writeBlockVerify(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length)
|
||||
{
|
||||
if (writeBlock(memoryAddress, buffer, length) != 0) return false;
|
||||
return verifyBlock(memoryAddress, buffer, length);
|
||||
}
|
||||
|
||||
|
||||
// return false if write or verify failed.
|
||||
bool I2C_eeprom::setBlockVerify(const uint16_t memoryAddress, const uint8_t value, const uint16_t length)
|
||||
{
|
||||
if (setBlock(memoryAddress, value, length) != 0) return false;
|
||||
uint8_t * data = (uint8_t *) malloc(length);
|
||||
if (data == NULL) return false;
|
||||
if (readBlock(memoryAddress, data, length) != length)
|
||||
{
|
||||
free(data);
|
||||
return false;
|
||||
}
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
if (data[i] != value)
|
||||
{
|
||||
free(data);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
free(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// return false if write or verify failed.
|
||||
bool I2C_eeprom::updateByteVerify(const uint16_t memoryAddress, const uint8_t value)
|
||||
{
|
||||
if (updateByte(memoryAddress, value) != 0 ) return false;
|
||||
uint8_t data = readByte(memoryAddress);
|
||||
return (data == value);
|
||||
}
|
||||
|
||||
|
||||
// return false if write or verify failed.
|
||||
bool I2C_eeprom::updateBlockVerify(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length)
|
||||
{
|
||||
// zero bytes written means nothing needs to be verified
|
||||
if (0 == updateBlock(memoryAddress, buffer, length)) return true;
|
||||
return verifyBlock(memoryAddress, buffer, length);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// METADATA SECTION
|
||||
//
|
||||
|
||||
// returns size in bytes
|
||||
// returns 0 if not connected
|
||||
//
|
||||
// tested for
|
||||
// 2 byte address
|
||||
@@ -217,7 +296,7 @@ int I2C_eeprom::updateBlock(const uint16_t memoryAddress, const uint8_t* buffer,
|
||||
// 24LC01 128 B YES
|
||||
uint32_t I2C_eeprom::determineSize(const bool debug)
|
||||
{
|
||||
// try to read a byte to see if connected
|
||||
// try to read a byte to see if connected
|
||||
if (! isConnected()) return 0;
|
||||
|
||||
uint8_t patAA = 0xAA;
|
||||
@@ -227,26 +306,26 @@ uint32_t I2C_eeprom::determineSize(const bool debug)
|
||||
{
|
||||
bool folded = false;
|
||||
|
||||
// store old values
|
||||
// store old values
|
||||
bool addressSize = _isAddressSizeTwoWords;
|
||||
_isAddressSizeTwoWords = (size <= 2048) ? false : true;
|
||||
_isAddressSizeTwoWords = size > I2C_DEVICESIZE_24LC16; // 2048
|
||||
uint8_t buf = readByte(size);
|
||||
|
||||
// test folding
|
||||
uint8_t cnt = 0;
|
||||
// test folding
|
||||
uint8_t count = 0;
|
||||
writeByte(size, pat55);
|
||||
if (readByte(0) == pat55) cnt++;
|
||||
if (readByte(0) == pat55) count++;
|
||||
writeByte(size, patAA);
|
||||
if (readByte(0) == patAA) cnt++;
|
||||
folded = (cnt == 2);
|
||||
if (readByte(0) == patAA) count++;
|
||||
folded = (count == 2);
|
||||
if (debug)
|
||||
{
|
||||
Serial.print(size, HEX);
|
||||
Serial.print('\t');
|
||||
Serial.println(readByte(size), HEX);
|
||||
SPRNH(size, HEX);
|
||||
SPRN('\t');
|
||||
SPRNLH(readByte(size), HEX);
|
||||
}
|
||||
|
||||
// restore old values
|
||||
// restore old values
|
||||
writeByte(size, buf);
|
||||
_isAddressSizeTwoWords = addressSize;
|
||||
|
||||
@@ -256,121 +335,414 @@ uint32_t I2C_eeprom::determineSize(const bool debug)
|
||||
}
|
||||
|
||||
|
||||
uint8_t I2C_eeprom::getPageSize(uint32_t deviceSize)
|
||||
// new 1.8.1 #61
|
||||
// updated 1.8.2 #63
|
||||
//
|
||||
// Returns:
|
||||
// 0 if device size cannot be determined or device is not online
|
||||
// 1 if device has default bytes in first dataFirstBytes bytes [0-BUFSIZE]
|
||||
// Write some dataFirstBytes to the first bytes and retry or use the determineSize method
|
||||
// 2 if device has all the same bytes in first dataFirstBytes bytes [0-BUFSIZE]
|
||||
// Write some random dataFirstBytes to the first bytes and retry or use the determineSize method
|
||||
// >= 128 Device size in bytes
|
||||
uint32_t I2C_eeprom::determineSizeNoWrite()
|
||||
{
|
||||
// determine page size from device size - based on Microchip 24LCXX datasheets.
|
||||
#define BUFSIZE (32)
|
||||
// try to read a byte to see if connected
|
||||
if (!isConnected()) return 0;
|
||||
|
||||
bool addressSize = _isAddressSizeTwoWords;
|
||||
_isAddressSizeTwoWords = true; // Otherwise reading large EEPROMS fails
|
||||
bool isModifiedFirstSector = false;
|
||||
bool dataIsDifferent = false;
|
||||
|
||||
byte dataFirstBytes[BUFSIZE];
|
||||
byte dataMatch[BUFSIZE];
|
||||
readBlock(0, dataFirstBytes, BUFSIZE);
|
||||
|
||||
for (uint8_t pos = 0; pos < BUFSIZE; pos++)
|
||||
{
|
||||
if (dataIsDifferent || pos == 0)
|
||||
{
|
||||
// ignore further comparison if dataFirstBytes is not the same in buffer
|
||||
// Ignore first byte
|
||||
}
|
||||
else if (dataFirstBytes[pos - 1] != dataFirstBytes[pos])
|
||||
{
|
||||
dataIsDifferent = true;
|
||||
}
|
||||
|
||||
if (dataFirstBytes[pos] != 0xFF && dataFirstBytes[pos] != 0x00)
|
||||
{
|
||||
// Default dataFirstBytes value is 0xFF or 0x00
|
||||
isModifiedFirstSector = true;
|
||||
}
|
||||
|
||||
if (dataIsDifferent && isModifiedFirstSector)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isModifiedFirstSector)
|
||||
{
|
||||
// Cannot determine diff, at least one of the first bytes within 0 - len [BUFSIZE] needs to be changed
|
||||
// to something other than 0x00 and 0xFF
|
||||
_isAddressSizeTwoWords = addressSize;
|
||||
return 1;
|
||||
}
|
||||
if (!dataIsDifferent)
|
||||
{
|
||||
// Data in first bytes within 0 - len [BUFSIZE] are all the same.
|
||||
_isAddressSizeTwoWords = addressSize;
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Read from largest to smallest size
|
||||
for (uint32_t size = 32768; size >= 64; size /= 2)
|
||||
{
|
||||
_isAddressSizeTwoWords = (size >= I2C_DEVICESIZE_24LC16); // == 2048
|
||||
|
||||
// Try to read last byte of the block, should return length of 0 when fails for single byte devices
|
||||
// Will return the same dataFirstBytes as initially read on other devices
|
||||
// as the data pointer could not be moved to the requested position
|
||||
delay(2);
|
||||
uint16_t bSize = readBlock(size, dataMatch, BUFSIZE);
|
||||
|
||||
if (bSize == BUFSIZE && memcmp(dataFirstBytes, dataMatch, BUFSIZE) != 0)
|
||||
{
|
||||
// Read is performed just over size (size + BUFSIZE),
|
||||
// this will only work for devices with mem > size;
|
||||
// therefore return size * 2
|
||||
_isAddressSizeTwoWords = addressSize;
|
||||
return size * 2;
|
||||
}
|
||||
}
|
||||
_isAddressSizeTwoWords = addressSize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint32_t I2C_eeprom::getDeviceSize()
|
||||
{
|
||||
return _deviceSize;
|
||||
}
|
||||
|
||||
|
||||
uint8_t I2C_eeprom::getPageSize()
|
||||
{
|
||||
return _pageSize;
|
||||
}
|
||||
|
||||
|
||||
uint8_t I2C_eeprom::calculatePageSize(uint32_t deviceSize)
|
||||
{
|
||||
// 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;
|
||||
if (deviceSize <= I2C_DEVICESIZE_24LC256) return 64;
|
||||
// I2C_DEVICESIZE_24LC512
|
||||
return 128;
|
||||
if (deviceSize <= I2C_DEVICESIZE_24LC512) return 128;
|
||||
// Error.
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t I2C_eeprom::getPageSize(uint32_t deviceSize)
|
||||
{
|
||||
return calculatePageSize(deviceSize);
|
||||
}
|
||||
|
||||
|
||||
uint32_t I2C_eeprom::getLastWrite()
|
||||
{
|
||||
return _lastWrite;
|
||||
}
|
||||
|
||||
|
||||
uint32_t I2C_eeprom::setDeviceSize(uint32_t deviceSize)
|
||||
{
|
||||
uint32_t size = 128;
|
||||
// force power of 2.
|
||||
while ((size <= 65536) && ( size <= deviceSize))
|
||||
{
|
||||
_deviceSize = size;
|
||||
size *= 2;
|
||||
}
|
||||
// Chips 16 Kbit (2048 Bytes) or smaller only have one-word addresses.
|
||||
this->_isAddressSizeTwoWords = _deviceSize > I2C_DEVICESIZE_24LC16;
|
||||
return _deviceSize;
|
||||
}
|
||||
|
||||
|
||||
uint8_t I2C_eeprom::setPageSize(uint8_t pageSize)
|
||||
{
|
||||
// force power of 2.
|
||||
if (pageSize >= 128) {
|
||||
_pageSize = 128;
|
||||
}
|
||||
else if (pageSize >= 64) {
|
||||
_pageSize = 64;
|
||||
}
|
||||
else if (pageSize >= 32) {
|
||||
_pageSize = 32;
|
||||
}
|
||||
else if (pageSize >= 16) {
|
||||
_pageSize = 16;
|
||||
}
|
||||
else {
|
||||
_pageSize = 8;
|
||||
}
|
||||
return _pageSize;
|
||||
}
|
||||
|
||||
|
||||
void I2C_eeprom::setExtraWriteCycleTime(uint8_t ms)
|
||||
{
|
||||
_extraTWR = ms;
|
||||
}
|
||||
|
||||
|
||||
uint8_t I2C_eeprom::getExtraWriteCycleTime()
|
||||
{
|
||||
return _extraTWR;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// WRITEPROTECT
|
||||
//
|
||||
bool I2C_eeprom::hasWriteProtectPin()
|
||||
{
|
||||
return (_writeProtectPin >= 0);
|
||||
}
|
||||
|
||||
|
||||
void I2C_eeprom::allowWrite()
|
||||
{
|
||||
if (hasWriteProtectPin())
|
||||
{
|
||||
digitalWrite(_writeProtectPin, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void I2C_eeprom::preventWrite()
|
||||
{
|
||||
if (hasWriteProtectPin())
|
||||
{
|
||||
digitalWrite(_writeProtectPin, HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void I2C_eeprom::setAutoWriteProtect(bool b)
|
||||
{
|
||||
if (hasWriteProtectPin())
|
||||
{
|
||||
_autoWriteProtect = b;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool I2C_eeprom::getAutoWriteProtect()
|
||||
{
|
||||
return _autoWriteProtect;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PRIVATE
|
||||
// PRIVATE
|
||||
//
|
||||
|
||||
// _pageBlock aligns buffer to page boundaries for writing.
|
||||
// and to TWI 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)
|
||||
// _pageBlock aligns buffer to page boundaries for writing.
|
||||
// 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)
|
||||
{
|
||||
uint16_t addr = memoryAddress;
|
||||
uint16_t address = memoryAddress;
|
||||
uint16_t len = length;
|
||||
while (len > 0)
|
||||
{
|
||||
uint8_t bytesUntilPageBoundary = this->_pageSize - addr % this->_pageSize;
|
||||
uint8_t bytesUntilPageBoundary = this->_pageSize - address % this->_pageSize;
|
||||
|
||||
uint8_t cnt = I2C_BUFFERSIZE;
|
||||
if (cnt > len) cnt = len;
|
||||
if (cnt > bytesUntilPageBoundary) cnt = bytesUntilPageBoundary;
|
||||
uint8_t count = I2C_BUFFERSIZE;
|
||||
if (count > len) count = len;
|
||||
if (count > bytesUntilPageBoundary) count = bytesUntilPageBoundary;
|
||||
|
||||
int rv = _WriteBlock(addr, buffer, cnt);
|
||||
int rv = _WriteBlock(address, buffer, count);
|
||||
if (rv != 0) return rv;
|
||||
|
||||
addr += cnt;
|
||||
if (incrBuffer) buffer += cnt;
|
||||
len -= cnt;
|
||||
address += count;
|
||||
if (incrBuffer) buffer += count;
|
||||
len -= count;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// supports one and 2 bytes addresses
|
||||
// supports one and two bytes addresses
|
||||
void I2C_eeprom::_beginTransmission(const uint16_t memoryAddress)
|
||||
{
|
||||
if (this->_isAddressSizeTwoWords)
|
||||
{
|
||||
_wire->beginTransmission(_deviceAddress);
|
||||
// Address High Byte
|
||||
// Address High Byte
|
||||
_wire->write((memoryAddress >> 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t addr = _deviceAddress | ((memoryAddress >> 8) & 0x07);
|
||||
_wire->beginTransmission(addr);
|
||||
uint8_t address = _deviceAddress | ((memoryAddress >> 8) & 0x07);
|
||||
_wire->beginTransmission(address);
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
|
||||
// pre: length <= this->_pageSize && length <= I2C_BUFFERSIZE;
|
||||
// returns 0 = OK otherwise error
|
||||
int I2C_eeprom::_WriteBlock(const uint16_t memoryAddress, const uint8_t* buffer, const uint8_t length)
|
||||
// pre: length <= this->_pageSize && length <= I2C_BUFFERSIZE;
|
||||
// returns 0 = OK otherwise error
|
||||
int I2C_eeprom::_WriteBlock(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length)
|
||||
{
|
||||
_waitEEReady();
|
||||
if (_autoWriteProtect)
|
||||
{
|
||||
digitalWrite(_writeProtectPin, LOW);
|
||||
}
|
||||
|
||||
this->_beginTransmission(memoryAddress);
|
||||
_wire->write(buffer, length);
|
||||
int rv = _wire->endTransmission();
|
||||
yield();
|
||||
|
||||
if (_autoWriteProtect)
|
||||
{
|
||||
digitalWrite(_writeProtectPin, HIGH);
|
||||
}
|
||||
|
||||
_lastWrite = micros();
|
||||
|
||||
yield(); // For OS scheduling
|
||||
|
||||
// if (rv != 0)
|
||||
// {
|
||||
// if (_debug)
|
||||
// {
|
||||
// SPRN("mem addr w: ");
|
||||
// SPRNH(memoryAddress, HEX);
|
||||
// SPRN("\t");
|
||||
// SPRNL(rv);
|
||||
// }
|
||||
// return -(abs(rv)); // error
|
||||
// }
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
// pre: buffer is large enough to hold length bytes
|
||||
// returns bytes read
|
||||
uint8_t I2C_eeprom::_ReadBlock(const uint16_t memoryAddress, uint8_t* buffer, const uint8_t length)
|
||||
// pre: buffer is large enough to hold length bytes
|
||||
// returns bytes read
|
||||
uint8_t I2C_eeprom::_ReadBlock(const uint16_t memoryAddress, uint8_t * buffer, const uint16_t length)
|
||||
{
|
||||
_waitEEReady();
|
||||
|
||||
this->_beginTransmission(memoryAddress);
|
||||
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);
|
||||
uint8_t cnt = 0;
|
||||
while (cnt < readBytes)
|
||||
if (rv != 0)
|
||||
{
|
||||
buffer[cnt++] = _wire->read();
|
||||
yield();
|
||||
// if (_debug)
|
||||
// {
|
||||
// SPRN("mem addr r: ");
|
||||
// SPRNH(memoryAddress, HEX);
|
||||
// SPRN("\t");
|
||||
// SPRNL(rv);
|
||||
// }
|
||||
return 0; // error
|
||||
}
|
||||
|
||||
// readBytes will always be equal or smaller to length
|
||||
uint8_t readBytes = 0;
|
||||
if (this->_isAddressSizeTwoWords)
|
||||
{
|
||||
readBytes = _wire->requestFrom((int)_deviceAddress, (int)length);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t address = _deviceAddress | ((memoryAddress >> 8) & 0x07);
|
||||
readBytes = _wire->requestFrom((int)address, (int)length);
|
||||
}
|
||||
yield(); // For OS scheduling
|
||||
uint8_t count = 0;
|
||||
while (count < readBytes)
|
||||
{
|
||||
buffer[count++] = _wire->read();
|
||||
}
|
||||
return readBytes;
|
||||
}
|
||||
|
||||
|
||||
// compares content of EEPROM with buffer.
|
||||
// returns true if equal.
|
||||
bool I2C_eeprom::_verifyBlock(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length)
|
||||
{
|
||||
_waitEEReady();
|
||||
|
||||
this->_beginTransmission(memoryAddress);
|
||||
int rv = _wire->endTransmission();
|
||||
if (rv != 0)
|
||||
{
|
||||
// if (_debug)
|
||||
// {
|
||||
// SPRN("mem addr r: ");
|
||||
// SPRNH(memoryAddress, HEX);
|
||||
// SPRN("\t");
|
||||
// SPRNL(rv);
|
||||
// }
|
||||
return false; // error
|
||||
}
|
||||
|
||||
// readBytes will always be equal or smaller to length
|
||||
uint8_t readBytes = 0;
|
||||
if (this->_isAddressSizeTwoWords)
|
||||
{
|
||||
readBytes = _wire->requestFrom((int)_deviceAddress, (int)length);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t address = _deviceAddress | ((memoryAddress >> 8) & 0x07);
|
||||
readBytes = _wire->requestFrom((int)address, (int)length);
|
||||
}
|
||||
yield(); // For OS scheduling
|
||||
uint8_t count = 0;
|
||||
while (count < readBytes)
|
||||
{
|
||||
if (buffer[count++] != _wire->read())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void I2C_eeprom::_waitEEReady()
|
||||
{
|
||||
#define I2C_WRITEDELAY 5000
|
||||
|
||||
// Wait until EEPROM gives ACK again.
|
||||
// this is a bit faster than the hardcoded 5 milliSeconds
|
||||
while ((micros() - _lastWrite) <= I2C_WRITEDELAY)
|
||||
// Wait until EEPROM gives ACK again.
|
||||
// this is a bit faster than the hardcoded 5 milliSeconds
|
||||
// TWR = WriteCycleTime
|
||||
uint32_t waitTime = I2C_WRITEDELAY + _extraTWR * 1000UL;
|
||||
while ((micros() - _lastWrite) <= waitTime)
|
||||
{
|
||||
_wire->beginTransmission(_deviceAddress);
|
||||
int x = _wire->endTransmission();
|
||||
if (x == 0) return;
|
||||
yield();
|
||||
if (isConnected()) return;
|
||||
// TODO remove pre 1.7.4 code
|
||||
// _wire->beginTransmission(_deviceAddress);
|
||||
// int x = _wire->endTransmission();
|
||||
// if (x == 0) return;
|
||||
yield(); // For OS scheduling
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
||||
+122
-46
@@ -2,19 +2,16 @@
|
||||
//
|
||||
// FILE: I2C_eeprom.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 1.4.3
|
||||
// VERSION: 1.9.4
|
||||
// PURPOSE: Arduino Library for external I2C EEPROM 24LC256 et al.
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM.git
|
||||
//
|
||||
// HISTORY: See I2C_eeprom.cpp
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Wire.h"
|
||||
|
||||
|
||||
#define I2C_EEPROM_VERSION (F("1.4.3"))
|
||||
|
||||
#define I2C_EEPROM_VERSION (F("1.9.4"))
|
||||
|
||||
#define I2C_DEVICESIZE_24LC512 65536
|
||||
#define I2C_DEVICESIZE_24LC256 32768
|
||||
@@ -28,10 +25,40 @@
|
||||
#define I2C_DEVICESIZE_24LC01 128
|
||||
|
||||
|
||||
// AT24C32 has a WriteCycle Time of max 20 ms
|
||||
// so one need to set I2C_WRITEDELAY to 20000.
|
||||
// can also be done on command line.
|
||||
// (see private _waitEEReady() function)
|
||||
#ifndef I2C_WRITEDELAY
|
||||
#define I2C_WRITEDELAY 5000
|
||||
#endif
|
||||
|
||||
|
||||
// set the flag EN_AUTO_WRITE_PROTECT to 1 to enable the Write Control at compile time
|
||||
// used if the write_protect pin is explicitly set in the begin() function.
|
||||
// the flag can be set as command line option.
|
||||
#ifndef EN_AUTO_WRITE_PROTECT
|
||||
#define EN_AUTO_WRITE_PROTECT 0
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef UNIT_TEST_FRIEND
|
||||
#define UNIT_TEST_FRIEND
|
||||
#endif
|
||||
|
||||
//#define ENABLE_DEBUG
|
||||
|
||||
#ifdef ENABLE_DEBUG
|
||||
#define SPRN Serial.print
|
||||
#define SPRNL Serial.println
|
||||
#define SPRNH Serial.print
|
||||
#define SPRNLH Serial.println
|
||||
#else
|
||||
#define SPRN(MSG)
|
||||
#define SPRNH(MSG,MSG2)
|
||||
#define SPRNL(MSG)
|
||||
#define SPRNLH(MSG,MSG2)
|
||||
#endif
|
||||
|
||||
class I2C_eeprom
|
||||
{
|
||||
@@ -47,75 +74,124 @@ public:
|
||||
* It will try to guess page size and address word size based on the size of the device.
|
||||
*
|
||||
* @param deviceAddress Byte address of the device.
|
||||
* @param deviceSize Max size in bytes of the device (divide your device size in Kbits by 8)
|
||||
* @param deviceSize Max size in bytes of the device (divide your device size in Kbits by 8 to get Kbytes)
|
||||
* @param wire Select alternative Wire interface
|
||||
*/
|
||||
I2C_eeprom(const uint8_t deviceAddress, const uint32_t deviceSize, TwoWire *wire = &Wire);
|
||||
|
||||
#if defined (ESP8266) || defined(ESP32)
|
||||
bool begin(uint8_t sda, uint8_t scl);
|
||||
#endif
|
||||
bool begin();
|
||||
|
||||
bool begin(int8_t writeProtectPin = -1);
|
||||
bool isConnected();
|
||||
uint8_t getAddress();
|
||||
|
||||
// writes a byte to memaddr
|
||||
|
||||
// user is responsible that address is in range of the EEPROM used.
|
||||
// writes a byte to memoryAddress
|
||||
// returns I2C status, 0 = OK
|
||||
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);
|
||||
// set length bytes in the EEPROM to the same value.
|
||||
// writes length bytes from buffer to EEPROM
|
||||
// returns I2C status, 0 = OK
|
||||
int writeBlock(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length);
|
||||
// set length bytes in the EEPROM to the same value.
|
||||
// returns I2C status, 0 = OK
|
||||
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);
|
||||
// reads length bytes into buffer
|
||||
// returns bytes read.
|
||||
uint16_t readBlock(const uint16_t memoryAddress, uint8_t * buffer, const uint16_t length);
|
||||
bool verifyBlock(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length);
|
||||
|
||||
|
||||
// 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.
|
||||
// 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.
|
||||
// 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);
|
||||
// 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!
|
||||
// returns bytes actually written <= length
|
||||
uint16_t updateBlock(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length);
|
||||
|
||||
uint32_t determineSize(const bool debug = false);
|
||||
|
||||
uint32_t getDeviceSize() { return _deviceSize; };
|
||||
uint8_t getPageSize() { return _pageSize; };
|
||||
// same functions as above but with verify
|
||||
// return false if write or verify failed.
|
||||
bool writeByteVerify(const uint16_t memoryAddress, const uint8_t value);
|
||||
bool writeBlockVerify(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length);
|
||||
bool setBlockVerify(const uint16_t memoryAddress, const uint8_t value, const uint16_t length);
|
||||
bool updateByteVerify(const uint16_t memoryAddress, const uint8_t value);
|
||||
bool updateBlockVerify(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length);
|
||||
|
||||
|
||||
// Meta data functions
|
||||
uint32_t getDeviceSize();
|
||||
uint8_t getPageSize();
|
||||
uint8_t calculatePageSize(uint32_t deviceSize);
|
||||
[[deprecated("Use calculatePageSize(deviceSize) instead.")]]
|
||||
uint8_t getPageSize(uint32_t deviceSize);
|
||||
uint32_t getLastWrite() { return _lastWrite; };
|
||||
uint32_t determineSizeNoWrite();
|
||||
uint32_t determineSize(const bool debug = false);
|
||||
uint32_t getLastWrite();
|
||||
|
||||
|
||||
// for overruling and debugging.
|
||||
// forces a power of 2
|
||||
uint32_t setDeviceSize(uint32_t deviceSize); // returns set size
|
||||
uint8_t setPageSize(uint8_t pageSize); // returns set size
|
||||
|
||||
|
||||
// TWR = WriteCycleTime
|
||||
// 5 ms is minimum, one can add extra ms here to adjust timing of both read() and write()
|
||||
void setExtraWriteCycleTime(uint8_t ms);
|
||||
uint8_t getExtraWriteCycleTime();
|
||||
|
||||
|
||||
// WRITEPROTECT
|
||||
// works only if WP pin is defined in begin().
|
||||
// see readme.md
|
||||
inline bool hasWriteProtectPin();
|
||||
void allowWrite();
|
||||
void preventWrite();
|
||||
void setAutoWriteProtect(bool b);
|
||||
bool getAutoWriteProtect();
|
||||
|
||||
|
||||
private:
|
||||
uint8_t _deviceAddress;
|
||||
uint32_t _lastWrite; // for waitEEReady
|
||||
uint32_t _deviceSize;
|
||||
uint8_t _pageSize;
|
||||
uint32_t _lastWrite = 0; // for waitEEReady
|
||||
uint32_t _deviceSize = 0;
|
||||
uint8_t _pageSize = 0;
|
||||
uint8_t _extraTWR = 0; // milliseconds
|
||||
|
||||
// 24LC32..24LC512 use two bytes for memory address
|
||||
// 24LC01..24LC16 use one-byte addresses + part of device address
|
||||
|
||||
// 24LC32..24LC512 use two bytes for memory address
|
||||
// 24LC01..24LC16 use one-byte addresses + part of device address
|
||||
bool _isAddressSizeTwoWords;
|
||||
|
||||
|
||||
/**
|
||||
* Begins wire transmission and selects the given address to write/read.
|
||||
*
|
||||
* @param memoryAddress Address to write/read
|
||||
*/
|
||||
void _beginTransmission(const uint16_t memoryAddress);
|
||||
|
||||
int _pageBlock(const uint16_t memoryAddress, const uint8_t* buffer, const uint16_t length, const bool incrBuffer);
|
||||
int _WriteBlock(const uint16_t memoryAddress, const uint8_t* buffer, const uint8_t length);
|
||||
uint8_t _ReadBlock(const uint16_t memoryAddress, uint8_t* buffer, const uint8_t length);
|
||||
// returns I2C status, 0 = OK
|
||||
// TODO incrBuffer is an implementation name, not a functional name.
|
||||
int _pageBlock(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length, const bool incrBuffer);
|
||||
// returns I2C status, 0 = OK
|
||||
int _WriteBlock(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length);
|
||||
// returns bytes read.
|
||||
uint8_t _ReadBlock(const uint16_t memoryAddress, uint8_t * buffer, const uint16_t length);
|
||||
// compare bytes in EEPROM.
|
||||
bool _verifyBlock(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length);
|
||||
|
||||
// to optimize the write latency of the EEPROM
|
||||
// to optimize the write latency of the EEPROM
|
||||
void _waitEEReady();
|
||||
|
||||
TwoWire * _wire;
|
||||
|
||||
bool _debug = false;
|
||||
|
||||
int8_t _writeProtectPin = -1;
|
||||
bool _autoWriteProtect = EN_AUTO_WRITE_PROTECT;
|
||||
|
||||
UNIT_TEST_FRIEND;
|
||||
};
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
||||
+21
-19
@@ -5,13 +5,15 @@
|
||||
// VERSION: 1.0.0
|
||||
// PURPOSE: Supplemental utility class for I2C_EEPROM library
|
||||
//
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM
|
||||
|
||||
|
||||
#include <I2C_eeprom.h>
|
||||
|
||||
/**
|
||||
* @brief This is a utility class for using an eeprom to store a simple
|
||||
* data structure.
|
||||
*
|
||||
*
|
||||
* The purpose of the utility is to extend the life of an eeprom memory by
|
||||
* rotating the writes over different pages to reduce the number of writes
|
||||
* to any individual page.
|
||||
@@ -23,7 +25,7 @@
|
||||
* version number which is then used for subsequent reads.
|
||||
* Whenever data is written the version number is incremented and the next
|
||||
* slot in sequence is used (or the first slot if going past the end).
|
||||
*
|
||||
*
|
||||
* Note that the data is stored in binary form which means it should not be
|
||||
* expected that the eeprom can be moved between architectures. Data stored
|
||||
* in an eeprom will also become invalid if the data structure is changed
|
||||
@@ -31,10 +33,10 @@
|
||||
*
|
||||
* If the data structure has changed or if the eeprom contains other data it
|
||||
* must first be formatted with a call to format().
|
||||
*
|
||||
*
|
||||
* Finally, since the version number is a long word, this class will
|
||||
* *derail and fail* to add new versions past 4294967295 writes.
|
||||
*
|
||||
*
|
||||
* @tparam T the type of the data structure to store, should only contain
|
||||
* **value** members and no constructor/destructor nor other
|
||||
* methods/functions - e g a pure DTO.
|
||||
@@ -45,10 +47,10 @@ class I2C_eeprom_cyclic_store
|
||||
public:
|
||||
/**
|
||||
* @brief Initializes the instance
|
||||
*
|
||||
*
|
||||
* This call searches the eeprom for the latest written version and
|
||||
* sets the current slot accordingly.
|
||||
*
|
||||
*
|
||||
* @param eeprom The instance of I2C_eeprom to use.
|
||||
* @param pageSize The number of bytes in each write page.
|
||||
* @param totalPages Specifies the total number of pages to use.
|
||||
@@ -69,12 +71,12 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Formats the eeprom
|
||||
*
|
||||
*
|
||||
* This must be done if the eeprom already contains data or if the
|
||||
* structure of the data stored changes.
|
||||
*
|
||||
* structure of the data stored changes.
|
||||
*
|
||||
* Formatting is done by writing the max version number to each slot,
|
||||
* thus it performs a write cycle to the first write page of each slot.
|
||||
* thus it performs a write cycle to the first write page of each slot.
|
||||
*
|
||||
* @return True if successful or false if unable to write to eeprom.
|
||||
*/
|
||||
@@ -93,14 +95,14 @@ public:
|
||||
_currentSlot = 0;
|
||||
_isInitialized = true;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read data from the eeprom into a buffer.
|
||||
*
|
||||
*
|
||||
* The data is read from the current slot of the eeprom.
|
||||
*
|
||||
*
|
||||
* @param buffer A reference to the buffer to read data into.
|
||||
* @return True if data was read successfully, false otherwise.
|
||||
*/
|
||||
@@ -108,9 +110,9 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Read data from the eeprom into a buffer.
|
||||
*
|
||||
*
|
||||
* The data is read from the current slot of the eeprom.
|
||||
*
|
||||
*
|
||||
* @param buffer A pointet to the buffer to read data into.
|
||||
* @return True if data was read successfully, false otherwise.
|
||||
*/
|
||||
@@ -127,9 +129,9 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Write a buffer to the next slot in the eeprom.
|
||||
*
|
||||
*
|
||||
* This updates the current slot of this instance.
|
||||
*
|
||||
*
|
||||
* @param buffer A reference to the buffer to write data from.
|
||||
* @return True if data was written successfully, false otherwise.
|
||||
*/
|
||||
@@ -181,11 +183,11 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Returns metrics for the eeprom usage.
|
||||
*
|
||||
*
|
||||
* Dividing the returned values of \p writeCounter with \p slots yields the average number of
|
||||
* writes to the individual write pages of the eeprom. This can be used to estimate the remaining
|
||||
* number of possible writes.
|
||||
*
|
||||
*
|
||||
* @param[out] slots The number of slots used to write the data buffer.
|
||||
* @param[out] writeCounter The total number of write to the eeprom since the last format (or first use).
|
||||
* @return True if the instance is initialized, false otherwise.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2011-2021 Rob Tillaart
|
||||
Copyright (c) 2011-2025 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
|
||||
|
||||
@@ -1,87 +1,311 @@
|
||||
|
||||
[](https://github.com/marketplace/actions/arduino_ci)
|
||||
[](https://github.com/RobTillaart/I2C_EEPROM/actions/workflows/arduino-lint.yml)
|
||||
[](https://github.com/RobTillaart/I2C_EEPROM/actions/workflows/jsoncheck.yml)
|
||||
[](https://github.com/RobTillaart/I2C_EEPROM/issues)
|
||||
|
||||
[](https://github.com/RobTillaart/I2C_EEPROM/blob/master/LICENSE)
|
||||
[](https://github.com/RobTillaart/I2C_EEPROM/releases)
|
||||
[](https://registry.platformio.org/libraries/robtillaart/I2C_EEPROM)
|
||||
|
||||
|
||||
|
||||
# I2C_EEPROM
|
||||
|
||||
Arduino Library for external I2C EEPROM - 24LC512, 24LC256, 24LC64/32/16/08/04/02/01
|
||||
Arduino Library for external I2C EEPROM - 24LC512, 24LC256, 24LC64/32/16/08/04/02/01.
|
||||
|
||||
|
||||
## Description
|
||||
|
||||
This library is to access external I2C EEPROM up to 64KB (= 512 Kbit) in size.
|
||||
MicroChip 24LC512, 24LC256, 24LC64, 24LC32, 24LC16, 24LC08, 24LC04, 24LC02, 24LC01 and equivalents.
|
||||
This library is used to access an external I2C EEPROM up to 64KB (= 512 Kbit) in size.
|
||||
The MicroChip 24LC512, 24LC256, 24LC64, 24LC32, 24LC16, 24LC08, 24LC04, 24LC02, 24LC01
|
||||
and equivalents are tested and working.
|
||||
|
||||
Also confirmed working M24512-W, M24512-R, M24512-DF (See #68).
|
||||
Not supported are the identification page functions.
|
||||
|
||||
The **I2C_eeprom_cyclic_store** interface is documented [here](README_cyclic_store.md)
|
||||
|
||||
**Warning**
|
||||
|
||||
The user is responsible to verify the used memoryAddress (range) exists in the used EEPROM. (read / write / verify functions).
|
||||
The library does not check this. If the address is larger than the EEPROM size,
|
||||
the address used will probably be memoryAddress % deviceSize.
|
||||
|
||||
|
||||
### RP2040
|
||||
|
||||
There are at least two boards modules for the RP2040 that use different Wire libraries.
|
||||
One from "Earle F. Philhower" and an "MBED" one. See issues #53 and #55 for details.
|
||||
In 1.7.3 defines are checked to select between these two and as far as tested this seems
|
||||
to solve the issue #53 while being backwards compatible.
|
||||
If a better solution is found, it will be implemented.
|
||||
|
||||
|
||||
### Breaking change 1.9.0
|
||||
|
||||
Version 1.9.0 fixed a memory leak in **verifyBlock()**.
|
||||
|
||||
### Breaking change 1.8.0
|
||||
|
||||
Version 1.8.0 introduced a breaking change.
|
||||
You cannot set the I2C pins in **begin()** any more.
|
||||
This reduces the dependency of processor dependent Wire (I2C) implementations.
|
||||
The user has to call **Wire.begin()** and can optionally set the Wire pins
|
||||
(if the board supports this), before calling **I2C_eeprom.begin()**.
|
||||
|
||||
|
||||
### Related
|
||||
|
||||
- https://github.com/RobTillaart/I2C_24LC1025
|
||||
- https://github.com/RobTillaart/I2C_CAT24M01
|
||||
- https://github.com/RobTillaart/I2C_EEPROM
|
||||
|
||||
|
||||
## Schematic
|
||||
|
||||
Verify the datasheet for your specific EEPROM.
|
||||
|
||||
```cpp
|
||||
+---U---+
|
||||
A0 | 1 8 | VCC = 1.7V to 5.5V
|
||||
A1 | 2 7 | WP = write protect pin
|
||||
A2 | 3 6 | SCL = I2C clock
|
||||
(VSS) GND | 4 5 | SDA = I2C data
|
||||
+-------+
|
||||
```
|
||||
|
||||
|
||||
## I2C
|
||||
|
||||
I2C address = 0x50 .. 0x57 depending on three address lines (A0, A1, A2).
|
||||
|
||||
Read the datasheet of your specific EEPROM, section device addressing.
|
||||
|
||||
|
||||
### I2C multiplexing
|
||||
|
||||
Sometimes you need to control more devices than possible with the default
|
||||
address range the device provides.
|
||||
This is possible with an I2C multiplexer e.g. TCA9548 which creates up
|
||||
to eight channels (think of it as I2C subnets) which can use the complete
|
||||
address range of the device.
|
||||
|
||||
Drawback of using a multiplexer is that it takes more administration in
|
||||
your code e.g. which device is on which channel.
|
||||
This will slow down the access, which must be taken into account when
|
||||
deciding which devices are on which channel.
|
||||
Also note that switching between channels will slow down other devices
|
||||
too if they are behind the multiplexer.
|
||||
|
||||
- https://github.com/RobTillaart/TCA9548
|
||||
|
||||
|
||||
## Interface
|
||||
|
||||
```cpp
|
||||
#include "I2C_eeprom.h"
|
||||
```
|
||||
|
||||
The interface is kept quite identical to the I2C_24LC1025 library.
|
||||
https://github.com/RobTillaart/I2C_24LC1025
|
||||
|
||||
Most important difference is that the latter uses 32 bit memory addresses.
|
||||
|
||||
|
||||
### Constructor
|
||||
|
||||
- **I2C_eeprom(uint8_t deviceAddress, TwoWire \*wire = &Wire)** constructor, optional Wire interface
|
||||
- **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.
|
||||
- **I2C_eeprom(uint8_t deviceAddress, TwoWire \*wire = &Wire)** constructor, to set the
|
||||
device address and optional Wire interface. The deviceSize == I2C_DEVICESIZE_24LC256 (32KB)
|
||||
is used as it is the most often used I2C_EEPROM size.
|
||||
Be aware that if you use other sized EEPROMs you have to use the next constructor,
|
||||
and name the deviceSize explicitly, otherwise errors might occur.
|
||||
- **I2C_eeprom(uint8_t deviceAddress, uint32_t deviceSize, TwoWire \*wire = &Wire)**
|
||||
constructor, idem as above, furthermore the deviceSize can be any of the defines in the
|
||||
table below or its number equivalent.
|
||||
The Wire interface is optional, default Wire.
|
||||
- **bool begin(uint8_t writeProtectPin = -1)** Optionally one can set the **WP**
|
||||
writeProtect pin. (see section below).
|
||||
If the **WP** pin is defined, the default behaviour will be to **not** allow writing.
|
||||
Furthermore it checks if the deviceAddress given in the constructor is available
|
||||
on the defined I2C bus.
|
||||
Returns true if deviceAddress is found on the I2C bus, false otherwise.
|
||||
- **bool isConnected()** returns true if the address given in the constructor is
|
||||
available on the defined I2C bus.
|
||||
- **uint8_t getAddress()** returns deviceAddress set in the constructor.
|
||||
Convenience.
|
||||
|
||||
|
||||
### Core functions
|
||||
Defined device sizes for constructor, more details see below.
|
||||
|
||||
- **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.
|
||||
| Define | bytes | Notes |
|
||||
|:-------------------------|--------:|:--------|
|
||||
| I2C_DEVICESIZE_24LC512 | 65536 |
|
||||
| I2C_DEVICESIZE_24LC256 | 32768 | most used
|
||||
| I2C_DEVICESIZE_24LC128 | 16384 |
|
||||
| I2C_DEVICESIZE_24LC64 | 8192 |
|
||||
| I2C_DEVICESIZE_24LC32 | 4096 |
|
||||
| I2C_DEVICESIZE_24LC16 | 2048 |
|
||||
| I2C_DEVICESIZE_24LC08 | 1024 |
|
||||
| I2C_DEVICESIZE_24LC04 | 512 |
|
||||
| I2C_DEVICESIZE_24LC02 | 256 |
|
||||
| I2C_DEVICESIZE_24LC01 | 128 |
|
||||
|
||||
|
||||
### Write functions
|
||||
|
||||
- **int writeByte(uint16_t memoryAddress, uint8_t value)** write a single byte to
|
||||
the specified memory address.
|
||||
Returns I2C status, 0 = OK.
|
||||
- **int writeBlock(uint16_t memoryAddress, uint8_t \* buffer, uint16_t length)**
|
||||
write a buffer starting at the specified memory address.
|
||||
Returns I2C status, 0 = OK.
|
||||
- **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 I2C status, 0 = OK.
|
||||
|
||||
|
||||
### Update functions
|
||||
|
||||
Using update instead of write functions does not write if the value is the same.
|
||||
The price is an extra read() call, but if there is no change the gain is performance.
|
||||
|
||||
- **int updateByte(uint16_t memoryAddress, uint8_t value)** write a single byte,
|
||||
but only if the value has changed.
|
||||
Returns 0 if value was same or write succeeded.
|
||||
- **uint16_t updateBlock(uint16_t memoryAddress, uint8_t \* buffer, uint16_t length)**
|
||||
write a buffer starting at the specified memory address, but only if changed.
|
||||
Returns bytes actually written <= length.
|
||||
|
||||
|
||||
### Read functions
|
||||
|
||||
- **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.
|
||||
The user is responsible that the used buffer can hold length bytes.
|
||||
|
||||
|
||||
### Verify functions
|
||||
|
||||
Since 1.6.0. - experimental, needs extensive testing.
|
||||
|
||||
Same as write and update functions above. Returns true if successful, false indicates an error.
|
||||
The user is responsible that the used buffer can hold length bytes.
|
||||
|
||||
- **bool writeByteVerify(uint16_t memoryAddress, uint8_t value)**
|
||||
- **bool writeBlockVerify(uint16_t memoryAddress, uint8_t \* buffer, uint16_t length)**
|
||||
- **bool setBlockVerify(uint16_t memoryAddress, uint8_t value, uint16_t length)**
|
||||
- **bool updateByteVerify(uint16_t memoryAddress, uint8_t value)**
|
||||
- **bool updateBlockVerify(uint16_t memoryAddress, uint8_t \* buffer, uint16_t length)**
|
||||
- **bool verifyBlock(uint16_t memoryAddress, uint8_t \* buffer, uint16_t length)**
|
||||
Returns true is buffer equals memoryAddress for length bytes.
|
||||
|
||||
|
||||
### Other
|
||||
|
||||
- **uint32_t getDeviceSize()** idem
|
||||
- **uint8_t getPageSize()** idem
|
||||
- **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.
|
||||
It is based upon the observation that memory wraps around.
|
||||
The debug flag gives some output to Serial.
|
||||
- **uint32_t getDeviceSize()** returns the current set deviceSize.
|
||||
- **uint8_t getPageSize()** returns the current set pageSize.
|
||||
- **uint8_t calculatePageSize(uint32_t deviceSize)** calculates the pageSize of a device
|
||||
with deviceSize. Note it does not set the pageSize!
|
||||
- **uint8_t getPageSize(uint32_t deviceSize)** deprecated, wrapper around calculatePageSize().
|
||||
- **uint32_t getLastWrite()** returns timestamp in millis since start of program.
|
||||
- **uint32_t determineSizeNoWrite()** function that determines the size of the EEPROM
|
||||
by detecting when a selected memory address is not readable. (new in 1.8.1).
|
||||
- **uint32_t determineSize(bool debug = false)**
|
||||
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 prints some output to Serial.
|
||||
**Warning**: this function has changed (again) in 1.4.0
|
||||
|
||||
**Warning**: this function has changed (again) in 1.4.0
|
||||
|
||||
Testresults
|
||||
Test results **determineSize()**
|
||||
|
||||
| Type | returns | Memory | Page Size | Notes |
|
||||
|:--------|:--------|:---------|:-----:|:------|
|
||||
| - | 0 | | | connect error, check device address / wiring |
|
||||
| 24LC512 | 65536 | 64 KB | 128 | |
|
||||
| 24LC256 | 32768 | 32 KB | 64 | |
|
||||
| 24LC128 | 16384 | 16 KB | 64 | |
|
||||
| 24LC64 | 8192 | 8 KB | 32 | |
|
||||
| 24LC32 | 4096 | 4 KB | 32 | not tested with hardware |
|
||||
| 24LC16 | 2048 | 2 KB | 16 | |
|
||||
| 24LC08 | 1024 | 1 KB | 16 | |
|
||||
| 24LC04 | 512 | 512 b | 16 | |
|
||||
| 24LC02 | 256 | 256 b | 8 | |
|
||||
| 24LC01 | 128 | 128 b | 8 | |
|
||||
|:--------|:--------|:---------|:---------:|:------|
|
||||
| - | 0 | | | connect error, check device address / wiring |
|
||||
| 24LC512 | 65536 | 64 KB | 128 | |
|
||||
| 24LC256 | 32768 | 32 KB | 64 | |
|
||||
| 24LC128 | 16384 | 16 KB | 64 | |
|
||||
| 24LC64 | 8192 | 8 KB | 32 | |
|
||||
| 24LC32 | 4096 | 4 KB | 32 | not tested with hardware |
|
||||
| 24LC16 | 2048 | 2 KB | 16 | |
|
||||
| 24LC08 | 1024 | 1 KB | 16 | |
|
||||
| 24LC04 | 512 | 512 b | 16 | |
|
||||
| 24LC02 | 256 | 256 b | 8 | |
|
||||
| 24LC01 | 128 | 128 b | 8 | |
|
||||
|
||||
The function cannot detect smaller than 128 bit EEPROMS.
|
||||
|
||||
|
||||
#### UpdateBlock()
|
||||
Experimental since 1.7.1 can be used for debugging and overruling constructor.
|
||||
|
||||
- **uint32_t setDeviceSize(uint32_t deviceSize)** overrules constructor setting.
|
||||
returns set size == 128, 256, ... 32768, 65536
|
||||
- **uint8_t setPageSize(uint8_t pageSize)** overrules constructor setting.
|
||||
returns set size == 8, 16, 32, 64, 128.
|
||||
|
||||
|
||||
### 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.
|
||||
As the function reads/writes the data in blocks with a maximum length of **I2C_TWIBUFFERSIZE**
|
||||
(== 30 AVR limitation; 128 for ESP32)
|
||||
It does this comparison in chunks if the length exceeds the length of the I2C buffer.
|
||||
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()**
|
||||
|
||||
|
||||
### ExtraWriteCycleTime (experimental)
|
||||
|
||||
To improve support older I2C EEPROMs e.g. IS24C16 two functions were
|
||||
added to increase the waiting time before a read and/or write as some
|
||||
older devices have a larger timeout
|
||||
than 5 milliseconds which is the minimum.
|
||||
|
||||
- **void setExtraWriteCycleTime(uint8_t ms)** idem
|
||||
- **uint8_t getExtraWriteCycleTime()** idem
|
||||
|
||||
It is also possible to adjust the **I2C_WRITEDELAY** in the .h file
|
||||
or overrule the define on the command line.
|
||||
|
||||
|
||||
### WriteProtectPin WP (experimental)
|
||||
|
||||
(since 1.7.4)
|
||||
|
||||
The library can control the **WP** = WriteProtect pin of the EEPROM.
|
||||
To do this one should connect a GPIO pin of the MCU to the **WP** pin of the EEPROM.
|
||||
Furthermore the **WP** should be defined as a parameter in **begin()**.
|
||||
If the **WP** pin is defined the default will be to **not** allow writing.
|
||||
The user has to enable writing either by manual or automatic control.
|
||||
|
||||
In the automatic mode the library only allows writing to the EEPROM when it
|
||||
actually writes to the EEPROM.
|
||||
So it keeps the EEPROM in a read only mode as much as possible.
|
||||
This prevents accidental writes due to (noisy) signals on the I2C bus. (#57)
|
||||
|
||||
|
||||
Status
|
||||
- **bool hasWriteProtectPin()** returns true if **WP** has been set.
|
||||
|
||||
Automatic control
|
||||
- **void setAutoWriteProtect(bool b)** if set to true, the library enables writing
|
||||
only when the EEPROM is actually written. This setting **overrules** the manual control.
|
||||
If **setAutoWriteProtect()** is set to false (== default) the manual control is leading.
|
||||
- **bool getAutoWriteProtect()** get current setting.
|
||||
|
||||
Manual control
|
||||
- **void allowWrite()** allows writing by setting **WP** to LOW.
|
||||
- **void preventWrite()** disables writing by setting **WP** to HIGH.
|
||||
|
||||
|
||||
## Limitation
|
||||
|
||||
The library does not offer multiple EEPROMS as one continuous storage device.
|
||||
@@ -89,13 +313,40 @@ The library does not offer multiple EEPROMS as one continuous storage device.
|
||||
|
||||
## Future
|
||||
|
||||
- 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.
|
||||
#### Must
|
||||
|
||||
- improve documentation
|
||||
|
||||
#### Should
|
||||
|
||||
- investigate multi-EEPROM storage ==> wrapper class!
|
||||
- improve error handling
|
||||
- address range check in begin
|
||||
- write functions should return bytes written (like Print() does)
|
||||
now they return I2C status... => error / status.
|
||||
- remove uint8_t getPageSize(uint32_t deviceSize) in 0.2.0. now deprecated.
|
||||
|
||||
#### Could
|
||||
|
||||
- investigate smarter strategy for **updateBlock()**
|
||||
=> find first and last changed position could possibly result in less writes.
|
||||
- can **setBlock()** use strategies from **updateBlock()**
|
||||
- **pageBlock()**: incrBuffer is an implementation name, not a functional name.
|
||||
- replace defines with const uint8_t / const uint16_t to force type checking?
|
||||
- sync order .h file and readme.md.
|
||||
|
||||
#### Wont
|
||||
|
||||
- investigate the print interface?
|
||||
- circular buffer? (see FRAM library)
|
||||
- dump function?
|
||||
|
||||
|
||||
## Operational
|
||||
## Support
|
||||
|
||||
See examples
|
||||
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,
|
||||
|
||||
|
||||
+26
-6
@@ -1,21 +1,38 @@
|
||||
|
||||
[](https://github.com/marketplace/actions/arduino_ci)
|
||||
[](https://github.com/RobTillaart/I2C_EEPROM/actions/workflows/arduino-lint.yml)
|
||||
[](https://github.com/RobTillaart/I2C_EEPROM/actions/workflows/jsoncheck.yml)
|
||||
[](https://github.com/RobTillaart/I2C_EEPROM/issues)
|
||||
|
||||
[](https://github.com/RobTillaart/I2C_EEPROM/blob/master/LICENSE)
|
||||
[](https://github.com/RobTillaart/I2C_EEPROM/releases)
|
||||
[](https://registry.platformio.org/libraries/robtillaart/I2C_EEPROM)
|
||||
|
||||
|
||||
# I2C_eeprom_cyclic_store
|
||||
|
||||
Utility class for storing data using cyclic writes to eeprom memory
|
||||
Utility class for storing data using cyclic writes to eeprom memory.
|
||||
|
||||
|
||||
## Description
|
||||
|
||||
In order to maximize the life expectancy of an eeprom this class implements a method to spread the write operations across as much of the eeprom as possible, rather than writing to the same fixed location.
|
||||
In order to maximize the life expectancy of an eeprom this class implements
|
||||
a method to spread the write operations across as much of the eeprom as possible,
|
||||
rather than writing to the same fixed location.
|
||||
|
||||
This is suitable for a situation where a single data structure (buffer), such as settings, configuration or metric data, is written to the eeprom.
|
||||
This is suitable for a situation where a single data structure (buffer),
|
||||
such as settings, configuration or metric data, is written to the eeprom.
|
||||
|
||||
It operates by partitioning the eeprom into slots large enough to hold the declared buffer (and header) and then writing each new version of the data to the next slot, overwriting any older version already in there. As it reaches the end of the alotted region of the eeprom it wraps around and starts writing from the start of the memory again. When initializing an instance it scans the eeprom to find the last written version and continues from that.
|
||||
It operates by partitioning the eeprom into slots large enough to hold the
|
||||
declared buffer (and header) and then writing each new version of the data
|
||||
to the next slot, overwriting any older version already in there.
|
||||
As it reaches the end of the alotted region of the eeprom it wraps around
|
||||
and starts writing from the start of the memory again.
|
||||
When initializing an instance it scans the eeprom to find the last written
|
||||
version and continues from that.
|
||||
|
||||
In order to use an eeprom that already has data (and if the structure of the buffer changes) the eeprom has to be prepared by formatting the indexes.
|
||||
In order to use an eeprom that already has data (and if the structure of the
|
||||
buffer changes) the eeprom has to be prepared by formatting the indexes.
|
||||
|
||||
The interface is pretty straightforward
|
||||
|
||||
@@ -25,9 +42,12 @@ The interface is pretty straightforward
|
||||
- **write(buffer)** write buffer to next location on eeprom
|
||||
- **getMetrics(slots, writeCounter)** get usage metrics
|
||||
|
||||
|
||||
## Limitation
|
||||
|
||||
The class does not handle changes in buffer size or structure, nor does it detect an eeprom that has data that wasn't written using the class.
|
||||
The class does not handle changes in buffer size or structure, nor does
|
||||
it detect an eeprom that has data that wasn't written using the class.
|
||||
|
||||
|
||||
## Operational
|
||||
|
||||
|
||||
@@ -3,30 +3,41 @@
|
||||
// AUTHOR: Tomas Hübner
|
||||
// VERSION: 1.0.0
|
||||
// PURPOSE: Simple example of how to use cyclic storage.
|
||||
//
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM
|
||||
|
||||
|
||||
#include <I2C_eeprom.h>
|
||||
#include <I2C_eeprom_cyclic_store.h>
|
||||
|
||||
#define MEMORY_SIZE 0x2000 // Total capacity of the EEPROM
|
||||
#define PAGE_SIZE 64 // Size of write page of device, use datasheet to find!
|
||||
#define MEMORY_SIZE 8192 // Total capacity of the EEPROM (8K == 8192 == 0x2000)
|
||||
#define PAGE_SIZE 64 // Size of write page of device, use datasheet to find!
|
||||
|
||||
|
||||
struct SampleData {
|
||||
public:
|
||||
uint32_t counter;
|
||||
// Must use fixed length string, avoid using the String class.
|
||||
// Must use fixed length string, avoid using the String class.
|
||||
char message[32];
|
||||
};
|
||||
|
||||
|
||||
SampleData data;
|
||||
|
||||
I2C_eeprom ee(0x50, MEMORY_SIZE);
|
||||
I2C_eeprom_cyclic_store<SampleData> cs;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while(!Serial);
|
||||
while (!Serial); // wait for Serial port to connect. Needed for Leonardo only
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("I2C_EEPROM_VERSION: ");
|
||||
Serial.println(I2C_EEPROM_VERSION);
|
||||
Serial.println();
|
||||
|
||||
Wire.begin();
|
||||
|
||||
ee.begin();
|
||||
|
||||
@@ -39,9 +50,9 @@ void setup()
|
||||
sprintf(data.message, "Initialized to %x", data.counter);
|
||||
cs.write(data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.println(data.message);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// FILE: I2C_eeprom_determineSize.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: test determinSize() function
|
||||
//
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM
|
||||
|
||||
|
||||
#include "Wire.h"
|
||||
@@ -17,9 +17,14 @@ uint32_t start, diff;
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); // wait for Serial port to connect. Needed for Leonardo only
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("I2C_EEPROM_VERSION: ");
|
||||
Serial.println(I2C_EEPROM_VERSION);
|
||||
Serial.println();
|
||||
|
||||
Wire.begin();
|
||||
|
||||
ee.begin();
|
||||
if (! ee.isConnected())
|
||||
@@ -32,7 +37,7 @@ void setup()
|
||||
delay(10);
|
||||
|
||||
start = micros();
|
||||
uint32_t size = ee.determineSize(false); // debug param
|
||||
uint32_t size = ee.determineSize(false); // debug parameter
|
||||
diff = micros() - start;
|
||||
Serial.print("TIME: ");
|
||||
Serial.print(diff);
|
||||
@@ -55,7 +60,7 @@ void setup()
|
||||
}
|
||||
|
||||
Serial.print("PAGE: ");
|
||||
uint8_t pageSize = ee.getPageSize(size);
|
||||
uint8_t pageSize = ee.calculatePageSize(size);
|
||||
Serial.print(pageSize);
|
||||
Serial.println(" bytes.");
|
||||
|
||||
@@ -67,4 +72,6 @@ void loop()
|
||||
{
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// FILE: I2C_eeprom_determineSizeNoWrite.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: test determineSizeNoWrite() function
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM
|
||||
|
||||
|
||||
#include "Wire.h"
|
||||
#include "I2C_eeprom.h"
|
||||
|
||||
|
||||
I2C_eeprom ee(0x50, I2C_DEVICESIZE_24LC256);
|
||||
|
||||
uint32_t start, diff;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); // wait for Serial port to connect. Needed for Leonardo only
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("I2C_EEPROM_VERSION: ");
|
||||
Serial.println(I2C_EEPROM_VERSION);
|
||||
Serial.println();
|
||||
|
||||
Wire.begin();
|
||||
|
||||
ee.begin();
|
||||
if (! ee.isConnected())
|
||||
{
|
||||
Serial.println("ERROR: Can't find eeprom\nstopped...");
|
||||
while (1);
|
||||
}
|
||||
|
||||
Serial.println("\nDetermine size no write");
|
||||
delay(100);
|
||||
|
||||
start = micros();
|
||||
uint32_t size = ee.determineSizeNoWrite();
|
||||
diff = micros() - start;
|
||||
Serial.print("TIME: ");
|
||||
Serial.print(diff);
|
||||
Serial.println(" us.");
|
||||
if (size == 0)
|
||||
{
|
||||
Serial.println("SIZE: could not determine size");
|
||||
}
|
||||
else if (size == 1)
|
||||
{
|
||||
Serial.println("SIZE: device has default data in first bytes, write some data and retry or use the determineSize method");
|
||||
}
|
||||
else if (size == 2)
|
||||
{
|
||||
Serial.println("SIZE: device has all the same data in first bytes, write some data and retry");
|
||||
}
|
||||
else if (size > 1024)
|
||||
{
|
||||
Serial.print("SIZE: ");
|
||||
Serial.print(size / 1024);
|
||||
Serial.println(" KB.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print("SIZE: ");
|
||||
Serial.print(size);
|
||||
Serial.println(" bytes.");
|
||||
}
|
||||
|
||||
Serial.print("PAGE: ");
|
||||
uint8_t pageSize = ee.calculatePageSize(size);
|
||||
Serial.print(pageSize);
|
||||
Serial.println(" bytes.");
|
||||
|
||||
Serial.println("Done...");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
@@ -2,7 +2,7 @@
|
||||
// FILE: I2C_eeprom_format.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo format EEPROM
|
||||
//
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM
|
||||
|
||||
|
||||
#include "Wire.h"
|
||||
@@ -17,9 +17,14 @@ uint32_t start, diff;
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); // wait for Serial port to connect. Needed for Leonardo only
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("I2C_EEPROM_VERSION: ");
|
||||
Serial.println(I2C_EEPROM_VERSION);
|
||||
Serial.println();
|
||||
|
||||
Wire.begin();
|
||||
|
||||
ee.begin();
|
||||
if (! ee.isConnected())
|
||||
@@ -30,7 +35,7 @@ void setup()
|
||||
|
||||
|
||||
Serial.println();
|
||||
uint32_t size = ee.determineSize(false); // debug param
|
||||
uint32_t size = ee.determineSize(false); // debug parameter
|
||||
if (size == 0)
|
||||
{
|
||||
Serial.println("SIZE: could not determine size");
|
||||
@@ -59,10 +64,10 @@ void setup()
|
||||
if ( ans == 'Y')
|
||||
{
|
||||
start = millis();
|
||||
for (uint32_t i = 0; i < size; i += 128)
|
||||
for (uint32_t address = 0; address < size; address += 128)
|
||||
{
|
||||
if (i % 1024 == 0) Serial.print('.');
|
||||
ee.setBlock(0, 0xFF, 128);
|
||||
if (address % 1024 == 0) Serial.print('.');
|
||||
ee.setBlock(address, 0xFF, 128);
|
||||
}
|
||||
diff = millis() - start;
|
||||
Serial.print("\nTIME: ");
|
||||
@@ -82,4 +87,5 @@ void loop()
|
||||
{
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// FILE: I2C_eeprom_struct.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo I2C_EEPROM library store /retrieve struct
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM
|
||||
//
|
||||
// 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, duration;
|
||||
|
||||
struct
|
||||
{
|
||||
float temperature;
|
||||
float humidity;
|
||||
float pressure;
|
||||
} measurement;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); // wait for Serial port to connect. Needed for Leonardo only
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("I2C_EEPROM_VERSION: ");
|
||||
Serial.println(I2C_EEPROM_VERSION);
|
||||
Serial.println();
|
||||
|
||||
Wire.begin();
|
||||
|
||||
ee.begin();
|
||||
if (! ee.isConnected())
|
||||
{
|
||||
Serial.println("ERROR: Can't find eeprom (stopped)...");
|
||||
// while (1);
|
||||
}
|
||||
|
||||
Serial.print("size: \t");
|
||||
Serial.println(sizeof(measurement));
|
||||
|
||||
// clear EEPROM part
|
||||
ee.setBlock(0, 0, sizeof(measurement));
|
||||
|
||||
// make measurement here
|
||||
measurement.temperature = 22.5;
|
||||
measurement.humidity = 53.1;
|
||||
measurement.pressure = 1000.9;
|
||||
|
||||
// store it in EEPROM
|
||||
start = micros();
|
||||
ee.writeBlock(0, (uint8_t *) &measurement, sizeof(measurement));
|
||||
duration = micros() - start;
|
||||
Serial.print("write: \t");
|
||||
Serial.println(duration);
|
||||
delay(10);
|
||||
|
||||
// clear measurement struct
|
||||
measurement.temperature = 0;
|
||||
measurement.humidity = 0;
|
||||
measurement.pressure = 0;
|
||||
|
||||
// retrieve old measurement
|
||||
start = micros();
|
||||
ee.readBlock(0, (uint8_t *) &measurement, sizeof(measurement));
|
||||
duration = micros() - start;
|
||||
Serial.print("read: \t");
|
||||
Serial.println(duration);
|
||||
delay(10);
|
||||
|
||||
Serial.print("temp:\t");
|
||||
Serial.println(measurement.temperature);
|
||||
Serial.print("hum:\t");
|
||||
Serial.println(measurement.humidity);
|
||||
Serial.print("pres:\t");
|
||||
Serial.println(measurement.pressure);
|
||||
|
||||
Serial.println("\ndone...");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
// FILE: I2C_eeprom_test.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: show/test I2C_EEPROM library
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM
|
||||
//
|
||||
// uses a 24LC256 (32KB) EEPROM
|
||||
// might need adaptions for other EEPROMS (page size etc)
|
||||
|
||||
// uses a 24LC256 (32KB) EEPROM
|
||||
// might need adaptions for other EEPROMS (page size etc)
|
||||
|
||||
#include "Wire.h"
|
||||
#include "I2C_eeprom.h"
|
||||
|
||||
|
||||
// UNO
|
||||
// UNO
|
||||
#define SERIAL_OUT Serial
|
||||
// Due
|
||||
// Due
|
||||
// #define SERIAL_OUT SerialUSB
|
||||
|
||||
|
||||
@@ -25,8 +26,14 @@ uint32_t start, diff, totals = 0;
|
||||
void setup()
|
||||
{
|
||||
SERIAL_OUT.begin(115200);
|
||||
while (!SERIAL_OUT); // wait for SERIAL_OUT port to connect. Needed for Leonardo only
|
||||
while (!SERIAL_OUT); // wait for SERIAL_OUT port to connect. Needed for Leonardo only
|
||||
SERIAL_OUT.println();
|
||||
SERIAL_OUT.println(__FILE__);
|
||||
SERIAL_OUT.print("I2C_EEPROM_VERSION: ");
|
||||
SERIAL_OUT.println(I2C_EEPROM_VERSION);
|
||||
SERIAL_OUT.println();
|
||||
|
||||
Wire.begin();
|
||||
|
||||
ee.begin();
|
||||
if (! ee.isConnected())
|
||||
@@ -34,14 +41,12 @@ void setup()
|
||||
SERIAL_OUT.println("ERROR: Can't find eeprom\nstopped...");
|
||||
while (1);
|
||||
}
|
||||
|
||||
SERIAL_OUT.print("I2C eeprom library: ");
|
||||
SERIAL_OUT.print(I2C_EEPROM_VERSION);
|
||||
SERIAL_OUT.println("\n");
|
||||
SERIAL_OUT.print("isConnected:\t");
|
||||
SERIAL_OUT.println(ee.isConnected());
|
||||
|
||||
SERIAL_OUT.println("\nTEST: determine size");
|
||||
start = micros();
|
||||
uint32_t size = ee.determineSize();
|
||||
uint32_t size = ee.determineSize(true);
|
||||
diff = micros() - start;
|
||||
SERIAL_OUT.print("TIME: ");
|
||||
SERIAL_OUT.println(diff);
|
||||
@@ -63,7 +68,9 @@ void setup()
|
||||
SERIAL_OUT.println("\nTEST: 64 byte page boundary writeBlock");
|
||||
ee.setBlock(0, 0, 128);
|
||||
dumpEEPROM(0, 128);
|
||||
char data[] = "11111111111111111111";
|
||||
Serial.println("---");
|
||||
// char data[] = "11111111111111111111";
|
||||
char data[] = "33333333333333333333";
|
||||
ee.writeBlock(60, (uint8_t*) data, 10);
|
||||
dumpEEPROM(0, 128);
|
||||
|
||||
@@ -149,7 +156,7 @@ void setup()
|
||||
SERIAL_OUT.println(totals);
|
||||
totals = 0;
|
||||
|
||||
// same tests but now with a 5 millisec delay in between.
|
||||
// same tests but now with a 5 millisec delay in between.
|
||||
delay(5);
|
||||
|
||||
SERIAL_OUT.print("\nTEST: timing writeByte()\t");
|
||||
@@ -194,7 +201,7 @@ void setup()
|
||||
SERIAL_OUT.println(totals);
|
||||
totals = 0;
|
||||
|
||||
// does it go well?
|
||||
// did it go well?
|
||||
SERIAL_OUT.println(xx);
|
||||
|
||||
SERIAL_OUT.println("\tDone...");
|
||||
@@ -209,7 +216,7 @@ void loop()
|
||||
void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
|
||||
{
|
||||
const int BLOCK_TO_LENGTH = 10;
|
||||
|
||||
|
||||
SERIAL_OUT.print("\t ");
|
||||
for (int x = 0; x < 10; x++)
|
||||
{
|
||||
@@ -218,7 +225,7 @@ void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
|
||||
}
|
||||
SERIAL_OUT.println();
|
||||
|
||||
// block to defined length
|
||||
// block to defined length
|
||||
memoryAddress = memoryAddress / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH;
|
||||
length = (length + BLOCK_TO_LENGTH - 1) / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH;
|
||||
|
||||
@@ -241,4 +248,6 @@ void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
|
||||
SERIAL_OUT.println();
|
||||
}
|
||||
|
||||
// END OF FILE
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
|
||||
Try this (not tested)
|
||||
[code]
|
||||
//#include <UTFT.h>
|
||||
#include <SD.h>
|
||||
#include <Wire.h>
|
||||
#include <ArduCAM.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#define SD_CS 9
|
||||
|
||||
|
||||
//UTFT(byte model, int RS, int WR, int RD, int CS)
|
||||
//UTFT myGLCD(ITDB32S,A2,A1,A0,10); // Remember to change the model parameter to suit your display module!
|
||||
//ArduCAM(byte model,int RS, int WR, int RD, int REG_CS, int FIFO_CS)
|
||||
ArduCAM myCAM(OV2640,A2,A1,A0,A3,10); // Remember to change the model parameter to suit your canera module!
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200); // <<<<<<<<<<<<<<<<<<<<<<<
|
||||
Serial.println("Start arducam test");
|
||||
|
||||
//Initialize I2C Bus
|
||||
Wire.begin();
|
||||
//Switch to FIFO Mode
|
||||
myCAM.write_reg(ARDUCHIP_TIM, MODE_MASK);
|
||||
//Set sensor to JPEG mode. Note don't all the camera modules support JPEG mode
|
||||
myCAM.OV2640_set_format(JPEG);
|
||||
//Initialize Camera Module
|
||||
myCAM.InitCAM();
|
||||
myCAM.OV2640_set_JPEG_size(OV2640_320x240);
|
||||
|
||||
Serial.println("SD.begin");
|
||||
//Initialize SD Card
|
||||
if (!SD.begin(SD_CS))
|
||||
{
|
||||
Serial.println("SD card failed");
|
||||
//while (1); //If failed, stop here
|
||||
}
|
||||
Serial.println("SD card success");
|
||||
Serial.println("End setup");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.print(millis());
|
||||
Serial.println("\tstart loop");
|
||||
|
||||
char str[8];
|
||||
File outFile;
|
||||
static int k = 0;
|
||||
uint8_t temp,temp_last;
|
||||
uint8_t start_capture = 0;
|
||||
|
||||
Serial.print(millis());
|
||||
Serial.println("\tWait trigger from shutter buttom");
|
||||
|
||||
//Wait trigger from shutter buttom
|
||||
if(myCAM.read_reg(ARDUCHIP_TRIG) & SHUTTER_MASK)
|
||||
{
|
||||
//Wait until buttom released
|
||||
while(myCAM.read_reg(ARDUCHIP_TRIG) & SHUTTER_MASK);
|
||||
start_capture = 1;
|
||||
}
|
||||
|
||||
|
||||
Serial.print(millis());
|
||||
Serial.println("\tStart capture I");
|
||||
//Start capture when detect a valid shutter press
|
||||
if(start_capture)
|
||||
{
|
||||
//Flush the FIFO
|
||||
myCAM.flush_fifo();
|
||||
//Start capture
|
||||
myCAM.start_capture();
|
||||
}
|
||||
|
||||
if(myCAM.read_reg(ARDUCHIP_TRIG) & CAP_DONE_MASK)
|
||||
{
|
||||
//Construct a file name
|
||||
k = k + 1;
|
||||
itoa(k, str, 10);
|
||||
strcat(str,".jpg");
|
||||
//Open the new file
|
||||
outFile = SD.open(str,FILE_WRITE);
|
||||
if (! outFile)
|
||||
{
|
||||
Serial.print(millis());
|
||||
Serial.println("\tfailure outfile");
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print(millis());
|
||||
Serial.println("\toutfile succes");
|
||||
|
||||
//Enable FIFO
|
||||
myCAM.enable_fifo();
|
||||
|
||||
uint32_t bytecounter = 0;
|
||||
//Read the first dummy byte from FIFO
|
||||
temp = myCAM.read_fifo();
|
||||
|
||||
//Read JPEG data from FIFO
|
||||
while( (temp != 0xD9) | (temp_last != 0xFF) )
|
||||
{
|
||||
bytecounter++;
|
||||
if (bytecounter % 32 == 0) Serial.print('.');
|
||||
if (bytecounter % 1024 == 0) Serial.println;
|
||||
temp_last = temp;
|
||||
temp = myCAM.read_fifo();
|
||||
//Write image data to file
|
||||
outFile.write(temp);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
//Disable FIFO when all the image data is saved to the file
|
||||
myCAM.disable_fifo();
|
||||
//Close the file
|
||||
outFile.close();
|
||||
|
||||
//Clear the capture done flag
|
||||
myCAM.clear_fifo_flag();
|
||||
//Clear the start capture flag
|
||||
start_capture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
[/code]
|
||||
@@ -2,7 +2,7 @@
|
||||
// FILE: I2C_eeprom_test_performance.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: test I2C_EEPROM library
|
||||
//
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM
|
||||
|
||||
|
||||
#include "Wire.h"
|
||||
@@ -17,10 +17,14 @@ uint32_t start, diff, totals = 0;
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); // wait for Serial port to connect. Needed for Leonardo only
|
||||
while (!Serial); // wait for Serial port to connect. Needed for Leonardo only
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("VERSION: ");
|
||||
Serial.print("I2C_EEPROM_VERSION: ");
|
||||
Serial.println(I2C_EEPROM_VERSION);
|
||||
Serial.println();
|
||||
|
||||
Wire.begin();
|
||||
|
||||
ee.begin();
|
||||
if (! ee.isConnected())
|
||||
@@ -39,6 +43,7 @@ void setup()
|
||||
Serial.println(speed);
|
||||
delay(10);
|
||||
test();
|
||||
dumpEEPROM(0, 100);
|
||||
}
|
||||
Serial.println("\ndone...");
|
||||
}
|
||||
@@ -53,8 +58,8 @@ void loop()
|
||||
|
||||
void test()
|
||||
{
|
||||
char data2[] = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999A";
|
||||
|
||||
char data2[] = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999A";
|
||||
|
||||
totals = 0;
|
||||
Serial.print("\nTEST: timing writeByte()\t");
|
||||
uint32_t start = micros();
|
||||
@@ -92,7 +97,7 @@ void test()
|
||||
Serial.println(totals);
|
||||
totals = 0;
|
||||
|
||||
// same tests but now with a 5 millisec delay in between.
|
||||
// same tests but now with a 5 milliseconds delay in between.
|
||||
delay(5);
|
||||
|
||||
Serial.print("\nTEST: timing writeByte()\t");
|
||||
@@ -137,7 +142,7 @@ void test()
|
||||
Serial.println(totals);
|
||||
totals = 0;
|
||||
|
||||
// does it go well?
|
||||
// did it go well?
|
||||
Serial.println(xx);
|
||||
}
|
||||
|
||||
@@ -145,7 +150,7 @@ void test()
|
||||
void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
|
||||
{
|
||||
const int BLOCK_TO_LENGTH = 10;
|
||||
|
||||
|
||||
Serial.print("\t ");
|
||||
for (int x = 0; x < 10; x++)
|
||||
{
|
||||
@@ -154,7 +159,7 @@ void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
// block to defined length
|
||||
// block to defined length
|
||||
memoryAddress = memoryAddress / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH;
|
||||
length = (length + BLOCK_TO_LENGTH - 1) / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH;
|
||||
|
||||
@@ -177,4 +182,6 @@ void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
// END OF FILE
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
// FILE: I2C_eeprom_update.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo I2C_EEPROM library - updateByte
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM
|
||||
//
|
||||
// uses a 24LC256 (32KB) EEPROM
|
||||
|
||||
// uses a 24LC256 (32KB) EEPROM
|
||||
|
||||
#include "Wire.h"
|
||||
#include "I2C_eeprom.h"
|
||||
@@ -15,14 +16,17 @@ I2C_eeprom ee(0x50, I2C_DEVICESIZE_24LC256);
|
||||
uint32_t start, dur1, dur2;
|
||||
|
||||
|
||||
void setup()
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); // wait for SERIAL_OUT port to connect. Needed for Leonardo only
|
||||
|
||||
Serial.begin(115200);
|
||||
while (!Serial); // wait for Serial port to connect. Needed for Leonardo only
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("VERSION: ");
|
||||
Serial.print("I2C_EEPROM_VERSION: ");
|
||||
Serial.println(I2C_EEPROM_VERSION);
|
||||
Serial.println();
|
||||
|
||||
Wire.begin();
|
||||
|
||||
ee.begin();
|
||||
if (! ee.isConnected())
|
||||
@@ -38,7 +42,7 @@ void setup()
|
||||
Serial.print("SIZE: ");
|
||||
Serial.print(size);
|
||||
Serial.println(" KB");
|
||||
}
|
||||
}
|
||||
else if (size == 0)
|
||||
{
|
||||
Serial.println("WARNING: Can't determine eeprom size");
|
||||
@@ -51,7 +55,7 @@ void setup()
|
||||
|
||||
Serial.println("\nTEST: 100x writebyte()");
|
||||
delay(10);
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
start = micros();
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
@@ -61,9 +65,9 @@ void setup()
|
||||
Serial.print("DUR1: ");
|
||||
Serial.println(dur1);
|
||||
delay(10);
|
||||
|
||||
|
||||
Serial.println("\nTEST: 100x updateByte()");
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
start = micros();
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
@@ -73,12 +77,15 @@ void setup()
|
||||
Serial.print("DUR2: ");
|
||||
Serial.println(dur2);
|
||||
delay(10);
|
||||
|
||||
|
||||
Serial.println("done...");
|
||||
}
|
||||
|
||||
void loop()
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
// -- END OF FILE
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// FILE: I2C_eeprom_updateBlock.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo I2C_EEPROM library - performance gain updateBlock
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM
|
||||
//
|
||||
|
||||
// uses a 24LC256 (32KB) EEPROM
|
||||
// as this test writes a lot it might wear out EEPROMs eventually.
|
||||
//
|
||||
|
||||
|
||||
#include "Wire.h"
|
||||
#include "I2C_eeprom.h"
|
||||
@@ -18,16 +18,19 @@ 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
|
||||
|
||||
while (!Serial); // wait for Serial port to connect. Needed for Leonardo only
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("VERSION: ");
|
||||
Serial.print("I2C_EEPROM_VERSION: ");
|
||||
Serial.println(I2C_EEPROM_VERSION);
|
||||
Serial.println();
|
||||
|
||||
Wire.begin();
|
||||
|
||||
ee.begin();
|
||||
if (! ee.isConnected())
|
||||
{
|
||||
@@ -47,16 +50,18 @@ void setup()
|
||||
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
|
||||
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;
|
||||
@@ -75,7 +80,7 @@ void test_1(int n)
|
||||
|
||||
Serial.print("TEST:\tupdateBlock()");
|
||||
delay(10);
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
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;
|
||||
@@ -85,11 +90,12 @@ void test_1(int n)
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void test_2()
|
||||
{
|
||||
Serial.println("\nTEST: 100x writeBlock()");
|
||||
delay(10);
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
start = micros();
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
@@ -103,7 +109,7 @@ void test_2()
|
||||
|
||||
|
||||
Serial.println("\nTEST: 100x updateBlock()");
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
start = micros();
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
@@ -119,14 +125,18 @@ void test_2()
|
||||
|
||||
void dump(uint32_t from, uint32_t to)
|
||||
{
|
||||
for (uint32_t i = from; i < to; i++) // I2C_DEVICESIZE_24LC512
|
||||
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);
|
||||
#if defined (ESP8266) || defined(ESP32)
|
||||
sprintf(buffer, "%08X\t", i); // ESP cast (long unsigned int)
|
||||
#else
|
||||
sprintf(buffer, "%08lX\t", i); // AVR needs lX
|
||||
#endif;
|
||||
Serial.print(buffer);
|
||||
}
|
||||
sprintf(buffer, "%02X\t", ee.readByte(i));
|
||||
@@ -136,4 +146,5 @@ void dump(uint32_t from, uint32_t to)
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE
|
||||
// -- END OF FILE --
|
||||
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
//
|
||||
// FILE: I2C_eeprom_verify.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo I2C_EEPROM library - updateByte
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM
|
||||
//
|
||||
// uses a 24LC256 (32KB) EEPROM
|
||||
|
||||
|
||||
#include "Wire.h"
|
||||
#include "I2C_eeprom.h"
|
||||
|
||||
#define NN 100
|
||||
|
||||
I2C_eeprom ee(0x50, I2C_DEVICESIZE_24LC256);
|
||||
|
||||
uint32_t start, dur1, dur2;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); // wait for Serial port to connect. Needed for Leonardo only
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("I2C_EEPROM_VERSION: ");
|
||||
Serial.println(I2C_EEPROM_VERSION);
|
||||
Serial.println();
|
||||
|
||||
Wire.begin();
|
||||
|
||||
ee.begin();
|
||||
if (! ee.isConnected())
|
||||
{
|
||||
Serial.println("ERROR: Can't find eeprom\nstopped...");
|
||||
while (1);
|
||||
}
|
||||
|
||||
Serial.print("\nTestruns NN: ");
|
||||
Serial.print(NN);
|
||||
Serial.println("\n");
|
||||
Serial.println("\nTEST: NN x writeByte()");
|
||||
delay(10);
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
start = micros();
|
||||
for (int i = 0; i < NN; i++)
|
||||
{
|
||||
ee.writeByte(i, 0);
|
||||
}
|
||||
dur1 = micros() - start;
|
||||
Serial.print("DUR1: ");
|
||||
Serial.println(dur1);
|
||||
delay(10);
|
||||
|
||||
Serial.println("\nTEST: NN x writeByteVerify()");
|
||||
delay(10);
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
start = micros();
|
||||
for (int i = 0; i < NN; i++)
|
||||
{
|
||||
if (ee.writeByteVerify(i, 0) == false)
|
||||
{
|
||||
Serial.print("X");
|
||||
}
|
||||
}
|
||||
dur1 = micros() - start;
|
||||
Serial.print("DUR1: ");
|
||||
Serial.println(dur1);
|
||||
delay(10);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
Serial.println("\nTEST: NN x updateByte() same data");
|
||||
delay(10);
|
||||
start = micros();
|
||||
for (int i = 0; i < NN; i++)
|
||||
{
|
||||
ee.updateByte(i, 0);
|
||||
}
|
||||
dur2 = micros() - start;
|
||||
Serial.print("DUR2: ");
|
||||
Serial.println(dur2);
|
||||
delay(10);
|
||||
|
||||
Serial.println("\nTEST: NN x updateByteVerify() same data");
|
||||
delay(10);
|
||||
start = micros();
|
||||
for (int i = 0; i < NN; i++)
|
||||
{
|
||||
if (ee.updateByteVerify(i, 0) == false)
|
||||
{
|
||||
Serial.print("X");
|
||||
}
|
||||
}
|
||||
dur2 = micros() - start;
|
||||
Serial.print("DUR2: ");
|
||||
Serial.println(dur2);
|
||||
delay(10);
|
||||
|
||||
Serial.println("\nTEST: NN x updateByteVerify() not same data");
|
||||
delay(10);
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
start = micros();
|
||||
for (int i = 0; i < NN; i++)
|
||||
{
|
||||
if (ee.updateByteVerify(i, i) == false)
|
||||
{
|
||||
Serial.print("X");
|
||||
}
|
||||
}
|
||||
dur2 = micros() - start;
|
||||
Serial.print("DUR2: ");
|
||||
Serial.println(dur2);
|
||||
delay(10);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
char buffer[] = "12345678901234567890123456789012345678901234567890"; // 50 bytes
|
||||
Serial.println("\nTEST: NN x writeBlock()");
|
||||
delay(10);
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
start = micros();
|
||||
for (int i = 0; i < NN; i++)
|
||||
{
|
||||
ee.writeBlock(0, (uint8_t *) buffer, 50);
|
||||
}
|
||||
dur1 = micros() - start;
|
||||
Serial.print("DUR1: ");
|
||||
Serial.println(dur1);
|
||||
delay(10);
|
||||
|
||||
|
||||
Serial.println("\nTEST: NN x writeBlockVerify()");
|
||||
delay(10);
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
start = micros();
|
||||
for (int i = 0; i < NN; i++)
|
||||
{
|
||||
if (ee.writeBlockVerify(0, (uint8_t *) buffer, 50) == false)
|
||||
{
|
||||
Serial.print("X");
|
||||
}
|
||||
}
|
||||
dur1 = micros() - start;
|
||||
Serial.print("DUR1: ");
|
||||
Serial.println(dur1);
|
||||
delay(10);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
Serial.println("\nTEST: NN x updateBlock() same data");
|
||||
delay(10);
|
||||
start = micros();
|
||||
for (int i = 0; i < NN; i++)
|
||||
{
|
||||
ee.updateBlock(0, (uint8_t *) buffer, 50);
|
||||
}
|
||||
dur2 = micros() - start;
|
||||
Serial.print("DUR2: ");
|
||||
Serial.println(dur2);
|
||||
delay(10);
|
||||
|
||||
|
||||
Serial.println("\nTEST: NN x updateBlockVerify() same data");
|
||||
delay(10);
|
||||
start = micros();
|
||||
for (int i = 0; i < NN; i++)
|
||||
{
|
||||
if (ee.updateBlockVerify(0, (uint8_t *) buffer, 50) == false)
|
||||
{
|
||||
Serial.print("X");
|
||||
}
|
||||
}
|
||||
dur2 = micros() - start;
|
||||
Serial.print("DUR2: ");
|
||||
Serial.println(dur2);
|
||||
delay(10);
|
||||
|
||||
strcpy(buffer, "98765432109876543210987654321098765432109876543210"); // 50 bytes
|
||||
Serial.println("\nTEST: NN x updateBlockVerify() not same data");
|
||||
delay(10);
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
start = micros();
|
||||
for (int i = 0; i < NN; i++)
|
||||
{
|
||||
if (ee.updateBlockVerify(0, (uint8_t *) buffer, 50) == false)
|
||||
{
|
||||
Serial.print("X");
|
||||
}
|
||||
}
|
||||
dur2 = micros() - start;
|
||||
Serial.print("DUR2: ");
|
||||
Serial.println(dur2);
|
||||
delay(10);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
Serial.println("\nTEST: NN x setBlock() same data");
|
||||
delay(10);
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
start = micros();
|
||||
for (int i = 0; i < NN; i++)
|
||||
{
|
||||
ee.setBlock(0, 0, 50);
|
||||
}
|
||||
dur2 = micros() - start;
|
||||
Serial.print("DUR2: ");
|
||||
Serial.println(dur2);
|
||||
delay(10);
|
||||
|
||||
Serial.println("\nTEST: NN x setBlockVerify() same data");
|
||||
delay(10);
|
||||
ee.setBlock(0, 0, 100); // clear first 100 bytes
|
||||
start = micros();
|
||||
for (int i = 0; i < NN; i++)
|
||||
{
|
||||
if (ee.setBlockVerify(0, 0, 50) == false)
|
||||
{
|
||||
Serial.print("X");
|
||||
}
|
||||
}
|
||||
dur2 = micros() - start;
|
||||
Serial.print("DUR2: ");
|
||||
Serial.println(dur2);
|
||||
delay(10);
|
||||
|
||||
Serial.println("\nTEST: NN x setBlockVerify() not same data");
|
||||
delay(10);
|
||||
start = micros();
|
||||
for (int i = 0; i < NN; i++)
|
||||
{
|
||||
if (ee.setBlockVerify(0, 1, 50) == false)
|
||||
{
|
||||
Serial.print("X");
|
||||
}
|
||||
}
|
||||
dur2 = micros() - start;
|
||||
Serial.print("DUR2: ");
|
||||
Serial.println(dur2);
|
||||
delay(10);
|
||||
|
||||
Serial.println("done...");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
@@ -0,0 +1,43 @@
|
||||
I2C_eeprom_verify\I2C_eeprom_verify.ino
|
||||
VERSION: 1.6.1
|
||||
|
||||
TEST: 100x writeByte()
|
||||
DUR1: 367668
|
||||
|
||||
TEST: 100x writeByteVerify()
|
||||
DUR1: 442276
|
||||
|
||||
TEST: 100x updateByte() same data
|
||||
DUR2: 58472
|
||||
|
||||
TEST: 100x updateByteVerify() same data
|
||||
DUR2: 116464
|
||||
|
||||
TEST: 100x updateByteVerify() not same data
|
||||
DUR2: 510476
|
||||
|
||||
TEST: 100x writeBlock()
|
||||
DUR1: 1216296
|
||||
|
||||
TEST: 100x writeBlockVerify()
|
||||
DUR1: 1814332
|
||||
|
||||
TEST: 100x updateBlock() same data
|
||||
DUR2: 595220
|
||||
|
||||
TEST: 100x updateBlockVerify() same data
|
||||
DUR2: 1190428
|
||||
|
||||
TEST: 100x updateBlockVerify() not same data
|
||||
DUR2: 1205792
|
||||
|
||||
TEST: 100x setBlock() same data
|
||||
DUR2: 1217796
|
||||
|
||||
TEST: 100x setBlockVerify() same data
|
||||
DUR2: 1815424
|
||||
|
||||
TEST: 100x setBlockVerify() not same data
|
||||
DUR2: 1812136
|
||||
done...
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
I2C_EEPROM_VERSION: 1.8.2
|
||||
|
||||
Testruns NN: 100
|
||||
|
||||
|
||||
TEST: NN x writeByte()
|
||||
DUR1: 466516
|
||||
|
||||
TEST: NN x writeByteVerify()
|
||||
DUR1: 542336
|
||||
|
||||
TEST: NN x updateByte() same data
|
||||
DUR2: 58616
|
||||
|
||||
TEST: NN x updateByteVerify() same data
|
||||
DUR2: 116896
|
||||
|
||||
TEST: NN x updateByteVerify() not same data
|
||||
DUR2: 596672
|
||||
|
||||
TEST: NN x writeBlock()
|
||||
DUR1: 1414432
|
||||
|
||||
TEST: NN x writeBlockVerify()
|
||||
DUR1: 2010844
|
||||
|
||||
TEST: NN x updateBlock() same data
|
||||
DUR2: 594796
|
||||
|
||||
TEST: NN x updateBlockVerify() same data
|
||||
DUR2: 1186644
|
||||
|
||||
TEST: NN x updateBlockVerify() not same data
|
||||
DUR2: 1204960
|
||||
|
||||
TEST: NN x setBlock() same data
|
||||
DUR2: 1415932
|
||||
|
||||
TEST: NN x setBlockVerify() same data
|
||||
DUR2: 2014048
|
||||
|
||||
TEST: NN x setBlockVerify() not same data
|
||||
DUR2: 2009780
|
||||
done...
|
||||
@@ -0,0 +1,101 @@
|
||||
//
|
||||
// FILE: I2C_eeprom_verifyBlock.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo I2C_EEPROM library
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM
|
||||
//
|
||||
// uses a 24LC256 (32KB) EEPROM
|
||||
|
||||
|
||||
#include "Wire.h"
|
||||
#include "I2C_eeprom.h"
|
||||
|
||||
I2C_eeprom ee(0x50, I2C_DEVICESIZE_24LC256);
|
||||
|
||||
uint32_t start, dur1;
|
||||
|
||||
char buffer[] = "12345678901234567890123456789012345678901234567890"; // 50 bytes
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); // wait for Serial port to connect. Needed for Leonardo only
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("I2C_EEPROM_VERSION: ");
|
||||
Serial.println(I2C_EEPROM_VERSION);
|
||||
Serial.println();
|
||||
|
||||
Wire.begin();
|
||||
|
||||
ee.begin();
|
||||
if (! ee.isConnected())
|
||||
{
|
||||
Serial.println("ERROR: Can't find eeprom\nstopped...");
|
||||
while (1);
|
||||
}
|
||||
|
||||
delay(10);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
Serial.println("\nTEST: writeBlock()");
|
||||
delay(10);
|
||||
start = micros();
|
||||
ee.writeBlock(0, (uint8_t *) buffer, 50);
|
||||
dur1 = micros() - start;
|
||||
Serial.print("DUR1: ");
|
||||
Serial.println(dur1);
|
||||
delay(10);
|
||||
|
||||
Serial.println("\nTEST: verifyBlock() no change");
|
||||
delay(10);
|
||||
start = micros();
|
||||
if (ee.verifyBlock(0, (uint8_t *) buffer, 50) == false)
|
||||
{
|
||||
Serial.print("X");
|
||||
}
|
||||
dur1 = micros() - start;
|
||||
Serial.print("DUR1: ");
|
||||
Serial.println(dur1);
|
||||
delay(10);
|
||||
|
||||
|
||||
for (uint8_t loc = 0; loc < 50; loc += 5)
|
||||
{
|
||||
disrupt(loc);
|
||||
}
|
||||
|
||||
Serial.println("done...");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void disrupt(uint8_t location)
|
||||
{
|
||||
bool flag = true;
|
||||
// disrupt memory
|
||||
Serial.print("\nTEST: verifyBlock() after change @ ");
|
||||
Serial.println(location);
|
||||
delay(10);
|
||||
ee.writeBlock(0, (uint8_t *) buffer, 50);
|
||||
ee.writeByte(location, 255);
|
||||
|
||||
start = micros();
|
||||
if (ee.verifyBlock(0, (uint8_t *) buffer, 50) == false)
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
dur1 = micros() - start;
|
||||
Serial.print("DUR1: ");
|
||||
Serial.println(dur1);
|
||||
Serial.println(flag);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
@@ -1,11 +1,14 @@
|
||||
//
|
||||
// FILE: I2C_small_eeprom_test.ino
|
||||
// AUTHOR: Tyler Freeman
|
||||
// VERSION: 0.1.1
|
||||
// VERSION: 0.1.2
|
||||
// PURPOSE: show/test I2C_EEPROM library with small EEPROMS
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM
|
||||
// HISTORY
|
||||
// 0.1.0 2014-05-xx initial version
|
||||
// 0.1.1 2020-07-14 fix #1 compile for ESP; fix author
|
||||
// 0.1.2 2025-08-27 add print filename and version number of library
|
||||
|
||||
|
||||
#include <Wire.h>
|
||||
#include <I2C_eeprom.h>
|
||||
@@ -38,11 +41,12 @@
|
||||
|
||||
I2C_eeprom eeprom(DEVICEADDRESS, EE24LC01MAXBYTES);
|
||||
|
||||
void readAndWriteVar() {
|
||||
SERIAL_DEBUG.println("----------------------------------------------");
|
||||
|
||||
void readAndWriteVar() {
|
||||
SERIAL_DEBUG.println("----------------------------------------------");
|
||||
SERIAL_DEBUG.print("SINGLE BYTE: writing and retreiving EEPROM on I2C at address ");
|
||||
SERIAL_DEBUG.println(DEVICEADDRESS);
|
||||
SERIAL_DEBUG.println("----------------------------------------------");
|
||||
SERIAL_DEBUG.println("----------------------------------------------");
|
||||
|
||||
byte curval = eeprom.readByte(TEST_ADDR);
|
||||
|
||||
@@ -59,11 +63,11 @@ void readAndWriteVar() {
|
||||
|
||||
curval = eeprom.readByte(TEST_ADDR);
|
||||
SERIAL_DEBUG.print("new value: ");
|
||||
SERIAL_DEBUG.println(curval);
|
||||
|
||||
SERIAL_DEBUG.println(curval);
|
||||
}
|
||||
|
||||
void readAndWritePage(unsigned int pageAddress, int bufferLen) {
|
||||
|
||||
void readAndWritePage(unsigned int pageAddress, int bufferLen) {
|
||||
// always make the maximum size, just don't use all of it.
|
||||
byte testBuffer[LONG_BUFFER_LEN + 1];
|
||||
|
||||
@@ -91,54 +95,61 @@ void readAndWritePage(unsigned int pageAddress, int bufferLen) {
|
||||
|
||||
eeprom.readBlock(pageAddress, testBuffer, bufferLen);
|
||||
SERIAL_DEBUG.print("new value: ");
|
||||
SERIAL_DEBUG.println((char*)testBuffer);
|
||||
|
||||
SERIAL_DEBUG.println((char*)testBuffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
SERIAL_DEBUG.begin(57600);
|
||||
while (!SERIAL_DEBUG); // wait for SERIAL_DEBUG port to connect. Needed for Leonardo only
|
||||
SERIAL_DEBUG.begin(57600);
|
||||
while (!SERIAL_DEBUG); // wait for SERIAL_DEBUG port to connect. Needed for Leonardo only
|
||||
SERIAL_DEBUG.println();
|
||||
SERIAL_DEBUG.println(__FILE__);
|
||||
SERIAL_DEBUG.print("I2C_EEPROM_VERSION: ");
|
||||
SERIAL_DEBUG.println(I2C_EEPROM_VERSION);
|
||||
SERIAL_DEBUG.println();
|
||||
|
||||
SERIAL_DEBUG.println("IT IS BEGINNING");
|
||||
SERIAL_DEBUG.println("WAIT FOR IT");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
SERIAL_DEBUG.println("IT IS BEGINNING");
|
||||
SERIAL_DEBUG.println("WAIT FOR IT");
|
||||
|
||||
eeprom.begin();
|
||||
|
||||
|
||||
readAndWriteVar();
|
||||
|
||||
SERIAL_DEBUG.println("----------------------------------------------");
|
||||
SERIAL_DEBUG.println("PAGE:");
|
||||
SERIAL_DEBUG.println("----------------------------------------------");
|
||||
SERIAL_DEBUG.println("PAGE:");
|
||||
SERIAL_DEBUG.print(" writing and retrieving EEPROM Page on I2C at address ");
|
||||
SERIAL_DEBUG.println(DEVICEADDRESS);
|
||||
SERIAL_DEBUG.println("----------------------------------------------");
|
||||
SERIAL_DEBUG.println("----------------------------------------------");
|
||||
|
||||
readAndWritePage(TEST_PAGE_ADDR, SHORT_BUFFER_LEN);
|
||||
|
||||
|
||||
|
||||
SERIAL_DEBUG.println("----------------------------------------------");
|
||||
SERIAL_DEBUG.println("MULTI-PAGE:");
|
||||
SERIAL_DEBUG.println("----------------------------------------------");
|
||||
SERIAL_DEBUG.println("MULTI-PAGE:");
|
||||
SERIAL_DEBUG.print("writing and retrieving EEPROM Pages on I2C at address ");
|
||||
SERIAL_DEBUG.println(DEVICEADDRESS);
|
||||
SERIAL_DEBUG.println("----------------------------------------------");
|
||||
SERIAL_DEBUG.println("----------------------------------------------");
|
||||
|
||||
readAndWritePage(LONG_TEST_PAGE_ADDR, LONG_BUFFER_LEN);
|
||||
|
||||
|
||||
|
||||
SERIAL_DEBUG.println("----------------------------------------------");
|
||||
SERIAL_DEBUG.println("MULTI-PAGE UNALINGED: ");
|
||||
SERIAL_DEBUG.println("----------------------------------------------");
|
||||
SERIAL_DEBUG.println("MULTI-PAGE UNALINGED: ");
|
||||
SERIAL_DEBUG.print("writing and retrieving EEPROM Pages on I2C at address ");
|
||||
SERIAL_DEBUG.println(DEVICEADDRESS);
|
||||
SERIAL_DEBUG.println("----------------------------------------------");
|
||||
SERIAL_DEBUG.println("----------------------------------------------");
|
||||
|
||||
readAndWritePage(UNALIGNED_TEST_PAGE_ADDR, UNALIGNED_BUFFER_LEN);
|
||||
|
||||
SERIAL_DEBUG.println("\nDone...");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Nothing to do during loop
|
||||
// Nothing to do during loop
|
||||
}
|
||||
|
||||
|
||||
+44
-6
@@ -1,7 +1,7 @@
|
||||
# Syntax Coloring Map For I2C_EEPROM
|
||||
# Syntax Colouring Map For I2C_EEPROM
|
||||
|
||||
|
||||
# Datatypes (KEYWORD1)
|
||||
# Data types (KEYWORD1)
|
||||
I2C_eeprom KEYWORD1
|
||||
I2C_eeprom_cyclic_store KEYWORD1
|
||||
|
||||
@@ -13,17 +13,41 @@ isConnected KEYWORD2
|
||||
|
||||
|
||||
# I2C_eeprom
|
||||
readByte KEYWORD2
|
||||
writeByte KEYWORD2
|
||||
setBlock KEYWORD2
|
||||
readBlock KEYWORD2
|
||||
writeBlock KEYWORD2
|
||||
determineSize KEYWORD2
|
||||
setBlock KEYWORD2
|
||||
|
||||
readByte KEYWORD2
|
||||
readBlock KEYWORD2
|
||||
verifyBlock KEYWORD2
|
||||
|
||||
updateByte KEYWORD2
|
||||
updateBlock KEYWORD2
|
||||
|
||||
writeByteVerify KEYWORD2
|
||||
writeBlockVerify KEYWORD2
|
||||
setBlockVerify KEYWORD2
|
||||
updateByteVerify KEYWORD2
|
||||
updateBlockVerify KEYWORD2
|
||||
|
||||
determineSize KEYWORD2
|
||||
determineSizeNoWrite KEYWORD2
|
||||
getDeviceSize KEYWORD2
|
||||
getPageSize KEYWORD2
|
||||
calculatePageSize KEYWORD2
|
||||
getLastWrite KEYWORD2
|
||||
|
||||
setDeviceSize KEYWORD2
|
||||
|
||||
setExtraWriteCycleTime KEYWORD2
|
||||
getExtraWriteCycleTime KEYWORD2
|
||||
|
||||
hasWriteProtectPin KEYWORD2
|
||||
allowWrite KEYWORD2
|
||||
preventWrite KEYWORD2
|
||||
setAutoWriteProtect KEYWORD2
|
||||
getAutoWriteProtect KEYWORD2
|
||||
|
||||
|
||||
# I2C_eeprom_cyclic_store
|
||||
format KEYWORD2
|
||||
@@ -31,4 +55,18 @@ read KEYWORD2
|
||||
write KEYWORD2
|
||||
getMetrics KEYWORD2
|
||||
|
||||
|
||||
# Constants (LITERAL1)
|
||||
I2C_EEPROM_VERSION LITERAL1
|
||||
|
||||
I2C_DEVICESIZE_24LC512 LITERAL1
|
||||
I2C_DEVICESIZE_24LC256 LITERAL1
|
||||
I2C_DEVICESIZE_24LC128 LITERAL1
|
||||
I2C_DEVICESIZE_24LC64 LITERAL1
|
||||
I2C_DEVICESIZE_24LC32 LITERAL1
|
||||
I2C_DEVICESIZE_24LC16 LITERAL1
|
||||
I2C_DEVICESIZE_24LC08 LITERAL1
|
||||
I2C_DEVICESIZE_24LC04 LITERAL1
|
||||
I2C_DEVICESIZE_24LC02 LITERAL1
|
||||
I2C_DEVICESIZE_24LC01 LITERAL1
|
||||
|
||||
|
||||
+5
-3
@@ -15,7 +15,9 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/I2C_EEPROM.git"
|
||||
},
|
||||
"version":"1.4.3",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*"
|
||||
"version": "1.9.4",
|
||||
"license": "MIT",
|
||||
"frameworks": "*",
|
||||
"platforms": "*",
|
||||
"headers": "I2C_eeprom.h"
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
name=I2C_EEPROM
|
||||
version=1.4.3
|
||||
version=1.9.4
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Library for I2C EEPROMS
|
||||
|
||||
+107
-4
@@ -38,36 +38,139 @@
|
||||
|
||||
unittest_setup()
|
||||
{
|
||||
fprintf(stderr, "I2C_EEPROM_VERSION: %s\n", ( char * ) I2C_EEPROM_VERSION);
|
||||
}
|
||||
|
||||
unittest_teardown()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
unittest(test_new_operator)
|
||||
{
|
||||
assertEqualINF(exp(800));
|
||||
assertEqualINF(0.0/0.0);
|
||||
assertEqualINF(42);
|
||||
|
||||
|
||||
assertEqualNAN(INFINITY - INFINITY);
|
||||
assertEqualNAN(0.0/0.0);
|
||||
assertEqualNAN(42);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
unittest(test_constructor)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
|
||||
Wire.begin();
|
||||
I2C_eeprom EE(0x50, 0x8000);
|
||||
|
||||
assertTrue(EE.begin());
|
||||
assertTrue(EE.isConnected());
|
||||
|
||||
assertEqual(1, 1);
|
||||
assertEqual(0, EE.getLastWrite());
|
||||
assertEqual(64, EE.getPageSize());
|
||||
}
|
||||
|
||||
|
||||
unittest(test_constants)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
I2C_eeprom EE(0x50, 0x8000);
|
||||
|
||||
assertEqual(I2C_DEVICESIZE_24LC512, 65536);
|
||||
assertEqual(I2C_DEVICESIZE_24LC256, 32768);
|
||||
assertEqual(I2C_DEVICESIZE_24LC128, 16384);
|
||||
assertEqual(I2C_DEVICESIZE_24LC64, 8192);
|
||||
assertEqual(I2C_DEVICESIZE_24LC32, 4096);
|
||||
assertEqual(I2C_DEVICESIZE_24LC16, 2048);
|
||||
assertEqual(I2C_DEVICESIZE_24LC08, 1024);
|
||||
assertEqual(I2C_DEVICESIZE_24LC04, 512);
|
||||
assertEqual(I2C_DEVICESIZE_24LC02, 256);
|
||||
assertEqual(I2C_DEVICESIZE_24LC01, 128);
|
||||
}
|
||||
|
||||
|
||||
unittest(test_getPageSize)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
I2C_eeprom EE(0x50, 0x8000);
|
||||
|
||||
assertEqual(EE.getPageSize(I2C_DEVICESIZE_24LC512), 128);
|
||||
assertEqual(EE.getPageSize(I2C_DEVICESIZE_24LC256), 64);
|
||||
assertEqual(EE.getPageSize(I2C_DEVICESIZE_24LC128), 64);
|
||||
assertEqual(EE.getPageSize(I2C_DEVICESIZE_24LC64), 32);
|
||||
assertEqual(EE.getPageSize(I2C_DEVICESIZE_24LC32), 32);
|
||||
assertEqual(EE.getPageSize(I2C_DEVICESIZE_24LC16), 16);
|
||||
assertEqual(EE.getPageSize(I2C_DEVICESIZE_24LC08), 16);
|
||||
assertEqual(EE.getPageSize(I2C_DEVICESIZE_24LC04), 16);
|
||||
assertEqual(EE.getPageSize(I2C_DEVICESIZE_24LC02), 8);
|
||||
assertEqual(EE.getPageSize(I2C_DEVICESIZE_24LC01), 8);
|
||||
|
||||
I2C_eeprom prom(0x50, 0x8123);
|
||||
assertEqual(prom.getDeviceSize(), 0x8000);
|
||||
assertEqual(prom.getPageSize(), 64);
|
||||
}
|
||||
|
||||
|
||||
unittest(test_setDeviceSize)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
I2C_eeprom EE(0x50, 0x8000);
|
||||
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC512), I2C_DEVICESIZE_24LC512);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC256), I2C_DEVICESIZE_24LC256);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC128), I2C_DEVICESIZE_24LC128);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC64), I2C_DEVICESIZE_24LC64);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC32), I2C_DEVICESIZE_24LC32);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC16), I2C_DEVICESIZE_24LC16);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC08), I2C_DEVICESIZE_24LC08);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC04), I2C_DEVICESIZE_24LC04);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC02), I2C_DEVICESIZE_24LC02);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC01), I2C_DEVICESIZE_24LC01);
|
||||
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC512 + 1), I2C_DEVICESIZE_24LC512);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC256 + 1), I2C_DEVICESIZE_24LC256);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC128 + 1), I2C_DEVICESIZE_24LC128);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC64 + 1), I2C_DEVICESIZE_24LC64);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC32 + 1), I2C_DEVICESIZE_24LC32);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC16 + 1), I2C_DEVICESIZE_24LC16);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC08 + 1), I2C_DEVICESIZE_24LC08);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC04 + 1), I2C_DEVICESIZE_24LC04);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC02 + 1), I2C_DEVICESIZE_24LC02);
|
||||
assertEqual(EE.setDeviceSize(I2C_DEVICESIZE_24LC01 + 1), I2C_DEVICESIZE_24LC01);
|
||||
|
||||
}
|
||||
|
||||
|
||||
unittest(test_setPageSize)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
I2C_eeprom EE(0x50, 0x8000);
|
||||
|
||||
assertEqual(EE.setPageSize(129), 128);
|
||||
assertEqual(EE.setPageSize(128), 128);
|
||||
assertEqual(EE.setPageSize(127), 64);
|
||||
assertEqual(EE.setPageSize(65), 64);
|
||||
assertEqual(EE.setPageSize(64), 64);
|
||||
assertEqual(EE.setPageSize(63), 32);
|
||||
assertEqual(EE.setPageSize(33), 32);
|
||||
assertEqual(EE.setPageSize(32), 32);
|
||||
assertEqual(EE.setPageSize(31), 16);
|
||||
assertEqual(EE.setPageSize(17), 16);
|
||||
assertEqual(EE.setPageSize(16), 16);
|
||||
assertEqual(EE.setPageSize(9), 8);
|
||||
assertEqual(EE.setPageSize(8), 8);
|
||||
}
|
||||
|
||||
|
||||
unittest_main()
|
||||
|
||||
// --------
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
// Note: The implementation of the I2C_eeprom_cyclic_store should have been
|
||||
// made injactable so that a mock or fake for I2C_eeprom could have been used
|
||||
// instead of having to rely on a test implementation of the Wire singleton.
|
||||
//
|
||||
//
|
||||
// This could have been done by changing the class to take two template
|
||||
// parameters, the first being one for I2C_eeprom or it's mock and the second
|
||||
// being the data type to store. For simplicity an alias could have been
|
||||
// introduced so that users wouldn't have to specify I2C_eeprom but that made
|
||||
// the editor lose track of the intellisense comments. :-/
|
||||
// the editor lose track of the intellisense comments. :-/
|
||||
//
|
||||
// Thus this remains until someone comes up with a brighter idea.
|
||||
|
||||
@@ -40,12 +40,13 @@ unittest_teardown()
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that I2C_eeprom_cyclic_store fails to
|
||||
* Verify that I2C_eeprom_cyclic_store fails to
|
||||
* initialize when unable to read from eeprom.
|
||||
*/
|
||||
unittest(cyclic_store_fails_begin)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
auto mosi = Wire.getMosi(I2C_EEPROM_ADDR);
|
||||
|
||||
@@ -57,18 +58,19 @@ unittest(cyclic_store_fails_begin)
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that I2C_eeprom_cyclic_store successfully
|
||||
* Verify that I2C_eeprom_cyclic_store successfully
|
||||
* initializes on empty eeprom.
|
||||
*/
|
||||
unittest(cyclic_store_empty_begin)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
auto mosi = Wire.getMosi(I2C_EEPROM_ADDR);
|
||||
|
||||
I2C_eeprom EE(I2C_EEPROM_ADDR, I2C_EEPROM_SIZE);
|
||||
EE.begin();
|
||||
|
||||
|
||||
auto miso = Wire.getMiso(I2C_EEPROM_ADDR);
|
||||
miso->push_back(0xff);
|
||||
miso->push_back(0xff);
|
||||
@@ -87,6 +89,7 @@ unittest(cyclic_store_empty_begin)
|
||||
unittest(cyclic_store_double_page_buffer)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
auto mosi = Wire.getMosi(I2C_EEPROM_ADDR);
|
||||
|
||||
@@ -100,13 +103,12 @@ unittest(cyclic_store_double_page_buffer)
|
||||
miso->push_back(0xff);
|
||||
|
||||
I2C_eeprom_cyclic_store<uint8_t[40]> CS;
|
||||
assertEqual(true, CS.begin(EE, 32, 4));
|
||||
assertTrue(CS.begin(EE, 32, 4));
|
||||
|
||||
uint16_t slots;
|
||||
uint32_t writes;
|
||||
|
||||
CS.getMetrics(slots, writes);
|
||||
|
||||
assertTrue(CS.getMetrics(slots, writes));
|
||||
assertEqual(2, slots);
|
||||
assertEqual(0, writes);
|
||||
}
|
||||
@@ -118,6 +120,7 @@ unittest(cyclic_store_double_page_buffer)
|
||||
unittest(cyclic_store_finds_single_stored_version)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
auto mosi = Wire.getMosi(I2C_EEPROM_ADDR);
|
||||
|
||||
@@ -156,6 +159,7 @@ unittest(cyclic_store_finds_single_stored_version)
|
||||
unittest(cyclic_store_finds_last_half_filled_eeprom)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
auto mosi = Wire.getMosi(I2C_EEPROM_ADDR);
|
||||
|
||||
@@ -206,6 +210,7 @@ unittest(cyclic_store_finds_last_half_filled_eeprom)
|
||||
unittest(cyclic_store_finds_version_if_last_slot)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
auto mosi = Wire.getMosi(I2C_EEPROM_ADDR);
|
||||
|
||||
@@ -257,6 +262,7 @@ unittest(cyclic_store_finds_version_if_last_slot)
|
||||
unittest(cyclic_store_finds_last_wrapped_eeprom)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
auto mosi = Wire.getMosi(I2C_EEPROM_ADDR);
|
||||
|
||||
@@ -305,12 +311,13 @@ unittest(cyclic_store_finds_last_wrapped_eeprom)
|
||||
* Verify that I2C_eeprom_cyclic_store successfully finds the last
|
||||
* entry after writes have wrapped around the end of the eeprom
|
||||
* when using a buffer that spans two pages. And that it does so
|
||||
* even if the number of pages is not evenly divisable by the
|
||||
* even if the number of pages is not evenly divisable by the
|
||||
* number of pages the buffer span.
|
||||
*/
|
||||
unittest(cyclic_store_finds_last_wrapped_eeprom_double_page_buffer)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
auto mosi = Wire.getMosi(I2C_EEPROM_ADDR);
|
||||
|
||||
@@ -362,6 +369,7 @@ unittest(cyclic_store_finds_last_wrapped_eeprom_double_page_buffer)
|
||||
unittest(cyclic_store_fails_init_on_too_large_buffer)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
I2C_eeprom EE(I2C_EEPROM_ADDR, I2C_EEPROM_SIZE);
|
||||
EE.begin();
|
||||
@@ -377,6 +385,7 @@ unittest(cyclic_store_fails_init_on_too_large_buffer)
|
||||
unittest(cyclic_store_empty_metrics)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
auto mosi = Wire.getMosi(I2C_EEPROM_ADDR);
|
||||
|
||||
@@ -408,6 +417,7 @@ unittest(cyclic_store_empty_metrics)
|
||||
unittest(cyclic_store_fails_metrics_when_failed_initialize)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
I2C_eeprom EE(I2C_EEPROM_ADDR, I2C_EEPROM_SIZE);
|
||||
EE.begin();
|
||||
@@ -428,6 +438,7 @@ unittest(cyclic_store_fails_metrics_when_failed_initialize)
|
||||
unittest(cyclic_store_fails_metrics_when_not_initialized)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
I2C_eeprom EE(I2C_EEPROM_ADDR, I2C_EEPROM_SIZE);
|
||||
EE.begin();
|
||||
@@ -441,13 +452,14 @@ unittest(cyclic_store_fails_metrics_when_not_initialized)
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that I2C_eeprom_cyclic_store correctly
|
||||
* Verify that I2C_eeprom_cyclic_store correctly
|
||||
* increments the number of writes when saving
|
||||
* new versions.
|
||||
*/
|
||||
unittest(cyclic_store_increments_write_counter)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
auto mosi = Wire.getMosi(I2C_EEPROM_ADDR);
|
||||
|
||||
@@ -490,6 +502,7 @@ unittest(cyclic_store_increments_write_counter)
|
||||
unittest(cyclic_store_format_single_page)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
auto mosi = Wire.getMosi(I2C_EEPROM_ADDR);
|
||||
|
||||
@@ -523,6 +536,7 @@ unittest(cyclic_store_format_single_page)
|
||||
unittest(cyclic_store_format_double_page)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
auto mosi = Wire.getMosi(I2C_EEPROM_ADDR);
|
||||
|
||||
@@ -557,6 +571,7 @@ unittest(cyclic_store_format_double_page)
|
||||
unittest(cyclic_store_format_double_page_odd_space)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
auto mosi = Wire.getMosi(I2C_EEPROM_ADDR);
|
||||
|
||||
@@ -591,12 +606,13 @@ unittest(cyclic_store_format_double_page_odd_space)
|
||||
unittest(cyclic_store_wrapping_single_page)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
auto mosi = Wire.getMosi(I2C_EEPROM_ADDR);
|
||||
|
||||
I2C_eeprom EE(I2C_EEPROM_ADDR, I2C_EEPROM_SIZE);
|
||||
EE.begin();
|
||||
|
||||
|
||||
auto miso = Wire.getMiso(I2C_EEPROM_ADDR);
|
||||
miso->push_back(0xff);
|
||||
miso->push_back(0xff);
|
||||
@@ -636,12 +652,13 @@ unittest(cyclic_store_wrapping_single_page)
|
||||
unittest(cyclic_store_wrapping_double_page)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
auto mosi = Wire.getMosi(I2C_EEPROM_ADDR);
|
||||
|
||||
I2C_eeprom EE(I2C_EEPROM_ADDR, I2C_EEPROM_SIZE);
|
||||
EE.begin();
|
||||
|
||||
|
||||
auto miso = Wire.getMiso(I2C_EEPROM_ADDR);
|
||||
miso->push_back(0xff);
|
||||
miso->push_back(0xff);
|
||||
@@ -678,12 +695,13 @@ unittest(cyclic_store_wrapping_double_page)
|
||||
unittest(cyclic_store_wrapping_double_page_odd_space)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
auto mosi = Wire.getMosi(I2C_EEPROM_ADDR);
|
||||
|
||||
I2C_eeprom EE(I2C_EEPROM_ADDR, I2C_EEPROM_SIZE);
|
||||
EE.begin();
|
||||
|
||||
|
||||
auto miso = Wire.getMiso(I2C_EEPROM_ADDR);
|
||||
miso->push_back(0xff);
|
||||
miso->push_back(0xff);
|
||||
@@ -714,4 +732,6 @@ unittest(cyclic_store_wrapping_double_page_odd_space)
|
||||
|
||||
unittest_main()
|
||||
|
||||
// --------
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
// https://github.com/Arduino-CI/arduino_ci/blob/master/REFERENCE.md
|
||||
//
|
||||
|
||||
|
||||
#include <ArduinoUnitTests.h>
|
||||
#include "Arduino.h"
|
||||
|
||||
@@ -17,6 +18,7 @@ class I2C_eeprom_wrapper;
|
||||
|
||||
#include "I2C_eeprom.h"
|
||||
|
||||
|
||||
class I2C_eeprom_wrapper {
|
||||
public:
|
||||
static uint8_t pageSize(I2C_eeprom &eeprom) { return eeprom._pageSize; }
|
||||
@@ -25,6 +27,7 @@ class I2C_eeprom_wrapper {
|
||||
|
||||
#define I2C_EEPROM_ADDR 0x50
|
||||
|
||||
|
||||
unittest_setup()
|
||||
{
|
||||
}
|
||||
@@ -33,14 +36,16 @@ unittest_teardown()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify that an instance gets the default page size
|
||||
* when the constructor without device size is used.
|
||||
* The expected outcome is I2C_EEPROM_PAGESIZE
|
||||
* The expected outcome is I2C_EEPROM_PAGESIZE
|
||||
*/
|
||||
unittest(i2c_eeprom_default_page_size)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
I2C_eeprom eeprom(I2C_EEPROM_ADDR);
|
||||
|
||||
@@ -49,6 +54,7 @@ unittest(i2c_eeprom_default_page_size)
|
||||
// assertEqual(false, I2C_eeprom_wrapper::isAddressSizeTwoWords(eeprom));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify that the constructor calculates the correct
|
||||
* page size and addressing for a 1K eeprom (e g AT24C01).
|
||||
@@ -56,6 +62,7 @@ unittest(i2c_eeprom_default_page_size)
|
||||
unittest(i2c_eeprom_1k_page_size)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
I2C_eeprom eeprom(I2C_EEPROM_ADDR, 0x80);
|
||||
|
||||
@@ -63,6 +70,7 @@ unittest(i2c_eeprom_1k_page_size)
|
||||
assertEqual(false, I2C_eeprom_wrapper::isAddressSizeTwoWords(eeprom));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify that the constructor calculates the correct
|
||||
* page size and addressing for a 2K eeprom (e g AT24C02).
|
||||
@@ -70,6 +78,7 @@ unittest(i2c_eeprom_1k_page_size)
|
||||
unittest(i2c_eeprom_2k_page_size)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
I2C_eeprom eeprom(I2C_EEPROM_ADDR, 0x100);
|
||||
|
||||
@@ -77,6 +86,7 @@ unittest(i2c_eeprom_2k_page_size)
|
||||
assertEqual(false, I2C_eeprom_wrapper::isAddressSizeTwoWords(eeprom));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify that the constructor calculates the correct
|
||||
* page size and addressing for a 4K eeprom (e g AT24C04).
|
||||
@@ -84,6 +94,7 @@ unittest(i2c_eeprom_2k_page_size)
|
||||
unittest(i2c_eeprom_4k_page_size)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
I2C_eeprom eeprom(I2C_EEPROM_ADDR, 0x200);
|
||||
|
||||
@@ -91,6 +102,7 @@ unittest(i2c_eeprom_4k_page_size)
|
||||
assertEqual(false, I2C_eeprom_wrapper::isAddressSizeTwoWords(eeprom));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify that the constructor calculates the correct
|
||||
* page size and addressing for a 8K eeprom (e g AT24C08).
|
||||
@@ -98,6 +110,7 @@ unittest(i2c_eeprom_4k_page_size)
|
||||
unittest(i2c_eeprom_8k_page_size)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
I2C_eeprom eeprom(I2C_EEPROM_ADDR, 0x400);
|
||||
|
||||
@@ -105,6 +118,7 @@ unittest(i2c_eeprom_8k_page_size)
|
||||
assertEqual(false, I2C_eeprom_wrapper::isAddressSizeTwoWords(eeprom));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify that the constructor calculates the correct
|
||||
* page size and addressing for a 16K eeprom (e g AT24C16).
|
||||
@@ -112,6 +126,7 @@ unittest(i2c_eeprom_8k_page_size)
|
||||
unittest(i2c_eeprom_16k_page_size)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
I2C_eeprom eeprom(I2C_EEPROM_ADDR, 0x800);
|
||||
|
||||
@@ -119,6 +134,7 @@ unittest(i2c_eeprom_16k_page_size)
|
||||
assertEqual(false, I2C_eeprom_wrapper::isAddressSizeTwoWords(eeprom));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify that the constructor calculates the correct
|
||||
* page size and addressing for a 32K eeprom (e g AT24C32).
|
||||
@@ -126,6 +142,7 @@ unittest(i2c_eeprom_16k_page_size)
|
||||
unittest(i2c_eeprom_32k_page_size)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
I2C_eeprom eeprom(I2C_EEPROM_ADDR, 0x1000);
|
||||
|
||||
@@ -133,6 +150,7 @@ unittest(i2c_eeprom_32k_page_size)
|
||||
assertEqual(true, I2C_eeprom_wrapper::isAddressSizeTwoWords(eeprom));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify that the constructor calculates the correct
|
||||
* page size and addressing for a 64K eeprom (e g AT24C64).
|
||||
@@ -140,6 +158,7 @@ unittest(i2c_eeprom_32k_page_size)
|
||||
unittest(i2c_eeprom_64k_page_size)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
I2C_eeprom eeprom(I2C_EEPROM_ADDR, 0x2000);
|
||||
|
||||
@@ -147,6 +166,7 @@ unittest(i2c_eeprom_64k_page_size)
|
||||
assertEqual(true, I2C_eeprom_wrapper::isAddressSizeTwoWords(eeprom));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify that the constructor calculates the correct
|
||||
* page size and addressing for a 128K eeprom (e g AT24C128).
|
||||
@@ -154,6 +174,7 @@ unittest(i2c_eeprom_64k_page_size)
|
||||
unittest(i2c_eeprom_128k_page_size)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
I2C_eeprom eeprom(I2C_EEPROM_ADDR, 0x4000);
|
||||
|
||||
@@ -161,6 +182,7 @@ unittest(i2c_eeprom_128k_page_size)
|
||||
assertEqual(true, I2C_eeprom_wrapper::isAddressSizeTwoWords(eeprom));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify that the constructor calculates the correct
|
||||
* page size and addressing for a 256K eeprom (e g AT24C256).
|
||||
@@ -168,6 +190,7 @@ unittest(i2c_eeprom_128k_page_size)
|
||||
unittest(i2c_eeprom_256k_page_size)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
Wire.begin();
|
||||
|
||||
I2C_eeprom eeprom(I2C_EEPROM_ADDR, 0x8000);
|
||||
|
||||
@@ -175,6 +198,9 @@ unittest(i2c_eeprom_256k_page_size)
|
||||
assertEqual(true, I2C_eeprom_wrapper::isAddressSizeTwoWords(eeprom));
|
||||
}
|
||||
|
||||
|
||||
unittest_main()
|
||||
|
||||
// ------------------
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
||||
Reference in New Issue
Block a user