5#include <hardware/flash.h>
6#include <hardware/sync.h>
20static const char *
const TAG =
"rp2040.preferences";
22static bool s_prevent_write =
false;
23static uint8_t *s_flash_storage =
nullptr;
24static bool s_flash_dirty =
false;
26static 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];
73 uint8_t crc =
calculate_crc(buffer.begin(), buffer.end() - 1, type);
74 if (buffer[buffer.size() - 1] != crc) {
78 memcpy(data, buffer.data(),
len);
83class RP2040Preferences :
public ESPPreferences {
85 uint32_t current_flash_offset = 0;
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);
94 ESPPreferenceObject make_preference(
size_t length, uint32_t
type,
bool in_flash)
override {
98 ESPPreferenceObject make_preference(
size_t length, uint32_t
type)
override {
99 uint32_t start = this->current_flash_offset;
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();
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
constexpr14 std::array< uint8_t, sizeof(T)> decode_value(T val)
Decode a value into its constituent bytes (from most to least significant).