From 692f1a300484724bbf87d7550df5906d72278109 Mon Sep 17 00:00:00 2001 From: Rob Tillaart Date: Fri, 29 Jan 2021 10:53:04 +0100 Subject: [PATCH] fix #21 addressing ST m24C08 et al + WireN support (#22) * fix #21 addressing ST m24C08 et al + WireN support --- I2C_eeprom.cpp | 50 ++++++++--------- I2C_eeprom.h | 10 ++-- README.md | 53 ++++++++++--------- .../I2C_eeprom_determineSize.ino | 5 ++ examples/I2C_eeprom_test/I2C_eeprom_test.ino | 3 +- keywords.txt | 8 +++ library.json | 2 +- library.properties | 2 +- 8 files changed, 71 insertions(+), 62 deletions(-) diff --git a/I2C_eeprom.cpp b/I2C_eeprom.cpp index e2a30e1..05f2966 100644 --- a/I2C_eeprom.cpp +++ b/I2C_eeprom.cpp @@ -1,7 +1,7 @@ // // FILE: I2C_eeprom.cpp // AUTHOR: Rob Tillaart -// VERSION: 1.4.0 +// VERSION: 1.4.1 // PURPOSE: Arduino Library for external I2C EEPROM 24LC256 et al. // URL: https://github.com/RobTillaart/I2C_EEPROM.git // @@ -34,6 +34,8 @@ // 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; #include @@ -58,48 +60,27 @@ #define I2C_TWIBUFFERSIZE 30 -I2C_eeprom::I2C_eeprom(const uint8_t deviceAddress) +I2C_eeprom::I2C_eeprom(const uint8_t deviceAddress, TwoWire *wire) { - I2C_eeprom(deviceAddress, I2C_PAGESIZE_24LC256); + I2C_eeprom(deviceAddress, I2C_PAGESIZE_24LC256, wire); } -I2C_eeprom::I2C_eeprom(const uint8_t deviceAddress, const uint32_t deviceSize) +I2C_eeprom::I2C_eeprom(const uint8_t deviceAddress, const uint32_t deviceSize, TwoWire *wire) { _deviceAddress = deviceAddress; _deviceSize = deviceSize; + _pageSize = getPageSize(_deviceSize); + _wire = wire; // Chips 16Kbit (2048 Bytes) or smaller only have one-word addresses. this->_isAddressSizeTwoWords = (deviceSize <= I2C_DEVICESIZE_24LC16) ? false : true; - - // Try to guess page size from device size (going by Microchip 24LCXX datasheets here). - if (deviceSize <= I2C_DEVICESIZE_24LC02) // 2Kbit - { - this->_pageSize = 8; - } - else if (deviceSize <= I2C_DEVICESIZE_24LC16) // 16Kbit - { - this->_pageSize = 16; - } - else if(deviceSize <= I2C_DEVICESIZE_24LC64) // 64Kbit - { - this->_pageSize = 32; - } - else if(deviceSize <= I2C_DEVICESIZE_24LC256) // 256Kbit - { - this->_pageSize = 64; - } - else // I2C_DEVICESIZE_24LC512 - { - this->_pageSize = 128; - } } #if defined (ESP8266) || defined(ESP32) bool I2C_eeprom::begin(uint8_t sda, uint8_t scl) { - _wire = &Wire; if ((sda < 255) && (scl < 255)) { _wire->begin(sda, scl); @@ -116,7 +97,6 @@ bool I2C_eeprom::begin(uint8_t sda, uint8_t scl) bool I2C_eeprom::begin() { - _wire = &Wire; _wire->begin(); _lastWrite = 0; return isConnected(); @@ -248,6 +228,18 @@ uint32_t I2C_eeprom::determineSize(const bool debug) } +uint8_t I2C_eeprom::getPageSize(uint32_t deviceSize) +{ + // determine page size from device size - based on Microchip 24LCXX datasheets. + 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; +} + + //////////////////////////////////////////////////////////////////// // // PRIVATE @@ -290,7 +282,7 @@ void I2C_eeprom::_beginTransmission(const uint16_t memoryAddress) } else { - uint8_t addr = 0x50 | ((memoryAddress >> 8) & 0x07); + uint8_t addr = _deviceAddress | ((memoryAddress >> 8) & 0x07); _wire->beginTransmission(addr); } diff --git a/I2C_eeprom.h b/I2C_eeprom.h index b188c8f..38368ae 100644 --- a/I2C_eeprom.h +++ b/I2C_eeprom.h @@ -2,7 +2,7 @@ // // FILE: I2C_eeprom.h // AUTHOR: Rob Tillaart -// VERSION: 1.4.0 +// VERSION: 1.4.1 // PURPOSE: Arduino Library for external I2C EEPROM 24LC256 et al. // URL: https://github.com/RobTillaart/I2C_EEPROM.git // @@ -13,7 +13,7 @@ #include "Wire.h" -#define I2C_EEPROM_VERSION (F("1.4.0")) +#define I2C_EEPROM_VERSION (F("1.4.1")) #define I2C_DEVICESIZE_24LC512 65536 @@ -39,7 +39,7 @@ public: /** * Initializes the EEPROM with a default deviceSize of I2C_DEVICESIZE_24LC256 (32K EEPROM) */ - I2C_eeprom(const uint8_t deviceAddress); + I2C_eeprom(const uint8_t deviceAddress, TwoWire *wire = &Wire); /** * Initializes the EEPROM for the given device address. @@ -48,8 +48,9 @@ public: * * @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 wire Select alternative Wire interface */ - I2C_eeprom(const uint8_t deviceAddress, const uint32_t deviceSize); + 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); @@ -80,6 +81,7 @@ public: uint32_t getDeviceSize() { return _deviceSize; }; uint8_t getPageSize() { return _pageSize; }; + uint8_t getPageSize(uint32_t deviceSize); uint32_t getLastWrite() { return _lastWrite; }; private: diff --git a/README.md b/README.md index 6c00e5c..07c9188 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,13 @@ # I2C_EEPROM -Arduino Library for external I2C EEPROM - 24LC256, 24LC64 +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. + The **I2C_eeprom_cyclic_store** interface is documented [here](README_cyclic_store.md) @@ -18,26 +20,28 @@ The **I2C_eeprom_cyclic_store** interface is documented [here](README_cyclic_sto ### Constructor -- **I2C_eeprom(deviceAddress)** 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(sda, scl)** idem for ESP32 / ESP8266 and alike. +- **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. ### Core functions -- **int writeByte(memoryAddress, value)** write a single byte to the specified memory address. -- **int writeBlock(memoryAddress, buffer, length)** write a buffer starting at the specified memory address. -- **int setBlock(memoryAddress, value, length)** writes the same byte to length places starting at the specified memory address. Returns 0 if OK. -- **uint8_t readByte(memoryAddress)** read a single byte from a given address -- **uint16_t readBlock(memoryAddress, buffer, length)** read length bytes into buffer starting at specified memory address. Returns the number of bytes read, which should be length. -- **int updateByte(memoryAddress, value)** write a single byte, but only if changed. Returns 0 if value was same or write succeeded. +- **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 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. ### 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. @@ -48,21 +52,21 @@ The debug flag gives some output to Serial. Testresults -| returns | Type | Memory | Page Size | Notes | +| Type | returns | Memory | Page Size | Notes | |:--------|:--------|:---------|:-----:|:------| -| 0 | - | | | connect error, check device address / wiring | -| 65536 | 24LC512 | 64 KB | 128 | | -| 32768 | 24LC256 | 32 KB | 64 | | -| 16384 | 24LC128 | 16 KB | 64 | | -| 8192 | 24LC64 | 8 KB | 32 | | -| 4096 | 24LC32 | 4 KB | 32 | not tested with hardware | -| 2048 | 24LC16 | 2 KB | 16 | | -| 1024 | 24LC08 | 1 KB | 16 | | -| 512 | 24LC04 | 512 b | 16 | | -| 256 | 24LC02 | 256 b | 8 | | -| 128 | 24LC01 | 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 (yet). +The function cannot detect smaller than 128 bit EEPROMS. ## Limitation @@ -70,15 +74,12 @@ The function cannot detect smaller than 128 bit EEPROMS (yet). The library does not offer multiple EEPROMS as one continuous storage device. - ## Future -- look into support of > 64KB EEPROM - improve error handling, write functions should return bytes written or so. - what can we do with the print interface? (investigate) -- Wire0 .. WireN support - investigate multi-EEPROM storage, -- investigate format / clear all function. + ## Operational diff --git a/examples/I2C_eeprom_determineSize/I2C_eeprom_determineSize.ino b/examples/I2C_eeprom_determineSize/I2C_eeprom_determineSize.ino index 6fdc2fe..ed8ff21 100644 --- a/examples/I2C_eeprom_determineSize/I2C_eeprom_determineSize.ino +++ b/examples/I2C_eeprom_determineSize/I2C_eeprom_determineSize.ino @@ -54,6 +54,11 @@ void setup() Serial.println(" bytes."); } + Serial.print("PAGE: "); + uint8_t pageSize = ee.getPageSize(size); + Serial.print(pageSize); + Serial.println(" bytes."); + Serial.println("Done..."); } diff --git a/examples/I2C_eeprom_test/I2C_eeprom_test.ino b/examples/I2C_eeprom_test/I2C_eeprom_test.ino index 0f77d84..8d1712f 100644 --- a/examples/I2C_eeprom_test/I2C_eeprom_test.ino +++ b/examples/I2C_eeprom_test/I2C_eeprom_test.ino @@ -5,6 +5,7 @@ // // uses a 24LC256 (32KB) EEPROM +// might need adaptions for other EEPROMS (page size etc) #include "Wire.h" #include "I2C_eeprom.h" @@ -48,7 +49,7 @@ void setup() { SERIAL_OUT.print("SIZE: "); SERIAL_OUT.print(size); - SERIAL_OUT.println(" KB"); + SERIAL_OUT.println(" Bytes"); } else if (size == 0) { SERIAL_OUT.println("WARNING: Can't determine eeprom size"); diff --git a/keywords.txt b/keywords.txt index ab670ac..6c99a77 100644 --- a/keywords.txt +++ b/keywords.txt @@ -1,14 +1,17 @@ # Syntax Coloring Map For I2C_EEPROM + # Datatypes (KEYWORD1) I2C_eeprom KEYWORD1 I2C_eeprom_cyclic_store KEYWORD1 + # Methods and Functions (KEYWORD2) # Common begin KEYWORD2 isConnected KEYWORD2 + # I2C_eeprom readByte KEYWORD2 writeByte KEYWORD2 @@ -17,6 +20,11 @@ readBlock KEYWORD2 writeBlock KEYWORD2 determineSize KEYWORD2 updateByte KEYWORD2 +getDeviceSize KEYWORD2 +getPageSize KEYWORD2 +getLastWrite KEYWORD2 + + # I2C_eeprom_cyclic_store format KEYWORD2 read KEYWORD2 diff --git a/library.json b/library.json index 0d9e1d0..dbecba2 100644 --- a/library.json +++ b/library.json @@ -15,7 +15,7 @@ "type": "git", "url": "https://github.com/RobTillaart/I2C_EEPROM.git" }, - "version":"1.4.0", + "version":"1.4.1", "frameworks": "arduino", "platforms": "*" } diff --git a/library.properties b/library.properties index be9a54a..e83cdff 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=I2C_EEPROM -version=1.4.0 +version=1.4.1 author=Rob Tillaart maintainer=Rob Tillaart sentence=Library for I2C EEPROMS