Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
### Added
- Add `__AVR__` to defines when compiling
- 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;
3 changes: 3 additions & 0 deletions cpp/arduino/Godmode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,6 @@ SPIClass SPI = SPIClass(&GODMODE()->spi.dataIn, &GODMODE()->spi.dataOut);

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

#include <EEPROM.h>
EEPROMClass EEPROM;
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 @@ -54,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) {
Expand Down Expand Up @@ -87,12 +99,19 @@ class GodmodeState {
spi.readDelayMicros = 0;
}

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

void reset() {
resetClock();
resetPins();
resetInterrupts();
resetPorts();
resetSPI();
resetEEPROM();
seed = 1;
}

Expand Down