Using littlefs (#438)
* add submodule littlefs * base fs * Save settings using littlefs * Small fixes and suggestions from PR * More small fixes from PR suggestions * Code clean up * Change SpiNorFlash functions to be private in FS
This commit is contained in:
@@ -4,108 +4,44 @@
|
||||
|
||||
using namespace Pinetime::Controllers;
|
||||
|
||||
struct SettingsHeader {
|
||||
uint8_t isActive; // 0xF1 = Block is active, 0xF0 = Block is inactive
|
||||
uint16_t version; // Current version, to verify if the saved data is for the current Version
|
||||
};
|
||||
|
||||
#define HEADER_SIZE sizeof(SettingsHeader)
|
||||
|
||||
Settings::Settings(Pinetime::Drivers::SpiNorFlash& spiNorFlash) : spiNorFlash {spiNorFlash} {
|
||||
Settings::Settings(Pinetime::Controllers::FS& fs) : fs {fs} {
|
||||
}
|
||||
|
||||
void Settings::Init() {
|
||||
|
||||
// Load default settings from Flash
|
||||
LoadSettingsFromFlash();
|
||||
LoadSettingsFromFile();
|
||||
}
|
||||
|
||||
void Settings::SaveSettings() {
|
||||
|
||||
// verify if is necessary to save
|
||||
if (settingsChanged) {
|
||||
SaveSettingsToFlash();
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
settingsChanged = false;
|
||||
}
|
||||
|
||||
bool Settings::FindHeader() {
|
||||
SettingsHeader settingsHeader;
|
||||
uint8_t bufferHead[sizeof(settingsHeader)];
|
||||
void Settings::LoadSettingsFromFile() {
|
||||
SettingsData bufferSettings;
|
||||
lfs_file_t settingsFile;
|
||||
|
||||
for (uint8_t block = 0; block < 10; block++) {
|
||||
|
||||
spiNorFlash.Read(settingsBaseAddr + (block * 0x1000), bufferHead, sizeof(settingsHeader));
|
||||
std::memcpy(&settingsHeader, bufferHead, sizeof(settingsHeader));
|
||||
if (settingsHeader.isActive == 0xF1 && settingsHeader.version == settingsVersion) {
|
||||
settingsFlashBlock = block;
|
||||
return true;
|
||||
}
|
||||
if ( fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT) != LFS_ERR_OK) {
|
||||
return;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Settings::ReadSettingsData() {
|
||||
uint8_t bufferSettings[sizeof(settings)];
|
||||
spiNorFlash.Read(settingsBaseAddr + (settingsFlashBlock * 0x1000) + HEADER_SIZE, bufferSettings, sizeof(settings));
|
||||
std::memcpy(&settings, bufferSettings, sizeof(settings));
|
||||
}
|
||||
|
||||
void Settings::EraseBlock() {
|
||||
|
||||
spiNorFlash.SectorErase(settingsBaseAddr + (settingsFlashBlock * 0x1000));
|
||||
}
|
||||
|
||||
void Settings::SetHeader(bool state) {
|
||||
SettingsHeader settingsHeader;
|
||||
uint8_t bufferHead[sizeof(settingsHeader)];
|
||||
settingsHeader.isActive = state ? 0xF1 : 0xF0;
|
||||
settingsHeader.version = settingsVersion;
|
||||
|
||||
std::memcpy(bufferHead, &settingsHeader, sizeof(settingsHeader));
|
||||
spiNorFlash.Write(settingsBaseAddr + (settingsFlashBlock * 0x1000), bufferHead, sizeof(settingsHeader));
|
||||
}
|
||||
|
||||
void Settings::SaveSettingsData() {
|
||||
uint8_t bufferSettings[sizeof(settings)];
|
||||
std::memcpy(bufferSettings, &settings, sizeof(settings));
|
||||
spiNorFlash.Write(settingsBaseAddr + (settingsFlashBlock * 0x1000) + HEADER_SIZE, bufferSettings, sizeof(settings));
|
||||
}
|
||||
|
||||
void Settings::LoadSettingsFromFlash() {
|
||||
|
||||
if (settingsFlashBlock == 99) {
|
||||
// Find current Block, if can't find use default settings and set block to 0 ans save !
|
||||
if (FindHeader()) {
|
||||
ReadSettingsData();
|
||||
} else {
|
||||
SaveSettingsToFlash();
|
||||
}
|
||||
} else {
|
||||
// Read Settings from flash...
|
||||
// never used :)
|
||||
ReadSettingsData();
|
||||
fs.FileRead(&settingsFile, reinterpret_cast<uint8_t*>(&bufferSettings), sizeof(settings));
|
||||
fs.FileClose(&settingsFile);
|
||||
if ( bufferSettings.version == settingsVersion ) {
|
||||
settings = bufferSettings;
|
||||
}
|
||||
}
|
||||
|
||||
void Settings::SaveSettingsToFlash() {
|
||||
void Settings::SaveSettingsToFile() {
|
||||
lfs_file_t settingsFile;
|
||||
|
||||
// calculate where to save...
|
||||
// mark current to inactive
|
||||
// erase the new location and save
|
||||
// set settingsFlashBlock
|
||||
|
||||
// if first time hever, only saves to block 0 and set settingsFlashBlock
|
||||
|
||||
if (settingsFlashBlock != 99) {
|
||||
SetHeader(false);
|
||||
if ( fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT) != LFS_ERR_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
settingsFlashBlock++;
|
||||
if (settingsFlashBlock > 9)
|
||||
settingsFlashBlock = 0;
|
||||
|
||||
EraseBlock();
|
||||
SetHeader(true);
|
||||
SaveSettingsData();
|
||||
fs.FileWrite(&settingsFile, reinterpret_cast<uint8_t*>(&settings), sizeof(settings));
|
||||
fs.FileClose(&settingsFile);
|
||||
}
|
||||
|
Reference in New Issue
Block a user