Skip to content

Commit 773a1fd

Browse files
committed
Merge pull request RobTillaart#7 from odbol/master
Updated I2C_EEPROM lib for Arduino Due, added support for smaller EEPROM chips
2 parents 2f60754 + 511d613 commit 773a1fd

File tree

4 files changed

+283
-82
lines changed

4 files changed

+283
-82
lines changed

libraries/I2C_EEPROM/I2C_eeprom.cpp

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,57 @@
2626

2727
#include <I2C_eeprom.h>
2828

29+
#if defined(ARDUINO) && ARDUINO >= 100
30+
#define WIRE_WRITE Wire.write
31+
#else
32+
#define WIRE_WRITE Wire.send
33+
#endif
34+
35+
2936
I2C_eeprom::I2C_eeprom(uint8_t device)
3037
{
3138
_deviceAddress = device;
39+
isAddressSizeTwoWords = true;
40+
this->pageSize = I2C_EEPROM_PAGESIZE;
41+
}
42+
43+
I2C_eeprom::I2C_eeprom(uint8_t device, unsigned int deviceSize) {
44+
_deviceAddress = device;
45+
46+
// Chips 16Kbit (2048KB) or smaller only have one-word addresses.
47+
// Also try to guess page size from device size (going by Microchip 24LCXX datasheets here).
48+
if (deviceSize > 256 * 8) {
49+
this->isAddressSizeTwoWords = true;
50+
this->pageSize = 32;
51+
}
52+
else {
53+
this->isAddressSizeTwoWords = false;
54+
55+
if (deviceSize <= 256) {
56+
this->pageSize = 8;
57+
}
58+
else {
59+
this->pageSize = 16;
60+
}
61+
}
3262
}
3363

3464
void I2C_eeprom::begin()
3565
{
3666
Wire.begin();
3767
_lastWrite = 0;
68+
69+
// TWBR is not available on Arduino Due
70+
#ifdef TWBR
3871
TWBR = 72;
3972
// 0=1000 1=888 2=800 8=500
4073
// 12=400KHz 24=250 32=200 72=100 152=50
4174
// F_CPU/16+(2*TWBR) // TWBR is a uint8_t
75+
#endif
4276
}
4377

78+
79+
4480
int I2C_eeprom::writeByte(uint16_t address, uint8_t data)
4581
{
4682
int rv = _WriteBlock(address, &data, 1);
@@ -136,7 +172,7 @@ int I2C_eeprom::_pageBlock(uint16_t address, uint8_t* buffer, uint16_t length, b
136172
int rv = 0;
137173
while (length > 0)
138174
{
139-
uint8_t bytesUntilPageBoundary = I2C_EEPROM_PAGESIZE - address % I2C_EEPROM_PAGESIZE;
175+
uint8_t bytesUntilPageBoundary = this->pageSize - address % this->pageSize;
140176
uint8_t cnt = min(length, bytesUntilPageBoundary);
141177
cnt = min(cnt, I2C_TWIBUFFERSIZE);
142178

@@ -150,22 +186,27 @@ int I2C_eeprom::_pageBlock(uint16_t address, uint8_t* buffer, uint16_t length, b
150186
return rv;
151187
}
152188

153-
// pre: length <= I2C_EEPROM_PAGESIZE && length <= I2C_TWIBUFFERSIZE;
189+
190+
void I2C_eeprom::_beginTransmission(uint16_t eeaddress){
191+
Wire.beginTransmission(_deviceAddress);
192+
193+
if (this->isAddressSizeTwoWords) {
194+
WIRE_WRITE((eeaddress >> 8)); // Address High Byte
195+
}
196+
197+
WIRE_WRITE((eeaddress & 0xFF)); // Address Low Byte (or only byte for chips 16K or smaller that only have one-word addresses)
198+
}
199+
200+
// pre: length <= this->pageSize && length <= I2C_TWIBUFFERSIZE;
154201
// returns 0 = OK otherwise error
155202
int I2C_eeprom::_WriteBlock(uint16_t address, uint8_t* buffer, uint8_t length)
156203
{
157204
waitEEReady();
158205

159-
Wire.beginTransmission(_deviceAddress);
160-
#if defined(ARDUINO) && ARDUINO >= 100
161-
Wire.write(address >> 8);
162-
Wire.write(address & 0xFF);
163-
Wire.write(buffer, length);
164-
#else
165-
Wire.send(address >> 8);
166-
Wire.send(address & 0xFF);
167-
Wire.send(buffer, length);
168-
#endif
206+
this->_beginTransmission(address);
207+
208+
WIRE_WRITE(buffer, length);
209+
169210
int rv = Wire.endTransmission();
170211
_lastWrite = micros();
171212
return rv;
@@ -177,14 +218,8 @@ uint8_t I2C_eeprom::_ReadBlock(uint16_t address, uint8_t* buffer, uint8_t length
177218
{
178219
waitEEReady();
179220

180-
Wire.beginTransmission(_deviceAddress);
181-
#if defined(ARDUINO) && ARDUINO >= 100
182-
Wire.write(address >> 8);
183-
Wire.write(address & 0xFF);
184-
#else
185-
Wire.send(address >> 8);
186-
Wire.send(address & 0xFF);
187-
#endif
221+
this->_beginTransmission(address);
222+
188223
int rv = Wire.endTransmission();
189224
if (rv != 0) return 0; // error
190225

libraries/I2C_EEPROM/I2C_eeprom.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#define I2C_EEPROM_VERSION "1.1.00"
2525

26+
// The DEFAULT page size. This is overriden if you use the second constructor.
2627
// I2C_EEPROM_PAGESIZE must be multiple of 2 e.g. 16, 32 or 64
2728
// 24LC256 -> 64 bytes
2829
#define I2C_EEPROM_PAGESIZE 64
@@ -40,8 +41,21 @@
4041
class I2C_eeprom
4142
{
4243
public:
44+
/**
45+
* Initializes the EEPROM with a default pagesize of I2C_EEPROM_PAGESIZE.
46+
*/
4347
I2C_eeprom(uint8_t deviceAddress);
4448

49+
/**
50+
* Initializes the EEPROM for the given device address.
51+
*
52+
* It will try to guess page size and address word size based on the size of the device.
53+
*
54+
* @param deviceAddress Byte address of the device.
55+
* @param deviceSize Max size in bytes of the device (divide your device size in Kbits by 8)
56+
*/
57+
I2C_eeprom(uint8_t deviceAddress, unsigned int deviceSize);
58+
4559
void begin();
4660
int writeByte(uint16_t address, uint8_t value);
4761
int writeBlock(uint16_t address, uint8_t* buffer, uint16_t length);
@@ -58,6 +72,18 @@ class I2C_eeprom
5872
uint8_t _deviceAddress;
5973
uint32_t _lastWrite; // for waitEEReady
6074

75+
uint8_t pageSize;
76+
77+
// for some smaller chips that use one-word addresses
78+
bool isAddressSizeTwoWords;
79+
80+
/**
81+
* Begins wire transmission and selects the given address to write/read.
82+
*
83+
* @param eeaddress Address to write/read
84+
*/
85+
void _beginTransmission(uint16_t eeaddress);
86+
6187
int _pageBlock(uint16_t address, uint8_t* buffer, uint16_t length, bool incrBuffer);
6288
int _WriteBlock(uint16_t address, uint8_t* buffer, uint8_t length);
6389
uint8_t _ReadBlock(uint16_t address, uint8_t* buffer, uint8_t length);

0 commit comments

Comments
 (0)