Firmware SDK
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
bc_config.c
1 
2 #include <bc_config.h>
3 #include <bc_sha256.h>
4 #include <bc_eeprom.h>
5 
6 #define _CONFIG_SIZEOF_HEADER sizeof(config_header_t)
7 #define _CONFIG_SIZEOF_CONFIG sizeof(config_t)
8 
9 #define _CONFIG_ADDRESS_HEADER 0
10 #define _CONFIG_ADDRESS_CONFIG (_CONFIG_ADDRESS_HEADER + _CONFIG_SIZEOF_HEADER)
11 
12 typedef struct
13 {
14  uint32_t signature;
15  void *config;
16  size_t size;
17  void *init_config;
18 
19 } bc_config_t;
20 
21 bc_config_t _bc_config;
22 
23 #pragma pack(push, 1)
24 
25 typedef struct
26 {
27  uint64_t signature;
28  uint8_t version;
29  uint16_t length;
30  uint8_t hash[6];
31 
33 
34 #pragma pack(pop)
35 
36 static void _config_eeprom_read(uint32_t address, void *buffer, size_t length);
37 static void _config_eeprom_write(uint32_t address, const void *buffer, size_t length);
38 
39 void bc_config_init(uint64_t signature, void *config, size_t size, void *init_config)
40 {
41  _bc_config.signature = signature;
42  _bc_config.config = config;
43  _bc_config.size = size;
44  _bc_config.init_config = init_config;
45 
46  if (!bc_config_load())
47  {
50  }
51 }
52 
53 void bc_config_reset(void)
54 {
55  if (!_bc_config.init_config)
56  {
57  // Initialize to zero if init_config is not set
58  memset(_bc_config.config, 0, _bc_config.size);
59  }
60  else
61  {
62  memcpy(_bc_config.config, _bc_config.init_config, _bc_config.size);
63  }
64 }
65 
66 bool bc_config_load(void)
67 {
68  config_header_t header;
69 
70  _config_eeprom_read(_CONFIG_ADDRESS_HEADER, &header, _CONFIG_SIZEOF_HEADER);
71 
72  if (header.signature != _bc_config.signature ||
73  header.length != _bc_config.size)
74  {
75  return false;
76  }
77 
78  _config_eeprom_read(_CONFIG_ADDRESS_CONFIG, _bc_config.config, _bc_config.size);
79 
80  static bc_sha256_t sha256;
81  static uint8_t hash[32];
82 
83  bc_sha256_init(&sha256);
84  bc_sha256_update(&sha256, _bc_config.config, _bc_config.size);
85  bc_sha256_final(&sha256, hash, false);
86 
87  if (memcmp(header.hash, hash, sizeof(header.hash)) != 0)
88  {
89  return false;
90  }
91 
92  return true;
93 }
94 
95 bool bc_config_save(void)
96 {
97  static bc_sha256_t sha256;
98  static uint8_t hash[32];
99 
100  bc_sha256_init(&sha256);
101  bc_sha256_update(&sha256, _bc_config.config, _bc_config.size);
102  bc_sha256_final(&sha256, hash, false);
103 
104  config_header_t header;
105 
106  header.signature = _bc_config.signature;
107  header.length = _bc_config.size;
108 
109  memcpy(header.hash, hash, sizeof(header.hash));
110 
111  _config_eeprom_write(_CONFIG_ADDRESS_HEADER, &header, _CONFIG_SIZEOF_HEADER);
112  _config_eeprom_write(_CONFIG_ADDRESS_CONFIG, _bc_config.config, _bc_config.size);
113 
114  return true;
115 }
116 
117 static void _config_eeprom_read(uint32_t address, void *buffer, size_t length)
118 {
119  uint8_t *p = buffer;
120 
121  for (size_t i = 0; i < length; i++)
122  {
123  uint8_t a, b, c;
124 
125  uint32_t offset_bank_a = 0;
126  uint32_t offset_bank_b = offset_bank_a + _CONFIG_SIZEOF_HEADER + _bc_config.size;
127  uint32_t offset_bank_c = offset_bank_b + _CONFIG_SIZEOF_HEADER + _bc_config.size;
128 
129  if (!bc_eeprom_read(offset_bank_a + address + i, &a, 1) ||
130  !bc_eeprom_read(offset_bank_b + address + i, &b, 1) ||
131  !bc_eeprom_read(offset_bank_c + address + i, &c, 1))
132  {
133  //app_error(APP_ERROR);
134  }
135 
136  *p++ = (a & b) | (a & c) | (b & c);
137  }
138 }
139 
140 static void _config_eeprom_write(uint32_t address, const void *buffer, size_t length)
141 {
142  uint32_t offset_bank_a = 0;
143  uint32_t offset_bank_b = offset_bank_a + _CONFIG_SIZEOF_HEADER + _bc_config.size;
144  uint32_t offset_bank_c = offset_bank_b + _CONFIG_SIZEOF_HEADER + _bc_config.size;
145 
146  if (!bc_eeprom_write(offset_bank_a + address, buffer, length) ||
147  !bc_eeprom_write(offset_bank_b + address, buffer, length) ||
148  !bc_eeprom_write(offset_bank_c + address, buffer, length))
149  {
150  //app_error(APP_ERROR_EEPROM);
151  }
152 }
bool bc_config_load(void)
Load EEPROM configuration.
Definition: bc_config.c:66
bool bc_config_save(void)
Save configuration to EEPROM.
Definition: bc_config.c:95
bool bc_eeprom_write(uint32_t address, const void *buffer, size_t length)
Write buffer to EEPROM area and verify it.
Definition: bc_eeprom.c:31
void bc_config_init(uint64_t signature, void *config, size_t size, void *init_config)
Initialize and load the config from EEPROM.
Definition: bc_config.c:39
void bc_config_reset(void)
Reset EEPROM configuration to zeros or init_config.
Definition: bc_config.c:53
bool bc_eeprom_read(uint32_t address, void *buffer, size_t length)
Read buffer from EEPROM area.
Definition: bc_eeprom.c:113
void bc_sha256_update(bc_sha256_t *self, const void *buffer, size_t length)
Compute SHA256 from data.
Definition: bc_sha256.c:40
void bc_sha256_final(bc_sha256_t *self, uint8_t *hash, bool little_endian)
Finalize SHA256 computation and read the final hash.
Definition: bc_sha256.c:58
void bc_sha256_init(bc_sha256_t *self)
Initialize SHA256 structure.
Definition: bc_sha256.c:26