+ 1.1.00 breaking interface

+ begin() addded, needs to be called before use - e.g. in setup() -
+ faster block Wire.Write()
+ removed int casting
+ updated and removed comments
+ updated test sketch
This commit is contained in:
Rob Tillaart 2013-12-15 17:00:26 +01:00
parent 0611abf7d3
commit a2547d9f51
3 changed files with 64 additions and 40 deletions

View File

@ -1,8 +1,8 @@
// //
// FILE: I2C_eeprom.cpp // FILE: I2C_eeprom.cpp
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 1.0.05 // VERSION: 1.1.00
// PURPOSE: Simple I2C_eeprom library for Arduino with EEPROM 24LC256 et al. // PURPOSE: I2C_eeprom library for Arduino with EEPROM 24LC256 et al.
// //
// HISTORY: // HISTORY:
// 0.1.00 - 2011-01-21 initial version // 0.1.00 - 2011-01-21 initial version
@ -13,8 +13,13 @@
// 1.0.01 - 2013-11-01 fixed writeBlock bug, refactor // 1.0.01 - 2013-11-01 fixed writeBlock bug, refactor
// 1.0.02 - 2013-11-03 optimize internal buffers, refactor // 1.0.02 - 2013-11-03 optimize internal buffers, refactor
// 1.0.03 - 2013-11-03 refactor 5 millis() write-latency // 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.04 - 2013-11-03 fix bug in readBlock, moved waitEEReady()
// 1.0.05 - 2013-11-06 improved waitEEReady(), added determineSize() // -> 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
// //
// Released to the public domain // Released to the public domain
// //
@ -24,9 +29,16 @@
I2C_eeprom::I2C_eeprom(uint8_t device) I2C_eeprom::I2C_eeprom(uint8_t device)
{ {
_deviceAddress = device; _deviceAddress = device;
}
void I2C_eeprom::begin()
{
Wire.begin(); Wire.begin();
_lastWrite = 0; _lastWrite = 0;
// TWBR = 12; // 12=400Khz 32=200 72=100 152=50 F_CPU/16+(2*TWBR) TWBR = 72;
// 0=1000 1=888 2=800 8=500
// 12=400KHz 24=250 32=200 72=100 152=50
// F_CPU/16+(2*TWBR) // TWBR is a uint8_t
} }
int I2C_eeprom::writeByte(uint16_t address, uint8_t data) int I2C_eeprom::writeByte(uint16_t address, uint8_t data)
@ -40,13 +52,13 @@ int I2C_eeprom::setBlock(uint16_t address, uint8_t data, uint16_t length)
uint8_t buffer[I2C_TWIBUFFERSIZE]; uint8_t buffer[I2C_TWIBUFFERSIZE];
for (uint8_t i =0; i< I2C_TWIBUFFERSIZE; i++) buffer[i] = data; for (uint8_t i =0; i< I2C_TWIBUFFERSIZE; i++) buffer[i] = data;
int rv = _pageBlock(address, buffer, length, false); // todo check return value.. int rv = _pageBlock(address, buffer, length, false);
return rv; return rv;
} }
int I2C_eeprom::writeBlock(uint16_t address, uint8_t* buffer, uint16_t length) int I2C_eeprom::writeBlock(uint16_t address, uint8_t* buffer, uint16_t length)
{ {
int rv = _pageBlock(address, buffer, length, true); // todo check return value.. int rv = _pageBlock(address, buffer, length, true);
return rv; return rv;
} }
@ -57,7 +69,6 @@ uint8_t I2C_eeprom::readByte(uint16_t address)
return rdata; return rdata;
} }
uint16_t I2C_eeprom::readBlock(uint16_t address, uint8_t* buffer, uint16_t length) uint16_t I2C_eeprom::readBlock(uint16_t address, uint8_t* buffer, uint16_t length)
{ {
uint16_t rv = 0; uint16_t rv = 0;
@ -125,11 +136,11 @@ int I2C_eeprom::_pageBlock(uint16_t address, uint8_t* buffer, uint16_t length, b
int rv = 0; int rv = 0;
while (length > 0) while (length > 0)
{ {
uint8_t bytesUntilPageBoundary = I2C_EEPROM_PAGESIZE - address%I2C_EEPROM_PAGESIZE; uint8_t bytesUntilPageBoundary = I2C_EEPROM_PAGESIZE - address % I2C_EEPROM_PAGESIZE;
uint8_t cnt = min(length, bytesUntilPageBoundary); uint8_t cnt = min(length, bytesUntilPageBoundary);
cnt = min(cnt, I2C_TWIBUFFERSIZE); cnt = min(cnt, I2C_TWIBUFFERSIZE);
int rv = _WriteBlock(address, buffer, cnt); // todo check return value.. int rv = _WriteBlock(address, buffer, cnt);
if (rv != 0) return rv; if (rv != 0) return rv;
address += cnt; address += cnt;
@ -147,35 +158,32 @@ int I2C_eeprom::_WriteBlock(uint16_t address, uint8_t* buffer, uint8_t length)
Wire.beginTransmission(_deviceAddress); Wire.beginTransmission(_deviceAddress);
#if defined(ARDUINO) && ARDUINO >= 100 #if defined(ARDUINO) && ARDUINO >= 100
Wire.write((int)(address >> 8)); Wire.write(address >> 8);
Wire.write((int)(address & 0xFF)); Wire.write(address & 0xFF);
for (uint8_t cnt = 0; cnt < length; cnt++) Wire.write(buffer, length);
Wire.write(buffer[cnt]);
#else #else
Wire.send((int)(address >> 8)); Wire.send(address >> 8);
Wire.send((int)(address & 0xFF)); Wire.send(address & 0xFF);
for (uint8_t cnt = 0; cnt < length; cnt++) Wire.send(buffer, length);
Wire.send(buffer[cnt]);
#endif #endif
int rv = Wire.endTransmission(); int rv = Wire.endTransmission();
_lastWrite = micros(); _lastWrite = micros();
return rv; return rv;
} }
// pre: buffer is large enough to hold length bytes // pre: buffer is large enough to hold length bytes
// returns bytes written // returns bytes read
uint8_t I2C_eeprom::_ReadBlock(uint16_t address, uint8_t* buffer, uint8_t length) uint8_t I2C_eeprom::_ReadBlock(uint16_t address, uint8_t* buffer, uint8_t length)
{ {
waitEEReady(); waitEEReady();
Wire.beginTransmission(_deviceAddress); Wire.beginTransmission(_deviceAddress);
#if defined(ARDUINO) && ARDUINO >= 100 #if defined(ARDUINO) && ARDUINO >= 100
Wire.write((int)(address >> 8)); Wire.write(address >> 8);
Wire.write((int)(address & 0xFF)); Wire.write(address & 0xFF);
#else #else
Wire.send((int)(address >> 8)); Wire.send(address >> 8);
Wire.send((int)(address & 0xFF)); Wire.send(address & 0xFF);
#endif #endif
int rv = Wire.endTransmission(); int rv = Wire.endTransmission();
if (rv != 0) return 0; // error if (rv != 0) return 0; // error
@ -199,7 +207,7 @@ void I2C_eeprom::waitEEReady()
#define I2C_WRITEDELAY 5000 #define I2C_WRITEDELAY 5000
// Wait until EEPROM gives ACK again. // Wait until EEPROM gives ACK again.
// this is a bit faster than the hardcoded 5 milli // this is a bit faster than the hardcoded 5 milliSeconds
while ((micros() - _lastWrite) <= I2C_WRITEDELAY) while ((micros() - _lastWrite) <= I2C_WRITEDELAY)
{ {
Wire.beginTransmission(_deviceAddress); Wire.beginTransmission(_deviceAddress);
@ -208,6 +216,4 @@ void I2C_eeprom::waitEEReady()
} }
} }
// // END OF FILE
// END OF FILE
//

View File

@ -3,8 +3,8 @@
// //
// FILE: I2C_eeprom.h // FILE: I2C_eeprom.h
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// PURPOSE: Simple I2C_eeprom library for Arduino with EEPROM 24LC256 et al. // PURPOSE: I2C_eeprom library for Arduino with EEPROM 24LC256 et al.
// VERSION: 1.0.05 // VERSION: 1.1.00
// HISTORY: See I2C_eeprom.cpp // HISTORY: See I2C_eeprom.cpp
// URL: http://arduino.cc/playground/Main/LibraryForI2CEEPROM // URL: http://arduino.cc/playground/Main/LibraryForI2CEEPROM
// //
@ -21,16 +21,17 @@
#include "Wiring.h" #include "Wiring.h"
#endif #endif
#define I2C_EEPROM_VERSION "1.0.05" #define I2C_EEPROM_VERSION "1.1.00"
// I2C_EEPROM_PAGESIZE must be multiple of 2 e.g. 16, 32 or 64 // I2C_EEPROM_PAGESIZE must be multiple of 2 e.g. 16, 32 or 64
// 24LC256 -> 64 bytes // 24LC256 -> 64 bytes
#define I2C_EEPROM_PAGESIZE 64 #define I2C_EEPROM_PAGESIZE 64
// TWI buffer needs max 2 bytes for address // TWI buffer needs max 2 bytes for eeprom address
// 1 byte for eeprom register address is available in txbuffer
#define I2C_TWIBUFFERSIZE 30 #define I2C_TWIBUFFERSIZE 30
// to break blocking read/write // to break blocking read/write after n millis()
#define I2C_EEPROM_TIMEOUT 1000 #define I2C_EEPROM_TIMEOUT 1000
// comment next line to keep lib small // comment next line to keep lib small
@ -41,6 +42,7 @@ class I2C_eeprom
public: public:
I2C_eeprom(uint8_t deviceAddress); I2C_eeprom(uint8_t deviceAddress);
void begin();
int writeByte(uint16_t address, uint8_t value); int writeByte(uint16_t address, uint8_t value);
int writeBlock(uint16_t address, uint8_t* buffer, uint16_t length); int writeBlock(uint16_t address, uint8_t* buffer, uint16_t length);
int setBlock(uint16_t address, uint8_t value, uint16_t length); int setBlock(uint16_t address, uint8_t value, uint16_t length);

View File

@ -1,7 +1,7 @@
// //
// FILE: I2C_eeprom_test.ino // FILE: I2C_eeprom_test.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.1.05 // VERSION: 0.1.06
// PURPOSE: show/test I2C_EEPROM library // PURPOSE: show/test I2C_EEPROM library
// //
@ -10,8 +10,12 @@
I2C_eeprom ee(0x50); I2C_eeprom ee(0x50);
uint32_t totals = 0;
void setup() void setup()
{ {
ee.begin();
Serial.begin(115200); Serial.begin(115200);
Serial.print("Demo I2C eeprom library "); Serial.print("Demo I2C eeprom library ");
Serial.print(I2C_EEPROM_VERSION); Serial.print(I2C_EEPROM_VERSION);
@ -69,12 +73,14 @@ void setup()
Serial.println(TWBR); Serial.println(TWBR);
Serial.println(); Serial.println();
totals = 0;
Serial.print("\nTEST: timing writeByte()\t"); Serial.print("\nTEST: timing writeByte()\t");
uint32_t start = micros(); uint32_t start = micros();
ee.writeByte(10, 1); ee.writeByte(10, 1);
uint32_t diff = micros() - start; uint32_t diff = micros() - start;
Serial.print("TIME: "); Serial.print("TIME: ");
Serial.println(diff); Serial.println(diff);
totals += diff;
Serial.print("TEST: timing writeBlock(50)\t"); Serial.print("TEST: timing writeBlock(50)\t");
start = micros(); start = micros();
@ -82,6 +88,7 @@ void setup()
diff = micros() - start; diff = micros() - start;
Serial.print("TIME: "); Serial.print("TIME: ");
Serial.println(diff); Serial.println(diff);
totals += diff;
Serial.print("TEST: timing readByte()\t\t"); Serial.print("TEST: timing readByte()\t\t");
start = micros(); start = micros();
@ -89,6 +96,7 @@ void setup()
diff = micros() - start; diff = micros() - start;
Serial.print("TIME: "); Serial.print("TIME: ");
Serial.println(diff); Serial.println(diff);
totals += diff;
Serial.print("TEST: timing readBlock(50)\t"); Serial.print("TEST: timing readBlock(50)\t");
start = micros(); start = micros();
@ -96,6 +104,11 @@ void setup()
diff = micros() - start; diff = micros() - start;
Serial.print("TIME: "); Serial.print("TIME: ");
Serial.println(diff); Serial.println(diff);
totals += diff;
Serial.print("TOTALS: ");
Serial.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); delay(5);
@ -106,6 +119,7 @@ void setup()
diff = micros() - start; diff = micros() - start;
Serial.print("TIME: "); Serial.print("TIME: ");
Serial.println(diff); Serial.println(diff);
totals += diff;
delay(5); delay(5);
@ -115,6 +129,7 @@ void setup()
diff = micros() - start; diff = micros() - start;
Serial.print("TIME: "); Serial.print("TIME: ");
Serial.println(diff); Serial.println(diff);
totals += diff;
delay(5); delay(5);
@ -124,6 +139,7 @@ void setup()
diff = micros() - start; diff = micros() - start;
Serial.print("TIME: "); Serial.print("TIME: ");
Serial.println(diff); Serial.println(diff);
totals += diff;
delay(5); delay(5);
@ -133,11 +149,15 @@ void setup()
diff = micros() - start; diff = micros() - start;
Serial.print("TIME: "); Serial.print("TIME: ");
Serial.println(diff); Serial.println(diff);
totals += diff;
Serial.print("TOTALS: ");
Serial.println(totals);
totals = 0;
// does it go well? // does it go well?
Serial.println(xx); Serial.println(xx);
Serial.println("\nTEST: determine size"); Serial.println("\nTEST: determine size");
start = micros(); start = micros();
int size = ee.determineSize(); int size = ee.determineSize();
@ -147,18 +167,14 @@ void setup()
Serial.print("SIZE: "); Serial.print("SIZE: ");
Serial.print(size); Serial.print(size);
Serial.println(" KB"); Serial.println(" KB");
Serial.println("\tDone..."); Serial.println("\tDone...");
} }
void loop() void loop()
{ {
} }
void dumpEEPROM(uint16_t addr, uint16_t length) void dumpEEPROM(uint16_t addr, uint16_t length)
{ {
// block to 10 // block to 10