I tried your suggestion:
#include "daisy_versio.h"
#include "daisysp.h"
using namespace daisy;
using namespace daisysp;
DaisyVersio hw;
//Setting Struct containing parameters we want to save to flash
struct Settings {
float p1; // DryWet
float p2; // Feedback
//Overloading the != operator
//This is necessary as this operator is used in the PersistentStorage source code
bool operator!=(const Settings& a) const {
return !(a.p1==p1 && a.p2==p2);
}
};
//Persistent Storage Declaration. Using type Settings and passed the devices qspi handle
PersistentStorage<Settings> SavedSettings(hw.seed.qspi);
//Reverb and Parameters
//ReverbSc Verb;
float test1 = 0.f;
float test2 = 0.f;
bool use_preset = false;
bool trigger_save = false;
bool save_flag = false;
bool load_flag = false;
void Load() {
//Reference to local copy of settings stored in flash
Settings &LocalSettings = SavedSettings.GetSettings();
test1 = LocalSettings.p1;
test2 = LocalSettings.p2;
use_preset = true;
}
void Save() {
//Reference to local copy of settings stored in flash
Settings &LocalSettings = SavedSettings.GetSettings();
LocalSettings.p1 = test1;
LocalSettings.p2 = test2;
trigger_save = true;
}
void ProcessControls() {
hw.ProcessAllControls();
hw.tap.Debounce();
//Switches
if(hw.tap.RisingEdge()){
if(use_preset) {
use_preset = false;
} else {
load_flag = true;
}
}
if(hw.tap.FallingEdge()){
save_flag = true;
}
// //Knobs
// if(!use_preset){
// Verb.SetFeedback(Feedback.Process());
// DryWet = hw.knob1.Process();
// }
// //LEDs
// if(use_preset)
// hw.led1.Set(0, 1, 0); // green
// else
// hw.led1.Set(1, 0, 0); // red
// if(trigger_save)
// hw.led2.Set(0, 1, 0); // green
// else
// hw.led2.Set(0, 0, 0); // red
// hw.UpdateLeds();
}
void AudioCallback(AudioHandle::InputBuffer in, AudioHandle::OutputBuffer out, size_t size)
{
hw.ProcessAllControls();
for (size_t i = 0; i < size; i++)
{
out[0][i] = in[0][i];
out[1][i] = in[1][i];
}
}
int main(void)
{
hw.Init();
hw.SetAudioBlockSize(4); // number of samples handled per callback
hw.SetAudioSampleRate(SaiHandle::Config::SampleRate::SAI_48KHZ);
// Verb.Init(hw.AudioSampleRate());
// Feedback.Init(hw.knob2, 0.0f, 1.0f, daisy::Parameter::LINEAR);
float test = 1.f;
test *= 2;
//Initilize the PersistentStorage Object with default values.
//Defaults will be the first values stored in flash when the device is first turned on. They can also be restored at a later date using the RestoreDefaults method
Settings DefaultSettings = {0.0f, 0.0f};
SavedSettings.Init(DefaultSettings);
hw.StartAdc();
hw.StartAudio(AudioCallback);
while(1) {
if(save_flag) {
Save();
save_flag = false;
}
if(trigger_save) {
SavedSettings.Save(); // Writing locally stored settings to the external flash
trigger_save = false;
}
if(load_flag) {
Load();
load_flag = false;
}
System::Delay(100);
}
}
It didn’t work. The problem is with the initialization of the qspi object. I do not know exactly what causes it though or why. I suspect it has something to do with the hardware of the versio? I see other people getting it working:
Very important though! I got it working yesterday for a little bit, persistence was working, but the audio became very distorted and it never worked again since. The power cable had become loose. There were no shorts though… Is it possible I fried the qspi? I don’t see why that would happen but maybe?
Here’s the assembly. The last line to get executed is 0x080006a8.
This is what was run after the assembly line just beforehand to get the value to be stored in register 0:
Register 0 is 603980728 after 6a2, then -1879048192 after 2460.
The value in register 0 at 0x080006a8 is -1879048192. Register 1 always stays 0, so this is probably the address offset? Register 3 does not get updated stepping into 0x080006a8 and I am immediately brought to the hard fault handler.
Invalid state or needs to be cleared?
In storage_data the following is defined:
daisy::PersistentStorage<Settings>::State::UNKNOWN
user_data:
p1: 0
p1: 0
Why is the state unknown?
Looking in qspi_:
daisy::QSPIHandle::E_HAL_ERROR
Looking in qspi_.halqspi_:
HAL_QSPI_STATE_ERROR
These flags are present immediately after 68e, line 114 in the code.
I stepped through all the lines of code in the debugger and found that it gets stuck here:
/* Wait until flag is in expected state */
while((__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)
{
/* Check for the Timeout */
if (Timeout != HAL_MAX_DELAY)
{
if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
{
hqspi->State = HAL_QSPI_STATE_ERROR;
hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
return HAL_ERROR;
}
}
}
return HAL_OK;
}
I wasn’t patient enough to see if it ever exits here, but it hands for like ten seconds when I hit step into and then the bus fault occurs.