summaryrefslogtreecommitdiff
path: root/src/components/settings/Settings.cpp
blob: 454df577e218fbdc7ede0ddfaf1a47f21a0e72fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "Settings.h"
#include <cstdlib>
#include <cstring>

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} {}

void Settings::Init() {

    // 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() {

    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();
    }
    
}

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();
}