/* EEPROM.h - EEPROM library Original Copyright (c) 2006 David A. Mellis. All right reserved. New version by Christopher Andrews 2015. Curie porting by Intel and Arduino LLC - 2016 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 #define ROM_WR_CTRL 0xb0100004 #define ROM_WR_DATA 0xb0100008 #define FLASH_STTS 0xb0000014 #define EEPROM_ADDR 0xfffff000 #define EEPROM_OFFSET 0x00001000 #define CTRL_REG 0xb0000018 #define EEPROM_SIZE 2048 //EEPROM size in bytes #include #include "Arduino.h" /* Curie specific implementation of "atomic" read8 and write8 on OTP flash storage */ void CurieClear(); void CurieRestoreMemory(uint32_t* buffer, uint32_t size); uint8_t CurieRead8(uint32_t address); uint32_t CurieRead32(uint32_t address); void CurieWrite8(uint32_t address, uint8_t data); /*** 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{ EERef( const int index ) : index( index ) {} //Access/read members. uint8_t operator*() const { return CurieRead8( (uint32_t) 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 CurieWrite8( (uint32_t) 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{ //Basic user access methods. EERef operator[]( const int idx ) { return idx; } uint8_t read( int idx ) { return EERef( idx ); } void write( int idx, uint8_t val ) { (EERef( idx )) = val; } void update( int idx, uint8_t val ) { 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 EEPROM_SIZE; } //Functionality to 'get' and 'put' objects to and from EEPROM. template< typename T > T &get( int idx, T &t ){ 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 ){ EEPtr e = idx; const uint8_t *ptr = (const uint8_t*) &t; for( int count = sizeof(T) ; count ; --count, ++e ) (*e).update( *ptr++ ); return t; } }; extern EEPROMClass EEPROM; #endif