From d457051fd4e53c7794dc5f1cbc26b0f3d70823df Mon Sep 17 00:00:00 2001 From: SukkoPera Date: Sat, 4 Jun 2016 15:21:46 +0200 Subject: [PATCH] Switch to Arduino-compliant EEPROM library --- .../libraries/DigiXEEPROM/Extensive_EEPROM.h | 179 --------------- .../Extensive_EEPROM_overview.ino | 130 ----------- digistump-sam/libraries/EEPROM/EEPROM.h | 203 ++++++++++++++++++ 3 files changed, 203 insertions(+), 309 deletions(-) delete mode 100644 digistump-sam/libraries/DigiXEEPROM/Extensive_EEPROM.h delete mode 100644 digistump-sam/libraries/DigiXEEPROM/Extensive_EEPROM_overview/Extensive_EEPROM_overview.ino create mode 100644 digistump-sam/libraries/EEPROM/EEPROM.h diff --git a/digistump-sam/libraries/DigiXEEPROM/Extensive_EEPROM.h b/digistump-sam/libraries/DigiXEEPROM/Extensive_EEPROM.h deleted file mode 100644 index aa31509..0000000 --- a/digistump-sam/libraries/DigiXEEPROM/Extensive_EEPROM.h +++ /dev/null @@ -1,179 +0,0 @@ -/* -Extensive TWI/I2C EEPROM Library - for 24LCxxx devices -version: 0.4.1 -target device: Microchip 24LC256 or similar -compatibility: designed with Arduino Due --> Ver. 0.4.1: Successfully tested with Arduino Uno R3 and Arduino Micro! -author: Dennis Schweer (Inglorious Engineer) -license: CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0/deed.en) - -Overview: - -bytewise reading/writing - void extEEPROMwrite(int chip_address, int address, byte value); - byte extEEPROMread(int chip_address, int address); - -pagewise reading/writing - void extEEPROMwritePage(int chip_address, int startaddress, byte* data_origin_array, int amount_of_transfered_bytes) - (!!!ATTENTION!!!: Limited to 30 Bytes only!) - void extEEPROMreadPage(int chip_address, int startaddress, byte* data_target_array, int amount_of_transfered_bytes) - (!!!ATTENTION!!!: Limited to 32 Bytes only) - Do not care about their size, just save them! - -read/write complete 32bit integers [Requires four bytes of your EEPROM.] - void extEEPROMwriteInt(int chip_address, int address, int data_to_be_stored) - int extEEPROMreadInt(int chip_address, int address) - -read/write your 10/12 bit sensor values (e.g., ADC values) [Requires two bytes of your EEPROM.] - void extEEPROMwriteSensor(int chip_address, int addresse, int data_to_be_stored) - int extEEPROMreadSensor(int chip_address, int addresse) - -NEW IN VERSION 0.4: -Now all functions include a device address parameter, allowing you to use two -or more external EEPROM chips simultaneously on a single bus. Just choose the -right device addresses and feet them into the library functions! - -NEW IN VERSION 0.4.1: -My library is designed with an Arduino Due, but now everything is successfully -tested to work on Arduino Uno R3 and Arduino Micro as well! Since all current -Arduinos are based on either ATmega328 (e.g., Uno), ATmega32U4 (e.g., Micro/ -Leonardo/Esplora) or ATSAM3X8E (Due), my library should work with ALL official -or 1:1-compatible boards. -!!! Unfortunately, Arduino Due appears to be the only device with the ability -to handle 32 bit integers. Hence none of my "writeInt" / "readInt" functions -run on 8-bit Arduinos !!! - - -Planned for future releases: - -erase byte - -erase page - -erase complete EEPROM - -read/write with autocorrection of "startaddress"-value -*/ - -#include "Arduino.h" -//========FUNCTIONS========================= - -///////////////// WRITE ///////////////////// - -void extEEPROMwrite(int EEPROM_addr, int addr, byte data) -{ - Wire.beginTransmission(EEPROM_addr); //Start transmission to EEPROM - Wire.write(highByte(addr)); // send high byte of address - Wire.write(lowByte(addr)); // send low byte of address - Wire.write((byte) data); // send data - Wire.endTransmission(true); // stop transmitting - delay(6); // wait for a successful write -} - -void extEEPROMwritePage(int EEPROM_addr, int addr, byte* data_origin, int amount) -{ - Wire.beginTransmission(EEPROM_addr); //Start transmission to EEPROM - Wire.write(highByte(addr)); // send high byte of address - Wire.write(lowByte(addr)); // send low byte of address - for(int i = 0; i> 8; - Wire.write(lowByte(data)); // send 2nd lowest byte of 32 bit integer - data = data >> 8; - Wire.write(lowByte(data)); // send 2nd highest byte of 32 bit integer - data = data >> 8; - Wire.write(lowByte(data)); // send highest byte of 32 bit integer - Wire.endTransmission(true); // stop transmitting - delay(6); // wait for a successful write -} - -void extEEPROMwriteSensor(int EEPROM_addr, int addr, int data) -{ - Wire.beginTransmission(EEPROM_addr); //Start transmission to EEPROM - Wire.write(highByte(addr)); // send high byte of address - Wire.write(lowByte(addr)); // send low byte of address - Wire.write(lowByte(data)); // send low byte of 12 bit integer - data = data >> 8; - Wire.write(lowByte(data)); // send high byte of 12 bit integer - Wire.endTransmission(true); // stop transmitting - delay(6); // wait for a successful write -} - -///////////////// READ ///////////////////// - -byte extEEPROMread(int EEPROM_addr, int addr) -{ - Wire.beginTransmission(EEPROM_addr); //Start transmission to EEPROM - Wire.write(highByte(addr)); // send high byte of address - Wire.write(lowByte(addr)); // send low byte of address - Wire.endTransmission(true); // stop transmitting - Wire.requestFrom(EEPROM_addr, 0x01, true); // request 1 byte form the device attached to EEPROM_addr - byte data_out = 64; - // read that byte - while(Wire.available() == 0) {} // wait for data - data_out = Wire.read(); //read single byte - return data_out; -} - -void extEEPROMreadPage(int EEPROM_addr, int addr, byte* data_target, int amount) -{ - Wire.beginTransmission(EEPROM_addr); //Start transmission to EEPROM - Wire.write(highByte(addr)); // send high byte of address - Wire.write(lowByte(addr)); // send low byte of address - Wire.endTransmission(true); // stop transmitting - Wire.requestFrom(EEPROM_addr, amount, true); // request 1 byte form the device attached to EEPROM_addr - // read that byte - while(Wire.available() == 0) {} // wait for data - for(int i = 0; i Ver. 0.4.1: Successfully tested with Arduino Uno R3 and Arduino Micro! -author: Dennis Schweer (Inglorious Engineer) -license: CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0/deed.en) - -Overview: - -bytewise reading/writing - void extEEPROMwrite(int chip_address, int address, byte value); - byte extEEPROMread(int chip_address, int address); - -pagewise reading/writing - void extEEPROMwritePage(int chip_address, int startaddress, byte* data_origin_array, int amount_of_transfered_bytes) - (!!!ATTENTION!!!: Limited to 30 Bytes only!) - void extEEPROMreadPage(int chip_address, int startaddress, byte* data_target_array, int amount_of_transfered_bytes) - (!!!ATTENTION!!!: Limited to 32 Bytes only) - Do not care about their size, just save them! - -read/write complete 32bit integers [Requires four bytes of your EEPROM.] - void extEEPROMwriteInt(int chip_address, int address, int data_to_be_stored) - int extEEPROMreadInt(int chip_address, int address) - -read/write your 10/12 bit sensor values (e.g., ADC values) [Requires two bytes of your EEPROM.] - void extEEPROMwriteSensor(int chip_address, int addresse, int data_to_be_stored) - int extEEPROMreadSensor(int chip_address, int addresse) - -NEW IN VERSION 0.4: -Now all functions include a device address parameter, allowing you to use two -or more external EEPROM chips simultaneously on a single bus. Just choose the -right device addresses and feet them into the library functions! - -NEW IN VERSION 0.4.1: -My library is designed with an Arduino Due, but now everything is successfully -tested to work on Arduino Uno R3 and Arduino Micro as well! Since all current -Arduinos are based on either ATmega328 (e.g., Uno), ATmega32U4 (e.g., Micro/ -Leonardo/Esplora) or ATSAM3X8E (Due), my library should work with ALL official -or 1:1-compatible boards. -!!! Unfortunately, Arduino Due appears to be the only device with the ability -to handle 32 bit integers. Hence none of my "writeInt" / "readInt" functions -run on 8-bit Arduinos !!! - - -Planned for future releases: - -erase byte - -erase page - -erase complete EEPROM - -read/write with autocorrection of "startaddress"-value -*/ -#include -#include - -const int EEPROM_addr = 0x50; - -// Testbed variables -int test = 1; - -void setup() -{ - Wire.begin(); // join i2c bus (address optional for master) - Serial.begin(9600); - test = 1; -} - -void loop() -{ - //Testbed - if(test == 1) //only run it once - { - //byte-wise writing/reading - Serial.println("//byte-wise writing/reading"); - for(int i = 0; i < 32; i++) - { - extEEPROMwrite(EEPROM_addr, i, i); //void extEEPROMwrite(int chip_address, int address, byte value); - } - int data_back; - for(int i = 0; i < 32; i++) - { - data_back = extEEPROMread(EEPROM_addr, i); //byte extEEPROMread(int chip_address, int address); - Serial.print("original data= "); - Serial.print(i); - Serial.print(" read_back= "); - Serial.println(data_back); - } - - - //page-wise writing/reading - Serial.println("//page-wise writing/reading"); - byte data_to_be_written[30]; - for(int i=0; i<30; i++) - { - data_to_be_written[i] = (29-i); //writes the numbers 29 downto 0 into cells 0-29 - Serial.print("Original Data = "); - Serial.println((29-i)); - } - //store array in EEPROM (max. 30 Bytes) - extEEPROMwritePage(EEPROM_addr, 32, data_to_be_written, 30); //void extEEPROMwritePage(int chip_address, int startaddress, byte* data_origin_array, int amount_of_transfered_bytes) - //read page into an array (max. 32 Bytes) - byte data_output[30]; - extEEPROMreadPage(EEPROM_addr, 32, data_output, 30); // void extEEPROMreadPage(int chip_address, int startaddress, byte* data_target_array, int amountof_transfered_bytes) - for(int j=0; j<30; j++) - { - Serial.print("Read Page= "); - Serial.println(data_output[j]); // Print array - } - - //write/read 32 bit integer - Serial.println("//write/read 32 bit integer"); - int original_int = 0x7FFFFFFF; - extEEPROMwriteInt(EEPROM_addr, 70, original_int); - int original_int_output; - original_int_output = extEEPROMreadInt(EEPROM_addr, 70); - Serial.print("Integer: in = "); - Serial.print(original_int); - Serial.print(" / out = "); - Serial.println(original_int_output); - - //write/read 10/12 bit sensor data - Serial.println("//write/read 10/12 bit sensor data"); - int original_sensor = 0x7FFF; - extEEPROMwriteInt(EEPROM_addr, 75, original_sensor); - int original_sensor_output; - original_sensor_output = extEEPROMreadInt(EEPROM_addr, 75); - Serial.print("Sensordata: in = "); - Serial.print(original_sensor); - Serial.print(" / out = "); - Serial.println(original_sensor_output); - - } - test = 2; // only perform this procedure once -} diff --git a/digistump-sam/libraries/EEPROM/EEPROM.h b/digistump-sam/libraries/EEPROM/EEPROM.h new file mode 100644 index 0000000..539ccd5 --- /dev/null +++ b/digistump-sam/libraries/EEPROM/EEPROM.h @@ -0,0 +1,203 @@ +/* + EEPROM.h - EEPROM library for the Digistump DigiX + + This is mostly the merger of the stock Arduino EEPROM library, original + Copyright (c) 2006 David A. Mellis/Christopher Andrews 2015 (LGPL 2.1) with a + few functions from Dennis Schweer (Inglorious Engineer)'s Extensive TWI/I2C + EEPROM Library for 24LCxxx devices v0.4.1 (CC-BY-SA), as distributed with the + DigiX core. + + Merging work by SukkoPera , 2016. + + The basic idea is to create a library that is interface-compatible with + Arduino's stock library that is used on non-Due boards, to achieve + compatibility at source level, so that the usual EEPROM.write()/read()/get() + /put() calls can be used. + + I'm not really sure of what license the resulting code should be released + under, so I'm leaving the LGPL 2.1, as most of the code here actually came + under that license, and the rest is pretty basic stuff, but let me know if I + should change that. + + 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 +*/ + +#ifndef EEPROM_h +#define EEPROM_h + +#include +#include + +static const int DIGIX_EEPROM_ADDR = 0x50; + +static const int E2END = 0xFFF; + +/*** + EERef class. + + This object references an EEPROM cell. + Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM. + This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell. +***/ + +struct EERef{ +private: + void extEEPROMwrite(int EEPROM_addr, int addr, byte data) + { + Wire.beginTransmission(EEPROM_addr); //Start transmission to EEPROM + Wire.write(highByte(addr)); // send high byte of address + Wire.write(lowByte(addr)); // send low byte of address + Wire.write((byte) data); // send data + Wire.endTransmission(true); // stop transmitting + delay(6); // wait for a successful write + } + + byte extEEPROMread(int EEPROM_addr, int addr) const + { + Wire.beginTransmission(EEPROM_addr); //Start transmission to EEPROM + Wire.write(highByte(addr)); // send high byte of address + Wire.write(lowByte(addr)); // send low byte of address + Wire.endTransmission(true); // stop transmitting + Wire.requestFrom(EEPROM_addr, 0x01, true); // request 1 byte form the device attached to EEPROM_addr + byte data_out = 64; + // read that byte + while(Wire.available() == 0) {} // wait for data + data_out = Wire.read(); //read single byte + return data_out; + } + +public: + EERef( const int index ) + : index( index ) {} + + //Access/read members. + uint8_t operator*() const { return extEEPROMread( DIGIX_EEPROM_ADDR, index ); } + operator const uint8_t() const { return **this; } + + //Assignment/write members. + EERef &operator=( const EERef &ref ) { return *this = *ref; } + EERef &operator=( uint8_t in ) { return extEEPROMwrite( DIGIX_EEPROM_ADDR, index, in ), *this; } + EERef &operator +=( uint8_t in ) { return *this = **this + in; } + EERef &operator -=( uint8_t in ) { return *this = **this - in; } + EERef &operator *=( uint8_t in ) { return *this = **this * in; } + EERef &operator /=( uint8_t in ) { return *this = **this / in; } + EERef &operator ^=( uint8_t in ) { return *this = **this ^ in; } + EERef &operator %=( uint8_t in ) { return *this = **this % in; } + EERef &operator &=( uint8_t in ) { return *this = **this & in; } + EERef &operator |=( uint8_t in ) { return *this = **this | in; } + EERef &operator <<=( uint8_t in ) { return *this = **this << in; } + EERef &operator >>=( uint8_t in ) { return *this = **this >> in; } + + EERef &update( uint8_t in ) { return in != *this ? *this = in : *this; } + + /** Prefix increment/decrement **/ + EERef& operator++() { return *this += 1; } + EERef& operator--() { return *this -= 1; } + + /** Postfix increment/decrement **/ + uint8_t operator++ (int){ + uint8_t ret = **this; + return ++(*this), ret; + } + + uint8_t operator-- (int){ + uint8_t ret = **this; + return --(*this), ret; + } + + int index; //Index of current EEPROM cell. +}; + +/*** + EEPtr class. + + This object is a bidirectional pointer to EEPROM cells represented by EERef objects. + Just like a normal pointer type, this can be dereferenced and repositioned using + increment/decrement operators. +***/ + +struct EEPtr{ + + EEPtr( const int index ) + : index( index ) {} + + operator const int() const { return index; } + EEPtr &operator=( int in ) { return index = in, *this; } + + //Iterator functionality. + bool operator!=( const EEPtr &ptr ) { return index != ptr.index; } + EERef operator*() { return index; } + + /** Prefix & Postfix increment/decrement **/ + EEPtr& operator++() { return ++index, *this; } + EEPtr& operator--() { return --index, *this; } + EEPtr operator++ (int) { return index++; } + EEPtr operator-- (int) { return index--; } + + int index; //Index of current EEPROM cell. +}; + +/*** + EEPROMClass class. + + This object represents the entire EEPROM space. + It wraps the functionality of EEPtr and EERef into a basic interface. + This class is also 100% backwards compatible with earlier Arduino core releases. +***/ + +struct EEPROMClass{ + boolean inited; + + // c'tor + EEPROMClass () { inited = false; } + + // Check if the i2c library was initialized, and do it if not. + // FIXME: What happens if the sketch has already called Wire.begin() on its + // own? + void checkInited () { if (!inited) { Wire.begin(); inited = true; } } + + //Basic user access methods. + EERef operator[]( const int idx ) { return idx; } + uint8_t read( int idx ) { checkInited (); return EERef( idx ); } + void write( int idx, uint8_t val ) { checkInited (); (EERef( idx )) = val; } + void update( int idx, uint8_t val ) { checkInited (); EERef( idx ).update( val ); } + + //STL and C++11 iteration capability. + EEPtr begin() { return 0x00; } + EEPtr end() { return length(); } //Standards requires this to be the item after the last valid entry. The returned pointer is invalid. + uint16_t length() { return E2END + 1; } + + //Functionality to 'get' and 'put' objects to and from EEPROM. + template< typename T > T &get( int idx, T &t ){ + checkInited (); + + EEPtr e = idx; + uint8_t *ptr = (uint8_t*) &t; + for( int count = sizeof(T) ; count ; --count, ++e ) *ptr++ = *e; + return t; + } + + template< typename T > const T &put( int idx, const T &t ){ + checkInited (); + + EEPtr e = idx; + const uint8_t *ptr = (const uint8_t*) &t; + for( int count = sizeof(T) ; count ; --count, ++e ) (*e).update( *ptr++ ); + return t; + } +}; + +static EEPROMClass EEPROM; +#endif