Skip to content

Commit 481ffaf

Browse files
author
James Foster
committed
Rewrite EEPROM.h to avoid GNU-licensed code.
1 parent 476dcda commit 481ffaf

File tree

4 files changed

+75
-161
lines changed

4 files changed

+75
-161
lines changed

Diff for: SampleProjects/TestSomething/test/eeprom.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#include <ArduinoUnitTests.h>
22
#include <Arduino.h>
3+
#include <Godmode.h>
34

45
// Only run EEPROM tests if there is hardware support!
5-
#if defined(EEPROM_SIZE) || (defined(E2END) && E2END)
6+
#if defined(EEPROM_SIZE)
67
#include <EEPROM.h>
78

89
GodmodeState* state = GODMODE();
10+
911
unittest_setup()
1012
{
1113
state->reset();
@@ -32,9 +34,9 @@ unittest(writeRead)
3234
a = EEPROM.read(0);
3335
assertEqual(128, a);
3436

35-
EEPROM.write(0, 256);
37+
EEPROM.write(0, 255);
3638
a = EEPROM.read(0);
37-
assertEqual(0, a);
39+
assertEqual(255, a);
3840

3941
int addr = EEPROM_SIZE / 2;
4042
EEPROM.write(addr, 63);

Diff for: cpp/arduino/EEPROM.h

+53-155
Original file line numberDiff line numberDiff line change
@@ -1,166 +1,64 @@
1-
/*
2-
EEPROM.h - EEPROM library
3-
Original Copyright (c) 2006 David A. Mellis. All right reserved.
4-
New version by Christopher Andrews 2015.
5-
6-
Copy of https://github.com/arduino/ArduinoCore-megaavr/blob/c8a1dd996c783777ec46167cfd8ad3fd2e6df185/libraries/EEPROM/src/EEPROM.h
7-
modified by James Foster in 2020 to work with Arduino CI.
8-
9-
This library is free software; you can redistribute it and/or
10-
modify it under the terms of the GNU Lesser General Public
11-
License as published by the Free Software Foundation; either
12-
version 2.1 of the License, or (at your option) any later version.
13-
14-
This library is distributed in the hope that it will be useful,
15-
but WITHOUT ANY WARRANTY; without even the implied warranty of
16-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17-
Lesser General Public License for more details.
18-
19-
You should have received a copy of the GNU Lesser General Public
20-
License along with this library; if not, write to the Free Software
21-
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22-
*/
23-
24-
#ifndef EEPROM_h
25-
#define EEPROM_h
1+
#pragma once
262

3+
#include <cassert>
274
#include <inttypes.h>
28-
#include <avr/io.h>
29-
30-
// different EEPROM implementations have different macros that leak out
31-
#if !defined(EEPROM_SIZE) && defined(E2END) && (E2END)
32-
#define EEPROM_SIZE (E2END + 1)
33-
#endif
5+
#include <Godmode.h>
346

357
// Does the current board have EEPROM?
368
#ifndef EEPROM_SIZE
37-
// In lieu of an "EEPROM.h not found" error for unsupported boards
38-
#error "EEPROM library not available for your board"
9+
// In lieu of an "EEPROM.h not found" error for unsupported boards
10+
#error "EEPROM library not available for your board"
3911
#endif
4012

41-
// On a real device this would be in hardware, but we have a mock board!
42-
static uint8_t eeprom[EEPROM_SIZE];
43-
inline uint8_t eeprom_read_byte( uint8_t* index ) { return eeprom[(unsigned long) index % EEPROM_SIZE]; }
44-
inline void eeprom_write_byte( uint8_t* index, uint8_t value ) { eeprom[(unsigned long) index % EEPROM_SIZE] = value; }
45-
46-
// Everything following is from the original (referenced above)
47-
48-
/***
49-
EERef class.
50-
51-
This object references an EEPROM cell.
52-
Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM.
53-
This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell.
54-
***/
55-
56-
struct EERef{
57-
58-
EERef( const int index )
59-
: index( index ) {}
60-
61-
//Access/read members.
62-
uint8_t operator*() const { return eeprom_read_byte( (uint8_t*) index ); }
63-
operator uint8_t() const { return **this; }
64-
65-
//Assignment/write members.
66-
EERef &operator=( const EERef &ref ) { return *this = *ref; }
67-
EERef &operator=( uint8_t in ) { return eeprom_write_byte( (uint8_t*) index, in ), *this; }
68-
EERef &operator +=( uint8_t in ) { return *this = **this + in; }
69-
EERef &operator -=( uint8_t in ) { return *this = **this - in; }
70-
EERef &operator *=( uint8_t in ) { return *this = **this * in; }
71-
EERef &operator /=( uint8_t in ) { return *this = **this / in; }
72-
EERef &operator ^=( uint8_t in ) { return *this = **this ^ in; }
73-
EERef &operator %=( uint8_t in ) { return *this = **this % in; }
74-
EERef &operator &=( uint8_t in ) { return *this = **this & in; }
75-
EERef &operator |=( uint8_t in ) { return *this = **this | in; }
76-
EERef &operator <<=( uint8_t in ) { return *this = **this << in; }
77-
EERef &operator >>=( uint8_t in ) { return *this = **this >> in; }
78-
79-
EERef &update( uint8_t in ) { return in != *this ? *this = in : *this; }
80-
81-
/** Prefix increment/decrement **/
82-
EERef& operator++() { return *this += 1; }
83-
EERef& operator--() { return *this -= 1; }
84-
85-
/** Postfix increment/decrement **/
86-
uint8_t operator++ (int){
87-
uint8_t ret = **this;
88-
return ++(*this), ret;
13+
class EEPROMClass {
14+
private:
15+
GodmodeState* state;
16+
public:
17+
// constructor
18+
EEPROMClass() {
19+
state = GODMODE();
20+
}
21+
// array subscript operator
22+
uint8_t &operator[](const int index) {
23+
assert(index < EEPROM_SIZE);
24+
return state->eeprom[index];
25+
}
26+
27+
uint8_t read(const int index) {
28+
assert(index < EEPROM_SIZE);
29+
return state->eeprom[index];
30+
}
31+
32+
void write(const int index, const uint8_t value) {
33+
assert(index < EEPROM_SIZE);
34+
state->eeprom[index] = value;
35+
}
36+
37+
void update(const int index, const uint8_t value) {
38+
assert(index < EEPROM_SIZE);
39+
state->eeprom[index] = value;
40+
}
41+
42+
uint16_t length() { return EEPROM_SIZE; }
43+
44+
// read any object
45+
template <typename T> T &get(const int index, T &object) {
46+
uint8_t *ptr = (uint8_t *)&object;
47+
for (int i = 0; i < sizeof(T); ++i) {
48+
*ptr++ = read(index + i);
8949
}
90-
91-
uint8_t operator-- (int){
92-
uint8_t ret = **this;
93-
return --(*this), ret;
50+
return object;
51+
}
52+
53+
// write any object
54+
template <typename T> const T &put(const int index, T &object) {
55+
const uint8_t *ptr = (const uint8_t *)&object;
56+
for (int i = 0; i < sizeof(T); ++i) {
57+
write(index + i, *ptr++);
9458
}
95-
96-
int index; //Index of current EEPROM cell.
59+
return object;
60+
}
9761
};
9862

99-
/***
100-
EEPtr class.
101-
102-
This object is a bidirectional pointer to EEPROM cells represented by EERef objects.
103-
Just like a normal pointer type, this can be dereferenced and repositioned using
104-
increment/decrement operators.
105-
***/
106-
107-
struct EEPtr{
108-
109-
EEPtr( const int index )
110-
: index( index ) {}
111-
112-
operator int() const { return index; }
113-
EEPtr &operator=( int in ) { return index = in, *this; }
114-
115-
//Iterator functionality.
116-
bool operator!=( const EEPtr &ptr ) { return index != ptr.index; }
117-
EERef operator*() { return index; }
118-
119-
/** Prefix & Postfix increment/decrement **/
120-
EEPtr& operator++() { return ++index, *this; }
121-
EEPtr& operator--() { return --index, *this; }
122-
EEPtr operator++ (int) { return index++; }
123-
EEPtr operator-- (int) { return index--; }
124-
125-
int index; //Index of current EEPROM cell.
126-
};
127-
128-
/***
129-
EEPROMClass class.
130-
131-
This object represents the entire EEPROM space.
132-
It wraps the functionality of EEPtr and EERef into a basic interface.
133-
This class is also 100% backwards compatible with earlier Arduino core releases.
134-
***/
135-
136-
struct EEPROMClass{
137-
138-
//Basic user access methods.
139-
EERef operator[]( const int idx ) { return idx; }
140-
uint8_t read( int idx ) { return EERef( idx ); }
141-
void write( int idx, uint8_t val ) { (EERef( idx )) = val; }
142-
void update( int idx, uint8_t val ) { EERef( idx ).update( val ); }
143-
144-
//STL and C++11 iteration capability.
145-
EEPtr begin() { return 0x00; }
146-
EEPtr end() { return length(); } //Standards requires this to be the item after the last valid entry. The returned pointer is invalid.
147-
uint16_t length() { return EEPROM_SIZE; }
148-
149-
//Functionality to 'get' and 'put' objects to and from EEPROM.
150-
template< typename T > T &get( int idx, T &t ){
151-
EEPtr e = idx;
152-
uint8_t *ptr = (uint8_t*) &t;
153-
for( int count = sizeof(T) ; count ; --count, ++e ) *ptr++ = *e;
154-
return t;
155-
}
156-
157-
template< typename T > const T &put( int idx, const T &t ){
158-
EEPtr e = idx;
159-
const uint8_t *ptr = (const uint8_t*) &t;
160-
for( int count = sizeof(T) ; count ; --count, ++e ) (*e).update( *ptr++ );
161-
return t;
162-
}
163-
};
164-
165-
static EEPROMClass EEPROM;
166-
#endif
63+
// global available in Godmode.cpp
64+
extern EEPROMClass EEPROM;

Diff for: cpp/arduino/Godmode.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,6 @@ SPIClass SPI = SPIClass(&GODMODE()->spi.dataIn, &GODMODE()->spi.dataOut);
113113

114114
// defined in Wire.h
115115
TwoWire Wire = TwoWire();
116+
117+
#include <EEPROM.h>
118+
EEPROMClass EEPROM;

Diff for: cpp/arduino/Godmode.h

+14-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#include <avr/io.h>
44
#include "WString.h"
55
#include "PinHistory.h"
6-
#include "EEPROM.h"
76

87
// random
98
void randomSeed(unsigned long seed);
@@ -31,6 +30,17 @@ unsigned long micros();
3130
#define NUM_SERIAL_PORTS 0
3231
#endif
3332

33+
// different EEPROM implementations have different macros that leak out
34+
#if !defined(EEPROM_SIZE) && defined(E2END) && (E2END)
35+
// public value indicates that feature is available
36+
#define EEPROM_SIZE (E2END + 1)
37+
// local array size
38+
#define _EEPROM_SIZE EEPROM_SIZE
39+
#else
40+
// feature is not available but we want to have the array so other code compiles
41+
#define _EEPROM_SIZE (0)
42+
#endif
43+
3444
class GodmodeState {
3545
private:
3646
struct PortDef {
@@ -55,6 +65,7 @@ class GodmodeState {
5565
struct PortDef serialPort[NUM_SERIAL_PORTS];
5666
struct InterruptDef interrupt[MOCK_PINS_COUNT]; // not sure how to get actual number
5767
struct PortDef spi;
68+
uint8_t eeprom[_EEPROM_SIZE];
5869

5970
void resetPins() {
6071
for (int i = 0; i < MOCK_PINS_COUNT; ++i) {
@@ -89,8 +100,8 @@ class GodmodeState {
89100
}
90101

91102
void resetEEPROM() {
92-
for(int i = 0; i < EEPROM.length(); ++i){
93-
EEPROM.update(i, 255);
103+
for(int i = 0; i < EEPROM_SIZE; ++i){
104+
eeprom[i] = 255;
94105
}
95106
}
96107

0 commit comments

Comments
 (0)