Skip to content

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
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
6b22fe6
Introduce EEPROM support (#166)
Oct 3, 2020
1888372
Merge branch 'master' into eeprom
Oct 5, 2020
1011dc4
Update CHANGELOG.md
Oct 5, 2020
3c437aa
Merge pull request #173 from jgfoster/eeprom
ianfixes Oct 5, 2020
c512f28
Only include EEPROM if board supports it.
Oct 5, 2020
d82c1cf
Merge branch 'master' into tdd
Oct 5, 2020
524d352
Add EEPROM_SIZE to mega boards.
Oct 6, 2020
8ed2732
Move `EEPROM_SIZE` macro to `misc/default.yml`.
Oct 6, 2020
fadc743
Use E2END to calculate EEPROM_SIZE.
Oct 6, 2020
0ee5170
EEPROM is tested by uno and due so we don't need to add mega2560 (one…
Oct 6, 2020
4605207
Simplify reference to EEPROM library.
Oct 7, 2020
3502211
Merge pull request #174 from jgfoster/eeprom
ianfixes Oct 9, 2020
74a35e0
Merge branch 'master' of https://github.com/Lizj96/arduino_ci into tdd
Oct 11, 2020
2ad0131
adding tests for EEPROM
Oct 11, 2020
5c26abd
test high memory and array read.
Oct 12, 2020
f923a7f
add setup to reset memory before each test
Oct 12, 2020
a0677ff
Merge pull request #178 from Arduino-CI/master
ianfixes Oct 12, 2020
9b5cd4c
Merge pull request #177 from Lizj96/tdd
ianfixes Oct 16, 2020
9c74e43
Add documentation of EEPROM (fix #190).
Oct 27, 2020
7784e37
Merge pull request #191 from jgfoster/tdd
ianfixes Oct 27, 2020
476dcda
Merge branch 'master' into tdd
ianfixes Nov 4, 2020
d7e7653
Rewrite EEPROM.h to avoid GNU-licensed code.
Nov 8, 2020
03e4168
Conditionalize inclusion of EEPROM.
Nov 9, 2020
a5dc7b6
Merge branch 'master' into tdd
ianfixes Nov 10, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Added
- Add `__AVR__` to defines when compiling
- Add support for `diditalPinToPort()`, `digitalPinToBitMask()`, and `portOutputRegister()`
- Support for mock EEPROM (but only if board supports it)

### Changed
- Move repository from https://github.com/ianfixes/arduino_ci to https://github.com/Arduino-CI/arduino_ci
Expand Down
37 changes: 37 additions & 0 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -581,3 +581,40 @@ unittest(spi) {
assertEqual("LMNOe", String(inBuf));
}
```

### EEPROM

`EEPROM` is a global with a simple API to read and write bytes to persistent memory (like a tiny hard disk) given an `int` location. Since the Arduino core already provides this as a global, and the core API is sufficient for basic testing (read/write), there is no direct tie to the `GODMODE` API. (If you need more, such as a log of intermediate values, enter a feature request.)

```C++
unittest(eeprom)
{
uint8_t a;
// size
assertEqual(EEPROM_SIZE, EEPROM.length());
// initial values
a = EEPROM.read(0);
assertEqual(255, a);
// write and read
EEPROM.write(0, 24);
a = EEPROM.read(0);
assertEqual(24, a);
// update
EEPROM.write(1, 14);
EEPROM.update(1, 22);
a = EEPROM.read(1);
assertEqual(22, a);
// put and get
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);
// array access
int val = 10;
EEPROM[2] = val;
a = EEPROM[2];
assertEqual(10, a);
}
```
80 changes: 80 additions & 0 deletions SampleProjects/TestSomething/test/eeprom.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include <ArduinoUnitTests.h>
#include <Arduino.h>
#include <Godmode.h>

// Only run EEPROM tests if there is hardware support!
#if defined(EEPROM_SIZE)
#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, 255);
a = EEPROM.read(0);
assertEqual(255, 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()
64 changes: 64 additions & 0 deletions cpp/arduino/EEPROM.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#pragma once

#include <cassert>
#include <inttypes.h>
#include <Godmode.h>

// 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

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 <typename T> 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);
}
return object;
}

// write any object
template <typename T> 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++);
}
return object;
}
};

// global available in Godmode.cpp
extern EEPROMClass EEPROM;
5 changes: 5 additions & 0 deletions cpp/arduino/Godmode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,8 @@ SPIClass SPI = SPIClass(&GODMODE()->spi.dataIn, &GODMODE()->spi.dataOut);

// defined in Wire.h
TwoWire Wire = TwoWire();

#if defined(EEPROM_SIZE)
#include <EEPROM.h>
EEPROMClass EEPROM;
#endif
19 changes: 19 additions & 0 deletions cpp/arduino/Godmode.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,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 {
Expand All @@ -56,6 +67,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) {
Expand Down Expand Up @@ -94,6 +106,12 @@ class GodmodeState {
mmapPorts[i] = 1;
}
}

void resetEEPROM() {
for(int i = 0; i < EEPROM_SIZE; ++i) {
eeprom[i] = 255;
}
}

void reset() {
resetClock();
Expand All @@ -102,6 +120,7 @@ class GodmodeState {
resetPorts();
resetSPI();
resetMmapPorts();
resetEEPROM();
seed = 1;
}

Expand Down