libDaisy
Hardware Library for Daisy
Loading...
Searching...
No Matches
PersistentStorage.h
Go to the documentation of this file.
1#pragma once
2
3#include "daisy_core.h"
4#include "per/qspi.h"
5#include "sys/dma.h"
6
7namespace daisy
8{
20template <typename SettingStruct>
22{
23 public:
37 enum class State
38 {
39 UNKNOWN = 0,
40 FACTORY = 1,
41 USER = 2,
42 };
43
48 : qspi_(qspi),
49 address_offset_(0),
50 default_settings_(),
51 settings_(),
52 state_(State::UNKNOWN)
53 {
54 }
55
67 {
68 default_settings_ = defaults;
69 settings_ = defaults;
70 address_offset_ = address_offset & (uint32_t)(~0xff);
71 auto storage_data
72 = reinterpret_cast<SaveStruct *>(qspi_.GetData(address_offset_));
73
74 // check to see if the state is already in use.
75 State cur_state = storage_data->storage_state;
77 {
78 // Initialize the Data store State::FACTORY, and the DefaultSettings
79 state_ = State::FACTORY;
80 StoreSettingsIfChanged();
81 }
82 else
83 {
84 state_ = cur_state;
85 settings_ = storage_data->user_data;
86 }
87 }
88
90 State GetState() const { return state_; }
91
93 SettingStruct &GetSettings() { return settings_; }
94
96 void Save()
97 {
98 state_ = State::USER;
99 StoreSettingsIfChanged();
100 }
101
104 {
105 settings_ = default_settings_;
106 state_ = State::FACTORY;
107 StoreSettingsIfChanged();
108 }
109
110 private:
111 struct SaveStruct
112 {
113 State storage_state;
114 SettingStruct user_data;
115 };
116
117 void StoreSettingsIfChanged()
118 {
119 SaveStruct s;
120 s.storage_state = state_;
121 s.user_data = settings_;
122
123 void *data_ptr = qspi_.GetData(address_offset_);
124
125#if !UNIT_TEST
126 // Caching behavior is different when running programs outside internal flash
127 // so we need to explicitly invalidate the QSPI mapped memory to ensure we are
128 // comparing the local settings with the most recently persisted settings.
131 {
132 dsy_dma_invalidate_cache_for_buffer((uint8_t *)data_ptr, sizeof(s));
133 }
134#endif
135
136 // Only actually save if the new data is different
137 // Use the `==operator` in custom SettingStruct to fine tune
138 // what may or may not trigger the erase/save.
139 auto storage_data = reinterpret_cast<SaveStruct *>(data_ptr);
140 if(settings_ != storage_data->user_data)
141 {
142 qspi_.Erase(address_offset_, address_offset_ + sizeof(s));
143 qspi_.Write(address_offset_, sizeof(s), (uint8_t *)&s);
144 }
145 }
146
147 QSPIHandle & qspi_;
148 uint32_t address_offset_;
149 SettingStruct default_settings_;
150 SettingStruct settings_;
151 State state_;
152};
153
154} // namespace daisy
Definition leddriver.h:33
Non Volatile storage class for persistent settings on an external flash device.
Definition PersistentStorage.h:22
void Save()
Definition PersistentStorage.h:96
void Init(const SettingStruct &defaults, uint32_t address_offset=0)
Definition PersistentStorage.h:66
State GetState() const
Definition PersistentStorage.h:90
PersistentStorage(QSPIHandle &qspi)
Definition PersistentStorage.h:47
SettingStruct & GetSettings()
Definition PersistentStorage.h:93
State
Definition PersistentStorage.h:38
void RestoreDefaults()
Definition PersistentStorage.h:103
Definition qspi.h:32
Result Erase(uint32_t start_addr, uint32_t end_addr)
void * GetData(uint32_t offset=0)
Result Write(uint32_t address, uint32_t size, uint8_t *buffer)
@ INTERNAL_FLASH
Definition system.h:64
static MemoryRegion GetProgramMemoryRegion()
void dsy_dma_invalidate_cache_for_buffer(uint8_t *buffer, size_t size)
Hardware defines and helpers for daisy field platform.
Definition index.h:2