/* * "preferences.cpp" * * This file has the functions that write and read the "config" and "setting" * structures to and from the flash memory on the ESP32; similar to how EEPROM * works on the Arduinos. * * The starting point for this version is the "tinySA_touch02" software developed * by Dave (M0WID). That software is based on the original version by Erik Kaashoek. * * Modified by John Price (WA2FZW): * * Version 1.0 - Just add comments and try to figure out how it all works! */ #include "Arduino.h" // Basic Arduino definitions #include // Preferences library header #include "preferences.h" // Our function prototypes #include "simpleSA.h" // General program-wide definitions and stuff extern Preferences preferences; // The Preferences object - Created in the main file extern void DisplayError ( uint8_t severity, const char *line1, const char *line2, const char *line3, const char *line4 ); /* * "ReadConfig" - Reads the "config" (see "tinySA.h") structure from flash memory */ void ReadConfig () { config_t tempConfig; // Temporary store to check data is valid size_t bytes; // Amount of data bytes = preferences.getBytes ( "config", &tempConfig, sizeof (tempConfig )); /* * If the "magic" entry is zero or what we read is the wrong size, the data is invalid. * * If nothing has yet been saved then nothing is retrieved and default values are used * * It might be better if "magic" was a specific number or maybe even a short string. * * If the size isn't correct, it could be that the size of the "config" structure was * changed in a newer release of the code. * * If what we read is invalid, we store the default values in the flash memory. */ if (( tempConfig.magic == 0 ) || ( bytes != sizeof ( tempConfig ))) { Serial.printf ( "Bytes got = %i - aiming for %i. No config saved - Storing default values\n", bytes, sizeof ( tempConfig )); preferences.remove ( "config" ); // Clear any old data just in case size has changed WriteConfig (); } else // Valid data was retrieved { // Serial.println ( "config retrieved" ); config = tempConfig; // Copy retrieved values to the real structure } } /* * "WriteConfig" - Writes the "config" structure to the flash memory. */ void WriteConfig () { size_t bytes; bytes = preferences.putBytes ( "config", &config, sizeof ( config )); if ( bytes == 0 ) // Writing failed Serial.println ( "Save of config failed" ); else Serial.println ( "config saved" ); } /* * "ReadSettings" - Reads the "setting" structure from the flash memory */ void ReadSettings() { settings_t tempSettings; // Temporary store to check data is valid size_t bytes; // Amount of data read bytes = preferences.getBytes ( "Settings", &tempSettings, sizeof ( tempSettings )); /* * If the "PowerGrid" entry is zero or what we read is the wrong size, the data is invalid. * * * It might be better if we included a "magic" element that is a specific number or maybe * even a short string. * * If the size isn't correct, it could be that the size of the "setting" structure was * changed in a newer release of the code. * * If what we read is invalid, we store the default values in the flash memory. */ if (( tempSettings.PowerGrid == 0 ) || ( bytes != sizeof ( tempSettings ))) { Serial.printf ( "Bytes got = %i - aiming for %i. No Settings saved - Storing default values\n", bytes, sizeof (tempSettings )); preferences.remove ( "Settings" ); // Clear any old data just in case size has changed WriteSettings (); // Write default values } else // Data retrieved looks valid { // Serial.println ( "Settings retrieved" ); setting = tempSettings; // Copy retrieved values to the real structure } } /* * "WriteSettings" - Writes the contents of the "setting" structure to the flash memory */ void WriteSettings () { size_t bytes; bytes = preferences.putBytes ( "Settings", &setting, sizeof ( setting )); if ( bytes == 0 ) // WA2FZW - Should we compare to expected size? Serial.println ( "Save of Settings failed" ); else Serial.println ( "Settings saved" ); } /* * "Save" and "Recall" were added in Version 2.1 by WA2FZW. * * I reactivated the "Save" and "Recall" menu items on the touch screen so * the user can save up to five scan configurations! Those commands will also * be added to the serial command handler. */ void Save ( uint8_t loc ) { char saveName[10]; sprintf ( saveName, "Save%d", loc ); if (( loc < 0 ) || ( loc > 4 )) { Serial.printf ( "Illegal location specification: %u\n", loc ); return; } // Serial.print ( "saveName = " ); Serial.println ( saveName ); size_t bytes; bytes = preferences.putBytes ( saveName, &setting, sizeof ( setting )); if ( bytes == 0 ) // WA2FZW - Should we compare to expected size? Serial.printf ( "Failed to save'%s'\n", saveName ); else Serial.printf ( "Settings saved to '%s'\n", saveName ); } void Recall ( uint8_t loc ) { char saveName[10]; // Place to construct the name of the data to recall size_t bytes; // Number of bytes read from the flash settings_t tempSettings; // Temporary store to check data is valid if (( loc < 0 ) || ( loc > 4 )) { Serial.printf ( "Illegal location specification: %u\n", loc ); return; } sprintf ( saveName, "Save%d", loc ); // Construct the name of the data to be recalled // Serial.print ( "saveName = " ); Serial.println ( saveName ); bytes = preferences.getBytes ( saveName, &tempSettings, sizeof ( tempSettings )); if ( bytes != sizeof ( tempSettings )) // Incorrect amount of data read Serial.printf ( "No data stored for '%s'\n", saveName ); else // Successful read! { Serial.printf ( "Settings recalled from '%s'\n", saveName ); setting = tempSettings; // Copy retrieved values to the real structure } } /* * "ReadSettings" - Reads the "setting" structure from the flash memory */ void ReadSigGenSettings() { sigGenSettings_t tempSettings; // Temporary store to check data is valid size_t bytes; // Amount of data read bytes = preferences.getBytes ( "SigGenLo", &tempSettings, sizeof ( tempSettings )); /* * If the "PowerGrid" entry is zero or what we read is the wrong size, the data is invalid. * * * It might be better if we included a "magic" element that is a specific number or maybe * even a short string. * * If the size isn't correct, it could be that the size of the "setting" structure was * changed in a newer release of the code. * * If what we read is invalid, we store the default values in the flash memory. */ if (( tempSettings.Dummy != 123 ) || ( bytes != sizeof ( tempSettings ))) { Serial.printf ( "Bytes got = %i - aiming for %i. No Sig Gen Settings saved - Storing default values\n", bytes, sizeof (tempSettings )); preferences.remove ( "SigGenLo" ); // Clear any old data just in case size has changed WriteSigGenSettings (); // Write default values } else // Data retrieved looks valid { // Serial.println ( "SigGenLo Settings retrieved" ); sigGenSetting = tempSettings; // Copy retrieved values to the real structure } } /* * "WriteSettings" - Writes the contents of the "setting" structure to the flash memory */ void WriteSigGenSettings () { size_t bytes; bytes = preferences.putBytes ( "SigGenLo", &sigGenSetting, sizeof ( sigGenSetting )); if ( bytes == 0 ) Serial.println ( "Save of sigGenLo failed" ); else Serial.println ( "sigGenLo saved" ); } /* * "ReadSettings" - Reads the "setting" structure from the flash memory */ void ReadTrackGenSettings() { trackGenSettings_t tempSettings; // Temporary store to check data is valid size_t bytes; // Amount of data read bytes = preferences.getBytes ( "TrackGen", &tempSettings, sizeof ( tempSettings )); /* * If the "dummy" entry is zero or what we read is the wrong size, the data is invalid. * * * It might be better if we included a "magic" element that is a specific number or maybe * even a short string. * * If the size isn't correct, it could be that the size of the "setting" structure was * changed in a newer release of the code. * * If what we read is invalid, we store the default values in the flash memory. */ if (( tempSettings.Dummy != 99 ) || ( bytes != sizeof ( tempSettings ))) { Serial.printf ( "Bytes got = %i - aiming for %i. No Track Gen Settings saved - Storing default values\n", bytes, sizeof (tempSettings )); preferences.remove ( "TrackGen" ); // Clear any old data just in case size has changed WriteTrackGenSettings (); // Write default values } else // Data retrieved looks valid { // Serial.println ( "Track Settings retrieved" ); trackGenSetting = tempSettings; // Copy retrieved values to the real structure } } /* * "WriteTrackGenSettings" - Writes the contents of the "trackGenSetting" structure to the flash memory */ void WriteTrackGenSettings () { size_t bytes; bytes = preferences.putBytes ( "TrackGen", &trackGenSetting, sizeof ( trackGenSetting )); if ( bytes == 0 ) Serial.println ( "Save of TrackGen failed" ); else Serial.println ( "TrackGen saved" ); } /* * "ReadBpfCalibration" - Reads the bandpass filter calibrations from the flash memory */ void ReadBpfCalibration() { double tempCal[MAX_SI4432_FILTERS]; // Temporary store to check data is valid size_t bytes; // Amount of data read bytes = preferences.getBytes ( "bpfCal", &tempCal, bpfCount * sizeof (bpfCalibrations[0])); /* * If the "dummy" entry is zero or what we read is the wrong size, the data is invalid. * * * It might be better if we included a "magic" element that is a specific number or maybe * even a short string. * * If the size isn't correct, it could be that the size of the "setting" structure was * changed in a newer release of the code. * * If what we read is invalid, we store the default values in the flash memory. */ if ( bytes != bpfCount * sizeof (bpfCalibrations[0]) ) { Serial.printf ( "Bytes got = %i - aiming for %i. No bandpass filter calibrations saved\n", bytes, bpfCount * sizeof (bpfCalibrations[0]) ); DisplayError ( ERR_WARN, "No Calibrations found", "Connect ref out, goto", "RXSweep mode then", "Choose bpfCalibrate" ); preferences.remove ( "bpfCal" ); // Clear any old data just in case size has changed } else // Data retrieved looks valid { Serial.printf ( "bpf calibrations read - %i bytes, %i filters \n", bytes, bpfCount); for (int i = 0; i < bpfCount; i++) { bpfCalibrations[i] = tempCal[i]; } } } /* * Save the bandpass filter calibrations to flash */ void SaveBpfCalibration ( ) { // double bpfCalibrations[MAX_SI4432_FILTERS]; // temporary storage for calibration values size_t bytes; bytes = preferences.putBytes ( "bpfCal", &bpfCalibrations, bpfCount * sizeof (bpfCalibrations[0]) ); if ( bytes == 0 ) Serial.println ( "Save of bandpass filter calibrations failed" ); else Serial.println ( "Bandpass filter calibrations saved" ); }