5 #include <hardware/flash.h> 6 #include <hardware/sync.h> 8 #include "preferences.h" 20 static const char *
const TAG =
"rp2040.preferences";
22 static bool s_prevent_write =
false;
23 static uint8_t *s_flash_storage =
nullptr;
24 static bool s_flash_dirty =
false;
26 static const uint32_t RP2040_FLASH_STORAGE_SIZE = 512;
32 uint8_t
crc = type_array[0] ^ type_array[1] ^ type_array[2] ^ type_array[3];
33 while (first != last) {
44 bool save(
const uint8_t *data,
size_t len)
override {
45 std::vector<uint8_t> buffer;
46 buffer.resize(len + 1);
47 memcpy(buffer.data(), data,
len);
48 buffer[buffer.size() - 1] =
calculate_crc(buffer.begin(), buffer.end() - 1,
type);
50 for (uint32_t i = 0; i < len + 1; i++) {
51 uint32_t j = offset + i;
52 if (j >= RP2040_FLASH_STORAGE_SIZE)
54 uint8_t v = buffer[i];
55 uint8_t *ptr = &s_flash_storage[j];
62 bool load(uint8_t *data,
size_t len)
override {
63 std::vector<uint8_t> buffer;
64 buffer.resize(len + 1);
66 for (
size_t i = 0; i < len + 1; i++) {
67 uint32_t j = offset + i;
68 if (j >= RP2040_FLASH_STORAGE_SIZE)
70 buffer[i] = s_flash_storage[j];
74 if (buffer[buffer.size() - 1] !=
crc) {
78 memcpy(data, buffer.data(),
len);
85 uint32_t current_flash_offset = 0;
87 RP2040Preferences() : eeprom_sector_(&_EEPROM_start) {}
89 s_flash_storage =
new uint8_t[RP2040_FLASH_STORAGE_SIZE];
90 ESP_LOGVV(TAG,
"Loading preferences from flash...");
91 memcpy(s_flash_storage, this->eeprom_sector_, RP2040_FLASH_STORAGE_SIZE);
95 return make_preference(length, type);
99 uint32_t start = this->current_flash_offset;
100 uint32_t
end = start + length + 1;
101 if (end > RP2040_FLASH_STORAGE_SIZE) {
104 auto *pref =
new RP2040PreferenceBackend();
105 pref->offset = start;
107 current_flash_offset =
end;
111 bool sync()
override {
117 ESP_LOGD(TAG,
"Saving preferences to flash...");
121 ::rp2040.idleOtherCore();
122 flash_range_erase((intptr_t) eeprom_sector_ - (intptr_t) XIP_BASE, 4096);
123 flash_range_program((intptr_t) eeprom_sector_ - (intptr_t) XIP_BASE, s_flash_storage, RP2040_FLASH_STORAGE_SIZE);
124 ::rp2040.resumeOtherCore();
127 s_flash_dirty =
false;
131 bool reset()
override {
132 ESP_LOGD(TAG,
"Cleaning up preferences in flash...");
135 ::rp2040.idleOtherCore();
136 flash_range_erase((intptr_t) eeprom_sector_ - (intptr_t) XIP_BASE, 4096);
137 ::rp2040.resumeOtherCore();
139 s_prevent_write =
true;
144 uint8_t *eeprom_sector_;
148 auto *prefs =
new RP2040Preferences();
ESPPreferences * global_preferences
uint8_t calculate_crc(It first, It last, uint32_t type)
void preferences_prevent_write(bool prevent)
constexpr14 std::array< uint8_t, sizeof(T)> decode_value(T val)
Decode a value into its constituent bytes (from most to least significant).
Helper class to disable interrupts.
Implementation of SPI Controller mode.