mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-30 20:09:14 +03:00
добавление mysensors в процессе не рабочая версия
This commit is contained in:
8
lib/MySensors/drivers/extEEPROM/LICENSE.md
Normal file
8
lib/MySensors/drivers/extEEPROM/LICENSE.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Arduino External EEPROM Library v3 #
|
||||
http://github.com/JChristensen/extEEPROM
|
||||
LICENSE file
|
||||
Jack Christensen Jul 2014
|
||||
|
||||

|
||||
## CC BY-SA ##
|
||||
"Arduino External EEPROM Library" by Jack Christensen is licensed under [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/).
|
||||
226
lib/MySensors/drivers/extEEPROM/ReadMe.md
Normal file
226
lib/MySensors/drivers/extEEPROM/ReadMe.md
Normal file
@@ -0,0 +1,226 @@
|
||||
# Arduino External EEPROM Library v3.4 #
|
||||
|
||||
Original library by http://github.com/JChristensen/extEEPROM
|
||||
|
||||
## Introduction ##
|
||||
**Arduino External EEPROM Library**
|
||||
|
||||
This library will work with most I2C serial EEPROM chips between 2k bits and 2048k bits (2M bits) in size. Multiple EEPROMs on the bus are supported as a single address space. I/O across block, page and device boundaries is supported. Certain assumptions are made regarding the EEPROM device addressing. These assumptions should be true for most EEPROMs but there are exceptions, so read the datasheet and know your hardware.
|
||||
|
||||
The library should also work for EEPROMs smaller than 2k bits, assuming that there is only one EEPROM on the bus and also that the user is careful to not exceed the maximum address for the EEPROM.
|
||||
|
||||
The **extEEPROM Library** has been tested with:
|
||||
- Microchip 24AA02E48 (2k bit)
|
||||
- 24xx32 (32k bit, thanks to Richard M)
|
||||
- Microchip 24LC256 (256k bit)
|
||||
- Microchip 24FC1026 (1M bit, thanks to Gabriele B on the Arduino forum)
|
||||
- ST Micro M24M02 (2M bit)
|
||||
- Atmel AT24C256C (32k x 8, thanks to Searobin)
|
||||
|
||||
The **extEEPROM Library** will **NOT** work with Microchip 24xx1025 as its control byte does not conform to the following assumptions.
|
||||
|
||||
**Device addressing assumptions:**
|
||||
- The I2C address sequence consists of a control byte followed by one address byte (for EEPROMs <= 16k bits) or two address bytes (for EEPROMs > 16k bits).
|
||||
- The three least-significant bits in the control byte (excluding the R/W bit) comprise the three most-significant bits for the entire address space, i.e. all chips on the bus. As such, these may be chip-select bits or block-select bits (for individual chips that have an internal block organization), or a combination of both (in which case the block-select bits must be of lesser significance than the chip-select bits).
|
||||
- Regardless of the number of bits needed to address the entire address space, the three most-significant bits always go in the control byte. Depending on EEPROM device size, this may result in one or more of the most significant bits in the I2C address bytes being unused (or "don't care" bits).
|
||||
- An EEPROM contains an integral number of pages.
|
||||
|
||||
Note that the Arduino Wire library has a buffer size of 32 bytes. This limits the size of physical I/Os that can be done to EEPROM. For writes, one or two bytes are used for the address, so writing is therefore limited to 31 or 30 bytes. Because the **extEEPROM Library** will handle I/O across block, page and device boundaries, the only consequence this has for the user is one of efficiency; arbitrarily large blocks of data can be written and read; however, carefully chosen block sizes may reduce the number of physical I/Os needed.
|
||||
|
||||
## Installation ##
|
||||
|
||||
### Install with the Library Manager
|
||||
- For Arduino IDE versions 1.6.2 and up, add library by selecting "Manage Libraries..." from the "Include Library" submenu within the Sketch menu.
|
||||
- The library manager will open and you will find a list of libraries that are already installed or ready for installation. Scroll the list to find **extEEPROM** library and click on it.
|
||||
- Select the version of the library you want to install.
|
||||
- Click on install and wait for the IDE to install the new library. Downloading may take time depending on your connection speed.
|
||||
- Once it has finished, an Installed tag should appear, You can close the library manager.
|
||||
|
||||
### Manual Install
|
||||
- Go to http://github.com/PaoloP74/extEEPROM, click the **Download ZIP** button and save the ZIP file to a convenient location on your PC.
|
||||
- Uncompress the downloaded file. This will result in a folder containing all the files for the library, that has a name that includes the branch name, usually **extEEPROM-master**.
|
||||
- Rename the folder to just **extEEPROM**.
|
||||
- Copy the renamed folder to the Arduino sketchbook\libraries folder.
|
||||
|
||||
## Examples ##
|
||||
The following example sketch is included with the **extEEPROM Library**:
|
||||
- **eepromReadWrite**
|
||||
- **eepromTest:** Writes 32-bit integers to the entire EEPROM address space, starting at address 0 and continuing to the topmost address. These are then read back in and verified; any discrepancies are reported to the serial monitor.
|
||||
- **eepromTest_Wire1**
|
||||
## Usage notes ##
|
||||
The **extEEPROM Library** is designed for use with Arduino version 1.0 or later.
|
||||
|
||||
To use the **extEEPROM Library**, the standard [Arduino Wire library](http://arduino.cc/en/Reference/Wire) must also be included. For brevity, this include is not repeated in the examples below:
|
||||
```c++
|
||||
#include <Wire.h> //http://arduino.cc/en/Reference/Wire (included with Arduino IDE)
|
||||
```
|
||||
## Enumerations ##
|
||||
### eeprom_size_t
|
||||
##### Description
|
||||
EEPROM device size in k-bits. Many manufacturers' EEPROM part numbers are designated in k-bits.
|
||||
##### Values
|
||||
- kbits_2
|
||||
- kbits_4
|
||||
- kbits_8
|
||||
- kbits_16
|
||||
- kbits_32
|
||||
- kbits_64
|
||||
- kbits_128
|
||||
- kbits_256
|
||||
- kbits_512
|
||||
- kbits_1024
|
||||
- kbits_2048
|
||||
### twiClockFreq_t
|
||||
##### Description
|
||||
I2C bus speed.
|
||||
##### Values
|
||||
- extEEPROM::twiClock100kHz
|
||||
- extEEPROM::twiClock400kHz
|
||||
|
||||
## Constructor ##
|
||||
### extEEPROM(eeprom_size_t devCap, byte nDev, unsigned int pgSize, byte busAddr)
|
||||
##### Description
|
||||
Instantiates an external EEPROM object.
|
||||
##### Syntax
|
||||
`extEEPROM myEEPROM(eeprom_size_t devCap, byte nDev, unsigned int pgSize, byte busAddr);`
|
||||
##### Parameters
|
||||
**devCap** *(eeprom_size_t)*: The size of one EEPROM device in k-bits. Choose a value from the eeprom_size_t enumeration above.
|
||||
**nDev** *(byte)*: The number of EEPROM devices on the bus. Note that if there are multiple EEPROM devices on the bus, they must be identical and each must have its address pins strapped properly.
|
||||
**pgSize** *(unsigned int)*: The EEPROM page size in bytes. Consult the datasheet if you are unsure of the page size.
|
||||
**busAddr** *(byte)*: The base I2C bus address for the EEPROM(s). 0x50 is a common value and this parameter can be omitted, in which case 0x50 will be used as the default.
|
||||
##### Example
|
||||
```c++
|
||||
extEEPROM myEEPROM(kbits_256, 2, 64); //two 24LC256 EEPROMS on the bus
|
||||
extEEPROM oddEEPROM(kbits_8, 1, 16, 0x42); //an EEPROM with a non-standard I2C address
|
||||
```
|
||||
|
||||
## Methods ##
|
||||
### begin(twiClockFreq_t freq, TwoWire *_comm)
|
||||
##### Description
|
||||
Initializes the library. Call this method once in the setup code. begin() does a dummy I/O so that the user may interrogate the return status to ensure the EEPROM is operational.
|
||||
##### Syntax
|
||||
`myEEPROM.begin(twiClockFreq_t freq);`
|
||||
or
|
||||
`myEEPROM.begin(twiClockFreq_t freq, TwoWire *_comm);`
|
||||
##### Parameters
|
||||
**freq** *(twiClockFreq_t)*: The desired I2C bus speed, `extEEPROM::twiClock100kHz` or `extEEPROM::twiClock400kHz`. Can be omitted in which case it will default to `twiClock100kHz`.
|
||||
**NOTE:** When using 400kHz, if there are other devices on the bus they must all support a 400kHz bus speed. **Secondly**, the other devices should be initialized first, as other libraries may not support adjusting the bus speed. To ensure the desired speed is set, call the extEEPROM.begin() function *after* initializing all other I2C devices.
|
||||
|
||||
**_comm** *(TwoWire * )*: The Used I2C TwoWire channel . Can be omitted in which case it will default to the first Arduino I2C channel `Wire`. If another of the possible I2C channel is used its pointer shall be passed as parameter.
|
||||
**NOTE:** If another I2C channel is unse, and not the default one, the first parameters **freq** MUST be defined.
|
||||
##### Returns
|
||||
I2C I/O status, zero if successful *(byte)*. See the [Arduino Wire.endTransmission() function](http://arduino.cc/en/Reference/WireEndTransmission) for a description of other return codes.
|
||||
|
||||
##### Examples
|
||||
```c++
|
||||
extEEPROM myEEPROM(kbits_256, 2, 64);
|
||||
byte i2cStat = myEEPROM.begin(extEEPROM::twiClock400kHz);
|
||||
if ( i2cStat != 0 ) {
|
||||
//there was a problem
|
||||
}
|
||||
```
|
||||
##### Use of other I2C channel
|
||||
```c++
|
||||
extEEPROM myEEPROM(kbits_256, 2, 64);
|
||||
byte i2cStat = myEEPROM.begin(extEEPROM::twiClock400kHz, &Wire1);
|
||||
if ( i2cStat != 0 ) {
|
||||
//there was a problem
|
||||
}
|
||||
```
|
||||
### write(unsigned long addr, byte *values, unsigned int nBytes)
|
||||
##### Description
|
||||
Write one or more bytes to external EEPROM.
|
||||
##### Syntax
|
||||
`myEEPROM.write(unsigned long addr, byte* values, byte nBytes);`
|
||||
##### Parameters
|
||||
**addr** *(unsigned long)*: The beginning EEPROM location to write.
|
||||
**values** _(byte*)_: Pointer to an array containing the data to write.
|
||||
**nBytes** *(unsigned int)*: The number of bytes to write.
|
||||
##### Returns
|
||||
I2C I/O status, zero if successful *(byte)*. See the [Arduino Wire.endTransmission() function](http://arduino.cc/en/Reference/WireEndTransmission) for a description of other return codes. Returns a status of EEPROM_ADDR_ERR if the I/O would extend past the top of the EEPROM address space.
|
||||
##### Example
|
||||
```c++
|
||||
byte myData[10];
|
||||
//write 10 bytes starting at location 42
|
||||
byte i2cStat = myEEPROM.write(42, &data, 10);
|
||||
if ( i2cStat != 0 ) {
|
||||
//there was a problem
|
||||
if ( i2cStat == EEPROM_ADDR_ERR) {
|
||||
//bad address
|
||||
}
|
||||
else {
|
||||
//some other I2C error
|
||||
}
|
||||
}
|
||||
```
|
||||
### write(unsigned long addr, byte value)
|
||||
##### Description
|
||||
Writes a single byte to external EEPROM.
|
||||
##### Syntax
|
||||
`myEEPROM.write(unsigned long addr, byte value);`
|
||||
##### Parameters
|
||||
**addr** *(unsigned long)*: The EEPROM location to write.
|
||||
**values** _(byte)_: The value to write.
|
||||
##### Returns
|
||||
Same as multiple-byte write() above.
|
||||
##### Example
|
||||
```c++
|
||||
//write the value 16 to EEPROM location 314.
|
||||
byte i2cStat = myEEPROM.write(314, 16);
|
||||
```
|
||||
### read(unsigned long addr, byte *values, unsigned int nBytes)
|
||||
##### Description
|
||||
Reads one or more bytes from external EEPROM into an array supplied by the caller.
|
||||
##### Syntax
|
||||
`myEEPROM.read(unsigned long addr, byte *values, byte nBytes);`
|
||||
##### Parameters
|
||||
**addr** *(unsigned long)*: The beginning EEPROM location to read from.
|
||||
**values** _(byte*)_: Pointer to an array to receive the data.
|
||||
**nBytes** *(unsigned int)*: The number of bytes to read.
|
||||
##### Returns
|
||||
I2C I/O status, zero if successful *(byte)*. See the [Arduino Wire.endTransmission() function](http://arduino.cc/en/Reference/WireEndTransmission) for a description of other return codes. Returns a status of EEPROM_ADDR_ERR if the I/O would extend past the top of the EEPROM address space.
|
||||
##### Example
|
||||
```c++
|
||||
byte myData[10];
|
||||
//read 10 bytes starting at location 42
|
||||
byte i2cStat = myEEPROM.read(42, &data, 10);
|
||||
if ( i2cStat != 0 ) {
|
||||
//there was a problem
|
||||
if ( i2cStat == EEPROM_ADDR_ERR) {
|
||||
//bad address
|
||||
}
|
||||
else {
|
||||
//some other I2C error
|
||||
}
|
||||
}
|
||||
```
|
||||
### read(unsigned long addr)
|
||||
##### Description
|
||||
Reads a single byte from external EEPROM.
|
||||
##### Syntax
|
||||
`myEEPROM.read(unsigned long addr);`
|
||||
##### Parameters
|
||||
**addr** *(unsigned long)*: The EEPROM location to read from.
|
||||
##### Returns
|
||||
The data read from EEPROM or an error code *(int)*. To distinguish error values from valid data, error values are returned as negative numbers. See the [Arduino Wire.endTransmission() function](http://arduino.cc/en/Reference/WireEndTransmission) for a description of return codes. Returns a status of EEPROM_ADDR_ERR if the I/O would extend past the top of the EEPROM address space.
|
||||
##### Example
|
||||
```c++
|
||||
int myData;
|
||||
//read a byte from location 42
|
||||
int readValue = myEEPROM.read(42);
|
||||
if ( readValue < 0 ) {
|
||||
//there was a problem
|
||||
if ( -readValue == EEPROM_ADDR_ERR) {
|
||||
//bad address
|
||||
}
|
||||
else {
|
||||
//some other I2C error
|
||||
}
|
||||
}
|
||||
else {
|
||||
//data read ok
|
||||
}
|
||||
```
|
||||
|
||||
"Arduino External EEPROM Library" by Jack Christensen is licensed under [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/).
|
||||

|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
Copyright (c) 2014 Arduino. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and / or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110 - 1301 USA
|
||||
*/
|
||||
|
||||
#include "extEEPROM.h"
|
||||
|
||||
extEEPROM myEEPROM(kbits_256, 1, 64, 0x57);
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
SerialUSB.begin(115200);
|
||||
while (!SerialUSB) {
|
||||
;
|
||||
}
|
||||
|
||||
byte i2cStat = myEEPROM.begin(myEEPROM.twiClock100kHz);
|
||||
if ( i2cStat != 0 ) {
|
||||
SerialUSB.println(F("I2C Problem"));
|
||||
}
|
||||
|
||||
SerialUSB.println(
|
||||
F("EEPROM Memory commands: read:(a)(l)(r) , write:(a)(d)(w), next read data (n)"));
|
||||
SerialUSB.println(F("- Commands TO PRESS:"));
|
||||
SerialUSB.println(F("\t a : memory address to read / write"));
|
||||
SerialUSB.println(F("\t d : data to write"));
|
||||
SerialUSB.println(F("\t l : data to write"));
|
||||
SerialUSB.println(F("\t r : read command"));
|
||||
SerialUSB.println(F("\t w : write command"));
|
||||
}
|
||||
|
||||
unsigned long address = 0;
|
||||
const unsigned int maxDataSize = 1024; //0x8000; // 32 k bytes (32768 = 0x8000) = 256 kbits
|
||||
|
||||
byte data[maxDataSize] = {'p', 'i', 'p', 'p', 'o'};
|
||||
unsigned int dataSize = 5;
|
||||
|
||||
void eprom_read_write(bool write)
|
||||
{
|
||||
byte i2cStat = 0;
|
||||
if (write) {
|
||||
i2cStat = myEEPROM.write(address, data, dataSize);
|
||||
} else {
|
||||
memset(data, 0, maxDataSize);
|
||||
i2cStat = myEEPROM.read(address, data, dataSize);
|
||||
}
|
||||
if ( i2cStat != 0 ) {
|
||||
//there was a problem
|
||||
SerialUSB.print(F("I2C Problem: "));
|
||||
if ( i2cStat == EEPROM_ADDR_ERR) {
|
||||
SerialUSB.println(F("Wrong address"));
|
||||
} else {
|
||||
SerialUSB.print(F("I2C error: "));
|
||||
SerialUSB.print(i2cStat);
|
||||
SerialUSB.println(F(""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void parse(char inChar)
|
||||
{
|
||||
const char addr_len = 5;
|
||||
char addr_char[addr_len] = "";
|
||||
const char data_len = 3;
|
||||
char data_char[data_len] = "";
|
||||
char size_char[data_len] = "";
|
||||
char inc = 0, i = 0, j = 0;
|
||||
|
||||
switch (inChar) {
|
||||
case 'a':
|
||||
SerialUSB.print(F("Insert Address as 4 Hex chars (without '0x'): "));
|
||||
|
||||
while (i < 4) {
|
||||
while (SerialUSB.available() <= 0)
|
||||
;
|
||||
inc = SerialUSB.read();
|
||||
|
||||
if (inc == 'q') {
|
||||
return;
|
||||
}
|
||||
|
||||
addr_char[i] = inc;
|
||||
++i;
|
||||
}
|
||||
address = (unsigned long)strtol(addr_char, NULL, 16);
|
||||
SerialUSB.println(address);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
SerialUSB.print(F("Insert Hex data sequence (without '0x'), return to enter: "));
|
||||
memset(data, 0, maxDataSize);
|
||||
while (true) {
|
||||
while (SerialUSB.available() <= 0)
|
||||
;
|
||||
inc = SerialUSB.read();
|
||||
if (inc == 'q') {
|
||||
return;
|
||||
}
|
||||
if (inc == '\r' || inc == '\n') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (inc >= 'a' && inc <= 'f') {
|
||||
data[j] += inc - 'a' + 10;
|
||||
} else if (inc >= 'A' && inc <= 'F') {
|
||||
data[j] += inc - 'A' + 10;
|
||||
} else if (inc >= '0' && inc <= '9') {
|
||||
data[j] += inc - '0';
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (i % 2) {
|
||||
j++;
|
||||
} else {
|
||||
data[j] = data[j] << 4;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
dataSize = j;
|
||||
SerialUSB.println(dataSize);
|
||||
SerialUSB.println(F(""));
|
||||
break;
|
||||
case 'l':
|
||||
SerialUSB.print(F("Insert data len as 2 Hex chars (without '0x'): "));
|
||||
while (i < 2) {
|
||||
while (SerialUSB.available() <= 0)
|
||||
;
|
||||
inc = SerialUSB.read();
|
||||
if (inc == 'q') {
|
||||
return;
|
||||
}
|
||||
|
||||
size_char[i] = inc;
|
||||
++i;
|
||||
if (inc == '\n') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dataSize = (unsigned int)strtol(size_char, NULL, 16);
|
||||
SerialUSB.println(dataSize);
|
||||
break;
|
||||
|
||||
|
||||
case 'n':
|
||||
address += dataSize;
|
||||
/* FALLTHROUGH */
|
||||
case 'r':
|
||||
SerialUSB.print(F("reading address: "));
|
||||
SerialUSB.println(address, HEX);
|
||||
|
||||
eprom_read_write(false);
|
||||
for (i = 0; i < dataSize ; ++i) {
|
||||
SerialUSB.print(data[i], HEX);
|
||||
SerialUSB.print(F(" "));
|
||||
}
|
||||
SerialUSB.println();
|
||||
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
SerialUSB.print(F("writing at address: "));
|
||||
SerialUSB.print(address, HEX);
|
||||
SerialUSB.print(F(", len: "));
|
||||
SerialUSB.println(address, dataSize);
|
||||
for (i = 0; i < dataSize ; ++i) {
|
||||
SerialUSB.print(data[i], HEX);
|
||||
SerialUSB.print(F(" "));
|
||||
}
|
||||
eprom_read_write(true);
|
||||
SerialUSB.println();
|
||||
|
||||
break;
|
||||
case 'T':
|
||||
SerialUSB.println(F("Memory test: writing and verifying the whole memory"));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
if (SerialUSB.available() > 0) {
|
||||
char inChar = SerialUSB.read();
|
||||
SerialUSB.print(inChar);
|
||||
parse(inChar);
|
||||
}
|
||||
|
||||
delay(10);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
//Test extEEPROM library.
|
||||
//Writes the EEPROM full of 32-bit integers and reads them back to verify.
|
||||
//Wire a button from digital pin 6 to ground, this is used as a start button
|
||||
//so the sketch doesn't do unnecessary EEPROM writes every time it's reset.
|
||||
//Jack Christensen 09Jul2014
|
||||
//Paolo Paolucci 17Mar2016 (fix 28Jun2017)
|
||||
|
||||
#include <extEEPROM.h> //https://github.com/PaoloP74/extEEPROM
|
||||
|
||||
//One 24LC256 EEPROMs on the bus
|
||||
const uint32_t totalKBytes = 32; //for read and write test functions
|
||||
extEEPROM eep(kbits_256, 1, 64); //device size, number of devices, page size
|
||||
|
||||
const uint8_t btnStart = 6; //start button
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
pinMode(btnStart, INPUT_PULLUP);
|
||||
Serial.begin(115200);
|
||||
uint8_t eepStatus = eep.begin(eep.twiClock400kHz); //go fast!
|
||||
if (eepStatus) {
|
||||
Serial.print(F("extEEPROM.begin() failed, status = "));
|
||||
Serial.println(eepStatus);
|
||||
while (1);
|
||||
}
|
||||
|
||||
Serial.println(F("Press button to start..."));
|
||||
while (digitalRead(btnStart) == HIGH) {
|
||||
delay(10); //wait for button push
|
||||
}
|
||||
|
||||
uint8_t chunkSize =
|
||||
64; //this can be changed, but must be a multiple of 4 since we're writing 32-bit integers
|
||||
// eeErase(chunkSize, 0, totalKBytes * 1024 - 1);
|
||||
eeWrite(chunkSize);
|
||||
eeRead(chunkSize);
|
||||
|
||||
dump(0, 32); //the first 32 bytes
|
||||
dump(32256, 64); //the last 64 bytes
|
||||
//dump(32512, 64); //across the device boundary
|
||||
//dump(65520, 16); //the last 16 bytes
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
}
|
||||
|
||||
//write test data (32-bit integers) to eeprom, "chunk" bytes at a time
|
||||
void eeWrite(uint8_t chunk)
|
||||
{
|
||||
chunk &= 0xFC; //force chunk to be a multiple of 4
|
||||
uint8_t data[chunk];
|
||||
uint32_t val = 0;
|
||||
Serial.println(F("Writing..."));
|
||||
uint32_t msStart = millis();
|
||||
|
||||
for (uint32_t addr = 0; addr < totalKBytes * 1024; addr += chunk) {
|
||||
if ( (addr & 0xFFF) == 0 ) {
|
||||
Serial.println(addr);
|
||||
}
|
||||
for (uint8_t c = 0; c < chunk; c += 4) {
|
||||
data[c + 0] = val >> 24;
|
||||
data[c + 1] = val >> 16;
|
||||
data[c + 2] = val >> 8;
|
||||
data[c + 3] = val;
|
||||
++val;
|
||||
}
|
||||
eep.write(addr, data, chunk);
|
||||
}
|
||||
uint32_t msLapse = millis() - msStart;
|
||||
Serial.print(F("Write lapse: "));
|
||||
Serial.print(msLapse);
|
||||
Serial.println(F(" ms"));
|
||||
}
|
||||
|
||||
//read test data (32-bit integers) from eeprom, "chunk" bytes at a time
|
||||
void eeRead(uint8_t chunk)
|
||||
{
|
||||
chunk &= 0xFC; //force chunk to be a multiple of 4
|
||||
uint8_t data[chunk];
|
||||
uint32_t val = 0, testVal;
|
||||
Serial.println(F("Reading..."));
|
||||
uint32_t msStart = millis();
|
||||
|
||||
for (uint32_t addr = 0; addr < totalKBytes * 1024; addr += chunk) {
|
||||
if ( (addr & 0xFFF) == 0 ) {
|
||||
Serial.println(addr);
|
||||
}
|
||||
eep.read(addr, data, chunk);
|
||||
for (uint8_t c = 0; c < chunk; c += 4) {
|
||||
testVal = ((uint32_t)data[c + 0] << 24) + ((uint32_t)data[c + 1] << 16) + ((
|
||||
uint32_t)data[c + 2] << 8) + (uint32_t)data[c + 3];
|
||||
if (testVal != val) {
|
||||
Serial.print(F("Error @ addr "));
|
||||
Serial.print(addr + c);
|
||||
Serial.print(F(" Expected "));
|
||||
Serial.print(val);
|
||||
Serial.print(F(" Read "));
|
||||
Serial.print(testVal);
|
||||
Serial.print(F(" 0x"));
|
||||
Serial.println(testVal, HEX);
|
||||
}
|
||||
++val;
|
||||
}
|
||||
}
|
||||
uint32_t msLapse = millis() - msStart;
|
||||
Serial.print(F("Last value: "));
|
||||
Serial.print(val);
|
||||
Serial.print(F(" Read lapse: "));
|
||||
Serial.print(msLapse);
|
||||
Serial.println(F(" ms"));
|
||||
}
|
||||
|
||||
//write 0xFF to eeprom, "chunk" bytes at a time
|
||||
void eeErase(uint8_t chunk, uint32_t startAddr, uint32_t endAddr)
|
||||
{
|
||||
chunk &= 0xFC; //force chunk to be a multiple of 4
|
||||
uint8_t data[chunk];
|
||||
Serial.println(F("Erasing..."));
|
||||
for (int i = 0; i < chunk; i++) {
|
||||
data[i] = 0xFF;
|
||||
}
|
||||
uint32_t msStart = millis();
|
||||
|
||||
for (uint32_t a = startAddr; a <= endAddr; a += chunk) {
|
||||
if ( (a & 0xFFF) == 0 ) {
|
||||
Serial.println(a);
|
||||
}
|
||||
eep.write(a, data, chunk);
|
||||
}
|
||||
uint32_t msLapse = millis() - msStart;
|
||||
Serial.print(F("Erase lapse: "));
|
||||
Serial.print(msLapse);
|
||||
Serial.print(F(" ms"));
|
||||
}
|
||||
|
||||
//dump eeprom contents, 16 bytes at a time.
|
||||
//always dumps a multiple of 16 bytes.
|
||||
void dump(uint32_t startAddr, uint32_t nBytes)
|
||||
{
|
||||
Serial.print(F("EEPROM DUMP 0x"));
|
||||
Serial.print(startAddr, HEX);
|
||||
Serial.print(F(" 0x"));
|
||||
Serial.print(nBytes, HEX);
|
||||
Serial.print(F(" "));
|
||||
Serial.print(startAddr);
|
||||
Serial.print(F(" "));
|
||||
Serial.println(nBytes);
|
||||
uint32_t nRows = (nBytes + 15) >> 4;
|
||||
|
||||
uint8_t d[16];
|
||||
for (uint32_t r = 0; r < nRows; r++) {
|
||||
uint32_t a = startAddr + 16 * r;
|
||||
eep.read(a, d, 16);
|
||||
Serial.print(F("0x"));
|
||||
if ( a < 16 * 16 * 16 ) {
|
||||
Serial.print(F("0"));
|
||||
}
|
||||
if ( a < 16 * 16 ) {
|
||||
Serial.print(F("0"));
|
||||
}
|
||||
if ( a < 16 ) {
|
||||
Serial.print(F("0"));
|
||||
}
|
||||
Serial.print(a, HEX);
|
||||
Serial.print(F(" "));
|
||||
for ( int c = 0; c < 16; c++ ) {
|
||||
if ( d[c] < 16 ) {
|
||||
Serial.print(F("0"));
|
||||
Serial.print(d[c], HEX);
|
||||
Serial.print( c == 7 ? " " : " ");
|
||||
}
|
||||
}
|
||||
Serial.println(F(""));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
//Test extEEPROM library.
|
||||
//Writes the EEPROM full of 32-bit integers and reads them back to verify.
|
||||
//Wire a button from digital pin 6 to ground, this is used as a start button
|
||||
//so the sketch doesn't do unnecessary EEPROM writes every time it's reset.
|
||||
//Jack Christensen 09Jul2014
|
||||
//Paolo Paolucci 17Mar2016 (fix 28Jun2017)
|
||||
//Mik 03Jan2017 (configured Library to use the Wire1 as I2C channel)
|
||||
|
||||
#include <extEEPROM.h> //https://github.com/PaoloP74/extEEPROM
|
||||
|
||||
//One 24LC256 EEPROMs on the bus
|
||||
const uint32_t totalKBytes = 32; //for read and write test functions
|
||||
extEEPROM eep(kbits_256, 1, 64, 0x57); //device size, number of devices, page size
|
||||
|
||||
const uint8_t btnStart = 6; //start button
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
uint8_t eepStatus;
|
||||
pinMode(btnStart, INPUT_PULLUP);
|
||||
Serial.begin(115200);
|
||||
while (!SerialUSB) {}
|
||||
|
||||
bool channelInsert = false;
|
||||
Serial.println(F("Select the number of Wire channel use the eeprom"));
|
||||
Serial.println(F("0 = Wire"));
|
||||
Serial.println(F("1 = Wire1"));
|
||||
Serial.println(F("...."));
|
||||
Serial.println(F("x = WIRE_INTERFACES_COUNT"));
|
||||
|
||||
do {
|
||||
if (Serial.available()) {
|
||||
char I2Cchannel = Serial.read();
|
||||
|
||||
// only number that are less than WIRE_INTERFACES_COUNT are allowed
|
||||
if ((I2Cchannel > '0') && (I2Cchannel < ('0' + WIRE_INTERFACES_COUNT))) {
|
||||
channelInsert = true;
|
||||
}
|
||||
|
||||
switch ((I2Cchannel - '0')) {
|
||||
|
||||
case 0:
|
||||
Serial.println(F("Using the default Wire interface"));
|
||||
eepStatus = eep.begin(eep.twiClock400kHz); //go fast!
|
||||
break;
|
||||
|
||||
case 1:
|
||||
Serial.println(F("Using the Wire1 interface"));
|
||||
eepStatus = eep.begin(eep.twiClock400kHz, &Wire1); //go fast!
|
||||
break;
|
||||
|
||||
/*
|
||||
Uncomment till the number of WIRE_INTERFACES_COUNT of your Arduino board
|
||||
case 2:
|
||||
Serial.println(F("Using the Wire2 interface"));
|
||||
eepStatus = eep.begin(eep.twiClock400kHz, &Wire2); //go fast!
|
||||
break;
|
||||
|
||||
case 3:
|
||||
Serial.println(F("Using the Wire3 interface"));
|
||||
eepStatus = eep.begin(eep.twiClock400kHz, &Wire3); //go fast!
|
||||
break;
|
||||
|
||||
case 4:
|
||||
Serial.println(F("Using the Wire4 interface"));
|
||||
eepStatus = eep.begin(eep.twiClock400kHz, &Wire4); //go fast!
|
||||
break;
|
||||
|
||||
case 5:
|
||||
Serial.println(F("Using the Wire5 interface"));
|
||||
eepStatus = eep.begin(eep.twiClock400kHz, &Wire5); //go fast!
|
||||
break;*/
|
||||
|
||||
default:
|
||||
Serial.println(F("A wrong channel has been inserted (Arduino manage max 5)"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (!channelInsert);
|
||||
|
||||
if (eepStatus) {
|
||||
Serial.print(F("extEEPROM.begin() failed, status = "));
|
||||
Serial.println(eepStatus);
|
||||
while (1);
|
||||
}
|
||||
|
||||
Serial.println(F("Started !!"));
|
||||
|
||||
uint8_t chunkSize =
|
||||
64; //this can be changed, but must be a multiple of 4 since we're writing 32-bit integers
|
||||
// eeErase(chunkSize, 0, totalKBytes * 1024 - 1);
|
||||
eeWrite(chunkSize);
|
||||
eeRead(chunkSize);
|
||||
|
||||
dump(0, 32); //the first 32 bytes
|
||||
dump(32256, 64); //the last 64 bytes
|
||||
//dump(32512, 64); //across the device boundary
|
||||
//dump(65520, 16); //the last 16 bytes
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
}
|
||||
|
||||
//write test data (32-bit integers) to eeprom, "chunk" bytes at a time
|
||||
void eeWrite(uint8_t chunk)
|
||||
{
|
||||
chunk &= 0xFC; //force chunk to be a multiple of 4
|
||||
uint8_t data[chunk];
|
||||
uint32_t val = 0;
|
||||
Serial.println(F("Writing..."));
|
||||
uint32_t msStart = millis();
|
||||
|
||||
for (uint32_t addr = 0; addr < totalKBytes * 1024; addr += chunk) {
|
||||
if ( (addr & 0xFFF) == 0 ) {
|
||||
Serial.println(addr);
|
||||
}
|
||||
for (uint8_t c = 0; c < chunk; c += 4) {
|
||||
data[c + 0] = val >> 24;
|
||||
data[c + 1] = val >> 16;
|
||||
data[c + 2] = val >> 8;
|
||||
data[c + 3] = val;
|
||||
++val;
|
||||
}
|
||||
eep.write(addr, data, chunk);
|
||||
}
|
||||
uint32_t msLapse = millis() - msStart;
|
||||
Serial.print(F("Write lapse: "));
|
||||
Serial.print(msLapse);
|
||||
Serial.println(F(" ms"));
|
||||
}
|
||||
|
||||
//read test data (32-bit integers) from eeprom, "chunk" bytes at a time
|
||||
void eeRead(uint8_t chunk)
|
||||
{
|
||||
chunk &= 0xFC; //force chunk to be a multiple of 4
|
||||
uint8_t data[chunk];
|
||||
uint32_t val = 0, testVal;
|
||||
Serial.println(F("Reading..."));
|
||||
uint32_t msStart = millis();
|
||||
|
||||
for (uint32_t addr = 0; addr < totalKBytes * 1024; addr += chunk) {
|
||||
if ( (addr & 0xFFF) == 0 ) {
|
||||
Serial.println(addr);
|
||||
}
|
||||
eep.read(addr, data, chunk);
|
||||
for (uint8_t c = 0; c < chunk; c += 4) {
|
||||
testVal = ((uint32_t)data[c + 0] << 24) + ((uint32_t)data[c + 1] << 16) + ((
|
||||
uint32_t)data[c + 2] << 8) + (uint32_t)data[c + 3];
|
||||
if (testVal != val) {
|
||||
Serial.print(F("Error @ addr "));
|
||||
Serial.print(addr + c);
|
||||
Serial.print(F(" Expected "));
|
||||
Serial.print(val);
|
||||
Serial.print(F(" Read "));
|
||||
Serial.print(testVal);
|
||||
Serial.print(F(" 0x"));
|
||||
Serial.println(testVal, HEX);
|
||||
}
|
||||
++val;
|
||||
}
|
||||
}
|
||||
uint32_t msLapse = millis() - msStart;
|
||||
Serial.print(F("Last value: "));
|
||||
Serial.print(val);
|
||||
Serial.print(F(" Read lapse: "));
|
||||
Serial.print(msLapse);
|
||||
Serial.println(F(" ms"));
|
||||
}
|
||||
|
||||
//write 0xFF to eeprom, "chunk" bytes at a time
|
||||
void eeErase(uint8_t chunk, uint32_t startAddr, uint32_t endAddr)
|
||||
{
|
||||
chunk &= 0xFC; //force chunk to be a multiple of 4
|
||||
uint8_t data[chunk];
|
||||
Serial.println(F("Erasing..."));
|
||||
for (int i = 0; i < chunk; i++) {
|
||||
data[i] = 0xFF;
|
||||
}
|
||||
uint32_t msStart = millis();
|
||||
|
||||
for (uint32_t a = startAddr; a <= endAddr; a += chunk) {
|
||||
if ( (a & 0xFFF) == 0 ) {
|
||||
Serial.println(a);
|
||||
}
|
||||
eep.write(a, data, chunk);
|
||||
}
|
||||
uint32_t msLapse = millis() - msStart;
|
||||
Serial.print(F("Erase lapse: "));
|
||||
Serial.print(msLapse);
|
||||
Serial.print(F(" ms"));
|
||||
}
|
||||
|
||||
//dump eeprom contents, 16 bytes at a time.
|
||||
//always dumps a multiple of 16 bytes.
|
||||
void dump(uint32_t startAddr, uint32_t nBytes)
|
||||
{
|
||||
Serial.print(F("EEPROM DUMP 0x"));
|
||||
Serial.print(startAddr, HEX);
|
||||
Serial.print(F(" 0x"));
|
||||
Serial.print(nBytes, HEX);
|
||||
Serial.print(F(" "));
|
||||
Serial.print(startAddr);
|
||||
Serial.print(F(" "));
|
||||
Serial.println(nBytes);
|
||||
uint32_t nRows = (nBytes + 15) >> 4;
|
||||
|
||||
uint8_t d[16];
|
||||
for (uint32_t r = 0; r < nRows; r++) {
|
||||
uint32_t a = startAddr + 16 * r;
|
||||
eep.read(a, d, 16);
|
||||
Serial.print(F("0x"));
|
||||
if ( a < 16 * 16 * 16 ) {
|
||||
Serial.print(F("0"));
|
||||
}
|
||||
if ( a < 16 * 16 ) {
|
||||
Serial.print(F("0"));
|
||||
}
|
||||
if ( a < 16 ) {
|
||||
Serial.print(F("0"));
|
||||
}
|
||||
Serial.print(a, HEX);
|
||||
Serial.print(F(" "));
|
||||
for ( int c = 0; c < 16; c++ ) {
|
||||
if ( d[c] < 16 ) {
|
||||
Serial.print(F("0"));
|
||||
Serial.print(d[c], HEX);
|
||||
Serial.print( c == 7 ? " " : " ");
|
||||
}
|
||||
}
|
||||
Serial.println(F(""));
|
||||
}
|
||||
}
|
||||
257
lib/MySensors/drivers/extEEPROM/extEEPROM.cpp
Normal file
257
lib/MySensors/drivers/extEEPROM/extEEPROM.cpp
Normal file
@@ -0,0 +1,257 @@
|
||||
/*-----------------------------------------------------------------------------*
|
||||
* extEEPROM.cpp - Arduino library to support external I2C EEPROMs. *
|
||||
* *
|
||||
* This library will work with most I2C serial EEPROM chips between 2k bits *
|
||||
* and 2048k bits (2M bits) in size. Multiple EEPROMs on the bus are supported *
|
||||
* as a single address space. I/O across block, page and device boundaries *
|
||||
* is supported. Certain assumptions are made regarding the EEPROM *
|
||||
* device addressing. These assumptions should be true for most EEPROMs *
|
||||
* but there are exceptions, so read the datasheet and know your hardware. *
|
||||
* *
|
||||
* The library should also work for EEPROMs smaller than 2k bits, assuming *
|
||||
* that there is only one EEPROM on the bus and also that the user is careful *
|
||||
* to not exceed the maximum address for the EEPROM. *
|
||||
* *
|
||||
* Library tested with: *
|
||||
* Microchip 24AA02E48 (2k bit) *
|
||||
* 24xx32 (32k bit, thanks to Richard M) *
|
||||
* Microchip 24LC256 (256k bit) *
|
||||
* Microchip 24FC1026 (1M bit, thanks to Gabriele B on the Arduino forum) *
|
||||
* ST Micro M24M02 (2M bit) *
|
||||
* *
|
||||
* Library will NOT work with Microchip 24xx1025 as its control byte does not *
|
||||
* conform to the following assumptions. *
|
||||
* *
|
||||
* Device addressing assumptions: *
|
||||
* 1. The I2C address sequence consists of a control byte followed by one *
|
||||
* address byte (for EEPROMs <= 16k bits) or two address bytes (for *
|
||||
* EEPROMs > 16k bits). *
|
||||
* 2. The three least-significant bits in the control byte (excluding the R/W *
|
||||
* bit) comprise the three most-significant bits for the entire address *
|
||||
* space, i.e. all chips on the bus. As such, these may be chip-select *
|
||||
* bits or block-select bits (for individual chips that have an internal *
|
||||
* block organization), or a combination of both (in which case the *
|
||||
* block-select bits must be of lesser significance than the chip-select *
|
||||
* bits). *
|
||||
* 3. Regardless of the number of bits needed to address the entire address *
|
||||
* space, the three most-significant bits always go in the control byte. *
|
||||
* Depending on EEPROM device size, this may result in one or more of the *
|
||||
* most significant bits in the I2C address bytes being unused (or "don't *
|
||||
* care"). *
|
||||
* 4. An EEPROM contains an integral number of pages. *
|
||||
* *
|
||||
* To use the extEEPROM library, the Arduino Wire library must also *
|
||||
* be included. *
|
||||
* *
|
||||
* Jack Christensen 23Mar2013 v1 *
|
||||
* 29Mar2013 v2 - Updated to span page boundaries (and therefore also *
|
||||
* device boundaries, assuming an integral number of pages per device) *
|
||||
* 08Jul2014 v3 - Generalized for 2kb - 2Mb EEPROMs. *
|
||||
* *
|
||||
* Paolo Paolucci 22-10-2015 v3.1 *
|
||||
* 09-01-2016 v3.2 Add update function. *
|
||||
* *
|
||||
* External EEPROM Library by Jack Christensen is licensed under CC BY-SA 4.0, *
|
||||
* http://creativecommons.org/licenses/by-sa/4.0/ *
|
||||
*-----------------------------------------------------------------------------*/
|
||||
|
||||
#include "extEEPROM.h"
|
||||
|
||||
// workaround, BUFFER_LENGTH is not defined in Wire.h for SAMD controllers
|
||||
#ifndef BUFFER_LENGTH
|
||||
#define BUFFER_LENGTH 32
|
||||
#endif
|
||||
|
||||
// Constructor.
|
||||
// - deviceCapacity is the capacity of a single EEPROM device in
|
||||
// kilobits (kb) and should be one of the values defined in the
|
||||
// eeprom_size_t enumeration in the extEEPROM.h file. (Most
|
||||
// EEPROM manufacturers use kbits in their part numbers.)
|
||||
// - nDevice is the number of EEPROM devices on the I2C bus (all must
|
||||
// be identical).
|
||||
// - pageSize is the EEPROM's page size in bytes.
|
||||
// - eepromAddr is the EEPROM's I2C address and defaults to 0x50 which is common.
|
||||
extEEPROM::extEEPROM(eeprom_size_t deviceCapacity, byte nDevice, unsigned int pageSize,
|
||||
uint8_t eepromAddr)
|
||||
{
|
||||
communication = NULL;
|
||||
_dvcCapacity = deviceCapacity;
|
||||
_nDevice = nDevice;
|
||||
_pageSize = pageSize;
|
||||
_eepromAddr = eepromAddr;
|
||||
_totalCapacity = _nDevice * _dvcCapacity * 1024UL / 8;
|
||||
_nAddrBytes = deviceCapacity > kbits_16 ? 2 :
|
||||
1; //two address bytes needed for eeproms > 16kbits
|
||||
|
||||
//determine the bitshift needed to isolate the chip select bits from the address to put into the control byte
|
||||
uint16_t kb = _dvcCapacity;
|
||||
if ( kb <= kbits_16 ) {
|
||||
_csShift = 8;
|
||||
} else if ( kb >= kbits_512 ) {
|
||||
_csShift = 16;
|
||||
} else {
|
||||
kb >>= 6;
|
||||
_csShift = 12;
|
||||
while ( kb >= 1 ) {
|
||||
++_csShift;
|
||||
kb >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//initialize the I2C bus and do a dummy write (no data sent)
|
||||
//to the device so that the caller can determine whether it is responding.
|
||||
//when using a 400kHz bus speed and there are multiple I2C devices on the
|
||||
//bus (other than EEPROM), call extEEPROM::begin() after any initialization
|
||||
//calls for the other devices to ensure the intended I2C clock speed is set.
|
||||
byte extEEPROM::begin(twiClockFreq_t twiFreq, TwoWire *_comm)
|
||||
{
|
||||
communication = _comm;
|
||||
communication->begin();
|
||||
communication->setClock(twiFreq);
|
||||
communication->beginTransmission(_eepromAddr);
|
||||
if (_nAddrBytes == 2) {
|
||||
communication->write((byte)0); //high addr byte
|
||||
}
|
||||
communication->write((byte)0); //low addr byte
|
||||
return communication->endTransmission();
|
||||
}
|
||||
|
||||
//Write bytes to external EEPROM.
|
||||
//If the I/O would extend past the top of the EEPROM address space,
|
||||
//a status of EEPROM_ADDR_ERR is returned. For I2C errors, the status
|
||||
//from the Arduino Wire library is passed back through to the caller.
|
||||
byte extEEPROM::write(unsigned long addr, byte *values, unsigned int nBytes)
|
||||
{
|
||||
uint8_t txStatus = 0; //transmit status
|
||||
|
||||
if (addr + nBytes > _totalCapacity) { //will this write go past the top of the EEPROM?
|
||||
return EEPROM_ADDR_ERR; //yes, tell the caller
|
||||
}
|
||||
|
||||
while (nBytes > 0) {
|
||||
const uint16_t nPage = _pageSize - ( addr & (_pageSize - 1) );
|
||||
//find min(nBytes, nPage, BUFFER_LENGTH) -- BUFFER_LENGTH is defined in the Wire library.
|
||||
uint16_t nWrite = nBytes < nPage ? nBytes : nPage;
|
||||
nWrite = BUFFER_LENGTH - _nAddrBytes < nWrite ? BUFFER_LENGTH - _nAddrBytes : nWrite;
|
||||
const uint8_t ctrlByte = _eepromAddr | (byte) (addr >> _csShift);
|
||||
communication->beginTransmission(ctrlByte);
|
||||
if (_nAddrBytes == 2) {
|
||||
communication->write( (byte) (addr >> 8) ); //high addr byte
|
||||
}
|
||||
communication->write( (byte) addr ); //low addr byte
|
||||
communication->write(values, nWrite);
|
||||
txStatus = communication->endTransmission();
|
||||
if (txStatus != 0) {
|
||||
return txStatus;
|
||||
}
|
||||
|
||||
//wait up to 50ms for the write to complete
|
||||
for (uint8_t i=100; i; --i) {
|
||||
delayMicroseconds(500); //no point in waiting too fast
|
||||
communication->beginTransmission(ctrlByte);
|
||||
if (_nAddrBytes == 2) {
|
||||
communication->write((byte)0); //high addr byte
|
||||
}
|
||||
communication->write((byte)0); //low addr byte
|
||||
txStatus = communication->endTransmission();
|
||||
if (txStatus == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (txStatus != 0) {
|
||||
return txStatus;
|
||||
}
|
||||
|
||||
addr += nWrite; //increment the EEPROM address
|
||||
values += nWrite; //increment the input data pointer
|
||||
nBytes -= nWrite; //decrement the number of bytes left to write
|
||||
}
|
||||
return txStatus;
|
||||
}
|
||||
|
||||
//Read bytes from external EEPROM.
|
||||
//If the I/O would extend past the top of the EEPROM address space,
|
||||
//a status of EEPROM_ADDR_ERR is returned. For I2C errors, the status
|
||||
//from the Arduino Wire library is passed back through to the caller.
|
||||
byte extEEPROM::read(unsigned long addr, byte *values, unsigned int nBytes)
|
||||
{
|
||||
if (addr + nBytes > _totalCapacity) { //will this read take us past the top of the EEPROM?
|
||||
return EEPROM_ADDR_ERR; //yes, tell the caller
|
||||
}
|
||||
|
||||
while (nBytes > 0) {
|
||||
const uint16_t nPage = _pageSize - ( addr & (_pageSize - 1) );
|
||||
uint16_t nRead = nBytes < nPage ? nBytes : nPage;
|
||||
nRead = BUFFER_LENGTH < nRead ? BUFFER_LENGTH : nRead;
|
||||
byte ctrlByte = _eepromAddr | (byte) (addr >> _csShift);
|
||||
communication->beginTransmission(ctrlByte);
|
||||
if (_nAddrBytes == 2) {
|
||||
communication->write( (byte) (addr >> 8) ); //high addr byte
|
||||
}
|
||||
communication->write( (byte) addr ); //low addr byte
|
||||
const byte rxStatus = communication->endTransmission();
|
||||
if (rxStatus != 0) {
|
||||
return rxStatus; //read error
|
||||
}
|
||||
|
||||
communication->requestFrom(ctrlByte, nRead);
|
||||
for (byte i=0; i<nRead; i++) {
|
||||
values[i] = communication->read();
|
||||
}
|
||||
|
||||
addr += nRead; //increment the EEPROM address
|
||||
values += nRead; //increment the input data pointer
|
||||
nBytes -= nRead; //decrement the number of bytes left to write
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Write a single byte to external EEPROM.
|
||||
//If the I/O would extend past the top of the EEPROM address space,
|
||||
//a status of EEPROM_ADDR_ERR is returned. For I2C errors, the status
|
||||
//from the Arduino Wire library is passed back through to the caller.
|
||||
byte extEEPROM::write(unsigned long addr, byte value)
|
||||
{
|
||||
return write(addr, &value, 1);
|
||||
}
|
||||
|
||||
//Read a single byte from external EEPROM.
|
||||
//If the I/O would extend past the top of the EEPROM address space,
|
||||
//a status of EEPROM_ADDR_ERR is returned. For I2C errors, the status
|
||||
//from the Arduino Wire library is passed back through to the caller.
|
||||
//To distinguish error values from valid data, error values are returned as negative numbers.
|
||||
int extEEPROM::read(unsigned long addr)
|
||||
{
|
||||
uint8_t data;
|
||||
int ret;
|
||||
|
||||
ret = read(addr, &data, 1);
|
||||
return ret == 0 ? data : -ret;
|
||||
}
|
||||
|
||||
//Update bytes to external EEPROM.
|
||||
//For I2C errors, the status from the Arduino Wire library is passed back through to the caller.
|
||||
byte extEEPROM::update(unsigned long addr, byte *values, unsigned int nBytes)
|
||||
{
|
||||
for (unsigned int i = 0; i < nBytes; i++) {
|
||||
const uint8_t newValue = values[i];
|
||||
if (newValue != read(addr + i)) {
|
||||
write(addr + i, newValue);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//Update a single byte to external EEPROM.
|
||||
//For I2C errors, the status from the Arduino Wire library is passed back through to the caller.
|
||||
byte extEEPROM::update(unsigned long addr, byte value)
|
||||
{
|
||||
return (value != read(addr) ? write(addr, &value, 1) : 0);
|
||||
}
|
||||
|
||||
//For I2C errors, the status from the Arduino Wire library is passed back through to the caller.
|
||||
unsigned long extEEPROM::length( void )
|
||||
{
|
||||
return _totalCapacity * 8;
|
||||
}
|
||||
131
lib/MySensors/drivers/extEEPROM/extEEPROM.h
Normal file
131
lib/MySensors/drivers/extEEPROM/extEEPROM.h
Normal file
@@ -0,0 +1,131 @@
|
||||
/*-----------------------------------------------------------------------------*
|
||||
* extEEPROM.h - Arduino library to support external I2C EEPROMs. *
|
||||
* *
|
||||
* This library will work with most I2C serial EEPROM chips between 2k bits *
|
||||
* and 2048k bits (2M bits) in size. Multiple EEPROMs on the bus are supported *
|
||||
* as a single address space. I/O across block, page and device boundaries *
|
||||
* is supported. Certain assumptions are made regarding the EEPROM *
|
||||
* device addressing. These assumptions should be true for most EEPROMs *
|
||||
* but there are exceptions, so read the datasheet and know your hardware. *
|
||||
* *
|
||||
* The library should also work for EEPROMs smaller than 2k bits, assuming *
|
||||
* that there is only one EEPROM on the bus and also that the user is careful *
|
||||
* to not exceed the maximum address for the EEPROM. *
|
||||
* *
|
||||
* Library tested with: *
|
||||
* Microchip 24AA02E48 (2k bit) *
|
||||
* 24xx32 (32k bit, thanks to Richard M) *
|
||||
* Microchip 24LC256 (256k bit) *
|
||||
* Microchip 24FC1026 (1M bit, thanks to Gabriele B on the Arduino forum) *
|
||||
* ST Micro M24M02 (2M bit) *
|
||||
* *
|
||||
* Library will NOT work with Microchip 24xx1025 as its control byte does not *
|
||||
* conform to the following assumptions. *
|
||||
* *
|
||||
* Device addressing assumptions: *
|
||||
* 1. The I2C address sequence consists of a control byte followed by one *
|
||||
* address byte (for EEPROMs <= 16k bits) or two address bytes (for *
|
||||
* EEPROMs > 16k bits). *
|
||||
* 2. The three least-significant bits in the control byte (excluding the R/W *
|
||||
* bit) comprise the three most-significant bits for the entire address *
|
||||
* space, i.e. all chips on the bus. As such, these may be chip-select *
|
||||
* bits or block-select bits (for individual chips that have an internal *
|
||||
* block organization), or a combination of both (in which case the *
|
||||
* block-select bits must be of lesser significance than the chip-select *
|
||||
* bits). *
|
||||
* 3. Regardless of the number of bits needed to address the entire address *
|
||||
* space, the three most-significant bits always go in the control byte. *
|
||||
* Depending on EEPROM device size, this may result in one or more of the *
|
||||
* most significant bits in the I2C address bytes being unused (or "don't *
|
||||
* care"). *
|
||||
* 4. An EEPROM contains an integral number of pages. *
|
||||
* *
|
||||
* To use the extEEPROM library, the Arduino Wire library must also *
|
||||
* be included. *
|
||||
* *
|
||||
* Jack Christensen 23Mar2013 v1 *
|
||||
* 29Mar2013 v2 - Updated to span page boundaries (and therefore also *
|
||||
* device boundaries, assuming an integral number of pages per device) *
|
||||
* 08Jul2014 v3 - Generalized for 2kb - 2Mb EEPROMs. *
|
||||
* *
|
||||
* Paolo Paolucci 22-10-2015 v3.2 *
|
||||
* 09-01-2016 v3.2 Add update function. *
|
||||
* *
|
||||
* External EEPROM Library by Jack Christensen is licensed under CC BY-SA 4.0, *
|
||||
* http://creativecommons.org/licenses/by-sa/4.0/ *
|
||||
*-----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* tekka 2018:
|
||||
* Re-implementing extEEPROM::update(unsigned long addr, byte value);
|
||||
*/
|
||||
#ifndef extEEPROM_h
|
||||
#define extEEPROM_h
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
|
||||
//EEPROM size in kilobits. EEPROM part numbers are usually designated in k-bits.
|
||||
enum eeprom_size_t {
|
||||
kbits_2 = 2,
|
||||
kbits_4 = 4,
|
||||
kbits_8 = 8,
|
||||
kbits_16 = 16,
|
||||
kbits_32 = 32,
|
||||
kbits_64 = 64,
|
||||
kbits_128 = 128,
|
||||
kbits_256 = 256,
|
||||
kbits_512 = 512,
|
||||
kbits_1024 = 1024,
|
||||
kbits_2048 = 2048
|
||||
};
|
||||
|
||||
//EEPROM addressing error, returned by write() or read() if upper address bound is exceeded
|
||||
const uint8_t EEPROM_ADDR_ERR = 9;
|
||||
|
||||
/** extEEPROM class */
|
||||
class extEEPROM
|
||||
{
|
||||
private:
|
||||
// the private attribute used to comunicate with the correct I2C SERCOM
|
||||
TwoWire *communication;
|
||||
|
||||
public:
|
||||
/**
|
||||
* I2C clock frequencies
|
||||
*/
|
||||
enum twiClockFreq_t {
|
||||
twiClock100kHz = 100000, //!< twiClock100kHz
|
||||
twiClock400kHz = 400000 //!< twiClock400kHz
|
||||
};
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param deviceCapacity
|
||||
* @param nDevice
|
||||
* @param pageSize
|
||||
* @param eepromAddr
|
||||
*/
|
||||
extEEPROM(eeprom_size_t deviceCapacity, byte nDevice, unsigned int pageSize,
|
||||
byte eepromAddr = 0x50);
|
||||
|
||||
// It is ready for every I2C Sercom, by default use the main Wire
|
||||
byte begin(twiClockFreq_t twiFreq = twiClock100kHz, TwoWire *_comm=&Wire); //!< begin()
|
||||
byte write(unsigned long addr, byte *values, unsigned int nBytes); //!< write()
|
||||
byte write(unsigned long addr, byte value); //!< write()
|
||||
byte read(unsigned long addr, byte *values, unsigned int nBytes); //!< read()
|
||||
int read(unsigned long addr); //!< read()
|
||||
byte update(unsigned long addr, byte *values, unsigned int nBytes); //!< update()
|
||||
byte update(unsigned long addr, byte value); //!< update()
|
||||
unsigned long length(); //!< length()
|
||||
|
||||
private:
|
||||
uint8_t _eepromAddr; //eeprom i2c address
|
||||
uint16_t _dvcCapacity; //capacity of one EEPROM device, in kbits
|
||||
uint8_t _nDevice; //number of devices on the bus
|
||||
uint16_t _pageSize; //page size in bytes
|
||||
uint8_t _csShift; //number of bits to shift address for chip select bits in control byte
|
||||
uint16_t _nAddrBytes; //number of address bytes (1 or 2)
|
||||
unsigned long _totalCapacity; //capacity of all EEPROM devices on the bus, in bytes
|
||||
};
|
||||
|
||||
#endif
|
||||
6
lib/MySensors/drivers/extEEPROM/keywords.txt
Normal file
6
lib/MySensors/drivers/extEEPROM/keywords.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
extEEPROM KEYWORD1
|
||||
begin KEYWORD2
|
||||
write KEYWORD2
|
||||
read KEYWORD2
|
||||
update KEYWORD2
|
||||
length KEYWORD2
|
||||
Reference in New Issue
Block a user