From f0ec05cc2030558c349610c8fb5dc01cd85d58fd Mon Sep 17 00:00:00 2001 From: Richard Bowman Date: Wed, 22 Feb 2023 17:09:51 +0000 Subject: [PATCH] Initialise EEPROM and save periodically This should be less of a disaster for the emulated EEPROM on the pico, but could use some finesse --- src/main.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/main.h | 1 + 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 84f36b2..2f4eb95 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,6 +20,11 @@ #include #include #include +#ifdef SUPPORT_EEPROM +#include +#else +#include "dummyEEPROM.h" +#endif #ifdef HELP #include "modules/help/help.h" @@ -54,6 +59,7 @@ uint8_t registered_loop_fn_count = 0; const Command core_commands[] = { {"version", get_version}, {"list_modules", get_modules}, + {"eeprom_last_commit", get_eeprom_last_commit}, END_COMMAND}; void register_module(const Command commands[], void (*loop_fn)(void)) @@ -135,8 +141,42 @@ void get_modules(String) comPort->println("--END--"); } +#if defined(SUPPORT_EEPROM) && defined(MCU_PICO) +unsigned long eeprom_last_commit; +void eeprom_commit_at_interval(unsigned long interval) +{ + unsigned long next_commit = eeprom_last_commit + interval; + unsigned long now = millis(); + // millis() can overflow - this if statement will trigger + // every `interval` accounting for overflows. + if ( (now > next_commit && next_commit > eeprom_last_commit) // no overflow + || (now > next_commit && now < eeprom_last_commit)) // overflow + { + EEPROM.commit(); + eeprom_last_commit = millis(); + } +} +#endif + +void get_eeprom_last_commit(String) +{ +#if defined(SUPPORT_EEPROM) && defined(MCU_PICO) + comPort->println(eeprom_last_commit); +#else + comPort->println("Not using pico"); +#endif + return; +} + void setup() { + #if defined(SUPPORT_EEPROM) && defined(MCU_PICO) + // On the Pico, EEPROM is emulated. + // This means we need to explicitly enable it, and also + // call EEPROM.commit() periodically to persist it to flash. + EEPROM.begin(256); + eeprom_last_commit = millis(); + #endif // initialise serial port #ifdef WIRING_SERIAL_TX Serial2.setTX(WIRING_SERIAL_TX); @@ -186,17 +226,26 @@ void setup() void loop() { + bool bytesAvailable = false; if (PRIMARY_SERIAL_PORT.available()) { comPort = (HardwareSerial*) &PRIMARY_SERIAL_PORT; - handle_command(comPort->readStringUntil('\n')); + bytesAvailable = true; } #if defined(SECONDARY_SERIAL_PORT) - if (SECONDARY_SERIAL_PORT.available()) + else if (SECONDARY_SERIAL_PORT.available()) { comPort = (HardwareSerial*) &SECONDARY_SERIAL_PORT; + bytesAvailable = true; + } + if (bytesAvailable) + { handle_command(comPort->readStringUntil('\n')); } + #if defined(SUPPORT_EEPROM) && defined(MCU_PICO) + // On the Pico, emulated EEPROM is only saved to flash when we call commit() + eeprom_commit_at_interval(10000); // NB this only writes to flash if something has changed. + #endif for (int i = 0; i < registered_loop_fn_count; i++) registered_loop_functions[i](); diff --git a/src/main.h b/src/main.h index 2ca26a8..2b74b83 100644 --- a/src/main.h +++ b/src/main.h @@ -29,5 +29,6 @@ extern void register_module(const Command commands[], void (*loop_fn)(void)); void get_version(String); void get_modules(String); +void get_eeprom_last_commit(String); #define MAIN_H #endif \ No newline at end of file