diff --git a/libraries/CurieEEPROM/examples/eeprom_clear/eeprom_clear.ino b/libraries/CurieEEPROM/examples/eeprom_clear/eeprom_clear.ino deleted file mode 100644 index 07f6613c..00000000 --- a/libraries/CurieEEPROM/examples/eeprom_clear/eeprom_clear.ino +++ /dev/null @@ -1,25 +0,0 @@ -/* - * EEPROM Clear - * - * Sets all of the bytes of the EEPROM to 0xFF. - * Please see eeprom_iteration for a more in depth - * look at how to traverse the EEPROM. - * - * This example code is in the public domain. - */ - -#include - -void setup() { - // initialize the LED pin as an output. - pinMode(13, OUTPUT); - - EEPROM.clear(); - - // turn the LED on when we're done - digitalWrite(13, HIGH); -} - -void loop() { - /** Empty loop. **/ -} diff --git a/libraries/CurieEEPROM/examples/eeprom_read/eeprom_read.ino b/libraries/CurieEEPROM/examples/eeprom_read/eeprom_read.ino deleted file mode 100644 index 2682d2dc..00000000 --- a/libraries/CurieEEPROM/examples/eeprom_read/eeprom_read.ino +++ /dev/null @@ -1,40 +0,0 @@ -/* - * EEPROM Read - * - * Reads the value of each DWORD of the EEPROM and prints it - * to the computer. - * This example code is in the public domain. - * 01/05/2016 - Modified for Arduino 101 - Dino Tinitigan - */ - -#include - -// start reading from the first byte (address 0) of the EEPROM -int address = 0; -unsigned long value; - -void setup() { - // initialize serial and wait for port to open: - Serial.begin(9600); - while (!Serial) { - ; // wait for serial port to connect. Needed for native USB port only - } -} - -void loop() { - // read a dword from the current address of the EEPROM - value = EEPROM.read(address); - - Serial.print(address); - Serial.print("\t"); - Serial.print(value, DEC); - Serial.println(); - - //increment address - address++; - if (address == EEPROM.length()) { - address = 0; - } - - delay(500); -} diff --git a/libraries/CurieEEPROM/examples/eeprom_write/eeprom_write.ino b/libraries/CurieEEPROM/examples/eeprom_write/eeprom_write.ino deleted file mode 100644 index eb55d180..00000000 --- a/libraries/CurieEEPROM/examples/eeprom_write/eeprom_write.ino +++ /dev/null @@ -1,38 +0,0 @@ -/* - * EEPROM Write - * - * Stores values read from analog input 0 into the EEPROM. - * These values will stay in the EEPROM when the board is - * turned off and may be retrieved later by another sketch. - * 01/05/2016 - Modified for Arduino 101 - Dino Tinitigan - */ - -#include - -/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/ -int addr = 0; - -void setup() { - Serial.begin(9600); - while (!Serial) { - ; // wait for serial port to connect. Needed for native USB port only - } - - for(int i = 0; i < 512; i++) - { - unsigned long val = analogRead(0); - Serial.print("Addr:\t"); - Serial.print(addr); - Serial.print("\tWriting: "); - Serial.println(val); - EEPROM.write(addr, val); - addr++; - delay(100); - } - - Serial.println("done writing"); -} - -void loop() { - -} \ No newline at end of file diff --git a/libraries/CurieEEPROM/library.properties b/libraries/CurieEEPROM/library.properties deleted file mode 100644 index 0f3c1e2b..00000000 --- a/libraries/CurieEEPROM/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=CurieEEPROM -version=1.0 -author=Intel -maintainer=Intel -sentence=Enables reading and writing to OTP flash area of Curie -paragraph=This library allows to read and write data on a memory type and area that keeps its content also when the board is powered off. -category=Data Storage -url=http://www.arduino.cc/en/Reference/EEPROM -architectures=arc32 - diff --git a/libraries/CurieEEPROM/releasenotes.txt b/libraries/CurieEEPROM/releasenotes.txt deleted file mode 100644 index d7c6e2cb..00000000 --- a/libraries/CurieEEPROM/releasenotes.txt +++ /dev/null @@ -1,7 +0,0 @@ -01/05/2016 v1.0 - --Initial commit for CurieEEPROM library --Implements EEPROM functionality using an available area of the ROM --supports both BYTE and DWORD reading/writing --EEPROM[] currently only supports reading --an empty DWORD cell has a value of 0xFFFFFFFF diff --git a/libraries/CurieEEPROM/src/CurieEEPROM.cpp b/libraries/CurieEEPROM/src/CurieEEPROM.cpp deleted file mode 100644 index 3127f18f..00000000 --- a/libraries/CurieEEPROM/src/CurieEEPROM.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation. All rights 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 Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ -#include "CurieEEPROM.h" - -CurieEEPROM EEPROM; - -void CurieEEPROM::clear() -{ - //erase the 2k bytes of the eeprom section inside the otp area - *(uint32_t*)(ROM_WR_CTRL) = 0x4002; - //wait for erase to be complete - //TODO: while(((*(uint32_t*)FLASH_STTS) & 0x01) == 0) //wait for FLASH_STTS.ER_DONE to be set to 1 - delay(1000); -} - -void CurieEEPROM::write(uint32_t address, uint32_t data) -{ - //make sure address is within valid range - if(address > 0x1FF) - { - return; - } - - uint32_t currentValue = read(address); - //only do something if value is different from what is currently stored - if(currentValue==data) - { - return; - } - - //allign address to 32-bit addressing - address*=sizeof(uint32_t); - - uint32_t rom_wr_ctrl = 0; - - //check if address is available for writing a new value. If not erase the whole 2K block and re-write the rest of the data - if(currentValue!=0xFFFFFFFF) - { - //read entire 2k of data - uint32_t blockdata[EEPROM_SIZE]; - for(int i = 0; i < EEPROM_SIZE; i++) - { - blockdata[i] = read(i*sizeof(uint32_t)); - } - - //update blockdata buffer - int blockIndex = address/4; - blockdata[blockIndex] = data; - - //clear EEPROM area - clear(); - - //write back all data with update data on passed address - for(int i = 0; i < EEPROM_SIZE; i++) - { - //store data into ROM_WR_DATA register - *(uint32_t*)(ROM_WR_DATA) = blockdata[i]; - address = EEPROM_OFFSET + i*sizeof(uint32_t); - rom_wr_ctrl = (address)<<2; //shift left 2 bits to store offset into bits 19:2 (WR_ADDR) - rom_wr_ctrl |= 0x00000001; //set (WR_REQ) bit - *(uint32_t*)(ROM_WR_CTRL) = rom_wr_ctrl; - delay(3); //give it enough time to finish writing - } - } - else - { - //store data into ROM_WR_DATA register - *(uint32_t*)(ROM_WR_DATA) = data; - address += EEPROM_OFFSET; - rom_wr_ctrl = (address)<<2; //shift left 2 bits to store offset into bits 19:2 (WR_ADDR) - rom_wr_ctrl |= 0x00000001; //set (WR_REQ) bit - *(uint32_t*)(ROM_WR_CTRL) = rom_wr_ctrl; - delay(3); //give it enough time to finish writing - } -} - -void CurieEEPROM::write8(uint32_t address, uint8_t data) -{ - uint8_t currentValue = read8(address); - //only do something if value is different from what is currently stored - if(currentValue==data) - { - return; - } - - uint32_t rom_wr_ctrl = 0; - //make sure address is valid - if((address > 0x7FF)) - { - return; - } - - //check if address is available for writing a new value. If not erase the whole 2K block and re-write the rest of the data - if(currentValue!=0xFF) - { - //read entire 2k of data - uint32_t blockdata[EEPROM_SIZE]; - for(int i = 0; i < EEPROM_SIZE; i++) - { - blockdata[i] = read(i*sizeof(uint32_t)); - } - - //update blockdata buffer - int offset = address%4; - int blockIndex = address/4; - uint32_t data32 = blockdata[blockIndex]; - uint8_t data_array[sizeof(uint32_t)]; - memcpy(data_array, &data32, sizeof(uint32_t)); - data_array[offset] = data; - memcpy(&data32, &data_array, sizeof(uint32_t)); - blockdata[blockIndex] = data32; - - //clear EEPROM area - clear(); - - //write back all data with update data on passed address - for(int i = 0; i < EEPROM_SIZE; i++) - { - //store data into ROM_WR_DATA register - *(uint32_t*)(ROM_WR_DATA) = blockdata[i]; - address = EEPROM_OFFSET + i*sizeof(uint32_t); - rom_wr_ctrl = (address)<<2; //shift left 2 bits to store offset into bits 19:2 (WR_ADDR) - rom_wr_ctrl |= 0x00000001; //set (WR_REQ) bit - *(uint32_t*)(ROM_WR_CTRL) = rom_wr_ctrl; - delay(3); //give it enough time to finish writing - } - } - else - { - int offset = address%4; - uint32_t data32 = 0xffffff00 + (uint32_t)data; - for(int i = 0; i < offset; i++) - { - data32<<=8; - data32+=0x000000ff; - } - //store data into ROM_WR_DATA register - *(uint32_t*)(ROM_WR_DATA) = data32; - address -= offset; - address += EEPROM_OFFSET; - rom_wr_ctrl = (address)<<2; //shift left 2 bits to store offset into bits 19:2 (WR_ADDR) - rom_wr_ctrl |= 0x00000001; //set (WR_REQ) bit - *(uint32_t*)(ROM_WR_CTRL) = rom_wr_ctrl; - delay(3); //give it enough time to finish writing - } -} - -void CurieEEPROM::update(uint32_t addr, uint32_t value) -{ - write(addr, value); -} -void CurieEEPROM::update8(uint32_t addr, uint8_t value) -{ - write8(addr, value); -} - -uint32_t CurieEEPROM::read(uint32_t address) -{ - //make sure address is within valid range - if(address > 0x1FF) - { - return 0; - } - - //allign address to 32-bit addressing - address*=sizeof(uint32_t); - - address += EEPROM_ADDR; - return *(uint32_t*)(address); -} - -uint8_t CurieEEPROM::read8(uint32_t address) -{ - if((address > 0x7FF)) - { - return 0; - } - int offset = address%4; - uint32_t value = *(uint32_t*)(EEPROM_ADDR+(address-offset)); - for(int i = 0; i < offset; i++) - { - value>>=8; - } - value &= 0x000000FF; - return (uint8_t)value; -} - -uint32_t& CurieEEPROM::operator[](int i) -{ - return *(uint32_t*)(EEPROM_ADDR+i*sizeof(uint32_t)); -} - -int CurieEEPROM::length() -{ - return EEPROM_SIZE; -} - -int CurieEEPROM::begin() -{ - return 0x00; -} - -int CurieEEPROM::end() -{ - return length(); -} diff --git a/libraries/CurieEEPROM/src/CurieEEPROM.h b/libraries/CurieEEPROM/src/CurieEEPROM.h deleted file mode 100644 index cfbce2cb..00000000 --- a/libraries/CurieEEPROM/src/CurieEEPROM.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation. All rights 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 Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#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 512 //EEPROM size in dwords - - -#include -#include "Arduino.h" - -class CurieEEPROM -{ -public: - CurieEEPROM() - { - - } - void clear(); - void write(uint32_t address, uint32_t data); - void write8(uint32_t address, uint8_t data); - void update(uint32_t addr, uint32_t value); - void update8(uint32_t addr, uint8_t value); - uint32_t read(uint32_t addr); - uint8_t read8(uint32_t addr); - - uint32_t& operator[](int i); - - int length(); - int begin(); - int end(); - - //Functionality to 'get' and 'put' objects to and from EEPROM. - template< typename T > T &get(uint32_t addr, T &t) - { - //make sure address is within valid range - if(addr > 0x1FF) - { - return t; - } - - int byteCount = sizeof(T); - //return if object size is too big - if(addr + byteCount > 0x7FC) - { - return t; - } - - //allign address to 32-bit addressing - addr*=sizeof(uint32_t); - - byte *bytes = to_bytes(t); - for(int i = 0; i < byteCount; i++) - { - bytes[i] = read8(addr+i); - } - from_bytes(bytes, t); - delete bytes; - return t; - } - template< typename T > T put(uint32_t addr, T t) - { - //make sure address is within valid range - if(addr > 0x1FF) - { - return t; - } - uint32_t rom_wr_ctrl = 0; - int byteCount = sizeof(T); - - //return if object size is too big - if(addr + byteCount > 0x7FC) - { - return t; - } - - size_t size = (sizeof(T)/4 + (((sizeof(T)%4)>1) ? 1 : 0)); - uint32_t *dwords = to_dwords(t); - - //check if address is empty and available for writing new data - bool blockAvailable = true; - for(int i =0; i < size; i++) - { - uint32_t data32 = read(addr+i); - if(data32 != 0xFFFFFFFF) - { - blockAvailable = false; - } - } - if(blockAvailable) - { - for(int i = 0; i byte* to_bytes(const T& object) - { - size_t buffer_size = sizeof(object); - byte *buffer = new byte[buffer_size]; - memcpy(buffer, &object, buffer_size); - - return buffer; - } - - template< typename T > uint32_t* to_dwords(const T& object) - { - size_t buffer_size = sizeof(object); - uint32_t *buffer = new uint32_t[buffer_size]; - memcpy(buffer, &object, buffer_size); - - return buffer; - } - - template< typename T > T& from_bytes(byte* bytes, T& object ) - { - memcpy(&object, bytes, sizeof(object)); - return object; - } -}; - -extern CurieEEPROM EEPROM; diff --git a/libraries/EEPROM/README.md b/libraries/EEPROM/README.md new file mode 100644 index 00000000..a6241361 --- /dev/null +++ b/libraries/EEPROM/README.md @@ -0,0 +1,139 @@ +## **EEPROM Library V2.0** for Arduino + +**Written by:** _Christopher Andrews_. + +### **What is the EEPROM library.** + +Th EEPROM library provides an easy to use interface to interact with the internal non-volatile storage found in AVR based Arduino boards. This library will work on many AVR devices like ATtiny and ATmega chips. + +### **How to use it** +The EEPROM library is included in your IDE download. To add its functionality to your sketch you'll need to reference the library header file. You do this by adding an include directive to the top of your sketch. + +```Arduino +#include + +void setup(){ + +} + +void loop(){ + +} + +``` + +The library provides a global variable named `EEPROM`, you use this variable to access the library functions. The methods provided in the EEPROM class are listed below. + +You can view all the examples [here](examples/). + +### **Library functions** + +#### **`EEPROM.read( address )`** [[_example_]](examples/eeprom_read/eeprom_read.ino) + +This function allows you to read a single byte of data from the eeprom. +Its only parameter is an `int` which should be set to the address you wish to read. + +The function returns an `unsigned char` containing the value read. + +#### **`EEPROM.write( address, value )`** [[_example_]](examples/eeprom_write/eeprom_write.ino) + +The `write()` method allows you to write a single byte of data to the EEPROM. +Two parameters are needed. The first is an `int` containing the address that is to be written, and the second is a the data to be written (`unsigned char`). + +This function does not return any value. + +#### **`EEPROM.update( address, value )`** [[_example_]](examples/eeprom_update/eeprom_update.ino) + +This function is similar to `EEPROM.write()` however this method will only write data if the cell contents pointed to by `address` is different to `value`. This method can help prevent unnecessary wear on the EEPROM cells. + +This function does not return any value. + +#### **`EEPROM.get( address, object )`** [[_example_]](examples/eeprom_get/eeprom_get.ino) + +This function will retrieve any object from the EEPROM. +Two parameters are needed to call this function. The first is an `int` containing the address that is to be written, and the second is the object you would like to read. + +This function returns a reference to the `object` passed in. It does not need to be used and is only returned for conveience. + +#### **`EEPROM.put( address, object )`** [[_example_]](examples/eeprom_put/eeprom_put.ino) + +This function will write any object to the EEPROM. +Two parameters are needed to call this function. The first is an `int` containing the address that is to be written, and the second is the object you would like to write. + +This function uses the _update_ method to write its data, and therefore only rewrites changed cells. + +This function returns a reference to the `object` passed in. It does not need to be used and is only returned for conveience. + +#### **Subscript operator: `EEPROM[address]`** [[_example_]](examples/eeprom_crc/eeprom_crc.ino) + +This operator allows using the identifier `EEPROM` like an array. +EEPROM cells can be read _and_ **_written_** directly using this method. + +This operator returns a reference to the EEPROM cell. + +```c++ +unsigned char val; + +//Read first EEPROM cell. +val = EEPROM[ 0 ]; + +//Write first EEPROM cell. +EEPROM[ 0 ] = val; + +//Compare contents +if( val == EEPROM[ 0 ] ){ + //Do something... +} +``` + +#### **`EEPROM.length()`** + +This function returns an `unsigned int` containing the number of cells in the EEPROM. + +--- + +### **Advanced features** + +This library uses a component based approach to provide its functionality. This means you can also use these components to design a customized approach. Two background classes are available for use: `EERef` & `EEPtr`. + +#### **`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. + +```C++ +EERef ref = EEPROM[ 10 ]; //Create a reference to 11th cell. + +ref = 4; //write to EEPROM cell. + +unsigned char val = ref; //Read referenced cell. +``` + +#### **`EEPtr` class** + +This object is a bidirectional pointer to EEPROM cells represented by `EERef` objects. +Just like a normal pointer type, this type can be dereferenced and repositioned using +increment/decrement operators. + +```C++ +EEPtr ptr = 10; //Create a pointer to 11th cell. + +*ptr = 4; //dereference and write to EEPROM cell. + +unsigned char val = *ptr; //dereference and read. + +ptr++; //Move to next EEPROM cell. +``` + +#### **`EEPROM.begin()`** + +This function returns an `EEPtr` pointing to the first cell in the EEPROM. +This is useful for STL objects, custom iteration and C++11 style ranged for loops. + +#### **`EEPROM.end()`** + +This function returns an `EEPtr` pointing at the location after the last EEPROM cell. +Used with `begin()` to provide custom iteration. + +**Note:** The `EEPtr` returned is invalid as it is out of range. Infact the hardware causes wrapping of the address (overflow) and `EEPROM.end()` actually references the first EEPROM cell. diff --git a/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino b/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino new file mode 100644 index 00000000..8b5121c8 --- /dev/null +++ b/libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino @@ -0,0 +1,39 @@ +/* + * EEPROM Clear + * + * Sets all of the bytes of the EEPROM to 0. + * Please see eeprom_iteration for a more in depth + * look at how to traverse the EEPROM. + * + * This example code is in the public domain. + */ + +#include + +void setup() { + // initialize the LED pin as an output. + pinMode(13, OUTPUT); + + /*** + Iterate through each byte of the EEPROM storage. + + Larger AVR processors have larger EEPROM sizes, E.g: + - Arduno Duemilanove: 512b EEPROM storage. + - Arduino Uno: 1kb EEPROM storage. + - Arduino Mega: 4kb EEPROM storage. + + Rather than hard-coding the length, you should use the pre-provided length function. + This will make your code portable to all AVR processors. + ***/ + + for (int i = 0 ; i < EEPROM.length() ; i++) { + EEPROM.write(i, 0); + } + + // turn the LED on when we're done + digitalWrite(13, HIGH); +} + +void loop() { + /** Empty loop. **/ +} diff --git a/libraries/CurieEEPROM/examples/eeprom_crc/eeprom_crc.ino b/libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino similarity index 88% rename from libraries/CurieEEPROM/examples/eeprom_crc/eeprom_crc.ino rename to libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino index 84294810..c6db85c3 100644 --- a/libraries/CurieEEPROM/examples/eeprom_crc/eeprom_crc.ino +++ b/libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino @@ -5,11 +5,10 @@ A CRC is a simple way of checking whether data has changed or become corrupted. This example calculates a CRC value directly on the EEPROM values. The purpose of this example is to highlight how the EEPROM object can be used just like an array. - - 01/05/2016 - Modified for Arduino 101 - Dino Tinitigan ***/ -#include +#include +#include void setup() { @@ -44,10 +43,10 @@ unsigned long eeprom_crc(void) { unsigned long crc = ~0L; - for (int index = 0 ; index < EEPROM.length(); ++index) { + for (int index = 0 ; index < EEPROM.length() ; ++index) { crc = crc_table[(crc ^ EEPROM[index]) & 0x0f] ^ (crc >> 4); crc = crc_table[(crc ^ (EEPROM[index] >> 4)) & 0x0f] ^ (crc >> 4); crc = ~crc; } return crc; -} \ No newline at end of file +} diff --git a/libraries/CurieEEPROM/examples/eeprom_get/eeprom_get.ino b/libraries/EEPROM/examples/eeprom_get/eeprom_get.ino similarity index 94% rename from libraries/CurieEEPROM/examples/eeprom_get/eeprom_get.ino rename to libraries/EEPROM/examples/eeprom_get/eeprom_get.ino index 2fd3e072..a07cee7c 100644 --- a/libraries/CurieEEPROM/examples/eeprom_get/eeprom_get.ino +++ b/libraries/EEPROM/examples/eeprom_get/eeprom_get.ino @@ -15,7 +15,7 @@ Released under MIT licence. ***/ -#include +#include void setup() { @@ -52,7 +52,7 @@ struct MyObject { }; void secondTest() { - int eeAddress = 1; //Move address to the next byte after float 'f'. + int eeAddress = sizeof(float); //Move address to the next byte after float 'f'. MyObject customVar; //Variable to store custom object read from EEPROM. EEPROM.get(eeAddress, customVar); diff --git a/libraries/EEPROM/examples/eeprom_iteration/eeprom_iteration.ino b/libraries/EEPROM/examples/eeprom_iteration/eeprom_iteration.ino new file mode 100644 index 00000000..3673b472 --- /dev/null +++ b/libraries/EEPROM/examples/eeprom_iteration/eeprom_iteration.ino @@ -0,0 +1,57 @@ +/*** + eeprom_iteration example. + + A set of example snippets highlighting the + simplest methods for traversing the EEPROM. + + Running this sketch is not necessary, this is + simply highlighting certain programming methods. + + Written by Christopher Andrews 2015 + Released under MIT licence. +***/ + +#include + +void setup() { + + /*** + Iterate the EEPROM using a for loop. + ***/ + + for (int index = 0 ; index < EEPROM.length() ; index++) { + + //Add one to each cell in the EEPROM + EEPROM[ index ] += 1; + } + + /*** + Iterate the EEPROM using a while loop. + ***/ + + int index = 0; + + while (index < EEPROM.length()) { + + //Add one to each cell in the EEPROM + EEPROM[ index ] += 1; + index++; + } + + /*** + Iterate the EEPROM using a do-while loop. + ***/ + + int idx = 0; //Used 'idx' to avoid name conflict with 'index' above. + + do { + + //Add one to each cell in the EEPROM + EEPROM[ idx ] += 1; + idx++; + } while (idx < EEPROM.length()); + + +} //End of setup function. + +void loop() {} \ No newline at end of file diff --git a/libraries/CurieEEPROM/examples/eeprom_put/eeprom_put.ino b/libraries/EEPROM/examples/eeprom_put/eeprom_put.ino similarity index 92% rename from libraries/CurieEEPROM/examples/eeprom_put/eeprom_put.ino rename to libraries/EEPROM/examples/eeprom_put/eeprom_put.ino index 4435e7c4..c1ba0a57 100644 --- a/libraries/CurieEEPROM/examples/eeprom_put/eeprom_put.ino +++ b/libraries/EEPROM/examples/eeprom_put/eeprom_put.ino @@ -14,7 +14,7 @@ Released under MIT licence. ***/ -#include +#include struct MyObject { float field1; @@ -47,7 +47,8 @@ void setup() { "Working!" }; - eeAddress++; + eeAddress += sizeof(float); //Move address to the next byte after float 'f'. + EEPROM.put(eeAddress, customVar); Serial.print("Written custom data type! \n\nView the example sketch eeprom_get to see how you can retrieve the values!"); } diff --git a/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino b/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino new file mode 100644 index 00000000..a8a3510d --- /dev/null +++ b/libraries/EEPROM/examples/eeprom_read/eeprom_read.ino @@ -0,0 +1,56 @@ +/* + * EEPROM Read + * + * Reads the value of each byte of the EEPROM and prints it + * to the computer. + * This example code is in the public domain. + */ + +#include + +// start reading from the first byte (address 0) of the EEPROM +int address = 0; +byte value; + +void setup() { + // initialize serial and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } +} + +void loop() { + // read a byte from the current address of the EEPROM + value = EEPROM.read(address); + + Serial.print(address); + Serial.print("\t"); + Serial.print(value, DEC); + Serial.println(); + + /*** + Advance to the next address, when at the end restart at the beginning. + + Larger AVR processors have larger EEPROM sizes, E.g: + - Arduno Duemilanove: 512b EEPROM storage. + - Arduino Uno: 1kb EEPROM storage. + - Arduino Mega: 4kb EEPROM storage. + + Rather than hard-coding the length, you should use the pre-provided length function. + This will make your code portable to all AVR processors. + ***/ + address = address + 1; + if (address == EEPROM.length()) { + address = 0; + } + + /*** + As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an + EEPROM address is also doable by a bitwise and of the length - 1. + + ++address &= EEPROM.length() - 1; + ***/ + + delay(500); +} diff --git a/libraries/EEPROM/examples/eeprom_update/eeprom_update.ino b/libraries/EEPROM/examples/eeprom_update/eeprom_update.ino new file mode 100644 index 00000000..5e3db5b4 --- /dev/null +++ b/libraries/EEPROM/examples/eeprom_update/eeprom_update.ino @@ -0,0 +1,71 @@ +/*** + EEPROM Update method + + Stores values read from analog input 0 into the EEPROM. + These values will stay in the EEPROM when the board is + turned off and may be retrieved later by another sketch. + + If a value has not changed in the EEPROM, it is not overwritten + which would reduce the life span of the EEPROM unnecessarily. + + Released using MIT licence. + ***/ + +#include + +/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/ +int address = 0; + +void setup() { + /** EMpty setup **/ +} + +void loop() { + /*** + need to divide by 4 because analog inputs range from + 0 to 1023 and each byte of the EEPROM can only hold a + value from 0 to 255. + ***/ + int val = analogRead(0) / 4; + + /*** + Update the particular EEPROM cell. + these values will remain there when the board is + turned off. + ***/ + EEPROM.update(address, val); + + /*** + The function EEPROM.update(address, val) is equivalent to the following: + + if( EEPROM.read(address) != val ){ + EEPROM.write(address, val); + } + ***/ + + + /*** + Advance to the next address, when at the end restart at the beginning. + + Larger AVR processors have larger EEPROM sizes, E.g: + - Arduno Duemilanove: 512b EEPROM storage. + - Arduino Uno: 1kb EEPROM storage. + - Arduino Mega: 4kb EEPROM storage. + + Rather than hard-coding the length, you should use the pre-provided length function. + This will make your code portable to all AVR processors. + ***/ + address = address + 1; + if (address == EEPROM.length()) { + address = 0; + } + + /*** + As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an + EEPROM address is also doable by a bitwise and of the length - 1. + + ++address &= EEPROM.length() - 1; + ***/ + + delay(100); +} diff --git a/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino b/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino new file mode 100644 index 00000000..f9bea641 --- /dev/null +++ b/libraries/EEPROM/examples/eeprom_write/eeprom_write.ino @@ -0,0 +1,60 @@ +/* + * EEPROM Write + * + * Stores values read from analog input 0 into the EEPROM. + * These values will stay in the EEPROM when the board is + * turned off and may be retrieved later by another sketch. + */ + +#include + +/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/ +int addr = 0; + +void setup() { + /** Empty setup. **/ +} + +void loop() { + /*** + Need to divide by 4 because analog inputs range from + 0 to 1023 and each byte of the EEPROM can only hold a + value from 0 to 255. + ***/ + + int val = analogRead(0) / 4; + + /*** + Write the value to the appropriate byte of the EEPROM. + these values will remain there when the board is + turned off. + ***/ + + EEPROM.write(addr, val); + + /*** + Advance to the next address, when at the end restart at the beginning. + + Larger AVR processors have larger EEPROM sizes, E.g: + - Arduno Duemilanove: 512b EEPROM storage. + - Arduino Uno: 1kb EEPROM storage. + - Arduino Mega: 4kb EEPROM storage. + + Rather than hard-coding the length, you should use the pre-provided length function. + This will make your code portable to all AVR processors. + ***/ + addr = addr + 1; + if (addr == EEPROM.length()) { + addr = 0; + } + + /*** + As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an + EEPROM address is also doable by a bitwise and of the length - 1. + + ++addr &= EEPROM.length() - 1; + ***/ + + + delay(100); +} diff --git a/libraries/CurieEEPROM/keywords.txt b/libraries/EEPROM/keywords.txt similarity index 70% rename from libraries/CurieEEPROM/keywords.txt rename to libraries/EEPROM/keywords.txt index 2225b9ce..2cabc0b0 100644 --- a/libraries/CurieEEPROM/keywords.txt +++ b/libraries/EEPROM/keywords.txt @@ -6,23 +6,16 @@ # Datatypes (KEYWORD1) ####################################### -CurieEEPROM KEYWORD1 -EEPROM KEYWORD1 +EEPROM KEYWORD1 +EERef KEYWORD1 +EEPtr KEYWORD2 ####################################### # Methods and Functions (KEYWORD2) ####################################### -write KEYWORD2 -write8 KEYWORD2 update KEYWORD2 -update8 KEYWORD2 -clear KEYWORD2 -begin KEYWORD2 -end KEYWORD2 -length KEYWORD2 -put KEYWORD2 -get KEYWORD2 + ####################################### # Constants (LITERAL1) ####################################### diff --git a/libraries/EEPROM/library.properties b/libraries/EEPROM/library.properties new file mode 100644 index 00000000..325290cf --- /dev/null +++ b/libraries/EEPROM/library.properties @@ -0,0 +1,10 @@ +name=EEPROM +version=2.0 +author=Arduino, Christopher Andrews, Intel +maintainer=Arduino +sentence=Enables reading and writing to the permanent board storage. +paragraph=This library allows to read and write data in a memory type, the EEPROM, that keeps its content also when the board is powered off. The amount of EEPROM available depends on the microcontroller type. +category=Data Storage +url=http://www.arduino.cc/en/Reference/EEPROM +architectures=arc32 + diff --git a/libraries/EEPROM/src/EEPROM.h b/libraries/EEPROM/src/EEPROM.h new file mode 100644 index 00000000..c52737c7 --- /dev/null +++ b/libraries/EEPROM/src/EEPROM.h @@ -0,0 +1,256 @@ +/* + 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() +{ + //erase the 2k bytes of the eeprom section inside the otp area + *(uint32_t*)(ROM_WR_CTRL) = 0x4002; + //wait for erase to be complete + #if 0 + while(((*(uint32_t*)FLASH_STTS) & 0x01) == 0) { // TODO: wait for FLASH_STTS.ER_DONE to be set to 1 + delay(1); + } + #endif + delay(5); +} + +void CurieRestoreMemory(uint32_t* buffer, uint32_t size) +{ + uint32_t rom_wr_ctrl = 0; + uint32_t address; + + for (uint32_t i=0; i 0x7FF)) + { + return 0; + } + int offset = address%4; + uint32_t value = *(uint32_t*)(EEPROM_ADDR+(address/4)*4); + value = (value >> ((3-offset)*8)) & 0xFF; + return (uint8_t)value; +} + +uint32_t CurieRead32(uint32_t address) +{ + if((address > 0x7FF)) + { + return 0; + } + uint32_t value = *(uint32_t*)(EEPROM_ADDR+(address/4)*4); + return value; +} + +void CurieWrite8(uint32_t address, uint8_t data) +{ + //make sure address is valid + if((address > 0x7FF)) + { + return; + } + + uint8_t currentValue = CurieRead8(address); + //only do something if value is different from what is currently stored + if(currentValue==data) + { + return; + } + + uint32_t currentDword = CurieRead32(address); + + int offset = address%4; + + uint32_t data32 = (currentDword & ~(uint32_t)(0xFF << ((3-offset)*8))); + data32 = data32 | (data << ((3-offset)*8)); + + if (currentValue != 0xFF) { + uint32_t dump[EEPROM_SIZE/4]; + memcpy(dump, (uint32_t *)EEPROM_ADDR, EEPROM_SIZE); + dump[(address >> 2)] = data32; + CurieClear(); + CurieRestoreMemory((uint32_t *)dump, EEPROM_SIZE/sizeof(uint32_t)); + return; + } + + uint32_t rom_wr_ctrl = 0; + + //store data into ROM_WR_DATA register + *(uint32_t*)(ROM_WR_DATA) = data32; + address = ((address >> 2) << 2) + EEPROM_OFFSET; + rom_wr_ctrl = (address)<<2; //shift left 2 bits to store offset into bits 19:2 (WR_ADDR) + rom_wr_ctrl |= 0x00000001; //set (WR_REQ) bit + *(uint32_t*)(ROM_WR_CTRL) = rom_wr_ctrl; + + delay(3); //give it enough time to finish writing +} + +/*** + 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; + } +}; + +static EEPROMClass EEPROM; +#endif \ No newline at end of file