From 481ffaf0a5fbe1a3ccaf443ce4a90ccc1c0e87f8 Mon Sep 17 00:00:00 2001 From: James Foster Date: Sat, 7 Nov 2020 21:08:04 -0800 Subject: [PATCH 1/2] Rewrite EEPROM.h to avoid GNU-licensed code. --- SampleProjects/TestSomething/test/eeprom.cpp | 8 +- cpp/arduino/EEPROM.h | 208 +++++-------------- cpp/arduino/Godmode.cpp | 3 + cpp/arduino/Godmode.h | 17 +- 4 files changed, 75 insertions(+), 161 deletions(-) diff --git a/SampleProjects/TestSomething/test/eeprom.cpp b/SampleProjects/TestSomething/test/eeprom.cpp index 5e2e7a6e..8a844249 100644 --- a/SampleProjects/TestSomething/test/eeprom.cpp +++ b/SampleProjects/TestSomething/test/eeprom.cpp @@ -1,11 +1,13 @@ #include #include +#include // Only run EEPROM tests if there is hardware support! -#if defined(EEPROM_SIZE) || (defined(E2END) && E2END) +#if defined(EEPROM_SIZE) #include GodmodeState* state = GODMODE(); + unittest_setup() { state->reset(); @@ -32,9 +34,9 @@ unittest(writeRead) a = EEPROM.read(0); assertEqual(128, a); - EEPROM.write(0, 256); + EEPROM.write(0, 255); a = EEPROM.read(0); - assertEqual(0, a); + assertEqual(255, a); int addr = EEPROM_SIZE / 2; EEPROM.write(addr, 63); diff --git a/cpp/arduino/EEPROM.h b/cpp/arduino/EEPROM.h index 39fa91f8..05b3daa5 100644 --- a/cpp/arduino/EEPROM.h +++ b/cpp/arduino/EEPROM.h @@ -1,166 +1,64 @@ -/* - 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 +#pragma once +#include #include -#include - -// different EEPROM implementations have different macros that leak out -#if !defined(EEPROM_SIZE) && defined(E2END) && (E2END) -#define EEPROM_SIZE (E2END + 1) -#endif +#include // 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" + // 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; +class EEPROMClass { +private: + GodmodeState* state; +public: + // constructor + EEPROMClass() { + state = GODMODE(); + } + // array subscript operator + uint8_t &operator[](const int index) { + assert(index < EEPROM_SIZE); + return state->eeprom[index]; + } + + uint8_t read(const int index) { + assert(index < EEPROM_SIZE); + return state->eeprom[index]; + } + + void write(const int index, const uint8_t value) { + assert(index < EEPROM_SIZE); + state->eeprom[index] = value; + } + + void update(const int index, const uint8_t value) { + assert(index < EEPROM_SIZE); + state->eeprom[index] = value; + } + + uint16_t length() { return EEPROM_SIZE; } + + // read any object + template T &get(const int index, T &object) { + uint8_t *ptr = (uint8_t *)&object; + for (int i = 0; i < sizeof(T); ++i) { + *ptr++ = read(index + i); } - - uint8_t operator-- (int){ - uint8_t ret = **this; - return --(*this), ret; + return object; + } + + // write any object + template const T &put(const int index, T &object) { + const uint8_t *ptr = (const uint8_t *)&object; + for (int i = 0; i < sizeof(T); ++i) { + write(index + i, *ptr++); } - - int index; //Index of current EEPROM cell. + return object; + } }; -/*** - 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 +// global available in Godmode.cpp +extern EEPROMClass EEPROM; diff --git a/cpp/arduino/Godmode.cpp b/cpp/arduino/Godmode.cpp index 102afca6..0c7afbf3 100644 --- a/cpp/arduino/Godmode.cpp +++ b/cpp/arduino/Godmode.cpp @@ -113,3 +113,6 @@ SPIClass SPI = SPIClass(&GODMODE()->spi.dataIn, &GODMODE()->spi.dataOut); // defined in Wire.h TwoWire Wire = TwoWire(); + +#include +EEPROMClass EEPROM; diff --git a/cpp/arduino/Godmode.h b/cpp/arduino/Godmode.h index 0cc16514..67e637b1 100644 --- a/cpp/arduino/Godmode.h +++ b/cpp/arduino/Godmode.h @@ -3,7 +3,6 @@ #include #include "WString.h" #include "PinHistory.h" -#include "EEPROM.h" // random void randomSeed(unsigned long seed); @@ -31,6 +30,17 @@ unsigned long micros(); #define NUM_SERIAL_PORTS 0 #endif +// different EEPROM implementations have different macros that leak out +#if !defined(EEPROM_SIZE) && defined(E2END) && (E2END) + // public value indicates that feature is available + #define EEPROM_SIZE (E2END + 1) + // local array size + #define _EEPROM_SIZE EEPROM_SIZE +#else + // feature is not available but we want to have the array so other code compiles + #define _EEPROM_SIZE (0) +#endif + class GodmodeState { private: struct PortDef { @@ -55,6 +65,7 @@ class GodmodeState { struct PortDef serialPort[NUM_SERIAL_PORTS]; struct InterruptDef interrupt[MOCK_PINS_COUNT]; // not sure how to get actual number struct PortDef spi; + uint8_t eeprom[_EEPROM_SIZE]; void resetPins() { for (int i = 0; i < MOCK_PINS_COUNT; ++i) { @@ -89,8 +100,8 @@ class GodmodeState { } void resetEEPROM() { - for(int i = 0; i < EEPROM.length(); ++i){ - EEPROM.update(i, 255); + for(int i = 0; i < EEPROM_SIZE; ++i){ + eeprom[i] = 255; } } From 53f60d48c3b249f1316f01d1f49da2d692ecdf70 Mon Sep 17 00:00:00 2001 From: James Foster Date: Sun, 8 Nov 2020 23:10:57 -0800 Subject: [PATCH 2/2] Conditionalize inclusion of EEPROM. --- cpp/arduino/Godmode.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cpp/arduino/Godmode.cpp b/cpp/arduino/Godmode.cpp index 0c7afbf3..f68867e4 100644 --- a/cpp/arduino/Godmode.cpp +++ b/cpp/arduino/Godmode.cpp @@ -114,5 +114,7 @@ SPIClass SPI = SPIClass(&GODMODE()->spi.dataIn, &GODMODE()->spi.dataOut); // defined in Wire.h TwoWire Wire = TwoWire(); -#include -EEPROMClass EEPROM; +#if defined(EEPROM_SIZE) + #include + EEPROMClass EEPROM; +#endif