diff --git a/openrtx/include/interfaces/nvmem.h b/openrtx/include/interfaces/nvmem.h index 4b559de1..7d8bef88 100644 --- a/openrtx/include/interfaces/nvmem.h +++ b/openrtx/include/interfaces/nvmem.h @@ -24,6 +24,7 @@ #include "platform.h" #include #include +#include /** * Interface for nonvolatile memory management, usually an external SPI flash @@ -89,4 +90,20 @@ int nvm_readZoneData(zone_t *zone, uint16_t pos); */ int nvm_readContactData(contact_t *contact, uint16_t pos); +/** + * Read OpenRTX settings from storage. + * + * @param settings: pointer to the settings_t data structure to be populated. + * @return 0 on success, -1 on failure + */ +int nvm_readSettings(settings_t *settings); + +/** + * Write OpenRTX settings to storage. + * + * @param settings: pointer to the settings_t data structure to be written. + * @return 0 on success, -1 on failure + */ +int nvm_writeSettings(settings_t *settings); + #endif /* NVMEM_H */ diff --git a/openrtx/include/settings.h b/openrtx/include/settings.h index 609832d3..ee7ae44e 100644 --- a/openrtx/include/settings.h +++ b/openrtx/include/settings.h @@ -23,12 +23,15 @@ typedef struct { + uint8_t valid[6]; // Should contain "OPNRTX" in a valid settings_t uint8_t brightness; uint8_t contrast; + int8_t utc_timezone; bool gps_enabled; bool gps_set_time; - int8_t utc_timezone; } settings_t; +extern const settings_t default_settings; + #endif /* SETTINGS_H */ diff --git a/openrtx/src/state.c b/openrtx/src/state.c index 60283e66..a893e548 100644 --- a/openrtx/src/state.c +++ b/openrtx/src/state.c @@ -28,6 +28,16 @@ state_t state; +const settings_t default_settings = +{ + "OPNRTX", // Settings valid string + 255, // Brightness + 60, // Contrast + 0, // UTC Timezone + false, // GPS enabled + true // GPS set time +}; + void state_init() { /* @@ -69,11 +79,15 @@ void state_init() state.voxLevel = 0; state.emergency = false; - // Initialize settings_t - // TODO: settings_t should be read from flash memory or from a factory default - state.settings = (settings_t){ 0 }; - state.settings.brightness = 255; - state.settings.contrast = 84; + + // Read settings from flash memory + int valid = nvm_readSettings(&state.settings); + // Settings in flash memory were not valid, restoring default settings + if(valid != 0) + { + state.settings = default_settings; + nvm_writeSettings(&state.settings); + } } void state_applyTimezone() diff --git a/platform/drivers/NVM/nvmem_GDx.c b/platform/drivers/NVM/nvmem_GDx.c index 9ae021dc..9c255eb7 100644 --- a/platform/drivers/NVM/nvmem_GDx.c +++ b/platform/drivers/NVM/nvmem_GDx.c @@ -409,3 +409,16 @@ int nvm_readContactData(contact_t *contact, uint16_t pos) return 0; } + +int nvm_readSettings(settings_t *settings) +{ + (void) settings; + return -1; +} + +int nvm_writeSettings(settings_t *settings) +{ + (void) settings; + return -1; +} + diff --git a/platform/drivers/NVM/nvmem_MD3x0.c b/platform/drivers/NVM/nvmem_MD3x0.c index e4ce8302..816a8277 100644 --- a/platform/drivers/NVM/nvmem_MD3x0.c +++ b/platform/drivers/NVM/nvmem_MD3x0.c @@ -312,3 +312,16 @@ int nvm_readContactData(contact_t *contact, uint16_t pos) return 0; } + +int nvm_readSettings(settings_t *settings) +{ + (void) settings; + return -1; +} + +int nvm_writeSettings(settings_t *settings) +{ + (void) settings; + return -1; +} + diff --git a/platform/drivers/NVM/nvmem_MDUV3x0.c b/platform/drivers/NVM/nvmem_MDUV3x0.c index d1ca5eae..f2c46e35 100644 --- a/platform/drivers/NVM/nvmem_MDUV3x0.c +++ b/platform/drivers/NVM/nvmem_MDUV3x0.c @@ -19,6 +19,7 @@ ***************************************************************************/ #include +#include #include #include #include @@ -33,6 +34,9 @@ const uint32_t contactBaseAddr = 0x140000; /**< Base address of contacts const uint32_t maxNumChannels = 3000; /**< Maximum number of channels in memory */ const uint32_t maxNumZones = 250; /**< Maximum number of zones and zone extensions in memory */ const uint32_t maxNumContacts = 10000; /**< Maximum number of contacts in memory */ +/* This address has been chosen by OpenRTX to store the settings + * because it is empty (0xFF) and has enough free space */ +const uint32_t settingsAddr = 0x6000; /** * \internal Utility function to convert 4 byte BCD values into a 32-bit @@ -348,3 +352,25 @@ int nvm_readContactData(contact_t *contact, uint16_t pos) return 0; } + +int nvm_readSettings(settings_t *settings) +{ + settings_t newSettings; + W25Qx_wakeup(); + delayUs(5); + W25Qx_readData(settingsAddr, ((uint8_t *) &newSettings), sizeof(settings_t)); + W25Qx_sleep(); + if(memcmp(newSettings.valid, default_settings.valid, 6) != 0) + return -1; + memcpy(settings, &newSettings, sizeof(settings_t)); + return 0; +} + +int nvm_writeSettings(settings_t *settings) +{ + W25Qx_wakeup(); + delayUs(5); + bool success = W25Qx_writeData(settingsAddr, ((uint8_t *) &settings), sizeof(settings_t)); + W25Qx_sleep(); + return success? 0 : -1; +} diff --git a/platform/drivers/NVM/nvmem_linux.c b/platform/drivers/NVM/nvmem_linux.c index 1291976f..08ab4b69 100644 --- a/platform/drivers/NVM/nvmem_linux.c +++ b/platform/drivers/NVM/nvmem_linux.c @@ -85,3 +85,15 @@ int nvm_readContactData(contact_t *contact, uint16_t pos) return 0; } +int nvm_readSettings(settings_t *settings) +{ + (void) settings; + return -1; +} + +int nvm_writeSettings(settings_t *settings) +{ + (void) settings; + return -1; +} +