eeconfig.c
8813 bytes
1#include <string.h>
2#include <stdint.h>
3#include <stdbool.h>
4#include "eeprom.h"
5#include "eeconfig.h"
6
7#if defined(EEPROM_DRIVER)
8# include "eeprom_driver.h"
9#endif
10
11#if defined(HAPTIC_ENABLE)
12# include "haptic.h"
13#endif
14
15#if defined(VIA_ENABLE)
16bool via_eeprom_is_valid(void);
17void via_eeprom_set_valid(bool valid);
18void eeconfig_init_via(void);
19#endif
20
21_Static_assert((intptr_t)EECONFIG_HANDEDNESS == 14, "EEPROM handedness offset is incorrect");
22
23/** \brief eeconfig enable
24 *
25 * FIXME: needs doc
26 */
27__attribute__((weak)) void eeconfig_init_user(void) {
28#if (EECONFIG_USER_DATA_SIZE) == 0
29 // Reset user EEPROM value to blank, rather than to a set value
30 eeconfig_update_user(0);
31#endif
32}
33
34__attribute__((weak)) void eeconfig_init_kb(void) {
35#if (EECONFIG_KB_DATA_SIZE) == 0
36 // Reset Keyboard EEPROM value to blank, rather than to a set value
37 eeconfig_update_kb(0);
38#endif
39
40 eeconfig_init_user();
41}
42
43/*
44 * FIXME: needs doc
45 */
46void eeconfig_init_quantum(void) {
47#if defined(EEPROM_DRIVER)
48 eeprom_driver_format(false);
49#endif
50
51 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
52 eeprom_update_byte(EECONFIG_DEBUG, 0);
53 default_layer_state = (layer_state_t)1 << 0;
54 eeconfig_update_default_layer(default_layer_state);
55 // Enable oneshot and autocorrect by default: 0b0001 0100 0000 0000
56 eeprom_update_word(EECONFIG_KEYMAP, 0x1400);
57 eeprom_update_byte(EECONFIG_BACKLIGHT, 0);
58 eeprom_update_byte(EECONFIG_AUDIO, 0);
59 eeprom_update_dword(EECONFIG_RGBLIGHT, 0);
60 eeprom_update_byte(EECONFIG_RGBLIGHT_EXTENDED, 0);
61 eeprom_update_byte(EECONFIG_UNICODEMODE, 0);
62 eeprom_update_byte(EECONFIG_STENOMODE, 0);
63 eeprom_write_qword(EECONFIG_RGB_MATRIX, 0);
64 eeprom_update_dword(EECONFIG_HAPTIC, 0);
65#if defined(HAPTIC_ENABLE)
66 haptic_reset();
67#endif
68
69#if (EECONFIG_KB_DATA_SIZE) > 0
70 eeconfig_init_kb_datablock();
71#endif
72
73#if (EECONFIG_USER_DATA_SIZE) > 0
74 eeconfig_init_user_datablock();
75#endif
76
77#if defined(VIA_ENABLE)
78 // Invalidate VIA eeprom config, and then reset.
79 // Just in case if power is lost mid init, this makes sure that it pets
80 // properly re-initialized.
81 via_eeprom_set_valid(false);
82 eeconfig_init_via();
83#endif
84
85 eeconfig_init_kb();
86}
87
88/** \brief eeconfig initialization
89 *
90 * FIXME: needs doc
91 */
92void eeconfig_init(void) {
93 eeconfig_init_quantum();
94}
95
96/** \brief eeconfig enable
97 *
98 * FIXME: needs doc
99 */
100void eeconfig_enable(void) {
101 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
102}
103
104/** \brief eeconfig disable
105 *
106 * FIXME: needs doc
107 */
108void eeconfig_disable(void) {
109#if defined(EEPROM_DRIVER)
110 eeprom_driver_format(false);
111#endif
112 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF);
113}
114
115/** \brief eeconfig is enabled
116 *
117 * FIXME: needs doc
118 */
119bool eeconfig_is_enabled(void) {
120 bool is_eeprom_enabled = (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER);
121#ifdef VIA_ENABLE
122 if (is_eeprom_enabled) {
123 is_eeprom_enabled = via_eeprom_is_valid();
124 }
125#endif
126 return is_eeprom_enabled;
127}
128
129/** \brief eeconfig is disabled
130 *
131 * FIXME: needs doc
132 */
133bool eeconfig_is_disabled(void) {
134 bool is_eeprom_disabled = (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF);
135#ifdef VIA_ENABLE
136 if (!is_eeprom_disabled) {
137 is_eeprom_disabled = !via_eeprom_is_valid();
138 }
139#endif
140 return is_eeprom_disabled;
141}
142
143/** \brief eeconfig read debug
144 *
145 * FIXME: needs doc
146 */
147uint8_t eeconfig_read_debug(void) {
148 return eeprom_read_byte(EECONFIG_DEBUG);
149}
150/** \brief eeconfig update debug
151 *
152 * FIXME: needs doc
153 */
154void eeconfig_update_debug(uint8_t val) {
155 eeprom_update_byte(EECONFIG_DEBUG, val);
156}
157
158/** \brief eeconfig read default layer
159 *
160 * FIXME: needs doc
161 */
162layer_state_t eeconfig_read_default_layer(void) {
163 uint8_t val = eeprom_read_byte(EECONFIG_DEFAULT_LAYER);
164
165#ifdef DEFAULT_LAYER_STATE_IS_VALUE_NOT_BITMASK
166 // stored as a layer number, so convert back to bitmask
167 return 1 << val;
168#else
169 // stored as 8-bit-wide bitmask, so read the value directly - handling padding to 16/32 bit layer_state_t
170 return val;
171#endif
172}
173/** \brief eeconfig update default layer
174 *
175 * FIXME: needs doc
176 */
177void eeconfig_update_default_layer(layer_state_t state) {
178#ifdef DEFAULT_LAYER_STATE_IS_VALUE_NOT_BITMASK
179 // stored as a layer number, so only store the highest layer
180 uint8_t val = get_highest_layer(state);
181#else
182 // stored as 8-bit-wide bitmask, so write the value directly - handling truncation from 16/32 bit layer_state_t
183 uint8_t val = state;
184#endif
185
186 eeprom_update_byte(EECONFIG_DEFAULT_LAYER, val);
187}
188
189/** \brief eeconfig read keymap
190 *
191 * FIXME: needs doc
192 */
193uint16_t eeconfig_read_keymap(void) {
194 return eeprom_read_word(EECONFIG_KEYMAP);
195}
196/** \brief eeconfig update keymap
197 *
198 * FIXME: needs doc
199 */
200void eeconfig_update_keymap(uint16_t val) {
201 eeprom_update_word(EECONFIG_KEYMAP, val);
202}
203
204/** \brief eeconfig read audio
205 *
206 * FIXME: needs doc
207 */
208uint8_t eeconfig_read_audio(void) {
209 return eeprom_read_byte(EECONFIG_AUDIO);
210}
211/** \brief eeconfig update audio
212 *
213 * FIXME: needs doc
214 */
215void eeconfig_update_audio(uint8_t val) {
216 eeprom_update_byte(EECONFIG_AUDIO, val);
217}
218
219#if (EECONFIG_KB_DATA_SIZE) == 0
220/** \brief eeconfig read kb
221 *
222 * FIXME: needs doc
223 */
224uint32_t eeconfig_read_kb(void) {
225 return eeprom_read_dword(EECONFIG_KEYBOARD);
226}
227/** \brief eeconfig update kb
228 *
229 * FIXME: needs doc
230 */
231void eeconfig_update_kb(uint32_t val) {
232 eeprom_update_dword(EECONFIG_KEYBOARD, val);
233}
234#endif // (EECONFIG_KB_DATA_SIZE) == 0
235
236#if (EECONFIG_USER_DATA_SIZE) == 0
237/** \brief eeconfig read user
238 *
239 * FIXME: needs doc
240 */
241uint32_t eeconfig_read_user(void) {
242 return eeprom_read_dword(EECONFIG_USER);
243}
244/** \brief eeconfig update user
245 *
246 * FIXME: needs doc
247 */
248void eeconfig_update_user(uint32_t val) {
249 eeprom_update_dword(EECONFIG_USER, val);
250}
251#endif // (EECONFIG_USER_DATA_SIZE) == 0
252
253/** \brief eeconfig read haptic
254 *
255 * FIXME: needs doc
256 */
257uint32_t eeconfig_read_haptic(void) {
258 return eeprom_read_dword(EECONFIG_HAPTIC);
259}
260/** \brief eeconfig update haptic
261 *
262 * FIXME: needs doc
263 */
264void eeconfig_update_haptic(uint32_t val) {
265 eeprom_update_dword(EECONFIG_HAPTIC, val);
266}
267
268/** \brief eeconfig read split handedness
269 *
270 * FIXME: needs doc
271 */
272bool eeconfig_read_handedness(void) {
273 return !!eeprom_read_byte(EECONFIG_HANDEDNESS);
274}
275/** \brief eeconfig update split handedness
276 *
277 * FIXME: needs doc
278 */
279void eeconfig_update_handedness(bool val) {
280 eeprom_update_byte(EECONFIG_HANDEDNESS, !!val);
281}
282
283#if (EECONFIG_KB_DATA_SIZE) > 0
284/** \brief eeconfig assert keyboard data block version
285 *
286 * FIXME: needs doc
287 */
288bool eeconfig_is_kb_datablock_valid(void) {
289 return eeprom_read_dword(EECONFIG_KEYBOARD) == (EECONFIG_KB_DATA_VERSION);
290}
291/** \brief eeconfig read keyboard data block
292 *
293 * FIXME: needs doc
294 */
295void eeconfig_read_kb_datablock(void *data) {
296 if (eeconfig_is_kb_datablock_valid()) {
297 eeprom_read_block(data, EECONFIG_KB_DATABLOCK, (EECONFIG_KB_DATA_SIZE));
298 } else {
299 memset(data, 0, (EECONFIG_KB_DATA_SIZE));
300 }
301}
302/** \brief eeconfig update keyboard data block
303 *
304 * FIXME: needs doc
305 */
306void eeconfig_update_kb_datablock(const void *data) {
307 eeprom_update_dword(EECONFIG_KEYBOARD, (EECONFIG_KB_DATA_VERSION));
308 eeprom_update_block(data, EECONFIG_KB_DATABLOCK, (EECONFIG_KB_DATA_SIZE));
309}
310/** \brief eeconfig init keyboard data block
311 *
312 * FIXME: needs doc
313 */
314__attribute__((weak)) void eeconfig_init_kb_datablock(void) {
315 uint8_t dummy_kb[(EECONFIG_KB_DATA_SIZE)] = {0};
316 eeconfig_update_kb_datablock(dummy_kb);
317}
318#endif // (EECONFIG_KB_DATA_SIZE) > 0
319
320#if (EECONFIG_USER_DATA_SIZE) > 0
321/** \brief eeconfig assert user data block version
322 *
323 * FIXME: needs doc
324 */
325bool eeconfig_is_user_datablock_valid(void) {
326 return eeprom_read_dword(EECONFIG_USER) == (EECONFIG_USER_DATA_VERSION);
327}
328/** \brief eeconfig read user data block
329 *
330 * FIXME: needs doc
331 */
332void eeconfig_read_user_datablock(void *data) {
333 if (eeconfig_is_user_datablock_valid()) {
334 eeprom_read_block(data, EECONFIG_USER_DATABLOCK, (EECONFIG_USER_DATA_SIZE));
335 } else {
336 memset(data, 0, (EECONFIG_USER_DATA_SIZE));
337 }
338}
339/** \brief eeconfig update user data block
340 *
341 * FIXME: needs doc
342 */
343void eeconfig_update_user_datablock(const void *data) {
344 eeprom_update_dword(EECONFIG_USER, (EECONFIG_USER_DATA_VERSION));
345 eeprom_update_block(data, EECONFIG_USER_DATABLOCK, (EECONFIG_USER_DATA_SIZE));
346}
347/** \brief eeconfig init user data block
348 *
349 * FIXME: needs doc
350 */
351__attribute__((weak)) void eeconfig_init_user_datablock(void) {
352 uint8_t dummy_user[(EECONFIG_USER_DATA_SIZE)] = {0};
353 eeconfig_update_user_datablock(dummy_user);
354}
355#endif // (EECONFIG_USER_DATA_SIZE) > 0