First batch of eeconfig conversions.

This commit is contained in:
Nick Brassel 2024-09-02 22:21:53 +10:00
parent a7ed82b39b
commit f78412d841
No known key found for this signature in database
22 changed files with 794 additions and 377 deletions

View File

@ -29,6 +29,8 @@ QUANTUM_SRC += \
$(QUANTUM_DIR)/logging/debug.c \
$(QUANTUM_DIR)/logging/sendchar.c \
include $(QUANTUM_DIR)/nvm/rules.mk
VPATH += $(QUANTUM_DIR)/logging
# Fall back to lib/printf if there is no platform provided print
ifeq ("$(wildcard $(PLATFORM_PATH)/$(PLATFORM_KEY)/printf.mk)","")
@ -625,6 +627,9 @@ ifeq ($(strip $(VIA_ENABLE)), yes)
RAW_ENABLE := yes
BOOTMAGIC_ENABLE := yes
TRI_LAYER_ENABLE := yes
QUANTUM_SRC += \
nvm_via.c
endif
VALID_CUSTOM_MATRIX_TYPES:= yes lite no

View File

@ -20,6 +20,6 @@
The size of the transient EEPROM buffer size.
*/
#ifndef TRANSIENT_EEPROM_SIZE
# include "eeconfig.h"
# include "nvm_eeconfig_eeprom.h"
# define TRANSIENT_EEPROM_SIZE (((EECONFIG_SIZE + 3) / 4) * 4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO
#endif

View File

@ -18,6 +18,7 @@
#include <string.h>
#include <math.h>
#include <lib/lib8tion/lib8tion.h>
#include "eeconfig.h"
#define LED_TRAIL 10
@ -105,7 +106,7 @@ static void swirl_set_color(HSV hsv) {
traverse_matrix();
if (!(top <= bottom && left <= right)) {
eeprom_read_block(&rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_matrix_config));
eeconfig_read_rgb_matrix(&rgb_matrix_config);
rgb_matrix_mode_noeeprom(rgb_matrix_config.mode);
return;
}

View File

@ -16,7 +16,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backlight.h"
#include "eeprom.h"
#include "eeconfig.h"
#include "debug.h"
@ -176,14 +175,6 @@ void backlight_level(uint8_t level) {
eeconfig_update_backlight(backlight_config.raw);
}
uint8_t eeconfig_read_backlight(void) {
return eeprom_read_byte(EECONFIG_BACKLIGHT);
}
void eeconfig_update_backlight(uint8_t val) {
eeprom_update_byte(EECONFIG_BACKLIGHT, val);
}
void eeconfig_update_backlight_current(void) {
eeconfig_update_backlight(backlight_config.raw);
}

View File

@ -4,76 +4,93 @@
#include "eeprom.h"
#include "eeconfig.h"
#include "action_layer.h"
#include "nvm_eeconfig.h"
#if defined(EEPROM_DRIVER)
#ifdef EEPROM_DRIVER
# include "eeprom_driver.h"
#endif
#endif // EEPROM_DRIVER
#if defined(HAPTIC_ENABLE)
#ifdef HAPTIC_ENABLE
# include "haptic.h"
#endif
#endif // HAPTIC_ENABLE
#if defined(VIA_ENABLE)
#ifdef VIA_ENABLE
bool via_eeprom_is_valid(void);
void via_eeprom_set_valid(bool valid);
void eeconfig_init_via(void);
#endif
#endif // VIA_ENABLE
_Static_assert((intptr_t)EECONFIG_HANDEDNESS == 14, "EEPROM handedness offset is incorrect");
/** \brief eeconfig enable
*
* FIXME: needs doc
*/
__attribute__((weak)) void eeconfig_init_user(void) {
#if (EECONFIG_USER_DATA_SIZE) == 0
// Reset user EEPROM value to blank, rather than to a set value
eeconfig_update_user(0);
#endif
#endif // (EECONFIG_USER_DATA_SIZE) == 0
}
__attribute__((weak)) void eeconfig_init_kb(void) {
#if (EECONFIG_KB_DATA_SIZE) == 0
// Reset Keyboard EEPROM value to blank, rather than to a set value
eeconfig_update_kb(0);
#endif
#endif // (EECONFIG_KB_DATA_SIZE) == 0
eeconfig_init_user();
}
/*
* FIXME: needs doc
*/
void eeconfig_init_quantum(void) {
#if defined(EEPROM_DRIVER)
#ifdef EEPROM_DRIVER
eeprom_driver_format(false);
#endif // EEPROM_DRIVER
eeconfig_enable();
eeconfig_update_debug(0);
default_layer_state = (layer_state_t)1 << 0;
eeconfig_update_default_layer(default_layer_state);
// Enable oneshot and autocorrect by default: 0b0001 0100 0000 0000
eeconfig_update_keymap(0x1400);
#ifdef BACKLIGHT_ENABLE
eeconfig_update_backlight(0);
#endif // BACKLIGHT_ENABLE
#ifdef AUDIO_ENABLE
eeconfig_update_audio(0);
#endif // AUDIO_ENABLE
#ifdef RGBLIGHT_ENABLE
rgblight_config_t rgblight_config = {0};
eeconfig_update_rgblight(&rgblight_config);
#endif // RGBLIGHT_ENABLE
#ifdef UNICODE_COMMON_ENABLE
eeconfig_update_unicode_mode(0);
#endif // UNICODE_COMMON_ENABLE
#ifdef STENO_ENABLE
nvm_eeconfig_update_steno_mode(0);
#endif // STENO_ENABLE
#ifdef RGB_MATRIX_ENABLE
rgb_config_t rgb_matrix_config = {0};
eeconfig_update_rgb_matrix(&rgb_matrix_config);
#endif
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
eeprom_update_byte(EECONFIG_DEBUG, 0);
default_layer_state = (layer_state_t)1 << 0;
eeprom_update_byte(EECONFIG_DEFAULT_LAYER, default_layer_state);
// Enable oneshot and autocorrect by default: 0b0001 0100 0000 0000
eeprom_update_word(EECONFIG_KEYMAP, 0x1400);
eeprom_update_byte(EECONFIG_BACKLIGHT, 0);
eeprom_update_byte(EECONFIG_AUDIO, 0);
eeprom_update_dword(EECONFIG_RGBLIGHT, 0);
eeprom_update_byte(EECONFIG_RGBLIGHT_EXTENDED, 0);
eeprom_update_byte(EECONFIG_UNICODEMODE, 0);
eeprom_update_byte(EECONFIG_STENOMODE, 0);
eeprom_write_qword(EECONFIG_RGB_MATRIX, 0);
eeprom_update_dword(EECONFIG_HAPTIC, 0);
#if defined(HAPTIC_ENABLE)
#ifdef LED_MATRIX_ENABLE
led_eeconfig_t led_matrix_config = {0};
eeconfig_update_led_matrix(&led_matrix_config);
#endif // LED_MATRIX_ENABLE
#ifdef HAPTIC_ENABLE
nvm_eeconfig_update_haptic(0);
haptic_reset();
#endif
#endif // HAPTIC_ENABLE
#if (EECONFIG_KB_DATA_SIZE) > 0
eeconfig_init_kb_datablock();
#endif
#endif // (EECONFIG_KB_DATA_SIZE) > 0
#if (EECONFIG_USER_DATA_SIZE) > 0
eeconfig_init_user_datablock();
#endif
#endif // (EECONFIG_USER_DATA_SIZE) > 0
#if defined(VIA_ENABLE)
// Invalidate VIA eeprom config, and then reset.
@ -86,255 +103,170 @@ void eeconfig_init_quantum(void) {
eeconfig_init_kb();
}
/** \brief eeconfig initialization
*
* FIXME: needs doc
*/
void eeconfig_init(void) {
eeconfig_init_quantum();
}
/** \brief eeconfig enable
*
* FIXME: needs doc
*/
void eeconfig_enable(void) {
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
nvm_eeconfig_enable();
}
/** \brief eeconfig disable
*
* FIXME: needs doc
*/
void eeconfig_disable(void) {
#if defined(EEPROM_DRIVER)
eeprom_driver_format(false);
#endif
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF);
nvm_eeconfig_disable();
}
/** \brief eeconfig is enabled
*
* FIXME: needs doc
*/
bool eeconfig_is_enabled(void) {
bool is_eeprom_enabled = (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER);
#ifdef VIA_ENABLE
if (is_eeprom_enabled) {
is_eeprom_enabled = via_eeprom_is_valid();
}
#endif
return is_eeprom_enabled;
return nvm_eeconfig_is_enabled();
}
/** \brief eeconfig is disabled
*
* FIXME: needs doc
*/
bool eeconfig_is_disabled(void) {
bool is_eeprom_disabled = (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF);
#ifdef VIA_ENABLE
if (!is_eeprom_disabled) {
is_eeprom_disabled = !via_eeprom_is_valid();
}
#endif
return is_eeprom_disabled;
return nvm_eeconfig_is_disabled();
}
/** \brief eeconfig read debug
*
* FIXME: needs doc
*/
uint8_t eeconfig_read_debug(void) {
return eeprom_read_byte(EECONFIG_DEBUG);
return nvm_eeconfig_read_debug();
}
/** \brief eeconfig update debug
*
* FIXME: needs doc
*/
void eeconfig_update_debug(uint8_t val) {
eeprom_update_byte(EECONFIG_DEBUG, val);
nvm_eeconfig_update_debug(val);
}
/** \brief eeconfig read default layer
*
* FIXME: needs doc
*/
uint8_t eeconfig_read_default_layer(void) {
return eeprom_read_byte(EECONFIG_DEFAULT_LAYER);
return nvm_eeconfig_read_default_layer();
}
/** \brief eeconfig update default layer
*
* FIXME: needs doc
*/
void eeconfig_update_default_layer(uint8_t val) {
eeprom_update_byte(EECONFIG_DEFAULT_LAYER, val);
nvm_eeconfig_update_default_layer(val);
}
/** \brief eeconfig read keymap
*
* FIXME: needs doc
*/
uint16_t eeconfig_read_keymap(void) {
return eeprom_read_word(EECONFIG_KEYMAP);
return nvm_eeconfig_read_keymap();
}
/** \brief eeconfig update keymap
*
* FIXME: needs doc
*/
void eeconfig_update_keymap(uint16_t val) {
eeprom_update_word(EECONFIG_KEYMAP, val);
nvm_eeconfig_update_keymap(val);
}
/** \brief eeconfig read audio
*
* FIXME: needs doc
*/
#ifdef AUDIO_ENABLE
uint8_t eeconfig_read_audio(void) {
return eeprom_read_byte(EECONFIG_AUDIO);
return nvm_eeconfig_read_audio();
}
/** \brief eeconfig update audio
*
* FIXME: needs doc
*/
void eeconfig_update_audio(uint8_t val) {
eeprom_update_byte(EECONFIG_AUDIO, val);
nvm_eeconfig_update_audio(val);
}
#endif // AUDIO_ENABLE
#ifdef UNICODE_COMMON_ENABLE
uint8_t eeconfig_read_unicode_mode(void) {
return nvm_eeconfig_read_unicode_mode();
}
void eeconfig_update_unicode_mode(uint8_t val) {
nvm_eeconfig_update_unicode_mode(val);
}
#endif // UNICODE_COMMON_ENABLE
#ifdef BACKLIGHT_ENABLE
uint8_t eeconfig_read_backlight(void) {
return nvm_eeconfig_read_backlight();
}
void eeconfig_update_backlight(uint8_t val) {
nvm_eeconfig_update_backlight(val);
}
#endif // BACKLIGHT_ENABLE
#ifdef STENO_ENABLE
uint8_t eeconfig_read_steno_mode(void) {
return nvm_eeconfig_read_steno_mode();
}
void eeconfig_update_steno_mode(uint8_t val) {
nvm_eeconfig_update_steno_mode(val);
}
#endif // STENO_ENABLE
#ifdef RGB_MATRIX_ENABLE
void eeconfig_read_rgb_matrix(rgb_config_t *rgb_matrix_config) {
nvm_eeconfig_read_rgb_matrix(rgb_matrix_config);
}
void eeconfig_update_rgb_matrix(const rgb_config_t *rgb_matrix_config) {
nvm_eeconfig_update_rgb_matrix(rgb_matrix_config);
}
#endif // RGB_MATRIX_ENABLE
#ifdef LED_MATRIX_ENABLE
void eeconfig_read_led_matrix(led_eeconfig_t *led_matrix_config) {
nvm_eeconfig_read_led_matrix(led_matrix_config);
}
void eeconfig_update_led_matrix(const led_eeconfig_t *led_matrix_config) {
nvm_eeconfig_update_led_matrix(led_matrix_config);
}
#endif // LED_MATRIX_ENABLE
#ifdef RGBLIGHT_ENABLE
void eeconfig_read_rgblight(rgblight_config_t *rgblight_config) {
nvm_eeconfig_read_rgblight(rgblight_config);
}
void eeconfig_update_rgblight(const rgblight_config_t *rgblight_config) {
nvm_eeconfig_update_rgblight(rgblight_config);
}
#endif // RGBLIGHT_ENABLE
#if (EECONFIG_KB_DATA_SIZE) == 0
/** \brief eeconfig read kb
*
* FIXME: needs doc
*/
uint32_t eeconfig_read_kb(void) {
return eeprom_read_dword(EECONFIG_KEYBOARD);
return nvm_eeconfig_read_kb();
}
/** \brief eeconfig update kb
*
* FIXME: needs doc
*/
void eeconfig_update_kb(uint32_t val) {
eeprom_update_dword(EECONFIG_KEYBOARD, val);
nvm_eeconfig_update_kb(val);
}
#endif // (EECONFIG_KB_DATA_SIZE) == 0
#if (EECONFIG_USER_DATA_SIZE) == 0
/** \brief eeconfig read user
*
* FIXME: needs doc
*/
uint32_t eeconfig_read_user(void) {
return eeprom_read_dword(EECONFIG_USER);
return nvm_eeconfig_read_user();
}
/** \brief eeconfig update user
*
* FIXME: needs doc
*/
void eeconfig_update_user(uint32_t val) {
eeprom_update_dword(EECONFIG_USER, val);
nvm_eeconfig_update_user(val);
}
#endif // (EECONFIG_USER_DATA_SIZE) == 0
/** \brief eeconfig read haptic
*
* FIXME: needs doc
*/
#ifdef HAPTIC_ENABLE
uint32_t eeconfig_read_haptic(void) {
return eeprom_read_dword(EECONFIG_HAPTIC);
return nvm_eeconfig_read_haptic();
}
/** \brief eeconfig update haptic
*
* FIXME: needs doc
*/
void eeconfig_update_haptic(uint32_t val) {
eeprom_update_dword(EECONFIG_HAPTIC, val);
nvm_eeconfig_update_haptic(val);
}
#endif // HAPTIC_ENABLE
/** \brief eeconfig read split handedness
*
* FIXME: needs doc
*/
bool eeconfig_read_handedness(void) {
return !!eeprom_read_byte(EECONFIG_HANDEDNESS);
return nvm_eeconfig_read_handedness();
}
/** \brief eeconfig update split handedness
*
* FIXME: needs doc
*/
void eeconfig_update_handedness(bool val) {
eeprom_update_byte(EECONFIG_HANDEDNESS, !!val);
nvm_eeconfig_update_handedness(val);
}
#if (EECONFIG_KB_DATA_SIZE) > 0
/** \brief eeconfig assert keyboard data block version
*
* FIXME: needs doc
*/
bool eeconfig_is_kb_datablock_valid(void) {
return eeprom_read_dword(EECONFIG_KEYBOARD) == (EECONFIG_KB_DATA_VERSION);
return nvm_eeconfig_is_kb_datablock_valid();
}
/** \brief eeconfig read keyboard data block
*
* FIXME: needs doc
*/
void eeconfig_read_kb_datablock(void *data) {
if (eeconfig_is_kb_datablock_valid()) {
eeprom_read_block(data, EECONFIG_KB_DATABLOCK, (EECONFIG_KB_DATA_SIZE));
} else {
memset(data, 0, (EECONFIG_KB_DATA_SIZE));
}
nvm_eeconfig_read_kb_datablock(data);
}
/** \brief eeconfig update keyboard data block
*
* FIXME: needs doc
*/
void eeconfig_update_kb_datablock(const void *data) {
eeprom_update_dword(EECONFIG_KEYBOARD, (EECONFIG_KB_DATA_VERSION));
eeprom_update_block(data, EECONFIG_KB_DATABLOCK, (EECONFIG_KB_DATA_SIZE));
nvm_eeconfig_update_kb_datablock(data);
}
/** \brief eeconfig init keyboard data block
*
* FIXME: needs doc
*/
__attribute__((weak)) void eeconfig_init_kb_datablock(void) {
uint8_t dummy_kb[(EECONFIG_KB_DATA_SIZE)] = {0};
eeconfig_update_kb_datablock(dummy_kb);
nvm_eeconfig_init_kb_datablock();
}
#endif // (EECONFIG_KB_DATA_SIZE) > 0
#if (EECONFIG_USER_DATA_SIZE) > 0
/** \brief eeconfig assert user data block version
*
* FIXME: needs doc
*/
bool eeconfig_is_user_datablock_valid(void) {
return eeprom_read_dword(EECONFIG_USER) == (EECONFIG_USER_DATA_VERSION);
return nvm_eeconfig_is_user_datablock_valid();
}
/** \brief eeconfig read user data block
*
* FIXME: needs doc
*/
void eeconfig_read_user_datablock(void *data) {
if (eeconfig_is_user_datablock_valid()) {
eeprom_read_block(data, EECONFIG_USER_DATABLOCK, (EECONFIG_USER_DATA_SIZE));
} else {
memset(data, 0, (EECONFIG_USER_DATA_SIZE));
}
nvm_eeconfig_read_user_datablock(data);
}
/** \brief eeconfig update user data block
*
* FIXME: needs doc
*/
void eeconfig_update_user_datablock(const void *data) {
eeprom_update_dword(EECONFIG_USER, (EECONFIG_USER_DATA_VERSION));
eeprom_update_block(data, EECONFIG_USER_DATABLOCK, (EECONFIG_USER_DATA_SIZE));
nvm_eeconfig_update_user_datablock(data);
}
/** \brief eeconfig init user data block
*
* FIXME: needs doc
*/
__attribute__((weak)) void eeconfig_init_user_datablock(void) {
uint8_t dummy_user[(EECONFIG_USER_DATA_SIZE)] = {0};
eeconfig_update_user_datablock(dummy_user);
nvm_eeconfig_init_user_datablock();
}
#endif // (EECONFIG_USER_DATA_SIZE) > 0

View File

@ -20,56 +20,18 @@ 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"
#ifndef EECONFIG_MAGIC_NUMBER
# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEE5 // When changing, decrement this value to avoid future re-init issues
#ifdef RGB_MATRIX_ENABLE
# include "rgb_matrix_types.h"
#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;
#ifdef LED_MATRIX_ENABLE
# include "led_matrix_types.h"
#endif
/* 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))
#ifdef RGBLIGHT_ENABLE
# include "rgblight.h"
#endif
// Size of EEPROM dedicated to keyboard- and user-specific data
#ifndef EECONFIG_KB_DATA_SIZE
@ -85,12 +47,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)
@ -116,7 +72,6 @@ void eeconfig_init_kb(void);
void eeconfig_init_user(void);
void eeconfig_enable(void);
void eeconfig_disable(void);
uint8_t eeconfig_read_debug(void);
@ -131,7 +86,37 @@ void eeconfig_update_keymap(uint16_t val);
#ifdef AUDIO_ENABLE
uint8_t eeconfig_read_audio(void);
void eeconfig_update_audio(uint8_t val);
#endif
#endif // AUDIO_ENABLE
#ifdef UNICODE_COMMON_ENABLE
uint8_t eeconfig_read_unicode_mode(void);
void eeconfig_update_unicode_mode(uint8_t val);
#endif // UNICODE_COMMON_ENABLE
#ifdef BACKLIGHT_ENABLE
uint8_t eeconfig_read_backlight(void);
void eeconfig_update_backlight(uint8_t val);
#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
void eeconfig_read_rgb_matrix(rgb_config_t *rgb_matrix_config);
void eeconfig_update_rgb_matrix(const rgb_config_t *rgb_matrix_config);
#endif // RGB_MATRIX_ENABLE
#ifdef LED_MATRIX_ENABLE
void eeconfig_read_led_matrix(led_eeconfig_t *led_matrix_config);
void eeconfig_update_led_matrix(const led_eeconfig_t *led_matrix_config);
#endif // LED_MATRIX_ENABLE
#ifdef RGBLIGHT_ENABLE
void eeconfig_read_rgblight(rgblight_config_t *rgblight_config);
void eeconfig_update_rgblight(const rgblight_config_t *rgblight_config);
#endif // RGBLIGHT_ENABLE
#if (EECONFIG_KB_DATA_SIZE) == 0
uint32_t eeconfig_read_kb(void);
@ -168,7 +153,7 @@ void eeconfig_init_user_datablock(void);
// 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); \
@ -177,13 +162,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; \
} \
@ -205,10 +190,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) {}

View File

@ -86,9 +86,9 @@ static last_hit_t last_hit_buffer;
const uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT;
#endif
EECONFIG_DEBOUNCE_HELPER(led_matrix, EECONFIG_LED_MATRIX, led_matrix_eeconfig);
EECONFIG_DEBOUNCE_HELPER(led_matrix, led_matrix_eeconfig);
void eeconfig_update_led_matrix(void) {
void eeconfig_force_flush_led_matrix(void) {
eeconfig_flush_led_matrix(true);
}

View File

@ -115,7 +115,7 @@ enum led_matrix_effects {
};
void eeconfig_update_led_matrix_default(void);
void eeconfig_update_led_matrix(void);
void eeconfig_force_flush_led_matrix(void);
void eeconfig_debug_led_matrix(void);
uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i);

View File

@ -0,0 +1,223 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#include <string.h>
#include "nvm_eeconfig.h"
#include "nvm_eeconfig_eeprom.h"
#include "eeprom.h"
#include "eeconfig.h"
#if defined(EEPROM_DRIVER)
# include "eeprom_driver.h"
#endif
#if defined(VIA_ENABLE)
bool via_eeprom_is_valid(void);
void via_eeprom_set_valid(bool valid);
void eeconfig_init_via(void);
#endif
bool nvm_eeconfig_is_enabled(void) {
bool is_eeprom_enabled = (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER);
#ifdef VIA_ENABLE
if (is_eeprom_enabled) {
is_eeprom_enabled = via_eeprom_is_valid();
}
#endif // VIA_ENABLE
return is_eeprom_enabled;
}
bool nvm_eeconfig_is_disabled(void) {
bool is_eeprom_disabled = (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF);
#ifdef VIA_ENABLE
if (!is_eeprom_disabled) {
is_eeprom_disabled = !via_eeprom_is_valid();
}
#endif // VIA_ENABLE
return is_eeprom_disabled;
}
void nvm_eeconfig_enable(void) {
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
}
void nvm_eeconfig_disable(void) {
#if defined(EEPROM_DRIVER)
eeprom_driver_format(false);
#endif
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF);
}
uint8_t nvm_eeconfig_read_debug(void) {
return eeprom_read_byte(EECONFIG_DEBUG);
}
void nvm_eeconfig_update_debug(uint8_t val) {
eeprom_update_byte(EECONFIG_DEBUG, val);
}
uint8_t nvm_eeconfig_read_default_layer(void) {
return eeprom_read_byte(EECONFIG_DEFAULT_LAYER);
}
void nvm_eeconfig_update_default_layer(uint8_t val) {
eeprom_update_byte(EECONFIG_DEFAULT_LAYER, val);
}
uint16_t nvm_eeconfig_read_keymap(void) {
return eeprom_read_word(EECONFIG_KEYMAP);
}
void nvm_eeconfig_update_keymap(uint16_t val) {
eeprom_update_word(EECONFIG_KEYMAP, val);
}
#ifdef AUDIO_ENABLE
uint8_t nvm_eeconfig_read_audio(void) {
return eeprom_read_byte(EECONFIG_AUDIO);
}
void nvm_eeconfig_update_audio(uint8_t val) {
eeprom_update_byte(EECONFIG_AUDIO, val);
}
#endif // AUDIO_ENABLE
#ifdef UNICODE_COMMON_ENABLE
uint8_t nvm_eeconfig_read_unicode_mode(void) {
return eeprom_read_byte(EECONFIG_UNICODEMODE);
}
void nvm_eeconfig_update_unicode_mode(uint8_t val) {
eeprom_update_byte(EECONFIG_UNICODEMODE, val);
}
#endif // UNICODE_COMMON_ENABLE
#ifdef BACKLIGHT_ENABLE
uint8_t nvm_eeconfig_read_backlight(void) {
return eeprom_read_byte(EECONFIG_BACKLIGHT);
}
void nvm_eeconfig_update_backlight(uint8_t val) {
eeprom_update_byte(EECONFIG_BACKLIGHT, val);
}
#endif // BACKLIGHT_ENABLE
#ifdef STENO_ENABLE
uint8_t nvm_eeconfig_read_steno_mode(void) {
return eeprom_read_byte(EECONFIG_STENOMODE);
}
void nvm_eeconfig_update_steno_mode(uint8_t val) {
eeprom_update_byte(EECONFIG_STENOMODE, val);
}
#endif // STENO_ENABLE
#ifdef RGBLIGHT_ENABLE
#endif // RGBLIGHT_ENABLE
#ifdef RGB_MATRIX_ENABLE
void nvm_eeconfig_read_rgb_matrix(rgb_config_t *rgb_matrix_config) {
eeprom_read_block(rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_config_t));
}
void nvm_eeconfig_update_rgb_matrix(const rgb_config_t *rgb_matrix_config) {
eeprom_update_block(rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_config_t));
}
#endif // RGB_MATRIX_ENABLE
#ifdef LED_MATRIX_ENABLE
void nvm_eeconfig_read_led_matrix(led_eeconfig_t *led_matrix_config) {
eeprom_read_block(led_matrix_config, EECONFIG_LED_MATRIX, sizeof(led_eeconfig_t));
}
void nvm_eeconfig_update_led_matrix(const led_eeconfig_t *led_matrix_config) {
eeprom_update_block(led_matrix_config, EECONFIG_LED_MATRIX, sizeof(led_eeconfig_t));
}
#endif // LED_MATRIX_ENABLE
#ifdef RGBLIGHT_ENABLE
void nvm_eeconfig_read_rgblight(rgblight_config_t *rgblight_config) {
rgblight_config->raw = eeprom_read_dword(EECONFIG_RGBLIGHT);
rgblight_config->raw |= ((uint64_t)eeprom_read_byte(EECONFIG_RGBLIGHT_EXTENDED) << 32);
}
void nvm_eeconfig_update_rgblight(const rgblight_config_t *rgblight_config) {
eeprom_update_dword(EECONFIG_RGBLIGHT, rgblight_config->raw & 0xFFFFFFFF);
eeprom_update_byte(EECONFIG_RGBLIGHT_EXTENDED, (rgblight_config->raw >> 32) & 0xFF);
}
#endif // RGBLIGHT_ENABLE
#if (EECONFIG_KB_DATA_SIZE) == 0
uint32_t nvm_eeconfig_read_kb(void) {
return eeprom_read_dword(EECONFIG_KEYBOARD);
}
void nvm_eeconfig_update_kb(uint32_t val) {
eeprom_update_dword(EECONFIG_KEYBOARD, val);
}
#endif // (EECONFIG_KB_DATA_SIZE) == 0
#if (EECONFIG_USER_DATA_SIZE) == 0
uint32_t nvm_eeconfig_read_user(void) {
return eeprom_read_dword(EECONFIG_USER);
}
void nvm_eeconfig_update_user(uint32_t val) {
eeprom_update_dword(EECONFIG_USER, val);
}
#endif // (EECONFIG_USER_DATA_SIZE) == 0
#ifdef HAPTIC_ENABLE
uint32_t nvm_eeconfig_read_haptic(void) {
return eeprom_read_dword(EECONFIG_HAPTIC);
}
void nvm_eeconfig_update_haptic(uint32_t val) {
eeprom_update_dword(EECONFIG_HAPTIC, val);
}
#endif // HAPTIC_ENABLE
bool nvm_eeconfig_read_handedness(void) {
return !!eeprom_read_byte(EECONFIG_HANDEDNESS);
}
void nvm_eeconfig_update_handedness(bool val) {
eeprom_update_byte(EECONFIG_HANDEDNESS, !!val);
}
#if (EECONFIG_KB_DATA_SIZE) > 0
bool nvm_eeconfig_is_kb_datablock_valid(void) {
return eeprom_read_dword(EECONFIG_KEYBOARD) == (EECONFIG_KB_DATA_VERSION);
}
void nvm_eeconfig_read_kb_datablock(void *data) {
if (eeconfig_is_kb_datablock_valid()) {
eeprom_read_block(data, EECONFIG_KB_DATABLOCK, (EECONFIG_KB_DATA_SIZE));
} else {
memset(data, 0, (EECONFIG_KB_DATA_SIZE));
}
}
void nvm_eeconfig_update_kb_datablock(const void *data) {
eeprom_update_dword(EECONFIG_KEYBOARD, (EECONFIG_KB_DATA_VERSION));
eeprom_update_block(data, EECONFIG_KB_DATABLOCK, (EECONFIG_KB_DATA_SIZE));
}
void nvm_eeconfig_init_kb_datablock(void) {
uint8_t dummy_kb[(EECONFIG_KB_DATA_SIZE)] = {0};
eeconfig_update_kb_datablock(dummy_kb);
}
#endif // (EECONFIG_KB_DATA_SIZE) > 0
#if (EECONFIG_USER_DATA_SIZE) > 0
bool nvm_eeconfig_is_user_datablock_valid(void) {
return eeprom_read_dword(EECONFIG_USER) == (EECONFIG_USER_DATA_VERSION);
}
void nvm_eeconfig_read_user_datablock(void *data) {
if (eeconfig_is_user_datablock_valid()) {
eeprom_read_block(data, EECONFIG_USER_DATABLOCK, (EECONFIG_USER_DATA_SIZE));
} else {
memset(data, 0, (EECONFIG_USER_DATA_SIZE));
}
}
void nvm_eeconfig_update_user_datablock(const void *data) {
eeprom_update_dword(EECONFIG_USER, (EECONFIG_USER_DATA_VERSION));
eeprom_update_block(data, EECONFIG_USER_DATABLOCK, (EECONFIG_USER_DATA_SIZE));
}
void nvm_eeconfig_init_user_datablock(void) {
uint8_t dummy_user[(EECONFIG_USER_DATA_SIZE)] = {0};
eeconfig_update_user_datablock(dummy_user);
}
#endif // (EECONFIG_USER_DATA_SIZE) > 0

View File

@ -0,0 +1,63 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <stdint.h>
#include <stddef.h> // offsetof
#include "eeconfig.h"
#ifndef EECONFIG_MAGIC_NUMBER
# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEE4 // 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))
#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))
_Static_assert((intptr_t)EECONFIG_HANDEDNESS == 14, "EEPROM handedness offset is incorrect");

View File

@ -0,0 +1,105 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#include "eeprom.h"
#include "via.h"
#include "nvm_via.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Keyboard level code can change where VIA stores the magic.
// The magic is the build date YYMMDD encoded as BCD in 3 bytes,
// thus installing firmware built on a different date to the one
// already installed can be detected and the EEPROM data is reset.
// The only reason this is important is in case EEPROM usage changes
// and the EEPROM was not explicitly reset by bootmagic lite.
#ifndef VIA_EEPROM_MAGIC_ADDR
# define VIA_EEPROM_MAGIC_ADDR (EECONFIG_SIZE)
#endif
#define VIA_EEPROM_LAYOUT_OPTIONS_ADDR (VIA_EEPROM_MAGIC_ADDR + 3)
// The end of the EEPROM memory used by VIA
// By default, dynamic keymaps will start at this if there is no
// custom config
#define VIA_EEPROM_CUSTOM_CONFIG_ADDR (VIA_EEPROM_LAYOUT_OPTIONS_ADDR + VIA_EEPROM_LAYOUT_OPTIONS_SIZE)
#define VIA_EEPROM_CONFIG_END (VIA_EEPROM_CUSTOM_CONFIG_ADDR + VIA_EEPROM_CUSTOM_CONFIG_SIZE)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void nvm_via_read_magic(uint8_t *magic0, uint8_t *magic1, uint8_t *magic2) {
if (magic0) {
*magic0 = eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 0);
}
if (magic1) {
*magic1 = eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 1);
}
if (magic2) {
*magic2 = eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 2);
}
}
void nvm_via_update_magic(uint8_t magic0, uint8_t magic1, uint8_t magic2) {
eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 0, magic0);
eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 1, magic1);
eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 2, magic2);
}
uint32_t nvm_via_read_layout_options(void) {
uint32_t value = 0;
// Start at the most significant byte
void *source = (void *)(VIA_EEPROM_LAYOUT_OPTIONS_ADDR);
for (uint8_t i = 0; i < VIA_EEPROM_LAYOUT_OPTIONS_SIZE; i++) {
value = value << 8;
value |= eeprom_read_byte(source);
source++;
}
return value;
}
void nvm_via_update_layout_options(uint32_t val) {
// Start at the least significant byte
void *target = (void *)(VIA_EEPROM_LAYOUT_OPTIONS_ADDR + VIA_EEPROM_LAYOUT_OPTIONS_SIZE - 1);
for (uint8_t i = 0; i < VIA_EEPROM_LAYOUT_OPTIONS_SIZE; i++) {
eeprom_update_byte(target, val & 0xFF);
val = val >> 8;
target--;
}
}
uint32_t nvm_via_read_custom_config(void *buf, uint32_t offset, uint32_t length) {
#if VIA_EEPROM_CUSTOM_CONFIG_SIZE > 0
void * ee_start = (void *)(uintptr_t)(VIA_EEPROM_CUSTOM_CONFIG_ADDR + offset);
void * ee_end = (void *)(uintptr_t)(VIA_EEPROM_CUSTOM_CONFIG_ADDR + MIN(VIA_EEPROM_CUSTOM_CONFIG_SIZE, offset + length));
uint32_t counter = 0;
uint8_t *source = (uint8_t *)ee_start;
uint8_t *dest = (uint8_t *)buf;
while (source != ee_end) {
*dest++ = eeprom_read_byte(source++);
counter++;
}
return counter;
#else
return 0;
#endif
}
uint32_t nvm_via_update_custom_config(const void *buf, uint32_t offset, uint32_t length) {
#if VIA_EEPROM_CUSTOM_CONFIG_SIZE > 0
void * ee_start = (void *)(uintptr_t)(VIA_EEPROM_CUSTOM_CONFIG_ADDR + offset);
void * ee_end = (void *)(uintptr_t)(VIA_EEPROM_CUSTOM_CONFIG_ADDR + MIN(VIA_EEPROM_CUSTOM_CONFIG_SIZE, offset + length));
uint32_t counter = 0;
uint8_t *dest = (uint8_t *)ee_start;
uint8_t *source = (uint8_t *)buf;
while (dest != ee_end) {
eeprom_update_byte(dest++, *source++);
counter++;
}
return counter;
#else
return 0;
#endif
}

100
quantum/nvm/nvm_eeconfig.h Normal file
View File

@ -0,0 +1,100 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <stdint.h>
#include <stdbool.h>
#ifdef RGB_MATRIX_ENABLE
# include "rgb_matrix_types.h"
#endif
#ifdef LED_MATRIX_ENABLE
# include "led_matrix_types.h"
#endif
#ifdef RGBLIGHT_ENABLE
# include "rgblight.h"
#endif
bool nvm_eeconfig_is_enabled(void);
bool nvm_eeconfig_is_disabled(void);
void nvm_eeconfig_enable(void);
void nvm_eeconfig_disable(void);
uint8_t nvm_eeconfig_read_debug(void);
void nvm_eeconfig_update_debug(uint8_t val);
uint8_t nvm_eeconfig_read_default_layer(void);
void nvm_eeconfig_update_default_layer(uint8_t val);
uint16_t nvm_eeconfig_read_keymap(void);
void nvm_eeconfig_update_keymap(uint16_t val);
#ifdef AUDIO_ENABLE
uint8_t nvm_eeconfig_read_audio(void);
void nvm_eeconfig_update_audio(uint8_t val);
#endif // AUDIO_ENABLE
#ifdef UNICODE_COMMON_ENABLE
uint8_t nvm_eeconfig_read_unicode_mode(void);
void nvm_eeconfig_update_unicode_mode(uint8_t val);
#endif // UNICODE_COMMON_ENABLE
#ifdef BACKLIGHT_ENABLE
uint8_t nvm_eeconfig_read_backlight(void);
void nvm_eeconfig_update_backlight(uint8_t val);
#endif // BACKLIGHT_ENABLE
#ifdef STENO_ENABLE
uint8_t nvm_eeconfig_read_steno_mode(void);
void nvm_eeconfig_update_steno_mode(uint8_t val);
#endif // STENO_ENABLE
#ifdef RGB_MATRIX_ENABLE
void nvm_eeconfig_read_rgb_matrix(rgb_config_t *rgb_matrix_config);
void nvm_eeconfig_update_rgb_matrix(const rgb_config_t *rgb_matrix_config);
#endif
#ifdef LED_MATRIX_ENABLE
void nvm_eeconfig_read_led_matrix(led_eeconfig_t *led_matrix_config);
void nvm_eeconfig_update_led_matrix(const led_eeconfig_t *led_matrix_config);
#endif // LED_MATRIX_ENABLE
#ifdef RGBLIGHT_ENABLE
void nvm_eeconfig_read_rgblight(rgblight_config_t *rgblight_config);
void nvm_eeconfig_update_rgblight(const rgblight_config_t *rgblight_config);
#endif // RGBLIGHT_ENABLE
#if (EECONFIG_KB_DATA_SIZE) == 0
uint32_t nvm_eeconfig_read_kb(void);
void nvm_eeconfig_update_kb(uint32_t val);
#endif // (EECONFIG_KB_DATA_SIZE) == 0
#if (EECONFIG_USER_DATA_SIZE) == 0
uint32_t nvm_eeconfig_read_user(void);
void nvm_eeconfig_update_user(uint32_t val);
#endif // (EECONFIG_USER_DATA_SIZE) == 0
#ifdef HAPTIC_ENABLE
uint32_t nvm_eeconfig_read_haptic(void);
void nvm_eeconfig_update_haptic(uint32_t val);
#endif // HAPTIC_ENABLE
bool nvm_eeconfig_read_handedness(void);
void nvm_eeconfig_update_handedness(bool val);
#if (EECONFIG_KB_DATA_SIZE) > 0
bool nvm_eeconfig_is_kb_datablock_valid(void);
void nvm_eeconfig_read_kb_datablock(void *data);
void nvm_eeconfig_update_kb_datablock(const void *data);
void nvm_eeconfig_init_kb_datablock(void);
#endif // (EECONFIG_KB_DATA_SIZE) > 0
#if (EECONFIG_USER_DATA_SIZE) > 0
bool nvm_eeconfig_is_user_datablock_valid(void);
void nvm_eeconfig_read_user_datablock(void *data);
void nvm_eeconfig_update_user_datablock(const void *data);
void nvm_eeconfig_init_user_datablock(void);
#endif // (EECONFIG_USER_DATA_SIZE) > 0

15
quantum/nvm/nvm_via.h Normal file
View File

@ -0,0 +1,15 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <stdint.h>
#include <stdbool.h>
void nvm_via_read_magic(uint8_t *magic0, uint8_t *magic1, uint8_t *magic2);
void nvm_via_update_magic(uint8_t magic0, uint8_t magic1, uint8_t magic2);
uint32_t nvm_via_read_layout_options(void);
void nvm_via_update_layout_options(uint32_t val);
uint32_t nvm_via_read_custom_config(void *buf, uint32_t offset, uint32_t length);
uint32_t nvm_via_update_custom_config(const void *buf, uint32_t offset, uint32_t length);

32
quantum/nvm/rules.mk Normal file
View File

@ -0,0 +1,32 @@
# Copyright 2024 Nick Brassel (@tzarc)
# SPDX-License-Identifier: GPL-2.0-or-later
VPATH += $(QUANTUM_DIR)/nvm
VALID_NVM_DRIVERS := eeprom custom none
NVM_DRIVER ?= eeprom
ifeq ($(filter $(NVM_DRIVER),$(VALID_NVM_DRIVERS)),)
$(call CATASTROPHIC_ERROR,Invalid NVM_DRIVER,NVM_DRIVER="$(NVM_DRIVER)" is not a valid NVM driver)
else
# If we don't want one, fake it with transient eeprom.
ifeq ($(NVM_DRIVER),none)
NVM_DRIVER := eeprom
EEPROM_DRIVER := transient
endif
NVM_DRIVER_UPPER := $(shell echo $(NVM_DRIVER) | tr '[:lower:]' '[:upper:]')
NVM_DRIVER_LOWER := $(shell echo $(NVM_DRIVER) | tr '[:upper:]' '[:lower:]')
OPT_DEFS += -DNVM_DRIVER_$(NVM_DRIVER_UPPER) -DNVM_DRIVER="$(NVM_DRIVER)"
ifneq ("$(wildcard $(QUANTUM_DIR)/nvm/$(NVM_DRIVER_LOWER))","")
VPATH += $(QUANTUM_DIR)/nvm/$(NVM_DRIVER_LOWER)
endif
QUANTUM_SRC += \
nvm_eeconfig.c
endif

View File

@ -20,9 +20,6 @@
#ifdef VIRTSER_ENABLE
# include "virtser.h"
#endif
#ifdef STENO_ENABLE_ALL
# include "eeprom.h"
#endif
// All steno keys that have been pressed to form this chord,
// stored in MAX_STROKE_SIZE groups of 8-bit arrays.
@ -128,13 +125,13 @@ static const uint16_t combinedmap_second[] PROGMEM = {STN_S2, STN_KL, STN_WL, ST
#ifdef STENO_ENABLE_ALL
void steno_init(void) {
mode = eeprom_read_byte(EECONFIG_STENOMODE);
mode = eeconfig_read_steno_mode();
}
void steno_set_mode(steno_mode_t new_mode) {
steno_clear_chord();
mode = new_mode;
eeprom_update_byte(EECONFIG_STENOMODE, mode);
eeconfig_update_steno_mode(mode);
}
#endif // STENO_ENABLE_ALL

View File

@ -83,9 +83,9 @@ static uint32_t rgb_timer_buffer;
static last_hit_t last_hit_buffer;
#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
EECONFIG_DEBOUNCE_HELPER(rgb_matrix, EECONFIG_RGB_MATRIX, rgb_matrix_config);
EECONFIG_DEBOUNCE_HELPER(rgb_matrix, rgb_matrix_config);
void eeconfig_update_rgb_matrix(void) {
void eeconfig_force_flush_rgb_matrix(void) {
eeconfig_flush_rgb_matrix(true);
}

View File

@ -140,7 +140,7 @@ enum rgb_matrix_effects {
};
void eeconfig_update_rgb_matrix_default(void);
void eeconfig_update_rgb_matrix(void);
void eeconfig_force_flush_rgb_matrix(void);
uint8_t rgb_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i);
uint8_t rgb_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i);
@ -212,7 +212,7 @@ void rgb_matrix_set_flags(led_flags_t flags);
void rgb_matrix_set_flags_noeeprom(led_flags_t flags);
#ifndef RGBLIGHT_ENABLE
# define eeconfig_update_rgblight_current eeconfig_update_rgb_matrix
# define eeconfig_update_rgblight_current eeconfig_force_flush_rgb_matrix
# define rgblight_reload_from_eeprom rgb_matrix_reload_from_eeprom
# define rgblight_toggle rgb_matrix_toggle
# define rgblight_toggle_noeeprom rgb_matrix_toggle_noeeprom

View File

@ -24,9 +24,7 @@
#include "util.h"
#include "led_tables.h"
#include <lib/lib8tion/lib8tion.h>
#ifdef EEPROM_ENABLE
# include "eeprom.h"
#endif
#include "eeconfig.h"
#ifdef RGBLIGHT_SPLIT
/* for split keyboard */
@ -178,24 +176,9 @@ void rgblight_check_config(void) {
}
}
uint64_t eeconfig_read_rgblight(void) {
#ifdef EEPROM_ENABLE
return (uint64_t)((eeprom_read_dword(EECONFIG_RGBLIGHT)) | ((uint64_t)eeprom_read_byte(EECONFIG_RGBLIGHT_EXTENDED) << 32));
#else
return 0;
#endif
}
void eeconfig_update_rgblight(uint64_t val) {
#ifdef EEPROM_ENABLE
rgblight_check_config();
eeprom_update_dword(EECONFIG_RGBLIGHT, val & 0xFFFFFFFF);
eeprom_update_byte(EECONFIG_RGBLIGHT_EXTENDED, (val >> 32) & 0xFF);
#endif
}
void eeconfig_update_rgblight_current(void) {
eeconfig_update_rgblight(rgblight_config.raw);
rgblight_check_config();
eeconfig_update_rgblight(&rgblight_config);
}
void eeconfig_update_rgblight_default(void) {
@ -207,7 +190,7 @@ void eeconfig_update_rgblight_default(void) {
rgblight_config.val = RGBLIGHT_DEFAULT_VAL;
rgblight_config.speed = RGBLIGHT_DEFAULT_SPD;
RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS;
eeconfig_update_rgblight(rgblight_config.raw);
eeconfig_update_rgblight(&rgblight_config);
}
void eeconfig_debug_rgblight(void) {
@ -230,12 +213,12 @@ void rgblight_init(void) {
}
dprintf("rgblight_init start!\n");
rgblight_config.raw = eeconfig_read_rgblight();
eeconfig_read_rgblight(&rgblight_config);
RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS;
if (!rgblight_config.mode) {
dprintf("rgblight_init rgblight_config.mode = 0. Write default values to EEPROM.\n");
eeconfig_update_rgblight_default();
rgblight_config.raw = eeconfig_read_rgblight();
eeconfig_read_rgblight(&rgblight_config);
}
rgblight_check_config();
@ -254,7 +237,7 @@ void rgblight_init(void) {
void rgblight_reload_from_eeprom(void) {
/* Reset back to what we have in eeprom */
rgblight_config.raw = eeconfig_read_rgblight();
eeconfig_read_rgblight(&rgblight_config);
RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS;
rgblight_check_config();
eeconfig_debug_rgblight(); // display current eeprom values
@ -343,7 +326,7 @@ void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
}
RGBLIGHT_SPLIT_SET_CHANGE_MODE;
if (write_to_eeprom) {
eeconfig_update_rgblight(rgblight_config.raw);
eeconfig_update_rgblight(&rgblight_config);
dprintf("rgblight mode [EEPROM]: %u\n", rgblight_config.mode);
} else {
dprintf("rgblight mode [NOEEPROM]: %u\n", rgblight_config.mode);
@ -388,7 +371,7 @@ void rgblight_toggle_noeeprom(void) {
void rgblight_enable(void) {
rgblight_config.enable = 1;
// No need to update EEPROM here. rgblight_mode() will do that, actually
// eeconfig_update_rgblight(rgblight_config.raw);
// eeconfig_update_rgblight(&rgblight_config);
dprintf("rgblight enable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
rgblight_mode(rgblight_config.mode);
}
@ -401,7 +384,7 @@ void rgblight_enable_noeeprom(void) {
void rgblight_disable(void) {
rgblight_config.enable = 0;
eeconfig_update_rgblight(rgblight_config.raw);
eeconfig_update_rgblight(&rgblight_config);
dprintf("rgblight disable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
rgblight_timer_disable();
RGBLIGHT_SPLIT_SET_CHANGE_MODE;
@ -489,7 +472,7 @@ void rgblight_increase_speed_helper(bool write_to_eeprom) {
if (rgblight_config.speed < 3) rgblight_config.speed++;
// RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED?
if (write_to_eeprom) {
eeconfig_update_rgblight(rgblight_config.raw);
eeconfig_update_rgblight(&rgblight_config);
}
}
void rgblight_increase_speed(void) {
@ -503,7 +486,7 @@ void rgblight_decrease_speed_helper(bool write_to_eeprom) {
if (rgblight_config.speed > 0) rgblight_config.speed--;
// RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED??
if (write_to_eeprom) {
eeconfig_update_rgblight(rgblight_config.raw);
eeconfig_update_rgblight(&rgblight_config);
}
}
void rgblight_decrease_speed(void) {
@ -589,7 +572,7 @@ void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool w
rgblight_config.sat = sat;
rgblight_config.val = val;
if (write_to_eeprom) {
eeconfig_update_rgblight(rgblight_config.raw);
eeconfig_update_rgblight(&rgblight_config);
dprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
} else {
dprintf("rgblight set hsv [NOEEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
@ -612,7 +595,7 @@ uint8_t rgblight_get_speed(void) {
void rgblight_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) {
rgblight_config.speed = speed;
if (write_to_eeprom) {
eeconfig_update_rgblight(rgblight_config.raw);
eeconfig_update_rgblight(&rgblight_config);
dprintf("rgblight set speed [EEPROM]: %u\n", rgblight_config.speed);
} else {
dprintf("rgblight set speed [NOEEPROM]: %u\n", rgblight_config.speed);

View File

@ -168,7 +168,6 @@ enum RGBLIGHT_EFFECT_MODE {
#include <stdbool.h>
#include "rgblight_drivers.h"
#include "progmem.h"
#include "eeconfig.h"
#include "ws2812.h"
#include "color.h"
@ -371,8 +370,6 @@ void rgblight_suspend(void);
void rgblight_wakeup(void);
uint64_t rgblight_read_qword(void);
void rgblight_update_qword(uint64_t qword);
uint64_t eeconfig_read_rgblight(void);
void eeconfig_update_rgblight(uint64_t val);
void eeconfig_update_rgblight_current(void);
void eeconfig_update_rgblight_default(void);
void eeconfig_debug_rgblight(void);

View File

@ -136,7 +136,7 @@ static void unicode_play_song(uint8_t mode) {
#endif
void unicode_input_mode_init(void) {
unicode_config.raw = eeprom_read_byte(EECONFIG_UNICODEMODE);
unicode_config.raw = eeconfig_read_unicode_mode();
#if UNICODE_SELECTED_MODES != -1
# if UNICODE_CYCLE_PERSIST
// Find input_mode in selected modes
@ -165,7 +165,7 @@ uint8_t get_unicode_input_mode(void) {
}
static void persist_unicode_input_mode(void) {
eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config.input_mode);
eeconfig_update_unicode_mode(unicode_config.input_mode);
}
void set_unicode_input_mode(uint8_t mode) {

View File

@ -32,6 +32,7 @@
#include "timer.h"
#include "wait.h"
#include "version.h" // for QMK_BUILDDATE used in EEPROM magic
#include "nvm_via.h"
#if defined(AUDIO_ENABLE)
# include "audio.h"
@ -65,20 +66,26 @@ bool via_eeprom_is_valid(void) {
uint8_t magic1 = ((p[5] & 0x0F) << 4) | (p[6] & 0x0F);
uint8_t magic2 = ((p[8] & 0x0F) << 4) | (p[9] & 0x0F);
return (eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 0) == magic0 && eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 1) == magic1 && eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 2) == magic2);
uint8_t ee_magic0;
uint8_t ee_magic1;
uint8_t ee_magic2;
nvm_via_read_magic(&ee_magic0, &ee_magic1, &ee_magic2);
return ee_magic0 == magic0 && ee_magic1 == magic1 && ee_magic2 == magic2;
}
// Sets VIA/keyboard level usage of EEPROM to valid/invalid
// Keyboard level code (eg. via_init_kb()) should not call this
void via_eeprom_set_valid(bool valid) {
char * p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54"
uint8_t magic0 = ((p[2] & 0x0F) << 4) | (p[3] & 0x0F);
uint8_t magic1 = ((p[5] & 0x0F) << 4) | (p[6] & 0x0F);
uint8_t magic2 = ((p[8] & 0x0F) << 4) | (p[9] & 0x0F);
eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 0, valid ? magic0 : 0xFF);
eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 1, valid ? magic1 : 0xFF);
eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 2, valid ? magic2 : 0xFF);
if (valid) {
char * p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54"
uint8_t magic0 = ((p[2] & 0x0F) << 4) | (p[3] & 0x0F);
uint8_t magic1 = ((p[5] & 0x0F) << 4) | (p[6] & 0x0F);
uint8_t magic2 = ((p[8] & 0x0F) << 4) | (p[9] & 0x0F);
nvm_via_update_magic(magic0, magic1, magic2);
} else {
nvm_via_update_magic(0xFF, 0xFF, 0xFF);
}
}
// Override this at the keyboard code level to check
@ -119,30 +126,25 @@ void eeconfig_init_via(void) {
// This is generalized so the layout options EEPROM usage can be
// variable, between 1 and 4 bytes.
uint32_t via_get_layout_options(void) {
uint32_t value = 0;
// Start at the most significant byte
void *source = (void *)(VIA_EEPROM_LAYOUT_OPTIONS_ADDR);
for (uint8_t i = 0; i < VIA_EEPROM_LAYOUT_OPTIONS_SIZE; i++) {
value = value << 8;
value |= eeprom_read_byte(source);
source++;
}
return value;
return nvm_via_read_layout_options();
}
__attribute__((weak)) void via_set_layout_options_kb(uint32_t value) {}
void via_set_layout_options(uint32_t value) {
via_set_layout_options_kb(value);
// Start at the least significant byte
void *target = (void *)(VIA_EEPROM_LAYOUT_OPTIONS_ADDR + VIA_EEPROM_LAYOUT_OPTIONS_SIZE - 1);
for (uint8_t i = 0; i < VIA_EEPROM_LAYOUT_OPTIONS_SIZE; i++) {
eeprom_update_byte(target, value & 0xFF);
value = value >> 8;
target--;
}
nvm_via_update_layout_options(value);
}
#if VIA_EEPROM_CUSTOM_CONFIG_SIZE > 0
uint32_t via_read_custom_config(void *buf, uint32_t offset, uint32_t length) {
return nvm_via_read_custom_config(buf, offset, length);
}
uint32_t via_update_custom_config(const void *buf, uint32_t offset, uint32_t length) {
return nvm_via_update_custom_config(buf, offset, length);
}
#endif
#if defined(AUDIO_ENABLE)
float via_device_indication_song[][2] = SONG(STARTUP_SOUND);
#endif // AUDIO_ENABLE
@ -715,7 +717,7 @@ void via_qmk_rgb_matrix_set_value(uint8_t *data) {
}
void via_qmk_rgb_matrix_save(void) {
eeconfig_update_rgb_matrix();
eeconfig_force_flush_rgb_matrix();
}
#endif // RGB_MATRIX_ENABLE
@ -794,7 +796,7 @@ void via_qmk_led_matrix_set_value(uint8_t *data) {
}
void via_qmk_led_matrix_save(void) {
eeconfig_update_led_matrix();
eeconfig_force_flush_led_matrix();
}
#endif // LED_MATRIX_ENABLE

View File

@ -16,21 +16,9 @@
#pragma once
#include "eeconfig.h" // for EECONFIG_SIZE
#include "nvm_eeconfig_eeprom.h" // for EECONFIG_SIZE
#include "action.h"
// Keyboard level code can change where VIA stores the magic.
// The magic is the build date YYMMDD encoded as BCD in 3 bytes,
// thus installing firmware built on a different date to the one
// already installed can be detected and the EEPROM data is reset.
// The only reason this is important is in case EEPROM usage changes
// and the EEPROM was not explicitly reset by bootmagic lite.
#ifndef VIA_EEPROM_MAGIC_ADDR
# define VIA_EEPROM_MAGIC_ADDR (EECONFIG_SIZE)
#endif
#define VIA_EEPROM_LAYOUT_OPTIONS_ADDR (VIA_EEPROM_MAGIC_ADDR + 3)
// Changing the layout options size after release will invalidate EEPROM,
// but this is something that should be set correctly on initial implementation.
// 1 byte is enough for most uses (i.e. 8 binary states, or 6 binary + 1 ternary/quaternary )
@ -46,17 +34,10 @@
# define VIA_EEPROM_LAYOUT_OPTIONS_DEFAULT 0x00000000
#endif
// The end of the EEPROM memory used by VIA
// By default, dynamic keymaps will start at this if there is no
// custom config
#define VIA_EEPROM_CUSTOM_CONFIG_ADDR (VIA_EEPROM_LAYOUT_OPTIONS_ADDR + VIA_EEPROM_LAYOUT_OPTIONS_SIZE)
#ifndef VIA_EEPROM_CUSTOM_CONFIG_SIZE
# define VIA_EEPROM_CUSTOM_CONFIG_SIZE 0
#endif
#define VIA_EEPROM_CONFIG_END (VIA_EEPROM_CUSTOM_CONFIG_ADDR + VIA_EEPROM_CUSTOM_CONFIG_SIZE)
// This is changed only when the command IDs change,
// so VIA Configurator can detect compatible firmware.
#define VIA_PROTOCOL_VERSION 0x000C
@ -160,6 +141,11 @@ uint32_t via_get_layout_options(void);
void via_set_layout_options(uint32_t value);
void via_set_layout_options_kb(uint32_t value);
#if VIA_EEPROM_CUSTOM_CONFIG_SIZE > 0
uint32_t via_read_custom_config(void *buf, uint32_t offset, uint32_t length);
uint32_t via_update_custom_config(const void *buf, uint32_t offset, uint32_t length);
#endif
// Used by VIA to tell a device to flash LEDs (or do something else) when that
// device becomes the active device being configured, on startup or switching
// between devices.
@ -202,4 +188,4 @@ void via_qmk_audio_command(uint8_t *data, uint8_t length);
void via_qmk_audio_set_value(uint8_t *data);
void via_qmk_audio_get_value(uint8_t *data);
void via_qmk_audio_save(void);
#endif
#endif