Merge pull request #15 from Trasselfrisyr/eepromfile

Eepromfile storage support
This commit is contained in:
Mikael Degerfält 2019-06-24 18:34:53 +02:00 committed by GitHub
commit 9074f56ae5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 4406 additions and 10 deletions

View file

@ -2,6 +2,7 @@
#define __EEPROM_H
#include <stdint.h>
#include <stdio.h>
struct EEPROMClass
{
@ -36,12 +37,19 @@ struct EEPROMClass
// return t;
// }
//Make EEPROM persistent by storing to a file
int16_t setStorage(const char* filename, bool write);
void closeStorage();
private:
char someFakeEEPROM_memory[4096];
uint8_t someFakeEEPROM_memory[2048]; //Teensy 3.2 size
FILE *storage;
bool autoUpdate;
};
static EEPROMClass EEPROM __attribute__ ((unused));
extern EEPROMClass EEPROM __unused;
#endif

4265
simulation/src/args.hxx Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,5 @@
#include <functional>
#include <string>
#include <SDL2/SDL.h>
@ -11,13 +12,16 @@
#include "GL/gl3w.h"
#include "examples/imgui_impl_sdl.h"
#include "examples/imgui_impl_opengl3.h"
#include "EEPROM.h"
#include <Arduino.h>
#include "args.hxx"
// Forward declarations
static void SimQuit(void);
static int SimInit(void);
static int SimRun(void);
static int SimRun(std::string eepromFile, bool eepromWrite, bool factoryReset);
static void SimLoop(std::function<bool()>, std::function<void()>);
@ -28,6 +32,8 @@ SimWire Wire;
SimSerial Serial;
SimSerial Serial3; //Midi
SimUsbMidi usbMIDI;
EEPROMClass EEPROM;
static const int scale = 3;
@ -503,16 +509,24 @@ static void SimLoop(std::function<bool()> continue_predicate, std::function<void
}
}
static int SimRun( )
static int SimRun(std::string eepromFile, bool eepromWrite, bool factoryReset)
{
if( 0 != SimInit() ) { return 1; }
// Dummy to always force full reset of EEPROM, to circumvent bug in NuEVI.ino
digitalInputs[mPin] = 0;
digitalInputs[ePin] = 0;
//Set up EEPROM file storage
if(eepromFile.length()>0) {
EEPROM.setStorage(eepromFile.c_str(), eepromWrite);
}
// Holding down buttons if doing a factory reset on startup
if(factoryReset) {
digitalInputs[mPin] = 0;
digitalInputs[ePin] = 0;
}
setup();
//Let it go, let it go, not resetting any more
digitalInputs[mPin] = 1;
digitalInputs[ePin] = 1;
@ -582,6 +596,8 @@ static void SimQuit()
{
printf("Leaving Sim, see you later!\n");
EEPROM.closeStorage();
if( window != NULL ) {
SDL_DestroyWindow( window );
// SDL_FreeSurface( surface );
@ -592,7 +608,26 @@ static void SimQuit()
#include "NuEVI.ino"
int main()
int main(int argc, const char** argv)
{
return SimRun();
args::ArgumentParser parser("This is a test program.", "This goes after the options.");
args::ValueFlag<std::string> eepromFile(parser, "eeprom-write", "File to use for EEPROM data", {'e', "eeprom-file"});
args::Flag eepromWrite(parser, "eeprom-write", "Write EEPROM changes to file", {'w', "eeprom-write"});
args::Flag factoryReset(parser, "factory-reset", "Trigger factory reset", {'r', "factory-reset"});
parser.ParseCLI(argc, argv);
std::string eepromFileName = args::get(eepromFile);
//Use a default EEPROM file if none is provided.
if(eepromFileName.length()==0)
{
eepromFileName = SDL_GetPrefPath("Vulk Data System", "NuEVI Simulator");
eepromFileName += "eeprom.bin";
}
return SimRun(eepromFileName, args::get(eepromWrite), args::get(factoryReset));
}

View file

@ -8,6 +8,8 @@
EEPROMClass::EEPROMClass() {
memset(someFakeEEPROM_memory, 0xff, sizeof(someFakeEEPROM_memory));
storage = NULL;
autoUpdate = false;
}
@ -21,16 +23,102 @@ uint8_t EEPROMClass::read( int idx )
void EEPROMClass::write( int idx, uint8_t val )
{
printf("Writing to EEPROM address %u = %u\n", idx, val);
if(val == someFakeEEPROM_memory[idx])
{
//Value unchanged, do nothing.
return;
}
someFakeEEPROM_memory[idx] = val;
if(autoUpdate && storage)
{
fseek(storage, idx, SEEK_SET);
fputc(val, storage);
fflush(storage);
}
}
void EEPROMClass::update( int idx, uint8_t val )
{
write(idx, val);
}
uint16_t EEPROMClass::length()
{
return sizeof(someFakeEEPROM_memory);
}
// TODO: Add missing functioality..
int16_t EEPROMClass::setStorage(const char* filename, bool write)
{
//Close any open storage file
if(storage)
{
fclose(storage);
storage = NULL;
}
autoUpdate = write;
storage = fopen(filename, "rb");
//If only reading, fail if file does not exist (makes no sense otherwise)
if(!storage && !autoUpdate) {
printf("Could not open EEPROM storage file: '%s'\n", filename);
return -1;
}
if(storage)
{
printf("Reading EEPROM storage file: '%s'\n", filename);
rewind(storage);
fread(someFakeEEPROM_memory, sizeof(someFakeEEPROM_memory), 1, storage);
}
if(!autoUpdate)
{
//No need for the file anymore, close it
fclose(storage);
storage = NULL;
}
//Create file if it doesn't exist (so we can write to it)
if(!storage && autoUpdate)
{
storage = fopen(filename, "wb");
if(!storage)
{
printf("Could not create EEPROM storage file: '%s'\n", filename);
autoUpdate = false;
return -2;
}
}
if(storage && autoUpdate)
{
//Reopen file for writing without overwriting it
storage = freopen(filename, "r+b", storage);
if(!storage)
{
printf("Could not access EEPROM storage file for writing: '%s'\n", filename);
autoUpdate = false;
return -3;
}
printf("Writing any EEPROM changes to '%s'\n", filename);
}
return 0;
}
void EEPROMClass::closeStorage() {
if(storage!=NULL)
{
fclose(storage);
storage=NULL;
}
}