eeconfig.h
9026 bytes
1/*
2Copyright 2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include <stdint.h>
21#include <stdbool.h>
22#include <stddef.h> // offsetof
23#include "eeprom.h"
24#include "util.h"
25#include "action_layer.h" // layer_state_t
26
27#ifndef EECONFIG_MAGIC_NUMBER
28# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEE5 // When changing, decrement this value to avoid future re-init issues
29#endif
30#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF
31
32// Dummy struct only used to calculate offsets
33typedef struct PACKED {
34 uint16_t magic;
35 uint8_t debug;
36 uint8_t default_layer;
37 uint16_t keymap;
38 uint8_t backlight;
39 uint8_t audio;
40 uint32_t rgblight;
41 uint8_t unicode;
42 uint8_t steno;
43 uint8_t handedness;
44 uint32_t keyboard;
45 uint32_t user;
46 union { // Mutually exclusive
47 uint32_t led_matrix;
48 uint64_t rgb_matrix;
49 };
50 uint32_t haptic;
51 uint8_t rgblight_ext;
52} eeprom_core_t;
53
54/* EEPROM parameter address */
55#define EECONFIG_MAGIC (uint16_t *)(offsetof(eeprom_core_t, magic))
56#define EECONFIG_DEBUG (uint8_t *)(offsetof(eeprom_core_t, debug))
57#define EECONFIG_DEFAULT_LAYER (uint8_t *)(offsetof(eeprom_core_t, default_layer))
58#define EECONFIG_KEYMAP (uint16_t *)(offsetof(eeprom_core_t, keymap))
59#define EECONFIG_BACKLIGHT (uint8_t *)(offsetof(eeprom_core_t, backlight))
60#define EECONFIG_AUDIO (uint8_t *)(offsetof(eeprom_core_t, audio))
61#define EECONFIG_RGBLIGHT (uint32_t *)(offsetof(eeprom_core_t, rgblight))
62#define EECONFIG_UNICODEMODE (uint8_t *)(offsetof(eeprom_core_t, unicode))
63#define EECONFIG_STENOMODE (uint8_t *)(offsetof(eeprom_core_t, steno))
64#define EECONFIG_HANDEDNESS (uint8_t *)(offsetof(eeprom_core_t, handedness))
65#define EECONFIG_KEYBOARD (uint32_t *)(offsetof(eeprom_core_t, keyboard))
66#define EECONFIG_USER (uint32_t *)(offsetof(eeprom_core_t, user))
67#define EECONFIG_LED_MATRIX (uint32_t *)(offsetof(eeprom_core_t, led_matrix))
68#define EECONFIG_RGB_MATRIX (uint64_t *)(offsetof(eeprom_core_t, rgb_matrix))
69#define EECONFIG_HAPTIC (uint32_t *)(offsetof(eeprom_core_t, haptic))
70#define EECONFIG_RGBLIGHT_EXTENDED (uint8_t *)(offsetof(eeprom_core_t, rgblight_ext))
71
72// Size of EEPROM being used for core data storage
73#define EECONFIG_BASE_SIZE ((uint8_t)sizeof(eeprom_core_t))
74
75// Size of EEPROM dedicated to keyboard- and user-specific data
76#ifndef EECONFIG_KB_DATA_SIZE
77# define EECONFIG_KB_DATA_SIZE 0
78#endif
79#ifndef EECONFIG_KB_DATA_VERSION
80# define EECONFIG_KB_DATA_VERSION (EECONFIG_KB_DATA_SIZE)
81#endif
82#ifndef EECONFIG_USER_DATA_SIZE
83# define EECONFIG_USER_DATA_SIZE 0
84#endif
85#ifndef EECONFIG_USER_DATA_VERSION
86# define EECONFIG_USER_DATA_VERSION (EECONFIG_USER_DATA_SIZE)
87#endif
88
89#define EECONFIG_KB_DATABLOCK ((uint8_t *)(EECONFIG_BASE_SIZE))
90#define EECONFIG_USER_DATABLOCK ((uint8_t *)((EECONFIG_BASE_SIZE) + (EECONFIG_KB_DATA_SIZE)))
91
92// Size of EEPROM being used, other code can refer to this for available EEPROM
93#define EECONFIG_SIZE ((EECONFIG_BASE_SIZE) + (EECONFIG_KB_DATA_SIZE) + (EECONFIG_USER_DATA_SIZE))
94
95/* debug bit */
96#define EECONFIG_DEBUG_ENABLE (1 << 0)
97#define EECONFIG_DEBUG_MATRIX (1 << 1)
98#define EECONFIG_DEBUG_KEYBOARD (1 << 2)
99#define EECONFIG_DEBUG_MOUSE (1 << 3)
100
101/* keyconf bit */
102#define EECONFIG_KEYMAP_SWAP_CONTROL_CAPSLOCK (1 << 0)
103#define EECONFIG_KEYMAP_CAPSLOCK_TO_CONTROL (1 << 1)
104#define EECONFIG_KEYMAP_SWAP_LALT_LGUI (1 << 2)
105#define EECONFIG_KEYMAP_SWAP_RALT_RGUI (1 << 3)
106#define EECONFIG_KEYMAP_NO_GUI (1 << 4)
107#define EECONFIG_KEYMAP_SWAP_GRAVE_ESC (1 << 5)
108#define EECONFIG_KEYMAP_SWAP_BACKSLASH_BACKSPACE (1 << 6)
109#define EECONFIG_KEYMAP_NKRO (1 << 7)
110
111bool eeconfig_is_enabled(void);
112bool eeconfig_is_disabled(void);
113
114void eeconfig_init(void);
115void eeconfig_init_quantum(void);
116void eeconfig_init_kb(void);
117void eeconfig_init_user(void);
118
119void eeconfig_enable(void);
120
121void eeconfig_disable(void);
122
123uint8_t eeconfig_read_debug(void);
124void eeconfig_update_debug(uint8_t val);
125
126layer_state_t eeconfig_read_default_layer(void);
127void eeconfig_update_default_layer(layer_state_t val);
128
129uint16_t eeconfig_read_keymap(void);
130void eeconfig_update_keymap(uint16_t val);
131
132#ifdef AUDIO_ENABLE
133uint8_t eeconfig_read_audio(void);
134void eeconfig_update_audio(uint8_t val);
135#endif
136
137#if (EECONFIG_KB_DATA_SIZE) == 0
138uint32_t eeconfig_read_kb(void);
139void eeconfig_update_kb(uint32_t val);
140#endif // (EECONFIG_KB_DATA_SIZE) == 0
141
142#if (EECONFIG_USER_DATA_SIZE) == 0
143uint32_t eeconfig_read_user(void);
144void eeconfig_update_user(uint32_t val);
145#endif // (EECONFIG_USER_DATA_SIZE) == 0
146
147#ifdef HAPTIC_ENABLE
148uint32_t eeconfig_read_haptic(void);
149void eeconfig_update_haptic(uint32_t val);
150#endif
151
152bool eeconfig_read_handedness(void);
153void eeconfig_update_handedness(bool val);
154
155#if (EECONFIG_KB_DATA_SIZE) > 0
156bool eeconfig_is_kb_datablock_valid(void);
157void eeconfig_read_kb_datablock(void *data);
158void eeconfig_update_kb_datablock(const void *data);
159void eeconfig_init_kb_datablock(void);
160#endif // (EECONFIG_KB_DATA_SIZE) > 0
161
162#if (EECONFIG_USER_DATA_SIZE) > 0
163bool eeconfig_is_user_datablock_valid(void);
164void eeconfig_read_user_datablock(void *data);
165void eeconfig_update_user_datablock(const void *data);
166void eeconfig_init_user_datablock(void);
167#endif // (EECONFIG_USER_DATA_SIZE) > 0
168
169// Any "checked" debounce variant used requires implementation of:
170// -- bool eeconfig_check_valid_##name(void)
171// -- void eeconfig_post_flush_##name(void)
172#define EECONFIG_DEBOUNCE_HELPER_CHECKED(name, offset, config) \
173 static uint8_t dirty_##name = false; \
174 \
175 bool eeconfig_check_valid_##name(void); \
176 void eeconfig_post_flush_##name(void); \
177 \
178 static inline void eeconfig_init_##name(void) { \
179 dirty_##name = true; \
180 if (eeconfig_check_valid_##name()) { \
181 eeprom_read_block(&config, offset, sizeof(config)); \
182 dirty_##name = false; \
183 } \
184 } \
185 static inline void eeconfig_flush_##name(bool force) { \
186 if (force || dirty_##name) { \
187 eeprom_update_block(&config, offset, sizeof(config)); \
188 eeconfig_post_flush_##name(); \
189 dirty_##name = false; \
190 } \
191 } \
192 static inline void eeconfig_flush_##name##_task(uint16_t timeout) { \
193 static uint16_t flush_timer = 0; \
194 if (timer_elapsed(flush_timer) > timeout) { \
195 eeconfig_flush_##name(false); \
196 flush_timer = timer_read(); \
197 } \
198 } \
199 static inline void eeconfig_flag_##name(bool v) { \
200 dirty_##name |= v; \
201 } \
202 static inline void eeconfig_write_##name(typeof(config) *conf) { \
203 if (memcmp(&config, conf, sizeof(config)) != 0) { \
204 memcpy(&config, conf, sizeof(config)); \
205 eeconfig_flag_##name(true); \
206 } \
207 }
208
209#define EECONFIG_DEBOUNCE_HELPER(name, offset, config) \
210 EECONFIG_DEBOUNCE_HELPER_CHECKED(name, offset, config) \
211 \
212 bool eeconfig_check_valid_##name(void) { \
213 return true; \
214 } \
215 void eeconfig_post_flush_##name(void) {}