commit 13338a5725eddb56c40ff0f8ff26ee3eef318633 Author: FReenen Date: Mon Sep 23 10:28:22 2024 +0000 inital commit diff --git a/eeprom_test/eeprom.cpp b/eeprom_test/eeprom.cpp new file mode 100644 index 0000000..8a3856f --- /dev/null +++ b/eeprom_test/eeprom.cpp @@ -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 +#include "EEPROM.h" +#include +#include + +#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 +#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; \ No newline at end of file diff --git a/eeprom_test/eeprom.h b/eeprom_test/eeprom.h new file mode 100644 index 0000000..114aa8e --- /dev/null +++ b/eeprom_test/eeprom.h @@ -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 +#include +#include + +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 + 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 + 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 + 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; \ No newline at end of file diff --git a/eeprom_test/eeprom_test.ino b/eeprom_test/eeprom_test.ino new file mode 100644 index 0000000..a49d11a --- /dev/null +++ b/eeprom_test/eeprom_test.ino @@ -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 +#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); + } +}