Skip to content

Commit 09b2f21

Browse files
committed
Store application configuration in EEPROM. (#9)
1 parent f58b15f commit 09b2f21

12 files changed

Lines changed: 1015 additions & 126 deletions

File tree

src/main/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
# -- Executable Configuration --
1010

11-
# Note that for the main executable, we use the project forced to lowercase
11+
# Note that for the main executable, we use the project name forced to lowercase
1212
string(TOLOWER "${CMAKE_PROJECT_NAME}" EXECUTABLE_NAME)
1313
set(EXECUTABLE_SOURCE application/buzzer.c
1414
application/buzzer.h
@@ -22,18 +22,24 @@ set(EXECUTABLE_SOURCE application/buzzer.c
2222
application/keyer.h
2323
application/led.c
2424
application/led.h
25+
application/storage.c
26+
application/storage.h
2527
application/wpm.c
2628
application/wpm.h
2729
core/main.c
2830
core/sys.c
2931
core/sys.h
3032
core/version.c
3133
core/version.h
34+
drivers/eeprom.c
35+
drivers/eeprom.h
3236
drivers/gpio.c
3337
drivers/gpio.h
3438
drivers/usart.c
3539
drivers/usart.h
3640
utility/constants.h
41+
utility/crc.c
42+
utility/crc.h
3743
utility/debug.c
3844
utility/debug.h
3945
utility/types.h

src/main/application/config.c

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,26 @@
1616
#include "application/input.h"
1717
#include "application/keyer.h"
1818
#include "application/led.h"
19+
#include "application/storage.h"
20+
#include "core/sys.h"
1921
#include "utility/debug.h"
22+
#include "utility/types.h"
2023
#include "utility/utility.h"
2124

25+
/* --------------------------------------------------- CONSTANTS ---------------------------------------------------- */
26+
27+
/**
28+
* @def CONFIG_VERSION_CURRENT
29+
* @brief The currently active configuration version.
30+
*/
31+
#define CONFIG_VERSION_CURRENT ( 1 )
32+
33+
/**
34+
* @def MINIMUM_SAVE_PERIOD
35+
* @brief Minimum elapsed time between saving config to storage.
36+
*/
37+
#define MINIMUM_SAVE_PERIOD ( 5 * TICKS_PER_SEC )
38+
2239
/* ----------------------------------------------------- MACROS ----------------------------------------------------- */
2340

2441
_Static_assert( _CONFIG_DFLT_WPM >= WPM_MINIMUM &&
@@ -31,9 +48,17 @@ _Static_assert( _CONFIG_DFLT_BUZZER_FREQUENCY >= BUZZER_MINIMUM_FREQUENCY &&
3148
/* --------------------------------------------------- VARIABLES ---------------------------------------------------- */
3249

3350
static config_t s_config; /**< Currently active app configuration. */
51+
static bool s_modified = false; /**< Has the configuration been modified? */
52+
static tick_t s_save_tick = 0; /**< Tick config was last saved. */
3453

3554
/* ---------------------------------------------- PROCEDURE PROTOTYPES ---------------------------------------------- */
3655

56+
/**
57+
* @fn flush( tick_t )
58+
* @brief Writes the configuration to non-volatile storage and updates state.
59+
*/
60+
static void flush( tick_t tick );
61+
3762
/**
3863
* @fn validate_config( config_t const * )
3964
* @brief Returns `true` if all fields in the specified configuration struct are valid.
@@ -83,17 +108,31 @@ void config_default( config_t * config )
83108
} /* config_default() */
84109

85110

111+
void config_flush( void )
112+
{
113+
flush( sys_get_tick() );
114+
115+
} /* config_flush() */
116+
117+
86118
void config_get( config_t * config )
87119
{
88-
memcpy( config, & s_config, sizeof( config_t ) );
120+
* config = s_config;
89121

90122
} /* config_get() */
91123

92124

93125
void config_init( void )
94126
{
95-
// Set configuration to defaults, for now
96-
config_default( & s_config );
127+
// Try to get configuration from storage, and restore defaults if that fails.
128+
// In this case, any existing configuration will be lost the next time config is saved.
129+
config_t config;
130+
if( ! storage_get_config( CONFIG_VERSION_CURRENT, sizeof( config_t ), & config ) ||
131+
! validate_config( & config ) )
132+
config_default( & config );
133+
134+
// Set local copy
135+
s_config = config;
97136

98137
} /* config_init() */
99138

@@ -110,12 +149,31 @@ bool config_set( config_t const * config )
110149
if( ! validate_config( config ) )
111150
return( false );
112151

113-
memcpy( & s_config, config, sizeof( config_t ) );
152+
s_config = * config;
153+
s_modified = true;
114154
return( true );
115155

116156
} /* config_set() */
117157

118158

159+
void config_tick( tick_t tick )
160+
{
161+
if( ! s_modified || sys_elapsed( tick, s_save_tick ) < MINIMUM_SAVE_PERIOD )
162+
return;
163+
flush( tick );
164+
165+
} /* config_tick() */
166+
167+
168+
static void flush( tick_t tick )
169+
{
170+
storage_set_config( CONFIG_VERSION_CURRENT, sizeof( config_t ), & s_config );
171+
s_modified = false;
172+
s_save_tick = tick;
173+
174+
} /* flush() */
175+
176+
119177
static bool validate_config( config_t const * config )
120178
{
121179
if( config->wpm < WPM_MINIMUM ||

src/main/application/config.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ typedef struct
5757

5858
} config_t;
5959

60+
/**
61+
* @typedef config_version_t
62+
* @brief Typedef for the configuration version number.
63+
*/
64+
typedef uint8_t config_version_t;
65+
6066
/* ----------------------------------------------------- MACROS ----------------------------------------------------- */
6167

6268
/**
@@ -74,6 +80,12 @@ typedef struct
7480
*/
7581
void config_default( config_t * config );
7682

83+
/**
84+
* @fn config_flush( void )
85+
* @brief Immediately writes the current configuration to storage.
86+
*/
87+
void config_flush( void );
88+
7789
/**
7890
* @fn config_get( config_t * )
7991
* @brief Copies the current application configuration into the specified struct.
@@ -100,4 +112,10 @@ config_t const * config_read_only( void );
100112
*/
101113
bool config_set( config_t const * config );
102114

115+
/**
116+
* @fn config_tick( tick_t )
117+
* @brief Performs periodic processing at the specified tick.
118+
*/
119+
void config_tick( tick_t tick );
120+
103121
#endif /* !defined( APPLICATION_CONFIG_H ) */

0 commit comments

Comments
 (0)