5#include <hardware/flash.h>
6#include <hardware/sync.h>
19static const char *
const TAG =
"rp2040.preferences";
21static constexpr uint32_t RP2040_FLASH_STORAGE_SIZE = 512;
23static bool s_prevent_write =
false;
25 s_flash_storage[RP2040_FLASH_STORAGE_SIZE];
26static bool s_flash_dirty =
false;
29static constexpr size_t PREF_MAX_BUFFER_SIZE = RP2040_FLASH_STORAGE_SIZE;
35 uint8_t crc = type_array[0] ^ type_array[1] ^ type_array[2] ^ type_array[3];
36 while (first != last) {
47 bool save(
const uint8_t *data,
size_t len)
override {
48 const size_t buffer_size =
len + 1;
49 if (buffer_size > PREF_MAX_BUFFER_SIZE)
51 uint8_t buffer[PREF_MAX_BUFFER_SIZE];
52 memcpy(buffer, data,
len);
55 for (
size_t i = 0; i < buffer_size; i++) {
56 uint32_t j = this->offset + i;
57 if (j >= RP2040_FLASH_STORAGE_SIZE)
59 uint8_t v = buffer[i];
60 uint8_t *ptr = &s_flash_storage[j];
67 bool load(uint8_t *data,
size_t len)
override {
68 const size_t buffer_size =
len + 1;
69 if (buffer_size > PREF_MAX_BUFFER_SIZE)
71 uint8_t buffer[PREF_MAX_BUFFER_SIZE];
73 for (
size_t i = 0; i < buffer_size; i++) {
75 if (j >= RP2040_FLASH_STORAGE_SIZE)
77 buffer[i] = s_flash_storage[j];
81 if (buffer[
len] != crc) {
85 memcpy(data, buffer,
len);
90class RP2040Preferences :
public ESPPreferences {
96 ESP_LOGVV(TAG,
"Loading preferences from flash");
97 memcpy(s_flash_storage, this->eeprom_sector_, RP2040_FLASH_STORAGE_SIZE);
100 ESPPreferenceObject make_preference(
size_t length, uint32_t
type,
bool in_flash)
override {
104 ESPPreferenceObject make_preference(
size_t length, uint32_t
type)
override {
105 uint32_t start = this->current_flash_offset;
107 if (
end > RP2040_FLASH_STORAGE_SIZE) {
110 auto *pref =
new RP2040PreferenceBackend();
111 pref->offset = start;
113 current_flash_offset =
end;
117 bool sync()
override {
123 ESP_LOGD(TAG,
"Saving");
127 ::rp2040.idleOtherCore();
128 flash_range_erase((intptr_t) eeprom_sector_ - (intptr_t) XIP_BASE, 4096);
129 flash_range_program((intptr_t) eeprom_sector_ - (intptr_t) XIP_BASE, s_flash_storage, RP2040_FLASH_STORAGE_SIZE);
130 ::rp2040.resumeOtherCore();
133 s_flash_dirty =
false;
137 bool reset()
override {
138 ESP_LOGD(TAG,
"Erasing storage");
141 ::rp2040.idleOtherCore();
142 flash_range_erase((intptr_t) eeprom_sector_ - (intptr_t) XIP_BASE, 4096);
143 ::rp2040.resumeOtherCore();
145 s_prevent_write =
true;
150 uint8_t *eeprom_sector_;
153static RP2040Preferences s_preferences;
156 s_preferences.setup();
void preferences_prevent_write(bool prevent)
uint8_t calculate_crc(It first, It last, uint32_t type)
Providing packet encoding functions for exchanging data with a remote host.
ESPPreferences * global_preferences
constexpr std::array< uint8_t, sizeof(T)> decode_value(T val)
Decode a value into its constituent bytes (from most to least significant).