-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathps_settings.c
181 lines (148 loc) · 5.5 KB
/
ps_settings.c
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/*
ps_settings.c - Handles storing and retrieving product specific settings from
Non Volatile Storage (EEPROM)
Copyright (c) 2017 Inventables Inc.
*/
#include "ps_settings.h"
#include "string.h"
#include "stdlib.h"
#include "eeprom.h"
#include "nuts_bolts.h"
#include <avr/pgmspace.h>
#define PS_SETTINGS_EEPROM_REVISION_OFFSET 0x1E
#define PS_SETTINGS_EEPROM_PARAM_SIZE_OFFSET 0x1F
#define PS_SETTINGS_EEPROM_PARAMETERS_OFFSET 0x20
const ps_settings_map_element gCarvinParameterMap[] =
{ // {Offset, Size, default value}
{ 0U, 4U, 1.75f }, // Spindle Current Overload Threshold
};
static uint8_t* ps_settings_ram_storage = 0U;
static const ps_settings_map_element* ps_settings_metadata = gCarvinParameterMap;
static const char* ps_settings_header = "Inventables Settings ";
static uint8_t storage_size = 0U;
static void set_default_values( uint8_t* data );
static void set_eeprom_storage_size( uint8_t size );
static void set_eeprom_header_and_revision( void );
static void write_ps_settings_to_eeprom( uint8_t* data, uint8_t data_size );
static uint8_t validate_eeprom_image( const uint8_t* data );
void ps_settings_init( void )
{
uint8_t error = 0U;
if ( PS_SETTINGS_NUM_PARAMETERS > 0 )
{
uint8_t eeprom_data[ 256U ];
uint8_t eeprom_data_size = eeprom_get_char( PS_SETTINGS_EEPROM_OFFSET + PS_SETTINGS_EEPROM_PARAM_SIZE_OFFSET );
uint8_t eeprom_revision = eeprom_get_char( PS_SETTINGS_EEPROM_OFFSET + PS_SETTINGS_EEPROM_REVISION_OFFSET );
uint8_t eeprom_checksum = 0U;
uint8_t element = 0U;
storage_size = 0U;
for ( ; element < PS_SETTINGS_NUM_PARAMETERS; ++element )
{
storage_size += ps_settings_metadata[ element ].size;
}
ps_settings_ram_storage = malloc( storage_size );
// set RAM storage to defaults
set_default_values( ps_settings_ram_storage );
// recall from EEPROM
// header "Inventables Settings "
memcpy_from_eeprom_no_checksum( eeprom_data,
PS_SETTINGS_EEPROM_OFFSET,
30U );
if ( (eeprom_data_size > 0U) &&
(eeprom_data_size < 255U) &&
(memcmp( ps_settings_header, eeprom_data, 30U ) == 0 ) )
{
eeprom_checksum = memcpy_from_eeprom_with_checksum( eeprom_data,
PS_SETTINGS_EEPROM_OFFSET + PS_SETTINGS_EEPROM_PARAMETERS_OFFSET,
eeprom_data_size );
if ( eeprom_checksum )
{
memcpy( ps_settings_ram_storage,
eeprom_data,
min( eeprom_data_size, storage_size ) );
}
if ( eeprom_data_size != storage_size )
{
if ( eeprom_data_size > storage_size )
{
// more data than expected --> downgrade
set_eeprom_storage_size( storage_size );
}
else if ( eeprom_data_size < storage_size )
{
// less data than expected --> upgrade
set_eeprom_storage_size( storage_size );
write_ps_settings_to_eeprom( ps_settings_ram_storage, storage_size );
}
}
}
else
{
ps_settings_restore();
}
}
}
void ps_settings_restore( void )
{
set_eeprom_header_and_revision();
set_eeprom_storage_size( storage_size );
set_default_values( ps_settings_ram_storage );
write_ps_settings_to_eeprom( ps_settings_ram_storage, storage_size );
}
uint8_t ps_settings_store_setting( uint8_t parameter, uint8_t* value )
{
uint8_t success = 1U;
if ( parameter <= PS_SETTINGS_NUM_PARAMETERS )
{
success = 0U; //(STATUS_OK)
memcpy( ps_settings_ram_storage + ps_settings_metadata[ parameter ].offset,
value,
ps_settings_metadata[ parameter ].size );
write_ps_settings_to_eeprom( ps_settings_ram_storage, storage_size );
}
return success;
}
uint8_t ps_settings_get_setting( uint8_t parameter, uint8_t* value )
{
uint8_t success = 1U;
if ( parameter < PS_SETTINGS_NUM_PARAMETERS )
{
if ( ps_settings_ram_storage )
{
success = 0U; //(STATUS_OK)
memcpy( value,
ps_settings_ram_storage + ps_settings_metadata[ parameter ].offset,
ps_settings_metadata[ parameter ].size );
}
}
return success;
}
void set_default_values( uint8_t* data )
{
uint8_t element = 0U;
uint8_t size = 0U;
for ( ; element <= PS_SETTINGS_NUM_PARAMETERS; ++element )
{
memcpy( &data[ ps_settings_metadata[ element ].offset ],
&ps_settings_metadata[ element ].default_value.integer,
ps_settings_metadata[ element ].size );
}
}
void set_eeprom_storage_size( uint8_t size )
{
eeprom_put_char( PS_SETTINGS_EEPROM_OFFSET + PS_SETTINGS_EEPROM_PARAM_SIZE_OFFSET, size );
}
void write_ps_settings_to_eeprom( uint8_t* data, uint8_t data_size )
{
if ( data && data_size )
{
memcpy_to_eeprom_with_checksum( PS_SETTINGS_EEPROM_OFFSET + PS_SETTINGS_EEPROM_PARAMETERS_OFFSET,
data,
data_size );
}
}
void set_eeprom_header_and_revision( void )
{
memcpy_to_eeprom_no_checksum( PS_SETTINGS_EEPROM_OFFSET, ps_settings_header, 30U );
eeprom_put_char( PS_SETTINGS_EEPROM_OFFSET + PS_SETTINGS_EEPROM_REVISION_OFFSET, PS_SETTINGS_VERSION );
}