inital commit
This commit is contained in:
commit
13338a5725
145
eeprom_test/eeprom.cpp
Normal file
145
eeprom_test/eeprom.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
EEPROM.cpp - RP2040 EEPROM emulation
|
||||
Copyright (c) 2021 Earle F. Philhower III. All rights reserved.
|
||||
|
||||
Based on ESP8266 EEPROM library, which is
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "EEPROM.h"
|
||||
#include <hardware/flash.h>
|
||||
#include <hardware/sync.h>
|
||||
|
||||
#ifdef USE_TINYUSB
|
||||
// For Serial when selecting TinyUSB. Can't include in the core because Arduino IDE
|
||||
// will not link in libraries called from the core. Instead, add the header to all
|
||||
// the standard libraries in the hope it will still catch some user cases where they
|
||||
// use these libraries.
|
||||
// See https://github.com/earlephilhower/arduino-pico/issues/167#issuecomment-848622174
|
||||
#include <Adafruit_TinyUSB.h>
|
||||
#endif
|
||||
|
||||
extern "C" uint8_t _EEPROM_start;
|
||||
|
||||
EEPROMClass::EEPROMClass(void)
|
||||
: _sector(&_EEPROM_start) {
|
||||
}
|
||||
|
||||
void EEPROMClass::begin(size_t size) {
|
||||
if ((size <= 0) || (size > 4096)) {
|
||||
size = 4096;
|
||||
}
|
||||
|
||||
size = (size + 255) & (~255); // Flash writes limited to 256 byte boundaries
|
||||
|
||||
// In case begin() is called a 2nd+ time, don't reallocate if size is the same
|
||||
if (_data && size != _size) {
|
||||
delete[] _data;
|
||||
_data = new uint8_t[size];
|
||||
} else if (!_data) {
|
||||
_data = new uint8_t[size];
|
||||
}
|
||||
|
||||
_size = size;
|
||||
|
||||
memcpy(_data, _sector, _size);
|
||||
|
||||
_dirty = false; //make sure dirty is cleared in case begin() is called 2nd+ time
|
||||
}
|
||||
|
||||
bool EEPROMClass::end() {
|
||||
bool retval;
|
||||
|
||||
if (!_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
retval = commit();
|
||||
if (_data) {
|
||||
delete[] _data;
|
||||
}
|
||||
_data = 0;
|
||||
_size = 0;
|
||||
_dirty = false;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
uint8_t EEPROMClass::read(int const address) {
|
||||
if (address < 0 || (size_t)address >= _size) {
|
||||
return 0;
|
||||
}
|
||||
if (!_data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _data[address];
|
||||
}
|
||||
|
||||
void EEPROMClass::write(int const address, uint8_t const value) {
|
||||
if (address < 0 || (size_t)address >= _size) {
|
||||
return;
|
||||
}
|
||||
if (!_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Optimise _dirty. Only flagged if data written is different.
|
||||
uint8_t* pData = &_data[address];
|
||||
if (*pData != value) {
|
||||
*pData = value;
|
||||
_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool EEPROMClass::commit() {
|
||||
if (!_size) {
|
||||
return false;
|
||||
}
|
||||
if (!_dirty) {
|
||||
return true;
|
||||
}
|
||||
if (!_data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!__isFreeRTOS) {
|
||||
noInterrupts();
|
||||
}
|
||||
rp2040.idleOtherCore();
|
||||
flash_range_erase((intptr_t)_sector - (intptr_t)XIP_BASE, 4096);
|
||||
flash_range_program((intptr_t)_sector - (intptr_t)XIP_BASE, _data, _size);
|
||||
rp2040.resumeOtherCore();
|
||||
if (!__isFreeRTOS) {
|
||||
interrupts();
|
||||
}
|
||||
_dirty = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t * EEPROMClass::getDataPtr() {
|
||||
_dirty = true;
|
||||
return &_data[0];
|
||||
}
|
||||
|
||||
uint8_t const * EEPROMClass::getConstDataPtr() const {
|
||||
return &_data[0];
|
||||
}
|
||||
|
||||
EEPROMClass EEPROM;
|
||||
86
eeprom_test/eeprom.h
Normal file
86
eeprom_test/eeprom.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
EEPROM.cpp - RPI2040 EEPROM emulation
|
||||
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
class EEPROMClass {
|
||||
public:
|
||||
EEPROMClass(void);
|
||||
|
||||
void begin(size_t size);
|
||||
uint8_t read(int const address);
|
||||
void write(int const address, uint8_t const val);
|
||||
bool commit();
|
||||
bool end();
|
||||
|
||||
uint8_t * getDataPtr();
|
||||
uint8_t const * getConstDataPtr() const;
|
||||
|
||||
template<typename T>
|
||||
T &get(int const address, T &t) {
|
||||
if (address < 0 || address + sizeof(T) > _size) {
|
||||
return t;
|
||||
}
|
||||
|
||||
memcpy((uint8_t*) &t, _data + address, sizeof(T));
|
||||
return t;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T &put(int const address, const T &t) {
|
||||
if (address < 0 || address + sizeof(T) > _size) {
|
||||
return t;
|
||||
}
|
||||
if (memcmp(_data + address, (const uint8_t*)&t, sizeof(T)) != 0) {
|
||||
_dirty = true;
|
||||
memcpy(_data + address, (const uint8_t*)&t, sizeof(T));
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T &update(int const address, const T &t) {
|
||||
return put(address, t);
|
||||
}
|
||||
size_t length() {
|
||||
return _size;
|
||||
}
|
||||
|
||||
uint8_t& operator[](int const address) {
|
||||
return getDataPtr()[address];
|
||||
}
|
||||
uint8_t const & operator[](int const address) const {
|
||||
return getConstDataPtr()[address];
|
||||
}
|
||||
|
||||
protected:
|
||||
uint8_t* _sector;
|
||||
uint8_t* _data = nullptr;
|
||||
size_t _size = 0;
|
||||
bool _dirty = false;
|
||||
};
|
||||
|
||||
extern EEPROMClass EEPROM;
|
||||
132
eeprom_test/eeprom_test.ino
Normal file
132
eeprom_test/eeprom_test.ino
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
EEPROM Write
|
||||
|
||||
Stores values read from analog input 0 into the EEPROM.
|
||||
These values will stay in the EEPROM when the board is
|
||||
turned off and may be retrieved later by another sketch.
|
||||
*/
|
||||
|
||||
|
||||
// the current address in the EEPROM (i.e. which byte
|
||||
// we're going to write to next)
|
||||
#include <EEPROM.h>
|
||||
#define EEP_ADDR (0)
|
||||
|
||||
typedef struct gameState_s {
|
||||
uint8_t pionSpelerA[4][2];
|
||||
uint8_t pionSpelerB[4][2];
|
||||
uint8_t pionSpelerC[4][2];
|
||||
uint8_t pionSpelerD[4][2];
|
||||
} gameState_t;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
EEPROM.begin(512);
|
||||
|
||||
gameState_t game;
|
||||
read(&game);
|
||||
printGameState(game);
|
||||
|
||||
for (int i=0; i < 4; i++)
|
||||
{
|
||||
game.pionSpelerA[i][0] = i*2;
|
||||
game.pionSpelerA[i][1] = i*2 + 1;
|
||||
}
|
||||
|
||||
for (int i=0; i < 4; i++)
|
||||
{
|
||||
game.pionSpelerB[i][0] = i*2;
|
||||
game.pionSpelerB[i][1] = i*2 + 1;
|
||||
}
|
||||
|
||||
for (int i=0; i < 4; i++)
|
||||
{
|
||||
game.pionSpelerC[i][0] = i*2;
|
||||
game.pionSpelerC[i][1] = i*2 + 1;
|
||||
}
|
||||
|
||||
for (int i=0; i < 4; i++)
|
||||
{
|
||||
game.pionSpelerD[i][0] = i*2;
|
||||
game.pionSpelerD[i][1] = i*2 + 1;
|
||||
}
|
||||
|
||||
write(game);
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void printGameState(gameState_t game)
|
||||
{
|
||||
Serial.println("player A:");
|
||||
for (int i=0; i < 4; i++)
|
||||
{
|
||||
Serial.print(" pion ");
|
||||
Serial.print(i + 1);
|
||||
Serial.print(": (");
|
||||
Serial.print(game.pionSpelerA[i][0]);
|
||||
Serial.print(",");
|
||||
Serial.print(game.pionSpelerA[i][1]);
|
||||
Serial.println(")");
|
||||
}
|
||||
Serial.println("player B:");
|
||||
for (int i=0; i < 4; i++)
|
||||
{
|
||||
Serial.print(" pion ");
|
||||
Serial.print(i + 1);
|
||||
Serial.print(": (");
|
||||
Serial.print(game.pionSpelerB[i][0]);
|
||||
Serial.print(",");
|
||||
Serial.print(game.pionSpelerB[i][1]);
|
||||
Serial.println(")");
|
||||
}
|
||||
Serial.println("player C:");
|
||||
for (int i=0; i < 4; i++)
|
||||
{
|
||||
Serial.print(" pion ");
|
||||
Serial.print(i + 1);
|
||||
Serial.print(": (");
|
||||
Serial.print(game.pionSpelerC[i][0]);
|
||||
Serial.print(",");
|
||||
Serial.print(game.pionSpelerC[i][1]);
|
||||
Serial.println(")");
|
||||
}
|
||||
Serial.println("player D:");
|
||||
for (int i=0; i < 4; i++)
|
||||
{
|
||||
Serial.print(" pion ");
|
||||
Serial.print(i + 1);
|
||||
Serial.print(": (");
|
||||
Serial.print(game.pionSpelerD[i][0]);
|
||||
Serial.print(",");
|
||||
Serial.print(game.pionSpelerD[i][1]);
|
||||
Serial.println(")");
|
||||
}
|
||||
}
|
||||
|
||||
void write(gameState_t game)
|
||||
{
|
||||
for (int i = 0; i < sizeof(game); i++)
|
||||
{
|
||||
EEPROM.write(EEP_ADDR + i, (uint8_t) *(((uint8_t*)&game) + i));
|
||||
}
|
||||
|
||||
if (EEPROM.commit()) {
|
||||
Serial.println("EEPROM successfully committed");
|
||||
} else {
|
||||
Serial.println("ERROR! EEPROM commit failed");
|
||||
}
|
||||
}
|
||||
|
||||
void read(gameState_t *game)
|
||||
{
|
||||
for (int i = 0; i < sizeof(game); i++)
|
||||
{
|
||||
*(((uint8_t*)&game) + i) = EEPROM.read(EEP_ADDR + i);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user