2021-02-24 14:40:24 -05:00
|
|
|
#include "Settings.h"
|
2021-04-03 22:08:51 -04:00
|
|
|
#include <cstdlib>
|
|
|
|
#include <cstring>
|
2021-02-24 14:40:24 -05:00
|
|
|
|
|
|
|
using namespace Pinetime::Controllers;
|
|
|
|
|
2021-04-03 22:08:51 -04:00
|
|
|
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} {}
|
2021-02-24 14:40:24 -05:00
|
|
|
|
|
|
|
void Settings::Init() {
|
|
|
|
|
2021-04-03 22:08:51 -04:00
|
|
|
// Load default settings from Flash
|
|
|
|
LoadSettingsFromFlash();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void Settings::SaveSettings() {
|
|
|
|
|
|
|
|
// verify if is necessary to save
|
|
|
|
if ( settingsChanged ) {
|
|
|
|
SaveSettingsToFlash();
|
|
|
|
}
|
|
|
|
settingsChanged = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Settings::FindHeader() {
|
|
|
|
SettingsHeader settingsHeader;
|
|
|
|
uint8_t bufferHead[sizeof(settingsHeader)];
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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() {
|
2021-02-24 14:40:24 -05:00
|
|
|
|
2021-04-03 22:08:51 -04:00
|
|
|
spiNorFlash.SectorErase(settingsBaseAddr + (settingsFlashBlock * 0x1000));
|
2021-02-24 14:40:24 -05:00
|
|
|
}
|
|
|
|
|
2021-04-03 22:08:51 -04:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void Settings::SaveSettingsToFlash() {
|
|
|
|
|
|
|
|
// 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 );
|
|
|
|
}
|
|
|
|
|
|
|
|
settingsFlashBlock++;
|
|
|
|
if ( settingsFlashBlock > 9 ) settingsFlashBlock = 0;
|
|
|
|
|
|
|
|
EraseBlock();
|
|
|
|
SetHeader( true );
|
|
|
|
SaveSettingsData();
|
|
|
|
}
|