mirror of
https://github.com/RobTillaart/I2C_EEPROM.git
synced 2026-07-27 20:06:07 +00:00
1.3.0 release
This commit is contained in:
+264
@@ -0,0 +1,264 @@
|
||||
//
|
||||
// FILE: I2C_eeprom.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 1.3.0
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include <I2C_eeprom.h>
|
||||
|
||||
|
||||
I2C_eeprom::I2C_eeprom(const uint8_t deviceAddress)
|
||||
{
|
||||
I2C_eeprom(deviceAddress, I2C_EEPROM_PAGESIZE);
|
||||
}
|
||||
|
||||
I2C_eeprom::I2C_eeprom(const uint8_t deviceAddress, const unsigned int deviceSize)
|
||||
{
|
||||
_deviceAddress = deviceAddress;
|
||||
|
||||
// Chips 16Kbit (2048 Bytes) or smaller only have one-word addresses.
|
||||
// Also try to guess page size from device size (going by Microchip 24LCXX datasheets here).
|
||||
if (deviceSize <= 256)
|
||||
{
|
||||
this->_isAddressSizeTwoWords = false;
|
||||
this->_pageSize = 8;
|
||||
}
|
||||
else if (deviceSize <= 256 * 8)
|
||||
{
|
||||
this->_isAddressSizeTwoWords = false;
|
||||
this->_pageSize = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->_isAddressSizeTwoWords = true;
|
||||
this->_pageSize = 32;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (ESP8266) || defined(ESP32)
|
||||
void I2C_eeprom::begin(uint8_t sda, uint8_t scl)
|
||||
{
|
||||
Wire.begin(sda, scl);
|
||||
_lastWrite = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void I2C_eeprom::begin()
|
||||
{
|
||||
Wire.begin();
|
||||
_lastWrite = 0;
|
||||
}
|
||||
|
||||
int I2C_eeprom::writeByte(const uint16_t memoryAddress, const uint8_t data)
|
||||
{
|
||||
int rv = _WriteBlock(memoryAddress, &data, 1);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int I2C_eeprom::setBlock(const uint16_t memoryAddress, const uint8_t data, const uint16_t length)
|
||||
{
|
||||
uint8_t buffer[I2C_TWIBUFFERSIZE];
|
||||
for (uint8_t i = 0; i < I2C_TWIBUFFERSIZE; i++)
|
||||
{
|
||||
buffer[i] = data;
|
||||
}
|
||||
int rv = _pageBlock(memoryAddress, buffer, length, false);
|
||||
return rv;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
uint8_t I2C_eeprom::readByte(const uint16_t memoryAddress)
|
||||
{
|
||||
uint8_t rdata;
|
||||
_ReadBlock(memoryAddress, &rdata, 1);
|
||||
return rdata;
|
||||
}
|
||||
|
||||
uint16_t I2C_eeprom::readBlock(const uint16_t memoryAddress, uint8_t* buffer, const uint16_t length)
|
||||
{
|
||||
uint16_t addr = memoryAddress;
|
||||
uint16_t len = length;
|
||||
uint16_t rv = 0;
|
||||
while (len > 0)
|
||||
{
|
||||
uint8_t cnt = I2C_TWIBUFFERSIZE;
|
||||
if (cnt > len) cnt = len;
|
||||
rv += _ReadBlock(addr, buffer, cnt);
|
||||
addr += cnt;
|
||||
buffer += cnt;
|
||||
len -= cnt;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// returns 64, 32, 16, 8, 4, 2, 1, 0
|
||||
// 0 is smaller than 1K
|
||||
int I2C_eeprom::determineSize()
|
||||
{
|
||||
int rv = 0; // unknown
|
||||
uint8_t orgValues[8];
|
||||
uint16_t addr;
|
||||
|
||||
// try to read a byte to see if connected
|
||||
rv += _ReadBlock(0x00, orgValues, 1);
|
||||
if (rv == 0) return -1;
|
||||
|
||||
// remember old values, non destructive
|
||||
for (uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
addr = (512 << i) + 1;
|
||||
orgValues[i] = readByte(addr);
|
||||
}
|
||||
|
||||
// scan page folding
|
||||
for (uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
rv = i;
|
||||
uint16_t addr1 = (512 << i) + 1;
|
||||
uint16_t addr2 = (512 << (i+1)) + 1;
|
||||
writeByte(addr1, 0xAA);
|
||||
writeByte(addr2, 0x55);
|
||||
if (readByte(addr1) == 0x55) // folded!
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// restore original values
|
||||
for (uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
uint16_t addr = (512 << i) + 1;
|
||||
writeByte(addr, orgValues[i]);
|
||||
}
|
||||
return 0x01 << (rv - 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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)
|
||||
{
|
||||
uint16_t addr = memoryAddress;
|
||||
uint16_t len = length;
|
||||
while (len > 0)
|
||||
{
|
||||
uint8_t bytesUntilPageBoundary = this->_pageSize - addr % this->_pageSize;
|
||||
|
||||
uint8_t cnt = I2C_TWIBUFFERSIZE;
|
||||
if (cnt > len) cnt = len;
|
||||
if (cnt > bytesUntilPageBoundary) cnt = bytesUntilPageBoundary;
|
||||
|
||||
int rv = _WriteBlock(addr, buffer, cnt);
|
||||
if (rv != 0) return rv;
|
||||
|
||||
addr += cnt;
|
||||
if (incrBuffer) buffer += cnt;
|
||||
len -= cnt;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// supports one and 2 bytes addresses
|
||||
void I2C_eeprom::_beginTransmission(const uint16_t memoryAddress)
|
||||
{
|
||||
Wire.beginTransmission(_deviceAddress);
|
||||
|
||||
if (this->_isAddressSizeTwoWords)
|
||||
{
|
||||
// Address High Byte
|
||||
Wire.write((memoryAddress >> 8));
|
||||
}
|
||||
|
||||
// Address Low Byte (or only byte for chips 16K or smaller that only have one-word addresses)
|
||||
Wire.write((memoryAddress & 0xFF));
|
||||
}
|
||||
|
||||
// pre: length <= this->_pageSize && length <= I2C_TWIBUFFERSIZE;
|
||||
// returns 0 = OK otherwise error
|
||||
int I2C_eeprom::_WriteBlock(const uint16_t memoryAddress, const uint8_t* buffer, const uint8_t length)
|
||||
{
|
||||
_waitEEReady();
|
||||
|
||||
this->_beginTransmission(memoryAddress);
|
||||
Wire.write(buffer, length);
|
||||
int rv = Wire.endTransmission();
|
||||
|
||||
_lastWrite = micros();
|
||||
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)
|
||||
{
|
||||
_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)
|
||||
{
|
||||
buffer[cnt++] = Wire.read();
|
||||
}
|
||||
return readBytes;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
Wire.beginTransmission(_deviceAddress);
|
||||
int x = Wire.endTransmission();
|
||||
if (x == 0) return;
|
||||
yield();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
||||
@@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
//
|
||||
// FILE: I2C_eeprom.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 1.3.0
|
||||
// PURPOSE: Arduino Library for external I2C EEPROM 24LC256 et al.
|
||||
// URL: https://github.com/RobTillaart/I2C_EEPROM.git
|
||||
//
|
||||
// HISTORY: See I2C_eeprom.cpp
|
||||
|
||||
|
||||
#include "Wire.h"
|
||||
#include "Arduino.h"
|
||||
|
||||
#define I2C_EEPROM_VERSION "1.3.0"
|
||||
|
||||
// The DEFAULT page size. This is overriden if you use the second constructor.
|
||||
// I2C_EEPROM_PAGESIZE must be multiple of 2 e.g. 16, 32 or 64
|
||||
// 24LC256 -> 64 bytes
|
||||
#define I2C_EEPROM_PAGESIZE 64
|
||||
|
||||
// TWI buffer needs max 2 bytes for eeprom address
|
||||
// 1 byte for eeprom register address is available in txbuffer
|
||||
#define I2C_TWIBUFFERSIZE 30
|
||||
|
||||
class I2C_eeprom
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initializes the EEPROM with a default pagesize of I2C_EEPROM_PAGESIZE.
|
||||
*/
|
||||
I2C_eeprom(const uint8_t deviceAddress);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param deviceAddress Byte address of the device.
|
||||
* @param deviceSize Max size in bytes of the device (divide your device size in Kbits by 8)
|
||||
*/
|
||||
I2C_eeprom(const uint8_t deviceAddress, const unsigned int deviceSize);
|
||||
|
||||
#if defined (ESP8266) || defined(ESP32)
|
||||
void begin(uint8_t sda, uint8_t scl);
|
||||
#endif
|
||||
void begin();
|
||||
|
||||
// writes a byte to memaddr
|
||||
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.
|
||||
int setBlock(const uint16_t memoryAddress, const uint8_t value, const uint16_t length);
|
||||
|
||||
// returns the value stored in memaddr
|
||||
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);
|
||||
|
||||
int determineSize();
|
||||
|
||||
|
||||
private:
|
||||
uint8_t _deviceAddress;
|
||||
uint32_t _lastWrite; // for waitEEReady
|
||||
uint8_t _pageSize;
|
||||
|
||||
// for some smaller chips that use one-word addresses
|
||||
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);
|
||||
|
||||
void _waitEEReady();
|
||||
};
|
||||
|
||||
// -- END OF FILE --
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Rob Tillaart
|
||||
Copyright (c) 2011-2020 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,2 +1,29 @@
|
||||
# I2C_EEPROM
|
||||
Library for I2C EEPROM - 24LC256
|
||||
|
||||
Arduino Library for external I2C EEPROM - 24LC256, 24LC64
|
||||
|
||||
## Description
|
||||
|
||||
Library to access external I2C EEPROM.
|
||||
|
||||
The interface is pretty straightforward
|
||||
|
||||
* readByte - read a single byte from a given address
|
||||
* writeByte
|
||||
* setBlock
|
||||
* readBlock
|
||||
* writeBlock
|
||||
* determineSize
|
||||
|
||||
|
||||
|
||||
## Limitation
|
||||
|
||||
The library does not offer multiple EEPROMS as one
|
||||
continuous storage device.
|
||||
|
||||
|
||||
## Operational
|
||||
|
||||
See examples
|
||||
|
||||
|
||||
@@ -0,0 +1,266 @@
|
||||
//
|
||||
// FILE: I2C_eeprom_test.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.09
|
||||
// PURPOSE: show/test I2C_EEPROM library
|
||||
//
|
||||
|
||||
#include <Wire.h> //I2C library
|
||||
#include <I2C_eeprom.h>
|
||||
|
||||
// UNO
|
||||
#define SERIAL_OUT Serial
|
||||
// Due
|
||||
// #define SERIAL_OUT SerialUSB
|
||||
|
||||
//for decimal display uncomment below two lines
|
||||
#define DISPLAY_DECIMAL
|
||||
#define BLOCK_TO_LENGTH 10
|
||||
|
||||
//for hex display uncomment below two lines
|
||||
//#define DISPLAY_HEX
|
||||
//#define BLOCK_TO_LENGTH 16
|
||||
|
||||
#define MEMORY_SIZE 0x2000 //total bytes can be accessed 24LC64 = 0x2000 (maximum address = 0x1FFF)
|
||||
|
||||
I2C_eeprom ee(0x50, MEMORY_SIZE);
|
||||
|
||||
uint32_t start, diff, totals = 0;
|
||||
|
||||
void setup()
|
||||
{
|
||||
ee.begin();
|
||||
|
||||
SERIAL_OUT.begin(57600);
|
||||
while (!SERIAL_OUT); // wait for SERIAL_OUT port to connect. Needed for Leonardo only
|
||||
|
||||
SERIAL_OUT.print("Demo I2C eeprom library ");
|
||||
SERIAL_OUT.print(I2C_EEPROM_VERSION);
|
||||
SERIAL_OUT.println("\n");
|
||||
|
||||
SERIAL_OUT.println("\nTEST: determine size");
|
||||
start = micros();
|
||||
int size = ee.determineSize();
|
||||
diff = micros() - start;
|
||||
SERIAL_OUT.print("TIME: ");
|
||||
SERIAL_OUT.println(diff);
|
||||
if (size > 0)
|
||||
{
|
||||
SERIAL_OUT.print("SIZE: ");
|
||||
SERIAL_OUT.print(size);
|
||||
SERIAL_OUT.println(" KB");
|
||||
} else if (size == 0)
|
||||
{
|
||||
SERIAL_OUT.println("WARNING: Can't determine eeprom size");
|
||||
}
|
||||
else
|
||||
{
|
||||
SERIAL_OUT.println("ERROR: Can't find eeprom\nstopped...");
|
||||
while(1);
|
||||
}
|
||||
|
||||
SERIAL_OUT.println("\nTEST: 64 byte page boundary writeBlock");
|
||||
ee.setBlock(0, 0, 128);
|
||||
dumpEEPROM(0, 128);
|
||||
char data[] = "11111111111111111111";
|
||||
ee.writeBlock(60, (uint8_t*) data, 10);
|
||||
dumpEEPROM(0, 128);
|
||||
|
||||
|
||||
SERIAL_OUT.println("\nTEST: 64 byte page boundary setBlock");
|
||||
ee.setBlock(0, 0, 128);
|
||||
dumpEEPROM(0, 128);
|
||||
ee.setBlock(60, '1', 10);
|
||||
dumpEEPROM(0, 128);
|
||||
|
||||
|
||||
SERIAL_OUT.println("\nTEST: 64 byte page boundary readBlock");
|
||||
ee.setBlock(0, 0, 128);
|
||||
ee.setBlock(60, '1', 6);
|
||||
dumpEEPROM(0, 128);
|
||||
char ar[100];
|
||||
memset(ar, 0, 100);
|
||||
ee.readBlock(60, (uint8_t*)ar, 10);
|
||||
SERIAL_OUT.println(ar);
|
||||
|
||||
|
||||
SERIAL_OUT.println("\nTEST: write large string readback in small steps");
|
||||
ee.setBlock(0, 0, 128);
|
||||
char data2[] = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999A";
|
||||
ee.writeBlock(10, (uint8_t *) &data2, sizeof(data2));
|
||||
dumpEEPROM(0, 128);
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
if (i % 10 == 0 ) SERIAL_OUT.println();
|
||||
SERIAL_OUT.print(' ');
|
||||
SERIAL_OUT.print(ee.readByte(10+i));
|
||||
}
|
||||
SERIAL_OUT.println();
|
||||
|
||||
|
||||
SERIAL_OUT.println("\nTEST: check almost endofPage writeBlock");
|
||||
ee.setBlock(0, 0, 128);
|
||||
char data3[] = "6666";
|
||||
ee.writeBlock(60, (uint8_t *) &data3, sizeof(data3));
|
||||
dumpEEPROM(0, 128);
|
||||
|
||||
// SERIAL_OUT.println();
|
||||
// SERIAL_OUT.print("\nI2C speed:\t");
|
||||
// SERIAL_OUT.println(16000/(16+2*TWBR));
|
||||
// SERIAL_OUT.print("TWBR:\t");
|
||||
// SERIAL_OUT.println(TWBR);
|
||||
// SERIAL_OUT.println();
|
||||
|
||||
totals = 0;
|
||||
SERIAL_OUT.print("\nTEST: timing writeByte()\t");
|
||||
uint32_t start = micros();
|
||||
ee.writeByte(10, 1);
|
||||
uint32_t diff = micros() - start;
|
||||
SERIAL_OUT.print("TIME: ");
|
||||
SERIAL_OUT.println(diff);
|
||||
totals += diff;
|
||||
|
||||
SERIAL_OUT.print("TEST: timing writeBlock(50)\t");
|
||||
start = micros();
|
||||
ee.writeBlock(10, (uint8_t *) &data2, 50);
|
||||
diff = micros() - start;
|
||||
SERIAL_OUT.print("TIME: ");
|
||||
SERIAL_OUT.println(diff);
|
||||
totals += diff;
|
||||
|
||||
SERIAL_OUT.print("TEST: timing readByte()\t\t");
|
||||
start = micros();
|
||||
ee.readByte(10);
|
||||
diff = micros() - start;
|
||||
SERIAL_OUT.print("TIME: ");
|
||||
SERIAL_OUT.println(diff);
|
||||
totals += diff;
|
||||
|
||||
SERIAL_OUT.print("TEST: timing readBlock(50)\t");
|
||||
start = micros();
|
||||
ee.readBlock(10, (uint8_t *) &data2, 50);
|
||||
diff = micros() - start;
|
||||
SERIAL_OUT.print("TIME: ");
|
||||
SERIAL_OUT.println(diff);
|
||||
totals += diff;
|
||||
|
||||
SERIAL_OUT.print("TOTALS: ");
|
||||
SERIAL_OUT.println(totals);
|
||||
totals = 0;
|
||||
|
||||
// same tests but now with a 5 millisec delay in between.
|
||||
delay(5);
|
||||
|
||||
SERIAL_OUT.print("\nTEST: timing writeByte()\t");
|
||||
start = micros();
|
||||
ee.writeByte(10, 1);
|
||||
diff = micros() - start;
|
||||
SERIAL_OUT.print("TIME: ");
|
||||
SERIAL_OUT.println(diff);
|
||||
totals += diff;
|
||||
|
||||
delay(5);
|
||||
|
||||
SERIAL_OUT.print("TEST: timing writeBlock(50)\t");
|
||||
start = micros();
|
||||
ee.writeBlock(10, (uint8_t *) &data2, 50);
|
||||
diff = micros() - start;
|
||||
SERIAL_OUT.print("TIME: ");
|
||||
SERIAL_OUT.println(diff);
|
||||
totals += diff;
|
||||
|
||||
delay(5);
|
||||
|
||||
SERIAL_OUT.print("TEST: timing readByte()\t\t");
|
||||
start = micros();
|
||||
ee.readByte(10);
|
||||
diff = micros() - start;
|
||||
SERIAL_OUT.print("TIME: ");
|
||||
SERIAL_OUT.println(diff);
|
||||
totals += diff;
|
||||
|
||||
delay(5);
|
||||
|
||||
SERIAL_OUT.print("TEST: timing readBlock(50)\t");
|
||||
start = micros();
|
||||
int xx = ee.readBlock(10, (uint8_t *) &data2, 50);
|
||||
diff = micros() - start;
|
||||
SERIAL_OUT.print("TIME: ");
|
||||
SERIAL_OUT.println(diff);
|
||||
totals += diff;
|
||||
|
||||
SERIAL_OUT.print("TOTALS: ");
|
||||
SERIAL_OUT.println(totals);
|
||||
totals = 0;
|
||||
|
||||
// does it go well?
|
||||
SERIAL_OUT.println(xx);
|
||||
|
||||
SERIAL_OUT.println("\tDone...");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
|
||||
{
|
||||
#ifdef DISPLAY_DECIMAL
|
||||
SERIAL_OUT.print("\t ");
|
||||
#endif
|
||||
#ifdef DISPLAY_HEX
|
||||
SERIAL_OUT.print("\t ");
|
||||
#endif
|
||||
for(int x = 0; x < BLOCK_TO_LENGTH; x++) {
|
||||
if(x != 0) {
|
||||
#ifdef DISPLAY_DECIMAL
|
||||
SERIAL_OUT.print(" ");
|
||||
#endif
|
||||
#ifdef DISPLAY_HEX
|
||||
SERIAL_OUT.print(" ");
|
||||
#endif
|
||||
}
|
||||
#ifdef DISPLAY_DECIMAL
|
||||
SERIAL_OUT.print(x);
|
||||
#endif
|
||||
#ifdef DISPLAY_HEX
|
||||
SERIAL_OUT.print(x,HEX);
|
||||
#endif
|
||||
}
|
||||
SERIAL_OUT.println();
|
||||
|
||||
// block to defined length
|
||||
memoryAddress = memoryAddress / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH;
|
||||
length = (length + BLOCK_TO_LENGTH - 1) / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH;
|
||||
|
||||
byte b = ee.readByte(memoryAddress);
|
||||
for (unsigned int i = 0; i < length; i++)
|
||||
{
|
||||
char buf[6];
|
||||
if (memoryAddress % BLOCK_TO_LENGTH == 0)
|
||||
{
|
||||
if(i != 0) {
|
||||
SERIAL_OUT.println();
|
||||
}
|
||||
#ifdef DISPLAY_DECIMAL
|
||||
sprintf(buf, "%05d", memoryAddress);
|
||||
#endif
|
||||
#ifdef DISPLAY_HEX
|
||||
sprintf(buf, "%04X", memoryAddress);
|
||||
#endif
|
||||
SERIAL_OUT.print(buf);
|
||||
SERIAL_OUT.print(":\t");
|
||||
}
|
||||
#ifdef DISPLAY_DECIMAL
|
||||
sprintf(buf, "%03d", b);
|
||||
#endif
|
||||
#ifdef DISPLAY_HEX
|
||||
sprintf(buf, "%02X", b);
|
||||
#endif
|
||||
SERIAL_OUT.print(buf);
|
||||
b = ee.readByte(++memoryAddress);
|
||||
SERIAL_OUT.print(" ");
|
||||
}
|
||||
SERIAL_OUT.println();
|
||||
}
|
||||
// END OF FILE
|
||||
@@ -0,0 +1,128 @@
|
||||
|
||||
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]
|
||||
@@ -0,0 +1,136 @@
|
||||
//
|
||||
// FILE: I2C_small_eeprom_test.ino
|
||||
// AUTHOR:
|
||||
// VERSION: 0.1.00
|
||||
// PURPOSE: show/test I2C_EEPROM library with small EEPROMS
|
||||
//
|
||||
#include <Wire.h>
|
||||
#include <I2C_eeprom.h>
|
||||
|
||||
|
||||
// it's only 1Kbit!!!
|
||||
#define EE24LC01MAXBYTES 1024/8
|
||||
|
||||
// the address of your EEPROM
|
||||
#define DEVICEADDRESS (0x50)
|
||||
|
||||
#define TEST_ADDR 16
|
||||
|
||||
// this must start on a page boundary!
|
||||
#define TEST_PAGE_ADDR 0
|
||||
#define SHORT_BUFFER_LEN 4
|
||||
|
||||
// this tests multi-page writes
|
||||
#define LONG_BUFFER_LEN 64
|
||||
// make sure it's aligned on a page boundary
|
||||
#define LONG_TEST_PAGE_ADDR (max(16, TEST_PAGE_ADDR + SHORT_BUFFER_LEN))
|
||||
|
||||
|
||||
// this tests multi-page writes that don't start on a boundary
|
||||
#define UNALIGNED_BUFFER_LEN 35
|
||||
#define UNALIGNED_TEST_PAGE_ADDR (LONG_TEST_PAGE_ADDR + LONG_BUFFER_LEN + 5)
|
||||
|
||||
#define SERIAL_DEBUG Serial
|
||||
|
||||
I2C_eeprom eeprom(DEVICEADDRESS, EE24LC01MAXBYTES);
|
||||
|
||||
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("----------------------------------------------");
|
||||
|
||||
byte curval = eeprom.readByte(TEST_ADDR);
|
||||
|
||||
SERIAL_DEBUG.print("last value: ");
|
||||
SERIAL_DEBUG.println(curval);
|
||||
|
||||
|
||||
curval += 1;
|
||||
eeprom.writeByte(TEST_ADDR, curval);
|
||||
|
||||
SERIAL_DEBUG.print("updating to: ");
|
||||
SERIAL_DEBUG.println(curval);
|
||||
delay(10);
|
||||
|
||||
curval = eeprom.readByte(TEST_ADDR);
|
||||
SERIAL_DEBUG.print("new value: ");
|
||||
SERIAL_DEBUG.println(curval);
|
||||
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
// null-terminate for printing!
|
||||
testBuffer[bufferLen] = '\0';
|
||||
|
||||
eeprom.readBlock(pageAddress, testBuffer, bufferLen);
|
||||
|
||||
|
||||
SERIAL_DEBUG.print("last value: ");
|
||||
SERIAL_DEBUG.println((char*)testBuffer);
|
||||
|
||||
for (int i = 0; i < bufferLen; i++) {
|
||||
// use max to init to all AAAA's on first run.
|
||||
testBuffer[i] = max('A', (testBuffer[i] + ((i % 4) + 1) % 'z'));
|
||||
}
|
||||
|
||||
eeprom.writeBlock(pageAddress, testBuffer, bufferLen);
|
||||
|
||||
SERIAL_DEBUG.print("updating to: ");
|
||||
SERIAL_DEBUG.println((char*)testBuffer);
|
||||
delay(10);
|
||||
|
||||
eeprom.readBlock(pageAddress, testBuffer, bufferLen);
|
||||
SERIAL_DEBUG.print("new value: ");
|
||||
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.println("IT IS BEGINNING");
|
||||
SERIAL_DEBUG.println("WAIT FOR IT");
|
||||
|
||||
eeprom.begin();
|
||||
|
||||
readAndWriteVar();
|
||||
|
||||
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("----------------------------------------------");
|
||||
|
||||
readAndWritePage(TEST_PAGE_ADDR, SHORT_BUFFER_LEN);
|
||||
|
||||
|
||||
|
||||
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("----------------------------------------------");
|
||||
|
||||
readAndWritePage(LONG_TEST_PAGE_ADDR, LONG_BUFFER_LEN);
|
||||
|
||||
|
||||
|
||||
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("----------------------------------------------");
|
||||
|
||||
readAndWritePage(UNALIGNED_TEST_PAGE_ADDR, UNALIGNED_BUFFER_LEN);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Nothing to do during loop
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
# Syntax Coloring Map For I2C_EEPROM
|
||||
|
||||
# Datatypes (KEYWORD1)
|
||||
I2C_eeprom KEYWORD1
|
||||
|
||||
# Methods and Functions (KEYWORD2)
|
||||
readByte KEYWORD2
|
||||
writeByte KEYWORD2
|
||||
setBlock KEYWORD2
|
||||
readBlock KEYWORD2
|
||||
writeBlock KEYWORD2
|
||||
determineSize KEYWORD2
|
||||
|
||||
# Constants (LITERAL1)
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "I2C_EEPROM",
|
||||
"keywords": "EEPROM, 24LC256, 24LC64",
|
||||
"description": "Library for I2C EEPROMS.",
|
||||
"authors":
|
||||
[
|
||||
{
|
||||
"name": "Rob Tillaart",
|
||||
"email": "Rob.Tillaart@gmail.com",
|
||||
"maintainer": true
|
||||
}
|
||||
],
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/I2C_EEPROM.git"
|
||||
},
|
||||
"version":"1.3.0",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
name=I2C_EEPROM
|
||||
version=1.3.0
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Library for I2C EEPROMS.
|
||||
paragraph=24LC256 et al
|
||||
category=Data Storage
|
||||
url=https://github.com/RobTillaart/Arduino/tree/master/libraries/
|
||||
architectures=*
|
||||
includes=I2C_eeprom.h
|
||||
depends=
|
||||
Reference in New Issue
Block a user