Non-volatile memory data repository pattern (#24356)

* First batch of eeconfig conversions.

* Offset and length for datablocks.

* `via`, `dynamic_keymap`.

* Fix filename.

* Commentary.

* wilba leds

* satisfaction75

* satisfaction75

* more keyboard whack-a-mole

* satisfaction75

* omnikeyish

* more whack-a-mole

* `generic_features.mk` to automatically pick up nvm repositories

* thievery

* deferred variable resolve

* whitespace

* convert api to structs/unions

* convert api to structs/unions

* convert api to structs/unions

* fixups

* code-side docs

* code size fix

* rollback

* nvm_xxxxx_erase

* Updated location of eeconfig magic numbers so non-EEPROM nvm drivers can use them too.

* Fixup build.

* Fixup compilation error with encoders.

* Build fixes.

* Add `via_ci` keymap to onekey to exercise VIA bindings (and thus dynamic keymap et.al.), fixup compilation errors based on preprocessor+sizeof.

* Build failure rectification.
This commit is contained in:
Nick Brassel 2025-03-21 23:38:34 +11:00 committed by GitHub
parent c9d62ddc78
commit 2b00b846dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
87 changed files with 1464 additions and 839 deletions

View file

@ -19,59 +19,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h> // offsetof
#include "eeprom.h"
#include "util.h"
#include <stddef.h> // offsetof
#include "action_layer.h" // layer_state_t
#ifndef EECONFIG_MAGIC_NUMBER
# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEE5 // When changing, decrement this value to avoid future re-init issues
#endif
#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF
// Dummy struct only used to calculate offsets
typedef struct PACKED {
uint16_t magic;
uint8_t debug;
uint8_t default_layer;
uint16_t keymap;
uint8_t backlight;
uint8_t audio;
uint32_t rgblight;
uint8_t unicode;
uint8_t steno;
uint8_t handedness;
uint32_t keyboard;
uint32_t user;
union { // Mutually exclusive
uint32_t led_matrix;
uint64_t rgb_matrix;
};
uint32_t haptic;
uint8_t rgblight_ext;
} eeprom_core_t;
/* EEPROM parameter address */
#define EECONFIG_MAGIC (uint16_t *)(offsetof(eeprom_core_t, magic))
#define EECONFIG_DEBUG (uint8_t *)(offsetof(eeprom_core_t, debug))
#define EECONFIG_DEFAULT_LAYER (uint8_t *)(offsetof(eeprom_core_t, default_layer))
#define EECONFIG_KEYMAP (uint16_t *)(offsetof(eeprom_core_t, keymap))
#define EECONFIG_BACKLIGHT (uint8_t *)(offsetof(eeprom_core_t, backlight))
#define EECONFIG_AUDIO (uint8_t *)(offsetof(eeprom_core_t, audio))
#define EECONFIG_RGBLIGHT (uint32_t *)(offsetof(eeprom_core_t, rgblight))
#define EECONFIG_UNICODEMODE (uint8_t *)(offsetof(eeprom_core_t, unicode))
#define EECONFIG_STENOMODE (uint8_t *)(offsetof(eeprom_core_t, steno))
#define EECONFIG_HANDEDNESS (uint8_t *)(offsetof(eeprom_core_t, handedness))
#define EECONFIG_KEYBOARD (uint32_t *)(offsetof(eeprom_core_t, keyboard))
#define EECONFIG_USER (uint32_t *)(offsetof(eeprom_core_t, user))
#define EECONFIG_LED_MATRIX (uint32_t *)(offsetof(eeprom_core_t, led_matrix))
#define EECONFIG_RGB_MATRIX (uint64_t *)(offsetof(eeprom_core_t, rgb_matrix))
#define EECONFIG_HAPTIC (uint32_t *)(offsetof(eeprom_core_t, haptic))
#define EECONFIG_RGBLIGHT_EXTENDED (uint8_t *)(offsetof(eeprom_core_t, rgblight_ext))
// Size of EEPROM being used for core data storage
#define EECONFIG_BASE_SIZE ((uint8_t)sizeof(eeprom_core_t))
// Size of EEPROM dedicated to keyboard- and user-specific data
#ifndef EECONFIG_KB_DATA_SIZE
# define EECONFIG_KB_DATA_SIZE 0
@ -86,12 +36,6 @@ typedef struct PACKED {
# define EECONFIG_USER_DATA_VERSION (EECONFIG_USER_DATA_SIZE)
#endif
#define EECONFIG_KB_DATABLOCK ((uint8_t *)(EECONFIG_BASE_SIZE))
#define EECONFIG_USER_DATABLOCK ((uint8_t *)((EECONFIG_BASE_SIZE) + (EECONFIG_KB_DATA_SIZE)))
// Size of EEPROM being used, other code can refer to this for available EEPROM
#define EECONFIG_SIZE ((EECONFIG_BASE_SIZE) + (EECONFIG_KB_DATA_SIZE) + (EECONFIG_USER_DATA_SIZE))
/* debug bit */
#define EECONFIG_DEBUG_ENABLE (1 << 0)
#define EECONFIG_DEBUG_MATRIX (1 << 1)
@ -117,22 +61,59 @@ void eeconfig_init_kb(void);
void eeconfig_init_user(void);
void eeconfig_enable(void);
void eeconfig_disable(void);
uint8_t eeconfig_read_debug(void);
void eeconfig_update_debug(uint8_t val);
typedef union debug_config_t debug_config_t;
void eeconfig_read_debug(debug_config_t *debug_config) __attribute__((nonnull));
void eeconfig_update_debug(const debug_config_t *debug_config) __attribute__((nonnull));
layer_state_t eeconfig_read_default_layer(void);
void eeconfig_update_default_layer(layer_state_t val);
void eeconfig_update_default_layer(layer_state_t state);
uint16_t eeconfig_read_keymap(void);
void eeconfig_update_keymap(uint16_t val);
typedef union keymap_config_t keymap_config_t;
void eeconfig_read_keymap(keymap_config_t *keymap_config) __attribute__((nonnull));
void eeconfig_update_keymap(const keymap_config_t *keymap_config) __attribute__((nonnull));
#ifdef AUDIO_ENABLE
uint8_t eeconfig_read_audio(void);
void eeconfig_update_audio(uint8_t val);
#endif
typedef union audio_config_t audio_config_t;
void eeconfig_read_audio(audio_config_t *audio_config) __attribute__((nonnull));
void eeconfig_update_audio(const audio_config_t *audio_config) __attribute__((nonnull));
#endif // AUDIO_ENABLE
#ifdef UNICODE_COMMON_ENABLE
typedef union unicode_config_t unicode_config_t;
void eeconfig_read_unicode_mode(unicode_config_t *unicode_config) __attribute__((nonnull));
void eeconfig_update_unicode_mode(const unicode_config_t *unicode_config) __attribute__((nonnull));
#endif // UNICODE_COMMON_ENABLE
#ifdef BACKLIGHT_ENABLE
typedef union backlight_config_t backlight_config_t;
void eeconfig_read_backlight(backlight_config_t *backlight_config) __attribute__((nonnull));
void eeconfig_update_backlight(const backlight_config_t *backlight_config) __attribute__((nonnull));
#endif // BACKLIGHT_ENABLE
#ifdef STENO_ENABLE
uint8_t eeconfig_read_steno_mode(void);
void eeconfig_update_steno_mode(uint8_t val);
#endif // STENO_ENABLE
#ifdef RGB_MATRIX_ENABLE
typedef union rgb_config_t rgb_config_t;
void eeconfig_read_rgb_matrix(rgb_config_t *rgb_matrix_config) __attribute__((nonnull));
void eeconfig_update_rgb_matrix(const rgb_config_t *rgb_matrix_config) __attribute__((nonnull));
#endif // RGB_MATRIX_ENABLE
#ifdef LED_MATRIX_ENABLE
typedef union led_eeconfig_t led_eeconfig_t;
void eeconfig_read_led_matrix(led_eeconfig_t *led_matrix_config) __attribute__((nonnull));
void eeconfig_update_led_matrix(const led_eeconfig_t *led_matrix_config) __attribute__((nonnull));
#endif // LED_MATRIX_ENABLE
#ifdef RGBLIGHT_ENABLE
typedef union rgblight_config_t rgblight_config_t;
void eeconfig_read_rgblight(rgblight_config_t *rgblight_config) __attribute__((nonnull));
void eeconfig_update_rgblight(const rgblight_config_t *rgblight_config) __attribute__((nonnull));
#endif // RGBLIGHT_ENABLE
#if (EECONFIG_KB_DATA_SIZE) == 0
uint32_t eeconfig_read_kb(void);
@ -145,31 +126,36 @@ void eeconfig_update_user(uint32_t val);
#endif // (EECONFIG_USER_DATA_SIZE) == 0
#ifdef HAPTIC_ENABLE
uint32_t eeconfig_read_haptic(void);
void eeconfig_update_haptic(uint32_t val);
typedef union haptic_config_t haptic_config_t;
void eeconfig_read_haptic(haptic_config_t *haptic_config) __attribute__((nonnull));
void eeconfig_update_haptic(const haptic_config_t *haptic_config) __attribute__((nonnull));
#endif
bool eeconfig_read_handedness(void);
void eeconfig_update_handedness(bool val);
#if (EECONFIG_KB_DATA_SIZE) > 0
bool eeconfig_is_kb_datablock_valid(void);
void eeconfig_read_kb_datablock(void *data);
void eeconfig_update_kb_datablock(const void *data);
void eeconfig_init_kb_datablock(void);
bool eeconfig_is_kb_datablock_valid(void);
uint32_t eeconfig_read_kb_datablock(void *data, uint32_t offset, uint32_t length) __attribute__((nonnull));
uint32_t eeconfig_update_kb_datablock(const void *data, uint32_t offset, uint32_t length) __attribute__((nonnull));
void eeconfig_init_kb_datablock(void);
# define eeconfig_read_kb_datablock_field(__object, __field) eeconfig_read_kb_datablock(&(__object.__field), offsetof(typeof(__object), __field), sizeof(__object.__field))
# define eeconfig_update_kb_datablock_field(__object, __field) eeconfig_update_kb_datablock(&(__object.__field), offsetof(typeof(__object), __field), sizeof(__object.__field))
#endif // (EECONFIG_KB_DATA_SIZE) > 0
#if (EECONFIG_USER_DATA_SIZE) > 0
bool eeconfig_is_user_datablock_valid(void);
void eeconfig_read_user_datablock(void *data);
void eeconfig_update_user_datablock(const void *data);
void eeconfig_init_user_datablock(void);
bool eeconfig_is_user_datablock_valid(void);
uint32_t eeconfig_read_user_datablock(void *data, uint32_t offset, uint32_t length) __attribute__((nonnull));
uint32_t eeconfig_update_user_datablock(const void *data, uint32_t offset, uint32_t length) __attribute__((nonnull));
void eeconfig_init_user_datablock(void);
# define eeconfig_read_user_datablock_field(__object, __field) eeconfig_read_user_datablock(&(__object.__field), offsetof(__object, __field), sizeof(__object.__field))
# define eeconfig_update_user_datablock_field(__object, __field) eeconfig_update_user_datablock(&(__object.__field), offsetof(__object, __field), sizeof(__object.__field))
#endif // (EECONFIG_USER_DATA_SIZE) > 0
// Any "checked" debounce variant used requires implementation of:
// -- bool eeconfig_check_valid_##name(void)
// -- void eeconfig_post_flush_##name(void)
#define EECONFIG_DEBOUNCE_HELPER_CHECKED(name, offset, config) \
#define EECONFIG_DEBOUNCE_HELPER_CHECKED(name, config) \
static uint8_t dirty_##name = false; \
\
bool eeconfig_check_valid_##name(void); \
@ -178,13 +164,13 @@ void eeconfig_init_user_datablock(void);
static inline void eeconfig_init_##name(void) { \
dirty_##name = true; \
if (eeconfig_check_valid_##name()) { \
eeprom_read_block(&config, offset, sizeof(config)); \
eeconfig_read_##name(&config); \
dirty_##name = false; \
} \
} \
static inline void eeconfig_flush_##name(bool force) { \
if (force || dirty_##name) { \
eeprom_update_block(&config, offset, sizeof(config)); \
eeconfig_update_##name(&config); \
eeconfig_post_flush_##name(); \
dirty_##name = false; \
} \
@ -206,10 +192,10 @@ void eeconfig_init_user_datablock(void);
} \
}
#define EECONFIG_DEBOUNCE_HELPER(name, offset, config) \
EECONFIG_DEBOUNCE_HELPER_CHECKED(name, offset, config) \
\
bool eeconfig_check_valid_##name(void) { \
return true; \
} \
#define EECONFIG_DEBOUNCE_HELPER(name, config) \
EECONFIG_DEBOUNCE_HELPER_CHECKED(name, config) \
\
bool eeconfig_check_valid_##name(void) { \
return true; \
} \
void eeconfig_post_flush_##name(void) {}