-
Notifications
You must be signed in to change notification settings - Fork 34
Add support for EEPROM #184
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Changes from 21 commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
6b22fe6
Introduce EEPROM support (#166)
1888372
Merge branch 'master' into eeprom
1011dc4
Update CHANGELOG.md
3c437aa
Merge pull request #173 from jgfoster/eeprom
ianfixes c512f28
Only include EEPROM if board supports it.
d82c1cf
Merge branch 'master' into tdd
524d352
Add EEPROM_SIZE to mega boards.
8ed2732
Move `EEPROM_SIZE` macro to `misc/default.yml`.
fadc743
Use E2END to calculate EEPROM_SIZE.
0ee5170
EEPROM is tested by uno and due so we don't need to add mega2560 (one…
4605207
Simplify reference to EEPROM library.
3502211
Merge pull request #174 from jgfoster/eeprom
ianfixes 74a35e0
Merge branch 'master' of https://github.com/Lizj96/arduino_ci into tdd
2ad0131
adding tests for EEPROM
5c26abd
test high memory and array read.
f923a7f
add setup to reset memory before each test
a0677ff
Merge pull request #178 from Arduino-CI/master
ianfixes 9b5cd4c
Merge pull request #177 from Lizj96/tdd
ianfixes 9c74e43
Add documentation of EEPROM (fix #190).
7784e37
Merge pull request #191 from jgfoster/tdd
ianfixes 476dcda
Merge branch 'master' into tdd
ianfixes d7e7653
Rewrite EEPROM.h to avoid GNU-licensed code.
03e4168
Conditionalize inclusion of EEPROM.
a5dc7b6
Merge branch 'master' into tdd
ianfixes File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
#include <ArduinoUnitTests.h> | ||
#include <Arduino.h> | ||
|
||
// Only run EEPROM tests if there is hardware support! | ||
#if defined(EEPROM_SIZE) || (defined(E2END) && E2END) | ||
#include <EEPROM.h> | ||
|
||
GodmodeState* state = GODMODE(); | ||
unittest_setup() | ||
{ | ||
state->reset(); | ||
} | ||
|
||
unittest(length) | ||
{ | ||
assertEqual(EEPROM_SIZE, EEPROM.length()); | ||
} | ||
|
||
unittest(firstRead) | ||
{ | ||
uint8_t a = EEPROM.read(0); | ||
assertEqual(255, a); | ||
} | ||
|
||
unittest(writeRead) | ||
{ | ||
EEPROM.write(0, 24); | ||
uint8_t a = EEPROM.read(0); | ||
assertEqual(24, a); | ||
|
||
EEPROM.write(0, 128); | ||
a = EEPROM.read(0); | ||
assertEqual(128, a); | ||
|
||
EEPROM.write(0, 256); | ||
a = EEPROM.read(0); | ||
assertEqual(0, a); | ||
|
||
int addr = EEPROM_SIZE / 2; | ||
EEPROM.write(addr, 63); | ||
a = EEPROM.read(addr); | ||
assertEqual(63, a); | ||
|
||
addr = EEPROM_SIZE - 1; | ||
EEPROM.write(addr, 188); | ||
a = EEPROM.read(addr); | ||
assertEqual(188, a); | ||
} | ||
|
||
unittest(updateWrite) | ||
{ | ||
EEPROM.write(1, 14); | ||
EEPROM.update(1, 22); | ||
uint8_t a = EEPROM.read(1); | ||
assertEqual(22, a); | ||
} | ||
|
||
unittest(putGet) | ||
{ | ||
const float f1 = 0.025f; | ||
float f2 = 0.0f; | ||
EEPROM.put(5, f1); | ||
assertEqual(0.0f, f2); | ||
EEPROM.get(5, f2); | ||
assertEqual(0.025f, f2); | ||
} | ||
|
||
unittest(array) | ||
{ | ||
int val = 10; | ||
EEPROM[2] = val; | ||
uint8_t a = EEPROM[2]; | ||
assertEqual(10, a); | ||
} | ||
|
||
#endif | ||
|
||
unittest_main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
/* | ||
EEPROM.h - EEPROM library | ||
Original Copyright (c) 2006 David A. Mellis. All right reserved. | ||
New version by Christopher Andrews 2015. | ||
|
||
Copy of https://github.com/arduino/ArduinoCore-megaavr/blob/c8a1dd996c783777ec46167cfd8ad3fd2e6df185/libraries/EEPROM/src/EEPROM.h | ||
modified by James Foster in 2020 to work with Arduino CI. | ||
|
||
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 <inttypes.h> | ||
#include <avr/io.h> | ||
|
||
// different EEPROM implementations have different macros that leak out | ||
#if !defined(EEPROM_SIZE) && defined(E2END) && (E2END) | ||
#define EEPROM_SIZE (E2END + 1) | ||
#endif | ||
|
||
// Does the current board have EEPROM? | ||
#ifndef EEPROM_SIZE | ||
// In lieu of an "EEPROM.h not found" error for unsupported boards | ||
#error "EEPROM library not available for your board" | ||
#endif | ||
|
||
// On a real device this would be in hardware, but we have a mock board! | ||
static uint8_t eeprom[EEPROM_SIZE]; | ||
inline uint8_t eeprom_read_byte( uint8_t* index ) { return eeprom[(unsigned long) index % EEPROM_SIZE]; } | ||
inline void eeprom_write_byte( uint8_t* index, uint8_t value ) { eeprom[(unsigned long) index % EEPROM_SIZE] = value; } | ||
|
||
// Everything following is from the original (referenced above) | ||
|
||
/*** | ||
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 eeprom_read_byte( (uint8_t*) index ); } | ||
operator uint8_t() const { return **this; } | ||
|
||
//Assignment/write members. | ||
EERef &operator=( const EERef &ref ) { return *this = *ref; } | ||
EERef &operator=( uint8_t in ) { return eeprom_write_byte( (uint8_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 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably reconsider adding this directly since its license is inconsistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm really out of my depth with regard to the terms of all the different licenses, and really can't offer advice one way or another. I have no idea whether your own rewrite counts as some "derivative" in the way the licenses are written.
I think as long as we're doing our best and intend to respond to any legal complaints -- fixing the license as appropriate -- (which I do intend to do) then I'm not sure what else it would take to move forward. In any case, if we keep the file let's keep the license and it can all get sorted out later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As owner of the project, you certainly have the last word on this. But (did you sense a "but" coming?), the difference between the GNU license and your Apache license is night and day (with slight exaggeration, think Catholics and Protestants in 16th, 17th, and 18th century Europe, or Antifa vs. Proud Boys today). While I can't promise that my replacement would withstand a legal challenge, I'm pretty confident that it would be better to leave out the GNU reference. Other than the file name and the published API, I made an effort to write the code from scratch and think that the risk is extremely small. By leaving in the GNU license, you risk attaching GNU to my code, and then you would need another rewrite.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw your rewrite after adding my comment, and I think your rewrite satisfies