Parent directory

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) {}