2020-11-27 05:16:22 -05:00
|
|
|
#pragma once
|
2013-11-03 08:20:59 -05:00
|
|
|
//
|
2013-09-30 10:38:08 -04:00
|
|
|
// FILE: I2C_eeprom.h
|
|
|
|
// AUTHOR: Rob Tillaart
|
2024-04-22 12:39:54 -04:00
|
|
|
// VERSION: 1.8.5
|
2020-11-27 05:16:22 -05:00
|
|
|
// PURPOSE: Arduino Library for external I2C EEPROM 24LC256 et al.
|
2024-04-21 05:00:27 -04:00
|
|
|
// URL: https://github.com/RobTillaart/I2C_EEPROM
|
2013-09-30 10:38:08 -04:00
|
|
|
|
2013-11-03 08:20:59 -05:00
|
|
|
|
|
|
|
#include "Arduino.h"
|
2021-01-29 06:31:58 -05:00
|
|
|
#include "Wire.h"
|
|
|
|
|
|
|
|
|
2024-04-22 12:39:54 -04:00
|
|
|
#define I2C_EEPROM_VERSION (F("1.8.5"))
|
2013-09-30 10:40:09 -04:00
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
#define I2C_DEVICESIZE_24LC512 65536
|
|
|
|
#define I2C_DEVICESIZE_24LC256 32768
|
|
|
|
#define I2C_DEVICESIZE_24LC128 16384
|
|
|
|
#define I2C_DEVICESIZE_24LC64 8192
|
|
|
|
#define I2C_DEVICESIZE_24LC32 4096
|
|
|
|
#define I2C_DEVICESIZE_24LC16 2048
|
|
|
|
#define I2C_DEVICESIZE_24LC08 1024
|
|
|
|
#define I2C_DEVICESIZE_24LC04 512
|
|
|
|
#define I2C_DEVICESIZE_24LC02 256
|
|
|
|
#define I2C_DEVICESIZE_24LC01 128
|
|
|
|
|
|
|
|
|
2023-05-02 07:06:57 -04:00
|
|
|
// 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
|
|
|
|
|
2024-04-21 05:00:27 -04:00
|
|
|
|
|
|
|
// 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
|
|
|
|
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
#ifndef UNIT_TEST_FRIEND
|
|
|
|
#define UNIT_TEST_FRIEND
|
|
|
|
#endif
|
2013-11-03 04:41:19 -05:00
|
|
|
|
2024-01-02 10:12:11 -05:00
|
|
|
//#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
|
2013-11-03 04:41:19 -05:00
|
|
|
|
2013-11-03 08:20:59 -05:00
|
|
|
class I2C_eeprom
|
2013-09-30 10:38:08 -04:00
|
|
|
{
|
2013-11-03 08:20:59 -05:00
|
|
|
public:
|
2019-09-03 05:41:28 -04:00
|
|
|
/**
|
2021-01-29 06:31:58 -05:00
|
|
|
* Initializes the EEPROM with a default deviceSize of I2C_DEVICESIZE_24LC256 (32K EEPROM)
|
2019-09-03 05:41:28 -04:00
|
|
|
*/
|
2021-01-29 06:31:58 -05:00
|
|
|
I2C_eeprom(const uint8_t deviceAddress, TwoWire *wire = &Wire);
|
2019-09-03 05:41:28 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Initializes the EEPROM for the given device address.
|
|
|
|
*
|
|
|
|
* It will try to guess page size and address word size based on the size of the device.
|
2020-11-27 05:16:22 -05:00
|
|
|
*
|
2019-09-03 05:41:28 -04:00
|
|
|
* @param deviceAddress Byte address of the device.
|
|
|
|
* @param deviceSize Max size in bytes of the device (divide your device size in Kbits by 8)
|
2021-01-29 06:31:58 -05:00
|
|
|
* @param wire Select alternative Wire interface
|
2019-09-03 05:41:28 -04:00
|
|
|
*/
|
2021-01-29 06:31:58 -05:00
|
|
|
I2C_eeprom(const uint8_t deviceAddress, const uint32_t deviceSize, TwoWire *wire = &Wire);
|
2019-09-03 05:41:28 -04:00
|
|
|
|
2022-10-31 11:53:19 -04:00
|
|
|
// use default I2C pins.
|
2023-09-08 05:35:43 -04:00
|
|
|
bool begin(int8_t writeProtectPin = -1);
|
2021-01-29 06:31:58 -05:00
|
|
|
bool isConnected();
|
2023-11-25 07:22:10 -05:00
|
|
|
uint8_t getAddress();
|
2020-11-27 05:16:22 -05:00
|
|
|
|
2022-06-12 06:47:07 -04:00
|
|
|
|
2021-12-19 14:05:24 -05:00
|
|
|
// writes a byte to memoryAddress
|
2022-06-12 06:47:07 -04:00
|
|
|
// returns I2C status, 0 = OK
|
2021-01-29 06:31:58 -05:00
|
|
|
int writeByte(const uint16_t memoryAddress, const uint8_t value);
|
2021-12-19 14:05:24 -05:00
|
|
|
// writes length bytes from buffer to EEPROM
|
2022-06-12 06:47:07 -04:00
|
|
|
// returns I2C status, 0 = OK
|
2022-06-07 11:43:11 -04:00
|
|
|
int writeBlock(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length);
|
2021-12-19 14:05:24 -05:00
|
|
|
// set length bytes in the EEPROM to the same value.
|
2022-06-12 06:47:07 -04:00
|
|
|
// returns I2C status, 0 = OK
|
2021-01-29 06:31:58 -05:00
|
|
|
int setBlock(const uint16_t memoryAddress, const uint8_t value, const uint16_t length);
|
|
|
|
|
2019-09-03 05:41:28 -04:00
|
|
|
|
2021-12-19 14:05:24 -05:00
|
|
|
// returns the value stored in memoryAddress
|
2020-11-27 05:16:22 -05:00
|
|
|
uint8_t readByte(const uint16_t memoryAddress);
|
2021-12-19 14:05:24 -05:00
|
|
|
// reads length bytes into buffer
|
2022-06-12 06:47:07 -04:00
|
|
|
// returns bytes read.
|
2022-06-07 11:43:11 -04:00
|
|
|
uint16_t readBlock(const uint16_t memoryAddress, uint8_t * buffer, const uint16_t length);
|
2024-03-28 05:50:48 -04:00
|
|
|
bool verifyBlock(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length);
|
2020-11-27 05:16:22 -05:00
|
|
|
|
2021-12-19 14:05:24 -05:00
|
|
|
// 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.
|
2021-01-29 06:31:58 -05:00
|
|
|
int updateByte(const uint16_t memoryAddress, const uint8_t value);
|
2021-12-19 14:05:24 -05:00
|
|
|
// 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!
|
2022-06-12 06:47:07 -04:00
|
|
|
// returns bytes written.
|
|
|
|
uint16_t updateBlock(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length);
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2022-06-07 11:43:11 -04:00
|
|
|
// same functions as above but with verify
|
2022-06-12 06:47:07 -04:00
|
|
|
// return false if write or verify failed.
|
2022-06-07 11:43:11 -04:00
|
|
|
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);
|
|
|
|
|
2022-06-12 06:47:07 -04:00
|
|
|
|
2022-06-07 11:43:11 -04:00
|
|
|
// Meta data functions
|
2021-01-29 06:31:58 -05:00
|
|
|
uint32_t determineSize(const bool debug = false);
|
2023-12-14 05:58:08 -05:00
|
|
|
uint32_t determineSizeNoWrite();
|
2023-05-02 07:06:57 -04:00
|
|
|
uint32_t getDeviceSize();
|
|
|
|
uint8_t getPageSize();
|
2021-01-29 06:31:58 -05:00
|
|
|
uint8_t getPageSize(uint32_t deviceSize);
|
2023-05-02 07:06:57 -04:00
|
|
|
uint32_t getLastWrite();
|
|
|
|
|
2013-11-03 08:20:59 -05:00
|
|
|
|
2023-01-12 11:52:04 -05:00
|
|
|
// 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
|
|
|
|
|
|
|
|
|
2021-11-08 07:26:03 -05:00
|
|
|
// TWR = WriteCycleTime
|
|
|
|
// 5 ms is minimum, one can add extra ms here to adjust timing of both read() and write()
|
2023-05-02 07:06:57 -04:00
|
|
|
void setExtraWriteCycleTime(uint8_t ms);
|
|
|
|
uint8_t getExtraWriteCycleTime();
|
2021-11-08 07:26:03 -05:00
|
|
|
|
2022-06-12 06:47:07 -04:00
|
|
|
|
2023-09-08 05:35:43 -04:00
|
|
|
// 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();
|
|
|
|
|
|
|
|
|
2013-11-03 08:20:59 -05:00
|
|
|
private:
|
2020-11-27 05:16:22 -05:00
|
|
|
uint8_t _deviceAddress;
|
2022-12-03 06:40:41 -05:00
|
|
|
uint32_t _lastWrite = 0; // for waitEEReady
|
|
|
|
uint32_t _deviceSize = 0;
|
|
|
|
uint8_t _pageSize = 0;
|
|
|
|
uint8_t _extraTWR = 0; // milliseconds
|
2014-05-12 04:41:31 -04:00
|
|
|
|
2023-09-08 05:35:43 -04:00
|
|
|
|
2021-12-19 14:05:24 -05:00
|
|
|
// 24LC32..24LC512 use two bytes for memory address
|
|
|
|
// 24LC01..24LC16 use one-byte addresses + part of device address
|
2020-11-27 05:16:22 -05:00
|
|
|
bool _isAddressSizeTwoWords;
|
2014-05-12 04:41:31 -04:00
|
|
|
|
2020-11-27 05:16:22 -05:00
|
|
|
void _beginTransmission(const uint16_t memoryAddress);
|
2015-03-06 11:29:14 -05:00
|
|
|
|
2022-06-12 06:47:07 -04:00
|
|
|
// returns I2C status, 0 = OK
|
2024-03-28 05:50:48 -04:00
|
|
|
// TODO incrBuffer is an implementation name, not a functional name.
|
2022-06-12 06:47:07 -04:00
|
|
|
int _pageBlock(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length, const bool incrBuffer);
|
|
|
|
// returns I2C status, 0 = OK
|
2024-04-21 05:00:27 -04:00
|
|
|
int _WriteBlock(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length);
|
2022-06-12 06:47:07 -04:00
|
|
|
// returns bytes read.
|
2024-04-21 05:00:27 -04:00
|
|
|
uint8_t _ReadBlock(const uint16_t memoryAddress, uint8_t * buffer, const uint16_t length);
|
2024-03-28 05:50:48 -04:00
|
|
|
// compare bytes in EEPROM.
|
2024-04-21 05:00:27 -04:00
|
|
|
bool _verifyBlock(const uint16_t memoryAddress, const uint8_t * buffer, const uint16_t length);
|
2013-11-03 11:06:53 -05:00
|
|
|
|
2021-12-19 14:05:24 -05:00
|
|
|
// to optimize the write latency of the EEPROM
|
2020-11-27 05:16:22 -05:00
|
|
|
void _waitEEReady();
|
2021-01-29 06:31:58 -05:00
|
|
|
|
|
|
|
TwoWire * _wire;
|
|
|
|
|
2022-06-12 06:47:07 -04:00
|
|
|
bool _debug = false;
|
|
|
|
|
2023-09-08 05:35:43 -04:00
|
|
|
int8_t _writeProtectPin = -1;
|
2024-04-21 05:00:27 -04:00
|
|
|
bool _autoWriteProtect = EN_AUTO_WRITE_PROTECT;
|
2023-09-08 05:35:43 -04:00
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
UNIT_TEST_FRIEND;
|
2013-09-30 10:38:08 -04:00
|
|
|
};
|
|
|
|
|
2021-12-19 14:05:24 -05:00
|
|
|
|
2023-05-02 07:06:57 -04:00
|
|
|
// -- END OF FILE --
|
2021-12-19 14:05:24 -05:00
|
|
|
|