This commit is contained in:
Nick Brassel 2024-11-21 17:32:05 +11:00 committed by GitHub
commit 3cc250fe28
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
82 changed files with 1400 additions and 816 deletions

View File

@ -29,6 +29,8 @@ QUANTUM_SRC += \
$(QUANTUM_DIR)/logging/debug.c \ $(QUANTUM_DIR)/logging/debug.c \
$(QUANTUM_DIR)/logging/sendchar.c \ $(QUANTUM_DIR)/logging/sendchar.c \
include $(QUANTUM_DIR)/nvm/rules.mk
VPATH += $(QUANTUM_DIR)/logging VPATH += $(QUANTUM_DIR)/logging
# Fall back to lib/printf if there is no platform provided print # Fall back to lib/printf if there is no platform provided print
ifeq ("$(wildcard $(PLATFORM_PATH)/$(PLATFORM_KEY)/printf.mk)","") ifeq ("$(wildcard $(PLATFORM_PATH)/$(PLATFORM_KEY)/printf.mk)","")

View File

@ -60,6 +60,7 @@ define HANDLE_GENERIC_FEATURE
SRC += $$(wildcard $$(QUANTUM_DIR)/process_keycode/process_$2.c) SRC += $$(wildcard $$(QUANTUM_DIR)/process_keycode/process_$2.c)
SRC += $$(wildcard $$(QUANTUM_DIR)/$2/$2.c) SRC += $$(wildcard $$(QUANTUM_DIR)/$2/$2.c)
SRC += $$(wildcard $$(QUANTUM_DIR)/$2.c) SRC += $$(wildcard $$(QUANTUM_DIR)/$2.c)
SRC += $$(wildcard $$(QUANTUM_DIR)/nvm/$$(NVM_DRIVER_LOWER)/nvm_$2.c)
VPATH += $$(wildcard $$(QUANTUM_DIR)/$2/) VPATH += $$(wildcard $$(QUANTUM_DIR)/$2/)
OPT_DEFS += -D$1_ENABLE OPT_DEFS += -D$1_ENABLE
endef endef

View File

@ -20,6 +20,6 @@
The size of the transient EEPROM buffer size. The size of the transient EEPROM buffer size.
*/ */
#ifndef TRANSIENT_EEPROM_SIZE #ifndef TRANSIENT_EEPROM_SIZE
# include "eeconfig.h" # include "nvm_eeprom_eeconfig_internal.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 # 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 #endif

View File

@ -164,7 +164,7 @@ bool process_record_kb(uint16_t keycode, keyrecord_t* record) {
if (record->event.pressed) { if (record->event.pressed) {
set_single_persistent_default_layer(MAC_B); set_single_persistent_default_layer(MAC_B);
keymap_config.no_gui = 0; keymap_config.no_gui = 0;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
return false; return false;
case QK_RGB_MATRIX_TOGGLE: case QK_RGB_MATRIX_TOGGLE:

View File

@ -53,6 +53,22 @@ void board_init(void) {
SYSCFG->CFGR1 &= ~(SYSCFG_CFGR1_SPI2_DMA_RMP); SYSCFG->CFGR1 &= ~(SYSCFG_CFGR1_SPI2_DMA_RMP);
} }
uint32_t read_custom_config(void *data, uint32_t offset, uint32_t length) {
#ifdef VIA_ENABLE
return via_read_custom_config(data, offset, length);
#else
return eeconfig_read_kb_datablock(data, offset, length);
#endif
}
uint32_t write_custom_config(const void *data, uint32_t offset, uint32_t length) {
#ifdef VIA_ENABLE
return via_update_custom_config(data, offset, length);
#else
return eeconfig_update_kb_datablock(data, offset, length);
#endif
}
void keyboard_post_init_kb(void) { void keyboard_post_init_kb(void) {
/* /*
This is a workaround to some really weird behavior This is a workaround to some really weird behavior
@ -78,7 +94,7 @@ void custom_set_value(uint8_t *data) {
switch ( *value_id ) { switch ( *value_id ) {
case id_oled_default_mode: case id_oled_default_mode:
{ {
eeprom_update_byte((uint8_t*)EEPROM_DEFAULT_OLED, value_data[0]); write_custom_config(&value_data[0], EEPROM_DEFAULT_OLED_OFFSET, 1);
break; break;
} }
case id_oled_mode: case id_oled_mode:
@ -92,7 +108,7 @@ void custom_set_value(uint8_t *data) {
uint8_t index = value_data[0]; uint8_t index = value_data[0];
uint8_t enable = value_data[1]; uint8_t enable = value_data[1];
enabled_encoder_modes = (enabled_encoder_modes & ~(1<<index)) | (enable<<index); enabled_encoder_modes = (enabled_encoder_modes & ~(1<<index)) | (enable<<index);
eeprom_update_byte((uint8_t*)EEPROM_ENABLED_ENCODER_MODES, enabled_encoder_modes); write_custom_config(&enabled_encoder_modes, EEPROM_ENABLED_ENCODER_MODES_OFFSET, 1);
break; break;
} }
case id_encoder_custom: case id_encoder_custom:
@ -113,7 +129,8 @@ void custom_get_value(uint8_t *data) {
switch ( *value_id ) { switch ( *value_id ) {
case id_oled_default_mode: case id_oled_default_mode:
{ {
uint8_t default_oled = eeprom_read_byte((uint8_t*)EEPROM_DEFAULT_OLED); uint8_t default_oled;
read_custom_config(&default_oled, EEPROM_DEFAULT_OLED_OFFSET, 1);
value_data[0] = default_oled; value_data[0] = default_oled;
break; break;
} }
@ -179,7 +196,6 @@ void via_custom_value_command_kb(uint8_t *data, uint8_t length) {
} }
#endif #endif
void read_host_led_state(void) { void read_host_led_state(void) {
led_t led_state = host_keyboard_led_state(); led_t led_state = host_keyboard_led_state();
if (led_state.num_lock) { if (led_state.num_lock) {
@ -290,25 +306,25 @@ bool encoder_update_kb(uint8_t index, bool clockwise) {
} }
void custom_config_reset(void){ void custom_config_reset(void){
void *p = (void*)(VIA_EEPROM_CUSTOM_CONFIG_ADDR); for(int i = 0; i < VIA_EEPROM_CUSTOM_CONFIG_SIZE; ++i) {
void *end = (void*)(VIA_EEPROM_CUSTOM_CONFIG_ADDR+VIA_EEPROM_CUSTOM_CONFIG_SIZE); uint8_t dummy = 0;
while ( p != end ) { write_custom_config(&dummy, i, 1);
eeprom_update_byte(p, 0);
++p;
} }
eeprom_update_byte((uint8_t*)EEPROM_ENABLED_ENCODER_MODES, 0x1F);
uint8_t encoder_modes = 0x1F;
write_custom_config(&encoder_modes, EEPROM_ENABLED_ENCODER_MODES_OFFSET, 1);
} }
void custom_config_load(void){ void custom_config_load(void){
#ifdef DYNAMIC_KEYMAP_ENABLE #ifdef DYNAMIC_KEYMAP_ENABLE
oled_mode = eeprom_read_byte((uint8_t*)EEPROM_DEFAULT_OLED); read_custom_config(&oled_mode, EEPROM_DEFAULT_OLED_OFFSET, 1);
enabled_encoder_modes = eeprom_read_byte((uint8_t*)EEPROM_ENABLED_ENCODER_MODES); read_custom_config(&enabled_encoder_modes, EEPROM_ENABLED_ENCODER_MODES_OFFSET, 1);
#endif #endif
} }
// Called from via_init() if VIA_ENABLE // Called from via_init() if VIA_ENABLE
// Called from matrix_init_kb() if not VIA_ENABLE // Called from matrix_init_kb() if not VIA_ENABLE
void via_init_kb(void) void satisfaction_core_init(void)
{ {
// This checks both an EEPROM reset (from bootmagic lite, keycodes) // This checks both an EEPROM reset (from bootmagic lite, keycodes)
// and also firmware build date (from via_eeprom_is_valid()) // and also firmware build date (from via_eeprom_is_valid())
@ -326,8 +342,7 @@ void via_init_kb(void)
void matrix_init_kb(void) void matrix_init_kb(void)
{ {
#ifndef VIA_ENABLE #ifndef VIA_ENABLE
via_init_kb(); satisfaction_core_init();
via_eeprom_set_valid(true);
#endif // VIA_ENABLE #endif // VIA_ENABLE
rtcGetTime(&RTCD1, &last_timespec); rtcGetTime(&RTCD1, &last_timespec);
@ -335,6 +350,11 @@ void matrix_init_kb(void)
oled_request_wakeup(); oled_request_wakeup();
} }
#ifdef VIA_ENABLE
void via_init_kb(void) {
satisfaction_core_init();
}
#endif // VIA_ENABLE
void housekeeping_task_kb(void) { void housekeeping_task_kb(void) {
rtcGetTime(&RTCD1, &last_timespec); rtcGetTime(&RTCD1, &last_timespec);
@ -345,52 +365,3 @@ void housekeeping_task_kb(void) {
oled_request_repaint(); oled_request_repaint();
} }
} }
//
// In the case of VIA being disabled, we still need to check if
// keyboard level EEPROM memory is valid before loading.
// Thus these are copies of the same functions in VIA, since
// the backlight settings reuse VIA's EEPROM magic/version,
// and the ones in via.c won't be compiled in.
//
// Yes, this is sub-optimal, and is only here for completeness
// (i.e. catering to the 1% of people that want wilba.tech LED bling
// AND want persistent settings BUT DON'T want to use dynamic keymaps/VIA).
//
#ifndef VIA_ENABLE
bool via_eeprom_is_valid(void)
{
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 );
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 );
}
// 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);
}
void via_eeprom_reset(void)
{
// Set the VIA specific EEPROM state as invalid.
via_eeprom_set_valid(false);
// Set the TMK/QMK EEPROM state as invalid.
eeconfig_disable();
}
#endif // VIA_ENABLE

View File

@ -6,12 +6,14 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <hal.h>
#include "via.h" // only for EEPROM address #include "via.h" // only for EEPROM address
#include "satisfaction_keycodes.h" #include "satisfaction_keycodes.h"
#define EEPROM_ENABLED_ENCODER_MODES (VIA_EEPROM_CUSTOM_CONFIG_ADDR) #define EEPROM_ENABLED_ENCODER_MODES_OFFSET 0
#define EEPROM_DEFAULT_OLED (VIA_EEPROM_CUSTOM_CONFIG_ADDR+1) #define EEPROM_DEFAULT_OLED_OFFSET 1
#define EEPROM_CUSTOM_ENCODER (VIA_EEPROM_CUSTOM_CONFIG_ADDR+2) #define EEPROM_CUSTOM_ENCODER_OFFSET 2
enum s75_keyboard_value_id { enum s75_keyboard_value_id {
id_encoder_modes = 1, id_encoder_modes = 1,
@ -94,3 +96,6 @@ void oled_request_repaint(void);
bool oled_task_needs_to_repaint(void); bool oled_task_needs_to_repaint(void);
void custom_config_load(void); void custom_config_load(void);
uint32_t read_custom_config(void *data, uint32_t offset, uint32_t length);
uint32_t write_custom_config(const void *data, uint32_t offset, uint32_t length);

View File

@ -215,10 +215,13 @@ uint16_t handle_encoder_press(void){
uint16_t retrieve_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior){ uint16_t retrieve_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior){
#ifdef DYNAMIC_KEYMAP_ENABLE #ifdef DYNAMIC_KEYMAP_ENABLE
void* addr = (void*)(EEPROM_CUSTOM_ENCODER + (encoder_idx * 6) + (behavior * 2)); uint32_t offset = EEPROM_CUSTOM_ENCODER_OFFSET + (encoder_idx * 6) + (behavior * 2);
//big endian //big endian
uint16_t keycode = eeprom_read_byte(addr) << 8; uint8_t hi, lo;
keycode |= eeprom_read_byte(addr + 1); read_custom_config(&hi, offset+0, 1);
read_custom_config(&lo, offset+1, 1);
uint16_t keycode = hi << 8;
keycode |= lo;
return keycode; return keycode;
#else #else
return 0; return 0;
@ -227,8 +230,10 @@ uint16_t retrieve_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior){
void set_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior, uint16_t new_code){ void set_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior, uint16_t new_code){
#ifdef DYNAMIC_KEYMAP_ENABLE #ifdef DYNAMIC_KEYMAP_ENABLE
void* addr = (void*)(EEPROM_CUSTOM_ENCODER + (encoder_idx * 6) + (behavior * 2)); uint32_t offset = EEPROM_CUSTOM_ENCODER_OFFSET + (encoder_idx * 6) + (behavior * 2);
eeprom_update_byte(addr, (uint8_t)(new_code >> 8)); uint8_t hi = new_code >> 8;
eeprom_update_byte(addr + 1, (uint8_t)(new_code & 0xFF)); uint8_t lo = new_code & 0xFF;
write_custom_config(&hi, offset+0, 1);
write_custom_config(&lo, offset+1, 1);
#endif #endif
} }

View File

@ -8,7 +8,6 @@
#include "matrix.h" #include "matrix.h"
#include "led.h" #include "led.h"
#include "host.h" #include "host.h"
#include "oled_driver.h"
#include "progmem.h" #include "progmem.h"
#include <stdio.h> #include <stdio.h>
@ -16,6 +15,7 @@ void draw_default(void);
void draw_clock(void); void draw_clock(void);
#ifdef OLED_ENABLE #ifdef OLED_ENABLE
#include "oled_driver.h"
oled_rotation_t oled_init_kb(oled_rotation_t rotation) { return OLED_ROTATION_0; } oled_rotation_t oled_init_kb(oled_rotation_t rotation) { return OLED_ROTATION_0; }

View File

@ -42,4 +42,7 @@
// 6 for 3x custom encoder settings, left, right, and press (18 bytes) // 6 for 3x custom encoder settings, left, right, and press (18 bytes)
#define VIA_EEPROM_CUSTOM_CONFIG_SIZE 20 #define VIA_EEPROM_CUSTOM_CONFIG_SIZE 20
// And if VIA isn't enabled, fall back to using standard QMK for configuration
#ifndef VIA_ENABLE
#define EECONFIG_KB_DATA_SIZE VIA_EEPROM_CUSTOM_CONFIG_SIZE
#endif

View File

@ -40,5 +40,10 @@
// 6 for 3x custom encoder settings, left, right, and press (18 bytes) // 6 for 3x custom encoder settings, left, right, and press (18 bytes)
#define VIA_EEPROM_CUSTOM_CONFIG_SIZE 20 #define VIA_EEPROM_CUSTOM_CONFIG_SIZE 20
// And if VIA isn't enabled, fall back to using standard QMK for configuration
#ifndef VIA_ENABLE
#define EECONFIG_KB_DATA_SIZE VIA_EEPROM_CUSTOM_CONFIG_SIZE
#endif
// VIA lighting is handled by the keyboard-level code // VIA lighting is handled by the keyboard-level code
#define VIA_CUSTOM_LIGHTING_ENABLE #define VIA_CUSTOM_LIGHTING_ENABLE

View File

@ -36,7 +36,7 @@ void eeconfig_init_kb(void) {
} }
} }
// Write default value to EEPROM now // Write default value to EEPROM now
eeconfig_update_kb_datablock(&eeprom_ec_config); eeconfig_update_kb_datablock(&eeprom_ec_config, 0, EECONFIG_KB_DATA_SIZE);
eeconfig_init_user(); eeconfig_init_user();
} }
@ -44,7 +44,7 @@ void eeconfig_init_kb(void) {
// On Keyboard startup // On Keyboard startup
void keyboard_post_init_kb(void) { void keyboard_post_init_kb(void) {
// Read custom menu variables from memory // Read custom menu variables from memory
eeconfig_read_kb_datablock(&eeprom_ec_config); eeconfig_read_kb_datablock(&eeprom_ec_config, 0, EECONFIG_KB_DATA_SIZE);
// Set runtime values to EEPROM values // Set runtime values to EEPROM values
ec_config.actuation_mode = eeprom_ec_config.actuation_mode; ec_config.actuation_mode = eeprom_ec_config.actuation_mode;

View File

@ -1,26 +0,0 @@
/* Copyright 2023 Cipulot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "eeprom.h"
#if (EECONFIG_KB_DATA_SIZE) > 0
# define EEPROM_KB_PARTIAL_UPDATE(__struct, __field) eeprom_update_block(&(__struct.__field), (void *)((void *)(EECONFIG_KB_DATABLOCK) + offsetof(typeof(__struct), __field)), sizeof(__struct.__field))
#endif
#if (EECONFIG_USER_DATA_SIZE) > 0
# define EEPROM_USER_PARTIAL_UPDATE(__struct, __field) eeprom_update_block(&(__struct.__field), (void *)((void *)(EECONFIG_USER_DATABLOCK) + offsetof(typeof(__struct), __field)), sizeof(__struct.__field))
#endif

View File

@ -73,7 +73,7 @@ void via_config_set_value(uint8_t *data) {
uprintf("# Actuation Mode: Rapid Trigger #\n"); uprintf("# Actuation Mode: Rapid Trigger #\n");
uprintf("#################################\n"); uprintf("#################################\n");
} }
EEPROM_KB_PARTIAL_UPDATE(eeprom_ec_config, actuation_mode); eeconfig_update_kb_datablock_field(eeprom_ec_config, actuation_mode);
break; break;
} }
case id_mode_0_actuation_threshold: { case id_mode_0_actuation_threshold: {
@ -293,7 +293,7 @@ void ec_save_threshold_data(uint8_t option) {
ec_rescale_values(3); ec_rescale_values(3);
ec_rescale_values(4); ec_rescale_values(4);
} }
eeconfig_update_kb_datablock(&eeprom_ec_config); eeconfig_update_kb_datablock(&eeprom_ec_config, 0, EECONFIG_KB_DATA_SIZE);
uprintf("####################################\n"); uprintf("####################################\n");
uprintf("# New thresholds applied and saved #\n"); uprintf("# New thresholds applied and saved #\n");
uprintf("####################################\n"); uprintf("####################################\n");
@ -321,7 +321,7 @@ void ec_save_bottoming_reading(void) {
ec_rescale_values(2); ec_rescale_values(2);
ec_rescale_values(3); ec_rescale_values(3);
ec_rescale_values(4); ec_rescale_values(4);
eeconfig_update_kb_datablock(&eeprom_ec_config); eeconfig_update_kb_datablock(&eeprom_ec_config, 0, EECONFIG_KB_DATA_SIZE);
} }
// Show the calibration data // Show the calibration data

View File

@ -44,7 +44,7 @@ void eeconfig_init_kb(void) {
} }
} }
// Write default value to EEPROM now // Write default value to EEPROM now
eeconfig_update_kb_datablock(&eeprom_ec_config); eeconfig_update_kb_datablock(&eeprom_ec_config, 0, EECONFIG_KB_DATA_SIZE);
eeconfig_init_user(); eeconfig_init_user();
} }
@ -52,7 +52,7 @@ void eeconfig_init_kb(void) {
// On Keyboard startup // On Keyboard startup
void keyboard_post_init_kb(void) { void keyboard_post_init_kb(void) {
// Read custom menu variables from memory // Read custom menu variables from memory
eeconfig_read_kb_datablock(&eeprom_ec_config); eeconfig_read_kb_datablock(&eeprom_ec_config, 0, EECONFIG_KB_DATA_SIZE);
// Set runtime values to EEPROM values // Set runtime values to EEPROM values
ec_config.actuation_mode = eeprom_ec_config.actuation_mode; ec_config.actuation_mode = eeprom_ec_config.actuation_mode;

View File

@ -44,7 +44,7 @@ void eeconfig_init_kb(void) {
} }
} }
// Write default value to EEPROM now // Write default value to EEPROM now
eeconfig_update_kb_datablock(&eeprom_ec_config); eeconfig_update_kb_datablock(&eeprom_ec_config, 0, EECONFIG_KB_DATA_SIZE);
eeconfig_init_user(); eeconfig_init_user();
} }
@ -52,7 +52,7 @@ void eeconfig_init_kb(void) {
// On Keyboard startup // On Keyboard startup
void keyboard_post_init_kb(void) { void keyboard_post_init_kb(void) {
// Read custom menu variables from memory // Read custom menu variables from memory
eeconfig_read_kb_datablock(&eeprom_ec_config); eeconfig_read_kb_datablock(&eeprom_ec_config, 0, EECONFIG_KB_DATA_SIZE);
// Set runtime values to EEPROM values // Set runtime values to EEPROM values
ec_config.actuation_mode = eeprom_ec_config.actuation_mode; ec_config.actuation_mode = eeprom_ec_config.actuation_mode;

View File

@ -240,9 +240,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!eeconfig_is_enabled()) { if (!eeconfig_is_enabled()) {
eeconfig_init(); eeconfig_init();
} }
keymap_config.raw = eeconfig_read_keymap(); eeconfig_read_keymap(&keymap_config);
keymap_config.nkro = 1; keymap_config.nkro = 1;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
return false; return false;
break; break;

View File

@ -329,9 +329,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!eeconfig_is_enabled()) { if (!eeconfig_is_enabled()) {
eeconfig_init(); eeconfig_init();
} }
keymap_config.raw = eeconfig_read_keymap(); eeconfig_read_keymap(&keymap_config);
keymap_config.nkro = 1; keymap_config.nkro = 1;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
return false; return false;
break; break;

View File

@ -199,9 +199,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!eeconfig_is_enabled()) { if (!eeconfig_is_enabled()) {
eeconfig_init(); eeconfig_init();
} }
keymap_config.raw = eeconfig_read_keymap(); eeconfig_read_keymap(&keymap_config);
keymap_config.nkro = 1; keymap_config.nkro = 1;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
return false; return false;
break; break;

View File

@ -32,7 +32,7 @@ void set_mac_mode_kb(bool macmode) {
* https://github.com/qmk/qmk_firmware/blob/fb4a6ad30ea7a648acd59793ed4a30c3a8d8dc32/quantum/process_keycode/process_magic.c#L80-L81 * https://github.com/qmk/qmk_firmware/blob/fb4a6ad30ea7a648acd59793ed4a30c3a8d8dc32/quantum/process_keycode/process_magic.c#L80-L81
*/ */
keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = !macmode; keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = !macmode;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
void matrix_init_kb(void) { void matrix_init_kb(void) {

View File

@ -27,7 +27,7 @@ void set_mac_mode(bool macmode) {
* https://github.com/qmk/qmk_firmware/blob/fb4a6ad30ea7a648acd59793ed4a30c3a8d8dc32/quantum/process_keycode/process_magic.c#L80-L81 * https://github.com/qmk/qmk_firmware/blob/fb4a6ad30ea7a648acd59793ed4a30c3a8d8dc32/quantum/process_keycode/process_magic.c#L80-L81
*/ */
keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = !macmode; keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = !macmode;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
#ifdef DIP_SWITCH_ENABLE #ifdef DIP_SWITCH_ENABLE

View File

@ -27,7 +27,7 @@ void set_mac_mode(bool macmode) {
* https://github.com/qmk/qmk_firmware/blob/fb4a6ad30ea7a648acd59793ed4a30c3a8d8dc32/quantum/process_keycode/process_magic.c#L80-L81 * https://github.com/qmk/qmk_firmware/blob/fb4a6ad30ea7a648acd59793ed4a30c3a8d8dc32/quantum/process_keycode/process_magic.c#L80-L81
*/ */
keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = !macmode; keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = !macmode;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
#ifdef DIP_SWITCH_ENABLE #ifdef DIP_SWITCH_ENABLE

View File

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

View File

@ -317,7 +317,7 @@ bool dip_switch_update_kb(uint8_t index, bool active) {
} }
if(active){ if(active){
keymap_config.no_gui = 0; keymap_config.no_gui = 0;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
return true; return true;
} }

View File

@ -472,9 +472,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!eeconfig_is_enabled()) { if (!eeconfig_is_enabled()) {
eeconfig_init(); eeconfig_init();
} }
keymap_config.raw = eeconfig_read_keymap(); eeconfig_read_keymap(&keymap_config);
keymap_config.nkro = 1; keymap_config.nkro = 1;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
return false; return false;
case EXT_PLV: case EXT_PLV:

View File

@ -190,7 +190,7 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
set_single_persistent_default_layer(MAC_B); set_single_persistent_default_layer(MAC_B);
layer_state_set(1<<MAC_B); layer_state_set(1<<MAC_B);
keymap_config.no_gui = 0; keymap_config.no_gui = 0;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
return false; return false;
case QK_RGB_MATRIX_TOGGLE: case QK_RGB_MATRIX_TOGGLE:

View File

@ -163,7 +163,7 @@ bool process_record_kb(uint16_t keycode, keyrecord_t* record) {
if (record->event.pressed) { if (record->event.pressed) {
set_single_persistent_default_layer(MAC_B); set_single_persistent_default_layer(MAC_B);
keymap_config.no_gui = 0; keymap_config.no_gui = 0;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
return false; return false;
case GU_TOGG: case GU_TOGG:

View File

@ -1,5 +1,6 @@
#include "omnikeyish.h" #include "omnikeyish.h"
#include <string.h> #include <string.h>
#include "eeprom.h"
dynamic_macro_t dynamic_macros[DYNAMIC_MACRO_COUNT]; dynamic_macro_t dynamic_macros[DYNAMIC_MACRO_COUNT];

View File

@ -233,9 +233,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!eeconfig_is_enabled()) { if (!eeconfig_is_enabled()) {
eeconfig_init(); eeconfig_init();
} }
keymap_config.raw = eeconfig_read_keymap(); eeconfig_read_keymap(&keymap_config);
keymap_config.nkro = 1; keymap_config.nkro = 1;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
return false; return false;
break; break;

View File

@ -270,9 +270,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!eeconfig_is_enabled()) { if (!eeconfig_is_enabled()) {
eeconfig_init(); eeconfig_init();
} }
keymap_config.raw = eeconfig_read_keymap(); eeconfig_read_keymap(&keymap_config);
keymap_config.nkro = 1; keymap_config.nkro = 1;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
return false; return false;
break; break;

View File

@ -14,6 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdlib.h>
#include "keycode_lookup.h" #include "keycode_lookup.h"
#include "quantum_keycodes.h" #include "quantum_keycodes.h"
#include "keymap_us.h" #include "keymap_us.h"

View File

@ -214,9 +214,9 @@ void plover(keyrecord_t *record) {
if (!eeconfig_is_enabled()) { if (!eeconfig_is_enabled()) {
eeconfig_init(); eeconfig_init();
} }
keymap_config.raw = eeconfig_read_keymap(); eeconfig_read_keymap(&keymap_config);
keymap_config.nkro = 1; keymap_config.nkro = 1;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
} }

View File

@ -214,9 +214,9 @@ void plover(keyrecord_t *record) {
if (!eeconfig_is_enabled()) { if (!eeconfig_is_enabled()) {
eeconfig_init(); eeconfig_init();
} }
keymap_config.raw = eeconfig_read_keymap(); eeconfig_read_keymap(&keymap_config);
keymap_config.nkro = 1; keymap_config.nkro = 1;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
} }

View File

@ -214,9 +214,9 @@ void plover(keyrecord_t *record) {
if (!eeconfig_is_enabled()) { if (!eeconfig_is_enabled()) {
eeconfig_init(); eeconfig_init();
} }
keymap_config.raw = eeconfig_read_keymap(); eeconfig_read_keymap(&keymap_config);
keymap_config.nkro = 1; keymap_config.nkro = 1;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
} }

View File

@ -16,6 +16,7 @@
*/ */
#include "quantum.h" #include "quantum.h"
#include "eeprom.h"
#include "usb_mux.h" #include "usb_mux.h"

View File

@ -12,7 +12,7 @@ bool is_keyboard_left(void) {
gpio_set_pin_input(SPLIT_HAND_PIN); gpio_set_pin_input(SPLIT_HAND_PIN);
return x; return x;
#elif defined(EE_HANDS) #elif defined(EE_HANDS)
return eeprom_read_byte(EECONFIG_HANDEDNESS); return eeconfig_read_handedness();
#endif #endif
return is_keyboard_master(); return is_keyboard_master();

View File

@ -33,7 +33,7 @@
// Called from via_init() if VIA_ENABLE // Called from via_init() if VIA_ENABLE
// Called from matrix_init_kb() if not VIA_ENABLE // Called from matrix_init_kb() if not VIA_ENABLE
void via_init_kb(void) void wt_main_init(void)
{ {
// This checks both an EEPROM reset (from bootmagic lite, keycodes) // This checks both an EEPROM reset (from bootmagic lite, keycodes)
// and also firmware build date (from via_eeprom_is_valid()) // and also firmware build date (from via_eeprom_is_valid())
@ -64,11 +64,9 @@ void via_init_kb(void)
void matrix_init_kb(void) void matrix_init_kb(void)
{ {
// If VIA is disabled, we still need to load backlight settings. // If VIA is disabled, we still need to load backlight settings.
// Call via_init_kb() the same way as via_init(), with setting // Call via_init_kb() the same way as via_init_kb() does.
// EEPROM valid afterwards.
#ifndef VIA_ENABLE #ifndef VIA_ENABLE
via_init_kb(); wt_main_init();
via_eeprom_set_valid(true);
#endif // VIA_ENABLE #endif // VIA_ENABLE
matrix_init_user(); matrix_init_user();
@ -109,6 +107,10 @@ void suspend_wakeup_init_kb(void)
// Moving this to the bottom of this source file is a workaround // Moving this to the bottom of this source file is a workaround
// for an intermittent compiler error for Atmel compiler. // for an intermittent compiler error for Atmel compiler.
#ifdef VIA_ENABLE #ifdef VIA_ENABLE
void via_init_kb(void) {
wt_main_init();
}
void via_custom_value_command_kb(uint8_t *data, uint8_t length) { void via_custom_value_command_kb(uint8_t *data, uint8_t length) {
uint8_t *command_id = &(data[0]); uint8_t *command_id = &(data[0]);
uint8_t *channel_id = &(data[1]); uint8_t *channel_id = &(data[1]);
@ -159,50 +161,3 @@ void via_set_device_indication(uint8_t value)
} }
#endif // VIA_ENABLE #endif // VIA_ENABLE
//
// In the case of VIA being disabled, we still need to check if
// keyboard level EEPROM memory is valid before loading.
// Thus these are copies of the same functions in VIA, since
// the backlight settings reuse VIA's EEPROM magic/version,
// and the ones in via.c won't be compiled in.
//
// Yes, this is sub-optimal, and is only here for completeness
// (i.e. catering to the 1% of people that want wilba.tech LED bling
// AND want persistent settings BUT DON'T want to use dynamic keymaps/VIA).
//
#ifndef VIA_ENABLE
bool via_eeprom_is_valid(void)
{
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 );
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 );
}
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);
}
void via_eeprom_reset(void)
{
// Set the VIA specific EEPROM state as invalid.
via_eeprom_set_valid(false);
// Set the TMK/QMK EEPROM state as invalid.
eeconfig_disable();
}
#endif // VIA_ENABLE

View File

@ -25,6 +25,8 @@
#include "progmem.h" #include "progmem.h"
#include "eeprom.h" #include "eeprom.h"
#include "nvm_eeprom_eeconfig_internal.h" // expose EEPROM addresses, no appetite to move legacy/deprecated code to nvm
#include "nvm_eeprom_via_internal.h" // expose EEPROM addresses, no appetite to move legacy/deprecated code to nvm
#include "via.h" // uses EEPROM address, lighting value IDs #include "via.h" // uses EEPROM address, lighting value IDs
#define MONO_BACKLIGHT_CONFIG_EEPROM_ADDR (VIA_EEPROM_CUSTOM_CONFIG_ADDR) #define MONO_BACKLIGHT_CONFIG_EEPROM_ADDR (VIA_EEPROM_CUSTOM_CONFIG_ADDR)

View File

@ -66,6 +66,8 @@
#include "quantum/color.h" #include "quantum/color.h"
#include "eeprom.h" #include "eeprom.h"
#include "nvm_eeprom_eeconfig_internal.h" // expose EEPROM addresses, no appetite to move legacy/deprecated code to nvm
#include "nvm_eeprom_via_internal.h" // expose EEPROM addresses, no appetite to move legacy/deprecated code to nvm
#include "via.h" // uses EEPROM address, lighting value IDs #include "via.h" // uses EEPROM address, lighting value IDs
#define RGB_BACKLIGHT_CONFIG_EEPROM_ADDR (VIA_EEPROM_CUSTOM_CONFIG_ADDR) #define RGB_BACKLIGHT_CONFIG_EEPROM_ADDR (VIA_EEPROM_CUSTOM_CONFIG_ADDR)

View File

@ -31,7 +31,7 @@ static void startup_animation_setleds(effect_params_t* params, bool dots) {
} else if (num == 0 || num == 1 || num == 2) { } else if (num == 0 || num == 1 || num == 2) {
return; return;
} else if (num >= 22) { } else if (num >= 22) {
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); rgb_matrix_mode_noeeprom(rgb_matrix_config.mode);
return; return;
} }

View File

@ -220,7 +220,7 @@ bool is_oneshot_layer_active(void) {
void oneshot_set(bool active) { void oneshot_set(bool active) {
if (keymap_config.oneshot_enable != active) { if (keymap_config.oneshot_enable != active) {
keymap_config.oneshot_enable = active; keymap_config.oneshot_enable = active;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
dprintf("Oneshot: active: %d\n", active); dprintf("Oneshot: active: %d\n", active);
} }

View File

@ -149,14 +149,14 @@ void audio_driver_start(void) {
} }
void eeconfig_update_audio_current(void) { void eeconfig_update_audio_current(void) {
eeconfig_update_audio(audio_config.raw); eeconfig_update_audio(&audio_config);
} }
void eeconfig_update_audio_default(void) { void eeconfig_update_audio_default(void) {
audio_config.valid = true; audio_config.valid = true;
audio_config.enable = AUDIO_DEFAULT_ON; audio_config.enable = AUDIO_DEFAULT_ON;
audio_config.clicky_enable = AUDIO_DEFAULT_CLICKY_ON; audio_config.clicky_enable = AUDIO_DEFAULT_CLICKY_ON;
eeconfig_update_audio(audio_config.raw); eeconfig_update_audio(&audio_config);
} }
void audio_init(void) { void audio_init(void) {
@ -164,7 +164,7 @@ void audio_init(void) {
return; return;
} }
audio_config.raw = eeconfig_read_audio(); eeconfig_read_audio(&audio_config);
if (!audio_config.valid) { if (!audio_config.valid) {
dprintf("audio_init audio_config.valid = 0. Write default values to EEPROM.\n"); dprintf("audio_init audio_config.valid = 0. Write default values to EEPROM.\n");
eeconfig_update_audio_default(); eeconfig_update_audio_default();
@ -196,7 +196,7 @@ void audio_toggle(void) {
stop_all_notes(); stop_all_notes();
} }
audio_config.enable ^= 1; audio_config.enable ^= 1;
eeconfig_update_audio(audio_config.raw); eeconfig_update_audio(&audio_config);
if (audio_config.enable) { if (audio_config.enable) {
audio_on_user(); audio_on_user();
} else { } else {
@ -206,7 +206,7 @@ void audio_toggle(void) {
void audio_on(void) { void audio_on(void) {
audio_config.enable = 1; audio_config.enable = 1;
eeconfig_update_audio(audio_config.raw); eeconfig_update_audio(&audio_config);
audio_on_user(); audio_on_user();
PLAY_SONG(audio_on_song); PLAY_SONG(audio_on_song);
} }
@ -217,7 +217,7 @@ void audio_off(void) {
wait_ms(100); wait_ms(100);
audio_stop_all(); audio_stop_all();
audio_config.enable = 0; audio_config.enable = 0;
eeconfig_update_audio(audio_config.raw); eeconfig_update_audio(&audio_config);
} }
bool audio_is_on(void) { bool audio_is_on(void) {

View File

@ -28,7 +28,7 @@
# include "audio_dac.h" # include "audio_dac.h"
#endif #endif
typedef union { typedef union audio_config_t {
uint8_t raw; uint8_t raw;
struct { struct {
bool enable : 1; bool enable : 1;

View File

@ -16,7 +16,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "backlight.h" #include "backlight.h"
#include "eeprom.h"
#include "eeconfig.h" #include "eeconfig.h"
#include "debug.h" #include "debug.h"
@ -55,7 +54,7 @@ static void backlight_check_config(void) {
* FIXME: needs doc * FIXME: needs doc
*/ */
void backlight_init(void) { void backlight_init(void) {
backlight_config.raw = eeconfig_read_backlight(); eeconfig_read_backlight(&backlight_config);
if (!backlight_config.valid) { if (!backlight_config.valid) {
dprintf("backlight_init backlight_config.valid = 0. Write default values to EEPROM.\n"); dprintf("backlight_init backlight_config.valid = 0. Write default values to EEPROM.\n");
eeconfig_update_backlight_default(); eeconfig_update_backlight_default();
@ -74,7 +73,7 @@ void backlight_increase(void) {
backlight_config.level++; backlight_config.level++;
} }
backlight_config.enable = 1; backlight_config.enable = 1;
eeconfig_update_backlight(backlight_config.raw); eeconfig_update_backlight(&backlight_config);
dprintf("backlight increase: %u\n", backlight_config.level); dprintf("backlight increase: %u\n", backlight_config.level);
backlight_set(backlight_config.level); backlight_set(backlight_config.level);
} }
@ -87,7 +86,7 @@ void backlight_decrease(void) {
if (backlight_config.level > 0) { if (backlight_config.level > 0) {
backlight_config.level--; backlight_config.level--;
backlight_config.enable = !!backlight_config.level; backlight_config.enable = !!backlight_config.level;
eeconfig_update_backlight(backlight_config.raw); eeconfig_update_backlight(&backlight_config);
} }
dprintf("backlight decrease: %u\n", backlight_config.level); dprintf("backlight decrease: %u\n", backlight_config.level);
backlight_set(backlight_config.level); backlight_set(backlight_config.level);
@ -116,7 +115,7 @@ void backlight_enable(void) {
backlight_config.enable = true; backlight_config.enable = true;
if (backlight_config.raw == 1) // enabled but level == 0 if (backlight_config.raw == 1) // enabled but level == 0
backlight_config.level = 1; backlight_config.level = 1;
eeconfig_update_backlight(backlight_config.raw); eeconfig_update_backlight(&backlight_config);
dprintf("backlight enable\n"); dprintf("backlight enable\n");
backlight_set(backlight_config.level); backlight_set(backlight_config.level);
} }
@ -129,7 +128,7 @@ void backlight_disable(void) {
if (!backlight_config.enable) return; // do nothing if backlight is already off if (!backlight_config.enable) return; // do nothing if backlight is already off
backlight_config.enable = false; backlight_config.enable = false;
eeconfig_update_backlight(backlight_config.raw); eeconfig_update_backlight(&backlight_config);
dprintf("backlight disable\n"); dprintf("backlight disable\n");
backlight_set(0); backlight_set(0);
} }
@ -152,7 +151,7 @@ void backlight_step(void) {
backlight_config.level = 0; backlight_config.level = 0;
} }
backlight_config.enable = !!backlight_config.level; backlight_config.enable = !!backlight_config.level;
eeconfig_update_backlight(backlight_config.raw); eeconfig_update_backlight(&backlight_config);
dprintf("backlight step: %u\n", backlight_config.level); dprintf("backlight step: %u\n", backlight_config.level);
backlight_set(backlight_config.level); backlight_set(backlight_config.level);
} }
@ -173,19 +172,11 @@ void backlight_level_noeeprom(uint8_t level) {
*/ */
void backlight_level(uint8_t level) { void backlight_level(uint8_t level) {
backlight_level_noeeprom(level); backlight_level_noeeprom(level);
eeconfig_update_backlight(backlight_config.raw); eeconfig_update_backlight(&backlight_config);
}
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) { void eeconfig_update_backlight_current(void) {
eeconfig_update_backlight(backlight_config.raw); eeconfig_update_backlight(&backlight_config);
} }
void eeconfig_update_backlight_default(void) { void eeconfig_update_backlight_default(void) {
@ -193,7 +184,7 @@ void eeconfig_update_backlight_default(void) {
backlight_config.enable = BACKLIGHT_DEFAULT_ON; backlight_config.enable = BACKLIGHT_DEFAULT_ON;
backlight_config.breathing = BACKLIGHT_DEFAULT_BREATHING; backlight_config.breathing = BACKLIGHT_DEFAULT_BREATHING;
backlight_config.level = BACKLIGHT_DEFAULT_LEVEL; backlight_config.level = BACKLIGHT_DEFAULT_LEVEL;
eeconfig_update_backlight(backlight_config.raw); eeconfig_update_backlight(&backlight_config);
} }
/** \brief Get backlight level /** \brief Get backlight level
@ -226,7 +217,7 @@ void backlight_enable_breathing(void) {
if (backlight_config.breathing) return; // do nothing if breathing is already on if (backlight_config.breathing) return; // do nothing if breathing is already on
backlight_config.breathing = true; backlight_config.breathing = true;
eeconfig_update_backlight(backlight_config.raw); eeconfig_update_backlight(&backlight_config);
dprintf("backlight breathing enable\n"); dprintf("backlight breathing enable\n");
breathing_enable(); breathing_enable();
} }
@ -239,7 +230,7 @@ void backlight_disable_breathing(void) {
if (!backlight_config.breathing) return; // do nothing if breathing is already off if (!backlight_config.breathing) return; // do nothing if breathing is already off
backlight_config.breathing = false; backlight_config.breathing = false;
eeconfig_update_backlight(backlight_config.raw); eeconfig_update_backlight(&backlight_config);
dprintf("backlight breathing disable\n"); dprintf("backlight breathing disable\n");
breathing_disable(); breathing_disable();
} }

View File

@ -34,7 +34,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# define BREATHING_PERIOD 6 # define BREATHING_PERIOD 6
#endif #endif
typedef union { typedef union backlight_config_t {
uint8_t raw; uint8_t raw;
struct { struct {
bool enable : 1; bool enable : 1;
@ -58,8 +58,6 @@ void backlight_level_noeeprom(uint8_t level);
void backlight_level(uint8_t level); void backlight_level(uint8_t level);
uint8_t get_backlight_level(void); uint8_t get_backlight_level(void);
uint8_t eeconfig_read_backlight(void);
void eeconfig_update_backlight(uint8_t val);
void eeconfig_update_backlight_current(void); void eeconfig_update_backlight_current(void);
void eeconfig_update_backlight_default(void); void eeconfig_update_backlight_default(void);

View File

@ -246,7 +246,7 @@ static void print_eeconfig(void) {
xprintf("eeconfig:\ndefault_layer: %u\n", eeconfig_read_default_layer()); xprintf("eeconfig:\ndefault_layer: %u\n", eeconfig_read_default_layer());
debug_config_t dc; debug_config_t dc;
dc.raw = eeconfig_read_debug(); eeconfig_read_debug(&dc);
xprintf(/* clang-format off */ xprintf(/* clang-format off */
"debug_config.raw: %02X\n" "debug_config.raw: %02X\n"
@ -263,7 +263,7 @@ static void print_eeconfig(void) {
); /* clang-format on */ ); /* clang-format on */
keymap_config_t kc; keymap_config_t kc;
kc.raw = eeconfig_read_keymap(); eeconfig_read_keymap(&kc);
xprintf(/* clang-format off */ xprintf(/* clang-format off */
"keymap_config.raw: %02X\n" "keymap_config.raw: %02X\n"
@ -296,7 +296,7 @@ static void print_eeconfig(void) {
# ifdef BACKLIGHT_ENABLE # ifdef BACKLIGHT_ENABLE
backlight_config_t bc; backlight_config_t bc;
bc.raw = eeconfig_read_backlight(); eeconfig_read_backlight(&bc);
xprintf(/* clang-format off */ xprintf(/* clang-format off */
"backlight_config" "backlight_config"

View File

@ -21,14 +21,7 @@
#include "progmem.h" #include "progmem.h"
#include "send_string.h" #include "send_string.h"
#include "keycodes.h" #include "keycodes.h"
#include "nvm_dynamic_keymap.h"
#ifdef VIA_ENABLE
# include "via.h"
# define DYNAMIC_KEYMAP_EEPROM_START (VIA_EEPROM_CONFIG_END)
#else
# include "eeconfig.h"
# define DYNAMIC_KEYMAP_EEPROM_START (EECONFIG_SIZE)
#endif
#ifdef ENCODER_ENABLE #ifdef ENCODER_ENABLE
# include "encoder.h" # include "encoder.h"
@ -36,67 +29,6 @@
# define NUM_ENCODERS 0 # define NUM_ENCODERS 0
#endif #endif
#ifndef DYNAMIC_KEYMAP_LAYER_COUNT
# define DYNAMIC_KEYMAP_LAYER_COUNT 4
#endif
#ifndef DYNAMIC_KEYMAP_MACRO_COUNT
# define DYNAMIC_KEYMAP_MACRO_COUNT 16
#endif
#ifndef TOTAL_EEPROM_BYTE_COUNT
# error Unknown total EEPROM size. Cannot derive maximum for dynamic keymaps.
#endif
#ifndef DYNAMIC_KEYMAP_EEPROM_MAX_ADDR
# define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR (TOTAL_EEPROM_BYTE_COUNT - 1)
#endif
#if DYNAMIC_KEYMAP_EEPROM_MAX_ADDR > (TOTAL_EEPROM_BYTE_COUNT - 1)
# pragma message STR(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) " > " STR((TOTAL_EEPROM_BYTE_COUNT - 1))
# error DYNAMIC_KEYMAP_EEPROM_MAX_ADDR is configured to use more space than what is available for the selected EEPROM driver
#endif
// Due to usage of uint16_t check for max 65535
#if DYNAMIC_KEYMAP_EEPROM_MAX_ADDR > 65535
# pragma message STR(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) " > 65535"
# error DYNAMIC_KEYMAP_EEPROM_MAX_ADDR must be less than 65536
#endif
// If DYNAMIC_KEYMAP_EEPROM_ADDR not explicitly defined in config.h,
#ifndef DYNAMIC_KEYMAP_EEPROM_ADDR
# define DYNAMIC_KEYMAP_EEPROM_ADDR DYNAMIC_KEYMAP_EEPROM_START
#endif
// Dynamic encoders starts after dynamic keymaps
#ifndef DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR
# define DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR (DYNAMIC_KEYMAP_EEPROM_ADDR + (DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2))
#endif
// Dynamic macro starts after dynamic encoders, but only when using ENCODER_MAP
#ifdef ENCODER_MAP_ENABLE
# ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR
# define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR (DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR + (DYNAMIC_KEYMAP_LAYER_COUNT * NUM_ENCODERS * 2 * 2))
# endif // DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR
#else // ENCODER_MAP_ENABLE
# ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR
# define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR (DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR)
# endif // DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR
#endif // ENCODER_MAP_ENABLE
// Sanity check that dynamic keymaps fit in available EEPROM
// If there's not 100 bytes available for macros, then something is wrong.
// The keyboard should override DYNAMIC_KEYMAP_LAYER_COUNT to reduce it,
// or DYNAMIC_KEYMAP_EEPROM_MAX_ADDR to increase it, *only if* the microcontroller has
// more than the default.
_Static_assert((DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) - (DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR) >= 100, "Dynamic keymaps are configured to use more EEPROM than is available.");
// Dynamic macros are stored after the keymaps and use what is available
// up to and including DYNAMIC_KEYMAP_EEPROM_MAX_ADDR.
#ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE
# define DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE (DYNAMIC_KEYMAP_EEPROM_MAX_ADDR - DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + 1)
#endif
#ifndef DYNAMIC_KEYMAP_MACRO_DELAY #ifndef DYNAMIC_KEYMAP_MACRO_DELAY
# define DYNAMIC_KEYMAP_MACRO_DELAY TAP_CODE_DELAY # define DYNAMIC_KEYMAP_MACRO_DELAY TAP_CODE_DELAY
#endif #endif
@ -105,52 +37,28 @@ uint8_t dynamic_keymap_get_layer_count(void) {
return DYNAMIC_KEYMAP_LAYER_COUNT; return DYNAMIC_KEYMAP_LAYER_COUNT;
} }
void *dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t column) {
// TODO: optimize this with some left shifts
return ((void *)DYNAMIC_KEYMAP_EEPROM_ADDR) + (layer * MATRIX_ROWS * MATRIX_COLS * 2) + (row * MATRIX_COLS * 2) + (column * 2);
}
uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column) { uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column) {
if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || row >= MATRIX_ROWS || column >= MATRIX_COLS) return KC_NO; return nvm_dynamic_keymap_read_keycode(layer, row, column);
void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column);
// Big endian, so we can read/write EEPROM directly from host if we want
uint16_t keycode = eeprom_read_byte(address) << 8;
keycode |= eeprom_read_byte(address + 1);
return keycode;
} }
void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode) { void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode) {
if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || row >= MATRIX_ROWS || column >= MATRIX_COLS) return; nvm_dynamic_keymap_update_keycode(layer, row, column, keycode);
void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column);
// Big endian, so we can read/write EEPROM directly from host if we want
eeprom_update_byte(address, (uint8_t)(keycode >> 8));
eeprom_update_byte(address + 1, (uint8_t)(keycode & 0xFF));
} }
#ifdef ENCODER_MAP_ENABLE #ifdef ENCODER_MAP_ENABLE
void *dynamic_keymap_encoder_to_eeprom_address(uint8_t layer, uint8_t encoder_id) {
return ((void *)DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR) + (layer * NUM_ENCODERS * 2 * 2) + (encoder_id * 2 * 2);
}
uint16_t dynamic_keymap_get_encoder(uint8_t layer, uint8_t encoder_id, bool clockwise) { uint16_t dynamic_keymap_get_encoder(uint8_t layer, uint8_t encoder_id, bool clockwise) {
if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || encoder_id >= NUM_ENCODERS) return KC_NO; return nvm_dynamic_keymap_read_encoder(layer, encoder_id, clockwise);
void *address = dynamic_keymap_encoder_to_eeprom_address(layer, encoder_id);
// Big endian, so we can read/write EEPROM directly from host if we want
uint16_t keycode = ((uint16_t)eeprom_read_byte(address + (clockwise ? 0 : 2))) << 8;
keycode |= eeprom_read_byte(address + (clockwise ? 0 : 2) + 1);
return keycode;
} }
void dynamic_keymap_set_encoder(uint8_t layer, uint8_t encoder_id, bool clockwise, uint16_t keycode) { void dynamic_keymap_set_encoder(uint8_t layer, uint8_t encoder_id, bool clockwise, uint16_t keycode) {
if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || encoder_id >= NUM_ENCODERS) return; nvm_dynamic_keymap_update_encoder(layer, encoder_id, clockwise, keycode);
void *address = dynamic_keymap_encoder_to_eeprom_address(layer, encoder_id);
// Big endian, so we can read/write EEPROM directly from host if we want
eeprom_update_byte(address + (clockwise ? 0 : 2), (uint8_t)(keycode >> 8));
eeprom_update_byte(address + (clockwise ? 0 : 2) + 1, (uint8_t)(keycode & 0xFF));
} }
#endif // ENCODER_MAP_ENABLE #endif // ENCODER_MAP_ENABLE
void dynamic_keymap_reset(void) { void dynamic_keymap_reset(void) {
// Erase the keymaps, if necessary.
nvm_dynamic_keymap_erase();
// Reset the keymaps in EEPROM to what is in flash. // Reset the keymaps in EEPROM to what is in flash.
for (int layer = 0; layer < DYNAMIC_KEYMAP_LAYER_COUNT; layer++) { for (int layer = 0; layer < DYNAMIC_KEYMAP_LAYER_COUNT; layer++) {
for (int row = 0; row < MATRIX_ROWS; row++) { for (int row = 0; row < MATRIX_ROWS; row++) {
@ -168,31 +76,11 @@ void dynamic_keymap_reset(void) {
} }
void dynamic_keymap_get_buffer(uint16_t offset, uint16_t size, uint8_t *data) { void dynamic_keymap_get_buffer(uint16_t offset, uint16_t size, uint8_t *data) {
uint16_t dynamic_keymap_eeprom_size = DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2; nvm_dynamic_keymap_read_buffer(offset, size, data);
void * source = (void *)(DYNAMIC_KEYMAP_EEPROM_ADDR + offset);
uint8_t *target = data;
for (uint16_t i = 0; i < size; i++) {
if (offset + i < dynamic_keymap_eeprom_size) {
*target = eeprom_read_byte(source);
} else {
*target = 0x00;
}
source++;
target++;
}
} }
void dynamic_keymap_set_buffer(uint16_t offset, uint16_t size, uint8_t *data) { void dynamic_keymap_set_buffer(uint16_t offset, uint16_t size, uint8_t *data) {
uint16_t dynamic_keymap_eeprom_size = DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2; nvm_dynamic_keymap_update_buffer(offset, size, data);
void * target = (void *)(DYNAMIC_KEYMAP_EEPROM_ADDR + offset);
uint8_t *source = data;
for (uint16_t i = 0; i < size; i++) {
if (offset + i < dynamic_keymap_eeprom_size) {
eeprom_update_byte(target, *source);
}
source++;
target++;
}
} }
uint16_t keycode_at_keymap_location(uint8_t layer_num, uint8_t row, uint8_t column) { uint16_t keycode_at_keymap_location(uint8_t layer_num, uint8_t row, uint8_t column) {
@ -216,42 +104,27 @@ uint8_t dynamic_keymap_macro_get_count(void) {
} }
uint16_t dynamic_keymap_macro_get_buffer_size(void) { uint16_t dynamic_keymap_macro_get_buffer_size(void) {
return DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE; return (uint16_t)nvm_dynamic_keymap_macro_size();
} }
void dynamic_keymap_macro_get_buffer(uint16_t offset, uint16_t size, uint8_t *data) { void dynamic_keymap_macro_get_buffer(uint16_t offset, uint16_t size, uint8_t *data) {
void * source = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + offset); nvm_dynamic_keymap_macro_read_buffer(offset, size, data);
uint8_t *target = data;
for (uint16_t i = 0; i < size; i++) {
if (offset + i < DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE) {
*target = eeprom_read_byte(source);
} else {
*target = 0x00;
}
source++;
target++;
}
} }
void dynamic_keymap_macro_set_buffer(uint16_t offset, uint16_t size, uint8_t *data) { void dynamic_keymap_macro_set_buffer(uint16_t offset, uint16_t size, uint8_t *data) {
void * target = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + offset); nvm_dynamic_keymap_macro_update_buffer(offset, size, data);
uint8_t *source = data;
for (uint16_t i = 0; i < size; i++) {
if (offset + i < DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE) {
eeprom_update_byte(target, *source);
}
source++;
target++;
}
} }
void dynamic_keymap_macro_reset(void) { void dynamic_keymap_macro_reset(void) {
void *p = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR); // Erase the macros, if necessary.
void *end = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE); nvm_dynamic_keymap_macro_erase();
while (p != end) { nvm_dynamic_keymap_macro_reset();
eeprom_update_byte(p, 0); }
++p;
} static uint8_t dynamic_keymap_read_byte(uint32_t offset) {
uint8_t d;
nvm_dynamic_keymap_macro_read_buffer(offset, 1, &d);
return d;
} }
void dynamic_keymap_macro_send(uint8_t id) { void dynamic_keymap_macro_send(uint8_t id) {
@ -263,25 +136,24 @@ void dynamic_keymap_macro_send(uint8_t id) {
// If it's not zero, then we are in the middle // If it's not zero, then we are in the middle
// of buffer writing, possibly an aborted buffer // of buffer writing, possibly an aborted buffer
// write. So do nothing. // write. So do nothing.
void *p = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE - 1); if (dynamic_keymap_read_byte(nvm_dynamic_keymap_macro_size() - 1) != 0) {
if (eeprom_read_byte(p) != 0) {
return; return;
} }
// Skip N null characters // Skip N null characters
// p will then point to the Nth macro // p will then point to the Nth macro
p = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR); uint32_t offset = 0;
void *end = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE); uint32_t end = nvm_dynamic_keymap_macro_size();
while (id > 0) { while (id > 0) {
// If we are past the end of the buffer, then there is // If we are past the end of the buffer, then there is
// no Nth macro in the buffer. // no Nth macro in the buffer.
if (p == end) { if (offset == end) {
return; return;
} }
if (eeprom_read_byte(p) == 0) { if (dynamic_keymap_read_byte(offset) == 0) {
--id; --id;
} }
++p; ++offset;
} }
// Send the macro string by making a temporary string. // Send the macro string by making a temporary string.
@ -289,7 +161,7 @@ void dynamic_keymap_macro_send(uint8_t id) {
// We already checked there was a null at the end of // We already checked there was a null at the end of
// the buffer, so this cannot go past the end // the buffer, so this cannot go past the end
while (1) { while (1) {
data[0] = eeprom_read_byte(p++); data[0] = dynamic_keymap_read_byte(offset++);
data[1] = 0; data[1] = 0;
// Stop at the null terminator of this macro string // Stop at the null terminator of this macro string
if (data[0] == 0) { if (data[0] == 0) {
@ -297,14 +169,14 @@ void dynamic_keymap_macro_send(uint8_t id) {
} }
if (data[0] == SS_QMK_PREFIX) { if (data[0] == SS_QMK_PREFIX) {
// Get the code // Get the code
data[1] = eeprom_read_byte(p++); data[1] = dynamic_keymap_read_byte(offset++);
// Unexpected null, abort. // Unexpected null, abort.
if (data[1] == 0) { if (data[1] == 0) {
return; return;
} }
if (data[1] == SS_TAP_CODE || data[1] == SS_DOWN_CODE || data[1] == SS_UP_CODE) { if (data[1] == SS_TAP_CODE || data[1] == SS_DOWN_CODE || data[1] == SS_UP_CODE) {
// Get the keycode // Get the keycode
data[2] = eeprom_read_byte(p++); data[2] = dynamic_keymap_read_byte(offset++);
// Unexpected null, abort. // Unexpected null, abort.
if (data[2] == 0) { if (data[2] == 0) {
return; return;
@ -316,7 +188,7 @@ void dynamic_keymap_macro_send(uint8_t id) {
// At most this is 4 digits plus '|' // At most this is 4 digits plus '|'
uint8_t i = 2; uint8_t i = 2;
while (1) { while (1) {
data[i] = eeprom_read_byte(p++); data[i] = dynamic_keymap_read_byte(offset++);
// Unexpected null, abort // Unexpected null, abort
if (data[i] == 0) { if (data[i] == 0) {
return; return;

View File

@ -18,8 +18,15 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#ifndef DYNAMIC_KEYMAP_LAYER_COUNT
# define DYNAMIC_KEYMAP_LAYER_COUNT 4
#endif
#ifndef DYNAMIC_KEYMAP_MACRO_COUNT
# define DYNAMIC_KEYMAP_MACRO_COUNT 16
#endif
uint8_t dynamic_keymap_get_layer_count(void); uint8_t dynamic_keymap_get_layer_count(void);
void * dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t column);
uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column); uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column);
void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode); void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode);
#ifdef ENCODER_MAP_ENABLE #ifdef ENCODER_MAP_ENABLE

View File

@ -1,340 +1,333 @@
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "debug.h"
#include "eeprom.h" #include "eeprom.h"
#include "eeconfig.h" #include "eeconfig.h"
#include "action_layer.h" #include "action_layer.h"
#include "nvm_eeconfig.h"
#include "keycode_config.h"
#if defined(EEPROM_DRIVER) #ifdef EEPROM_DRIVER
# include "eeprom_driver.h" # include "eeprom_driver.h"
#endif #endif // EEPROM_DRIVER
#if defined(HAPTIC_ENABLE) #ifdef BACKLIGHT_ENABLE
# include "backlight.h"
#endif // BACKLIGHT_ENABLE
#ifdef AUDIO_ENABLE
# include "audio.h"
#endif // AUDIO_ENABLE
#ifdef RGBLIGHT_ENABLE
# include "rgblight.h"
#endif // RGBLIGHT_ENABLE
#ifdef RGB_MATRIX_ENABLE
# include "rgb_matrix_types.h"
#endif // RGB_MATRIX_ENABLE
#ifdef LED_MATRIX_ENABLE
# include "led_matrix_types.h"
#endif // LED_MATRIX_ENABLE
#ifdef UNICODE_COMMON_ENABLE
# include "unicode.h"
#endif // UNICODE_COMMON_ENABLE
#ifdef HAPTIC_ENABLE
# include "haptic.h" # include "haptic.h"
#endif #endif // HAPTIC_ENABLE
#if defined(VIA_ENABLE) #ifdef VIA_ENABLE
bool via_eeprom_is_valid(void); bool via_eeprom_is_valid(void);
void via_eeprom_set_valid(bool valid); void via_eeprom_set_valid(bool valid);
void eeconfig_init_via(void); void eeconfig_init_via(void);
#endif #else
void dynamic_keymap_reset(void);
#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) { __attribute__((weak)) void eeconfig_init_user(void) {
#if (EECONFIG_USER_DATA_SIZE) == 0 #if (EECONFIG_USER_DATA_SIZE) == 0
// Reset user EEPROM value to blank, rather than to a set value // Reset user EEPROM value to blank, rather than to a set value
eeconfig_update_user(0); eeconfig_update_user(0);
#endif #endif // (EECONFIG_USER_DATA_SIZE) == 0
} }
__attribute__((weak)) void eeconfig_init_kb(void) { __attribute__((weak)) void eeconfig_init_kb(void) {
#if (EECONFIG_KB_DATA_SIZE) == 0 #if (EECONFIG_KB_DATA_SIZE) == 0
// Reset Keyboard EEPROM value to blank, rather than to a set value // Reset Keyboard EEPROM value to blank, rather than to a set value
eeconfig_update_kb(0); eeconfig_update_kb(0);
#endif #endif // (EECONFIG_KB_DATA_SIZE) == 0
eeconfig_init_user(); eeconfig_init_user();
} }
/*
* FIXME: needs doc
*/
void eeconfig_init_quantum(void) { void eeconfig_init_quantum(void) {
#if defined(EEPROM_DRIVER) nvm_eeconfig_erase();
eeprom_driver_format(false);
eeconfig_enable();
debug_config_t debug_config = {0};
eeconfig_update_debug(&debug_config);
default_layer_state = (layer_state_t)1 << 0;
eeconfig_update_default_layer(default_layer_state);
keymap_config_t keymap_config = {
.swap_control_capslock = false,
.capslock_to_control = false,
.swap_lalt_lgui = false,
.swap_ralt_rgui = false,
.no_gui = false,
.swap_grave_esc = false,
.swap_backslash_backspace = false,
.nkro = false,
.swap_lctl_lgui = false,
.swap_rctl_rgui = false,
.oneshot_enable = true, // Enable oneshot by default
.swap_escape_capslock = false,
.autocorrect_enable = true, // Enable autocorrect by default
};
eeconfig_update_keymap(&keymap_config);
#ifdef BACKLIGHT_ENABLE
backlight_config_t backlight_config = {0};
eeconfig_update_backlight(&backlight_config);
#endif // BACKLIGHT_ENABLE
#ifdef AUDIO_ENABLE
audio_config_t audio_config = {0};
eeconfig_update_audio(&audio_config);
#endif // AUDIO_ENABLE
#ifdef RGBLIGHT_ENABLE
rgblight_config_t rgblight_config = {0};
eeconfig_update_rgblight(&rgblight_config);
#endif // RGBLIGHT_ENABLE
#ifdef UNICODE_COMMON_ENABLE
unicode_config_t unicode_config = {0};
eeconfig_update_unicode_mode(&unicode_config);
#endif // UNICODE_COMMON_ENABLE
#ifdef STENO_ENABLE
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 #endif
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); #ifdef LED_MATRIX_ENABLE
eeprom_update_byte(EECONFIG_DEBUG, 0); led_eeconfig_t led_matrix_config = {0};
default_layer_state = (layer_state_t)1 << 0; eeconfig_update_led_matrix(&led_matrix_config);
eeprom_update_byte(EECONFIG_DEFAULT_LAYER, default_layer_state); #endif // LED_MATRIX_ENABLE
// Enable oneshot and autocorrect by default: 0b0001 0100 0000 0000
eeprom_update_word(EECONFIG_KEYMAP, 0x1400); #ifdef HAPTIC_ENABLE
eeprom_update_byte(EECONFIG_BACKLIGHT, 0); haptic_config_t haptic_config = {0};
eeprom_update_byte(EECONFIG_AUDIO, 0); eeconfig_update_haptic(&haptic_config);
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)
haptic_reset(); haptic_reset();
#endif #endif // HAPTIC_ENABLE
#if (EECONFIG_KB_DATA_SIZE) > 0 #if (EECONFIG_KB_DATA_SIZE) > 0
eeconfig_init_kb_datablock(); eeconfig_init_kb_datablock();
#endif #endif // (EECONFIG_KB_DATA_SIZE) > 0
#if (EECONFIG_USER_DATA_SIZE) > 0 #if (EECONFIG_USER_DATA_SIZE) > 0
eeconfig_init_user_datablock(); eeconfig_init_user_datablock();
#endif #endif // (EECONFIG_USER_DATA_SIZE) > 0
#if defined(VIA_ENABLE) #if defined(VIA_ENABLE)
// Invalidate VIA eeprom config, and then reset. // Invalidate VIA eeprom config, and then reset.
// Just in case if power is lost mid init, this makes sure that it pets // Just in case if power is lost mid init, this makes sure that it gets
// properly re-initialized. // properly re-initialized.
via_eeprom_set_valid(false);
eeconfig_init_via(); eeconfig_init_via();
#elif defined(DYNAMIC_KEYMAP_ENABLE)
dynamic_keymap_reset();
#endif #endif
eeconfig_init_kb(); eeconfig_init_kb();
} }
/** \brief eeconfig initialization
*
* FIXME: needs doc
*/
void eeconfig_init(void) { void eeconfig_init(void) {
eeconfig_init_quantum(); eeconfig_init_quantum();
} }
/** \brief eeconfig enable
*
* FIXME: needs doc
*/
void eeconfig_enable(void) { 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) { void eeconfig_disable(void) {
#if defined(EEPROM_DRIVER) nvm_eeconfig_disable();
eeprom_driver_format(false);
#endif
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF);
} }
/** \brief eeconfig is enabled
*
* FIXME: needs doc
*/
bool eeconfig_is_enabled(void) { bool eeconfig_is_enabled(void) {
bool is_eeprom_enabled = (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER); bool is_eeprom_enabled = nvm_eeconfig_is_enabled();
#ifdef VIA_ENABLE #ifdef VIA_ENABLE
if (is_eeprom_enabled) { if (is_eeprom_enabled) {
is_eeprom_enabled = via_eeprom_is_valid(); is_eeprom_enabled = via_eeprom_is_valid();
} }
#endif #endif // VIA_ENABLE
return is_eeprom_enabled; return is_eeprom_enabled;
} }
/** \brief eeconfig is disabled
*
* FIXME: needs doc
*/
bool eeconfig_is_disabled(void) { bool eeconfig_is_disabled(void) {
bool is_eeprom_disabled = (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF); bool is_eeprom_disabled = nvm_eeconfig_is_disabled();
#ifdef VIA_ENABLE #ifdef VIA_ENABLE
if (!is_eeprom_disabled) { if (!is_eeprom_disabled) {
is_eeprom_disabled = !via_eeprom_is_valid(); is_eeprom_disabled = !via_eeprom_is_valid();
} }
#endif #endif // VIA_ENABLE
return is_eeprom_disabled; return is_eeprom_disabled;
} }
/** \brief eeconfig read debug void eeconfig_read_debug(debug_config_t *debug_config) {
* nvm_eeconfig_read_debug(debug_config);
* FIXME: needs doc
*/
uint8_t eeconfig_read_debug(void) {
return eeprom_read_byte(EECONFIG_DEBUG);
} }
/** \brief eeconfig update debug void eeconfig_update_debug(const debug_config_t *debug_config) {
* nvm_eeconfig_update_debug(debug_config);
* FIXME: needs doc
*/
void eeconfig_update_debug(uint8_t val) {
eeprom_update_byte(EECONFIG_DEBUG, val);
} }
/** \brief eeconfig read default layer
*
* FIXME: needs doc
*/
uint8_t eeconfig_read_default_layer(void) { 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) { 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 void eeconfig_read_keymap(keymap_config_t *keymap_config) {
* nvm_eeconfig_read_keymap(keymap_config);
* FIXME: needs doc
*/
uint16_t eeconfig_read_keymap(void) {
return eeprom_read_word(EECONFIG_KEYMAP);
} }
/** \brief eeconfig update keymap void eeconfig_update_keymap(const keymap_config_t *keymap_config) {
* nvm_eeconfig_update_keymap(keymap_config);
* FIXME: needs doc
*/
void eeconfig_update_keymap(uint16_t val) {
eeprom_update_word(EECONFIG_KEYMAP, val);
} }
/** \brief eeconfig read audio #ifdef AUDIO_ENABLE
* void eeconfig_read_audio(audio_config_t *audio_config) {
* FIXME: needs doc nvm_eeconfig_read_audio(audio_config);
*/
uint8_t eeconfig_read_audio(void) {
return eeprom_read_byte(EECONFIG_AUDIO);
} }
/** \brief eeconfig update audio void eeconfig_update_audio(const audio_config_t *audio_config) {
* nvm_eeconfig_update_audio(audio_config);
* FIXME: needs doc
*/
void eeconfig_update_audio(uint8_t val) {
eeprom_update_byte(EECONFIG_AUDIO, val);
} }
#endif // AUDIO_ENABLE
#ifdef UNICODE_COMMON_ENABLE
void eeconfig_read_unicode_mode(unicode_config_t *unicode_config) {
return nvm_eeconfig_read_unicode_mode(unicode_config);
}
void eeconfig_update_unicode_mode(const unicode_config_t *unicode_config) {
nvm_eeconfig_update_unicode_mode(unicode_config);
}
#endif // UNICODE_COMMON_ENABLE
#ifdef BACKLIGHT_ENABLE
void eeconfig_read_backlight(backlight_config_t *backlight_config) {
nvm_eeconfig_read_backlight(backlight_config);
}
void eeconfig_update_backlight(const backlight_config_t *backlight_config) {
nvm_eeconfig_update_backlight(backlight_config);
}
#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 #if (EECONFIG_KB_DATA_SIZE) == 0
/** \brief eeconfig read kb
*
* FIXME: needs doc
*/
uint32_t eeconfig_read_kb(void) { 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) { void eeconfig_update_kb(uint32_t val) {
eeprom_update_dword(EECONFIG_KEYBOARD, val); nvm_eeconfig_update_kb(val);
} }
#endif // (EECONFIG_KB_DATA_SIZE) == 0 #endif // (EECONFIG_KB_DATA_SIZE) == 0
#if (EECONFIG_USER_DATA_SIZE) == 0 #if (EECONFIG_USER_DATA_SIZE) == 0
/** \brief eeconfig read user
*
* FIXME: needs doc
*/
uint32_t eeconfig_read_user(void) { 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) { void eeconfig_update_user(uint32_t val) {
eeprom_update_dword(EECONFIG_USER, val); nvm_eeconfig_update_user(val);
} }
#endif // (EECONFIG_USER_DATA_SIZE) == 0 #endif // (EECONFIG_USER_DATA_SIZE) == 0
/** \brief eeconfig read haptic #ifdef HAPTIC_ENABLE
* void eeconfig_read_haptic(haptic_config_t *haptic_config) {
* FIXME: needs doc nvm_eeconfig_read_haptic(haptic_config);
*/
uint32_t eeconfig_read_haptic(void) {
return eeprom_read_dword(EECONFIG_HAPTIC);
} }
/** \brief eeconfig update haptic void eeconfig_update_haptic(const haptic_config_t *haptic_config) {
* nvm_eeconfig_update_haptic(haptic_config);
* FIXME: needs doc
*/
void eeconfig_update_haptic(uint32_t val) {
eeprom_update_dword(EECONFIG_HAPTIC, val);
} }
#endif // HAPTIC_ENABLE
/** \brief eeconfig read split handedness
*
* FIXME: needs doc
*/
bool eeconfig_read_handedness(void) { 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) { void eeconfig_update_handedness(bool val) {
eeprom_update_byte(EECONFIG_HANDEDNESS, !!val); nvm_eeconfig_update_handedness(val);
} }
#if (EECONFIG_KB_DATA_SIZE) > 0 #if (EECONFIG_KB_DATA_SIZE) > 0
/** \brief eeconfig assert keyboard data block version
*
* FIXME: needs doc
*/
bool eeconfig_is_kb_datablock_valid(void) { 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 uint32_t eeconfig_read_kb_datablock(void *data, uint32_t offset, uint32_t length) {
* return nvm_eeconfig_read_kb_datablock(data, offset, length);
* 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));
}
} }
/** \brief eeconfig update keyboard data block uint32_t eeconfig_update_kb_datablock(const void *data, uint32_t offset, uint32_t length) {
* return nvm_eeconfig_update_kb_datablock(data, offset, length);
* 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));
} }
/** \brief eeconfig init keyboard data block
*
* FIXME: needs doc
*/
__attribute__((weak)) void eeconfig_init_kb_datablock(void) { __attribute__((weak)) void eeconfig_init_kb_datablock(void) {
uint8_t dummy_kb[(EECONFIG_KB_DATA_SIZE)] = {0}; nvm_eeconfig_init_kb_datablock();
eeconfig_update_kb_datablock(dummy_kb);
} }
#endif // (EECONFIG_KB_DATA_SIZE) > 0 #endif // (EECONFIG_KB_DATA_SIZE) > 0
#if (EECONFIG_USER_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) { 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 uint32_t eeconfig_read_user_datablock(void *data, uint32_t offset, uint32_t length) {
* return nvm_eeconfig_read_user_datablock(data, offset, length);
* 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));
}
} }
/** \brief eeconfig update user data block uint32_t eeconfig_update_user_datablock(const void *data, uint32_t offset, uint32_t length) {
* return nvm_eeconfig_update_user_datablock(data, offset, length);
* 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));
} }
/** \brief eeconfig init user data block
*
* FIXME: needs doc
*/
__attribute__((weak)) void eeconfig_init_user_datablock(void) { __attribute__((weak)) void eeconfig_init_user_datablock(void) {
uint8_t dummy_user[(EECONFIG_USER_DATA_SIZE)] = {0}; nvm_eeconfig_init_user_datablock();
eeconfig_update_user_datablock(dummy_user);
} }
#endif // (EECONFIG_USER_DATA_SIZE) > 0 #endif // (EECONFIG_USER_DATA_SIZE) > 0

View File

@ -20,56 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> // offsetof #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
#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 // Size of EEPROM dedicated to keyboard- and user-specific data
#ifndef EECONFIG_KB_DATA_SIZE #ifndef EECONFIG_KB_DATA_SIZE
@ -85,12 +35,6 @@ typedef struct PACKED {
# define EECONFIG_USER_DATA_VERSION (EECONFIG_USER_DATA_SIZE) # define EECONFIG_USER_DATA_VERSION (EECONFIG_USER_DATA_SIZE)
#endif #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 */ /* debug bit */
#define EECONFIG_DEBUG_ENABLE (1 << 0) #define EECONFIG_DEBUG_ENABLE (1 << 0)
#define EECONFIG_DEBUG_MATRIX (1 << 1) #define EECONFIG_DEBUG_MATRIX (1 << 1)
@ -116,22 +60,59 @@ void eeconfig_init_kb(void);
void eeconfig_init_user(void); void eeconfig_init_user(void);
void eeconfig_enable(void); void eeconfig_enable(void);
void eeconfig_disable(void); void eeconfig_disable(void);
uint8_t eeconfig_read_debug(void); typedef union debug_config_t debug_config_t;
void eeconfig_update_debug(uint8_t val); void eeconfig_read_debug(debug_config_t *debug_config) __attribute__((nonnull));
void eeconfig_update_debug(const debug_config_t *debug_config) __attribute__((nonnull));
uint8_t eeconfig_read_default_layer(void); uint8_t eeconfig_read_default_layer(void);
void eeconfig_update_default_layer(uint8_t val); void eeconfig_update_default_layer(uint8_t val);
uint16_t eeconfig_read_keymap(void); typedef union keymap_config_t keymap_config_t;
void eeconfig_update_keymap(uint16_t val); 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 #ifdef AUDIO_ENABLE
uint8_t eeconfig_read_audio(void); typedef union audio_config_t audio_config_t;
void eeconfig_update_audio(uint8_t val); void eeconfig_read_audio(audio_config_t *audio_config) __attribute__((nonnull));
#endif 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 #if (EECONFIG_KB_DATA_SIZE) == 0
uint32_t eeconfig_read_kb(void); uint32_t eeconfig_read_kb(void);
@ -144,8 +125,9 @@ void eeconfig_update_user(uint32_t val);
#endif // (EECONFIG_USER_DATA_SIZE) == 0 #endif // (EECONFIG_USER_DATA_SIZE) == 0
#ifdef HAPTIC_ENABLE #ifdef HAPTIC_ENABLE
uint32_t eeconfig_read_haptic(void); typedef union haptic_config_t haptic_config_t;
void eeconfig_update_haptic(uint32_t val); void eeconfig_read_haptic(haptic_config_t *haptic_config) __attribute__((nonnull));
void eeconfig_update_haptic(const haptic_config_t *haptic_config) __attribute__((nonnull));
#endif #endif
bool eeconfig_read_handedness(void); bool eeconfig_read_handedness(void);
@ -153,22 +135,26 @@ void eeconfig_update_handedness(bool val);
#if (EECONFIG_KB_DATA_SIZE) > 0 #if (EECONFIG_KB_DATA_SIZE) > 0
bool eeconfig_is_kb_datablock_valid(void); bool eeconfig_is_kb_datablock_valid(void);
void eeconfig_read_kb_datablock(void *data); uint32_t eeconfig_read_kb_datablock(void *data, uint32_t offset, uint32_t length) __attribute__((nonnull));
void eeconfig_update_kb_datablock(const void *data); uint32_t eeconfig_update_kb_datablock(const void *data, uint32_t offset, uint32_t length) __attribute__((nonnull));
void eeconfig_init_kb_datablock(void); void eeconfig_init_kb_datablock(void);
# define eeconfig_read_kb_datablock_field(__object, __field) eeconfig_read_kb_datablock(&(__object.__field), offsetof(__object, __field), sizeof(__object.__field))
# define eeconfig_update_kb_datablock_field(__object, __field) eeconfig_update_kb_datablock(&(__object.__field), offsetof(__object, __field), sizeof(__object.__field))
#endif // (EECONFIG_KB_DATA_SIZE) > 0 #endif // (EECONFIG_KB_DATA_SIZE) > 0
#if (EECONFIG_USER_DATA_SIZE) > 0 #if (EECONFIG_USER_DATA_SIZE) > 0
bool eeconfig_is_user_datablock_valid(void); bool eeconfig_is_user_datablock_valid(void);
void eeconfig_read_user_datablock(void *data); uint32_t eeconfig_read_user_datablock(void *data, uint32_t offset, uint32_t length) __attribute__((nonnull));
void eeconfig_update_user_datablock(const void *data); uint32_t eeconfig_update_user_datablock(const void *data, uint32_t offset, uint32_t length) __attribute__((nonnull));
void eeconfig_init_user_datablock(void); 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 #endif // (EECONFIG_USER_DATA_SIZE) > 0
// Any "checked" debounce variant used requires implementation of: // Any "checked" debounce variant used requires implementation of:
// -- bool eeconfig_check_valid_##name(void) // -- bool eeconfig_check_valid_##name(void)
// -- void eeconfig_post_flush_##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; \ static uint8_t dirty_##name = false; \
\ \
bool eeconfig_check_valid_##name(void); \ bool eeconfig_check_valid_##name(void); \
@ -177,13 +163,13 @@ void eeconfig_init_user_datablock(void);
static inline void eeconfig_init_##name(void) { \ static inline void eeconfig_init_##name(void) { \
dirty_##name = true; \ dirty_##name = true; \
if (eeconfig_check_valid_##name()) { \ if (eeconfig_check_valid_##name()) { \
eeprom_read_block(&config, offset, sizeof(config)); \ eeconfig_read_##name(&config); \
dirty_##name = false; \ dirty_##name = false; \
} \ } \
} \ } \
static inline void eeconfig_flush_##name(bool force) { \ static inline void eeconfig_flush_##name(bool force) { \
if (force || dirty_##name) { \ if (force || dirty_##name) { \
eeprom_update_block(&config, offset, sizeof(config)); \ eeconfig_update_##name(&config); \
eeconfig_post_flush_##name(); \ eeconfig_post_flush_##name(); \
dirty_##name = false; \ dirty_##name = false; \
} \ } \
@ -205,8 +191,8 @@ void eeconfig_init_user_datablock(void);
} \ } \
} }
#define EECONFIG_DEBOUNCE_HELPER(name, offset, config) \ #define EECONFIG_DEBOUNCE_HELPER(name, config) \
EECONFIG_DEBOUNCE_HELPER_CHECKED(name, offset, config) \ EECONFIG_DEBOUNCE_HELPER_CHECKED(name, config) \
\ \
bool eeconfig_check_valid_##name(void) { \ bool eeconfig_check_valid_##name(void) { \
return true; \ return true; \

View File

@ -67,7 +67,7 @@ void haptic_init(void) {
if (!eeconfig_is_enabled()) { if (!eeconfig_is_enabled()) {
eeconfig_init(); eeconfig_init();
} }
haptic_config.raw = eeconfig_read_haptic(); eeconfig_read_haptic(&haptic_config);
#ifdef HAPTIC_SOLENOID #ifdef HAPTIC_SOLENOID
solenoid_set_dwell(haptic_config.dwell); solenoid_set_dwell(haptic_config.dwell);
#endif #endif
@ -122,13 +122,13 @@ void eeconfig_debug_haptic(void) {
void haptic_enable(void) { void haptic_enable(void) {
set_haptic_config_enable(true); set_haptic_config_enable(true);
dprintf("haptic_config.enable = %u\n", haptic_config.enable); dprintf("haptic_config.enable = %u\n", haptic_config.enable);
eeconfig_update_haptic(haptic_config.raw); eeconfig_update_haptic(&haptic_config);
} }
void haptic_disable(void) { void haptic_disable(void) {
set_haptic_config_enable(false); set_haptic_config_enable(false);
dprintf("haptic_config.enable = %u\n", haptic_config.enable); dprintf("haptic_config.enable = %u\n", haptic_config.enable);
eeconfig_update_haptic(haptic_config.raw); eeconfig_update_haptic(&haptic_config);
} }
void haptic_toggle(void) { void haptic_toggle(void) {
@ -137,14 +137,14 @@ void haptic_toggle(void) {
} else { } else {
haptic_enable(); haptic_enable();
} }
eeconfig_update_haptic(haptic_config.raw); eeconfig_update_haptic(&haptic_config);
} }
void haptic_feedback_toggle(void) { void haptic_feedback_toggle(void) {
haptic_config.feedback++; haptic_config.feedback++;
if (haptic_config.feedback >= HAPTIC_FEEDBACK_MAX) haptic_config.feedback = KEY_PRESS; if (haptic_config.feedback >= HAPTIC_FEEDBACK_MAX) haptic_config.feedback = KEY_PRESS;
dprintf("haptic_config.feedback = %u\n", !haptic_config.feedback); dprintf("haptic_config.feedback = %u\n", !haptic_config.feedback);
eeconfig_update_haptic(haptic_config.raw); eeconfig_update_haptic(&haptic_config);
} }
void haptic_buzz_toggle(void) { void haptic_buzz_toggle(void) {
@ -225,26 +225,26 @@ void haptic_reset(void) {
haptic_config.dwell = 0; haptic_config.dwell = 0;
haptic_config.buzz = 0; haptic_config.buzz = 0;
#endif #endif
eeconfig_update_haptic(haptic_config.raw); eeconfig_update_haptic(&haptic_config);
dprintf("haptic_config.feedback = %u\n", haptic_config.feedback); dprintf("haptic_config.feedback = %u\n", haptic_config.feedback);
dprintf("haptic_config.mode = %u\n", haptic_config.mode); dprintf("haptic_config.mode = %u\n", haptic_config.mode);
} }
void haptic_set_feedback(uint8_t feedback) { void haptic_set_feedback(uint8_t feedback) {
haptic_config.feedback = feedback; haptic_config.feedback = feedback;
eeconfig_update_haptic(haptic_config.raw); eeconfig_update_haptic(&haptic_config);
dprintf("haptic_config.feedback = %u\n", haptic_config.feedback); dprintf("haptic_config.feedback = %u\n", haptic_config.feedback);
} }
void haptic_set_mode(uint8_t mode) { void haptic_set_mode(uint8_t mode) {
haptic_config.mode = mode; haptic_config.mode = mode;
eeconfig_update_haptic(haptic_config.raw); eeconfig_update_haptic(&haptic_config);
dprintf("haptic_config.mode = %u\n", haptic_config.mode); dprintf("haptic_config.mode = %u\n", haptic_config.mode);
} }
void haptic_set_amplitude(uint8_t amp) { void haptic_set_amplitude(uint8_t amp) {
haptic_config.amplitude = amp; haptic_config.amplitude = amp;
eeconfig_update_haptic(haptic_config.raw); eeconfig_update_haptic(&haptic_config);
dprintf("haptic_config.amplitude = %u\n", haptic_config.amplitude); dprintf("haptic_config.amplitude = %u\n", haptic_config.amplitude);
#ifdef HAPTIC_DRV2605L #ifdef HAPTIC_DRV2605L
drv2605l_amplitude(amp); drv2605l_amplitude(amp);
@ -253,13 +253,13 @@ void haptic_set_amplitude(uint8_t amp) {
void haptic_set_buzz(uint8_t buzz) { void haptic_set_buzz(uint8_t buzz) {
haptic_config.buzz = buzz; haptic_config.buzz = buzz;
eeconfig_update_haptic(haptic_config.raw); eeconfig_update_haptic(&haptic_config);
dprintf("haptic_config.buzz = %u\n", haptic_config.buzz); dprintf("haptic_config.buzz = %u\n", haptic_config.buzz);
} }
void haptic_set_dwell(uint8_t dwell) { void haptic_set_dwell(uint8_t dwell) {
haptic_config.dwell = dwell; haptic_config.dwell = dwell;
eeconfig_update_haptic(haptic_config.raw); eeconfig_update_haptic(&haptic_config);
dprintf("haptic_config.dwell = %u\n", haptic_config.dwell); dprintf("haptic_config.dwell = %u\n", haptic_config.dwell);
} }
@ -291,7 +291,7 @@ uint8_t haptic_get_dwell(void) {
void haptic_enable_continuous(void) { void haptic_enable_continuous(void) {
haptic_config.cont = 1; haptic_config.cont = 1;
dprintf("haptic_config.cont = %u\n", haptic_config.cont); dprintf("haptic_config.cont = %u\n", haptic_config.cont);
eeconfig_update_haptic(haptic_config.raw); eeconfig_update_haptic(&haptic_config);
#ifdef HAPTIC_DRV2605L #ifdef HAPTIC_DRV2605L
drv2605l_rtp_init(); drv2605l_rtp_init();
#endif #endif
@ -300,7 +300,7 @@ void haptic_enable_continuous(void) {
void haptic_disable_continuous(void) { void haptic_disable_continuous(void) {
haptic_config.cont = 0; haptic_config.cont = 0;
dprintf("haptic_config.cont = %u\n", haptic_config.cont); dprintf("haptic_config.cont = %u\n", haptic_config.cont);
eeconfig_update_haptic(haptic_config.raw); eeconfig_update_haptic(&haptic_config);
#ifdef HAPTIC_DRV2605L #ifdef HAPTIC_DRV2605L
drv2605l_write(DRV2605L_REG_MODE, 0x00); drv2605l_write(DRV2605L_REG_MODE, 0x00);
#endif #endif

View File

@ -28,7 +28,7 @@
#endif #endif
/* EEPROM config settings */ /* EEPROM config settings */
typedef union { typedef union haptic_config_t {
uint32_t raw; uint32_t raw;
struct { struct {
bool enable : 1; bool enable : 1;

View File

@ -389,8 +389,8 @@ void quantum_init(void) {
} }
/* init globals */ /* init globals */
debug_config.raw = eeconfig_read_debug(); eeconfig_read_debug(&debug_config);
keymap_config.raw = eeconfig_read_keymap(); eeconfig_read_keymap(&keymap_config);
#ifdef BOOTMAGIC_ENABLE #ifdef BOOTMAGIC_ENABLE
bootmagic(); bootmagic();
@ -461,7 +461,7 @@ void keyboard_init(void) {
#endif #endif
#if defined(NKRO_ENABLE) && defined(FORCE_NKRO) #if defined(NKRO_ENABLE) && defined(FORCE_NKRO)
keymap_config.nkro = 1; keymap_config.nkro = 1;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
#endif #endif
#ifdef DIP_SWITCH_ENABLE #ifdef DIP_SWITCH_ENABLE
dip_switch_init(); dip_switch_init();

View File

@ -28,7 +28,7 @@ uint16_t keycode_config(uint16_t keycode);
uint8_t mod_config(uint8_t mod); uint8_t mod_config(uint8_t mod);
/* NOTE: Not portable. Bit field order depends on implementation */ /* NOTE: Not portable. Bit field order depends on implementation */
typedef union { typedef union keymap_config_t {
uint16_t raw; uint16_t raw;
struct { struct {
bool swap_control_capslock : 1; bool swap_control_capslock : 1;

View File

@ -86,9 +86,9 @@ static last_hit_t last_hit_buffer;
const uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT; const uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT;
#endif #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); 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_default(void);
void eeconfig_update_led_matrix(void); void eeconfig_force_flush_led_matrix(void);
void eeconfig_debug_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); uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i);

View File

@ -71,7 +71,7 @@ typedef struct PACKED {
uint8_t flags[LED_MATRIX_LED_COUNT]; uint8_t flags[LED_MATRIX_LED_COUNT];
} led_config_t; } led_config_t;
typedef union { typedef union led_eeconfig_t {
uint32_t raw; uint32_t raw;
struct PACKED { struct PACKED {
uint8_t enable : 2; uint8_t enable : 2;

View File

@ -28,7 +28,7 @@ extern "C" {
/* /*
* Debug output control * Debug output control
*/ */
typedef union { typedef union debug_config_t {
struct { struct {
bool enable : 1; bool enable : 1;
bool matrix : 1; bool matrix : 1;

View File

@ -0,0 +1,195 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#include "keycodes.h"
#include "eeprom.h"
#include "dynamic_keymap.h"
#include "nvm_dynamic_keymap.h"
#include "nvm_eeprom_eeconfig_internal.h"
#include "nvm_eeprom_via_internal.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef VIA_ENABLE
# include "via.h"
# define DYNAMIC_KEYMAP_EEPROM_START (VIA_EEPROM_CONFIG_END)
#else
# define DYNAMIC_KEYMAP_EEPROM_START (EECONFIG_SIZE)
#endif
#ifndef DYNAMIC_KEYMAP_EEPROM_MAX_ADDR
# define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR (TOTAL_EEPROM_BYTE_COUNT - 1)
#endif
#if DYNAMIC_KEYMAP_EEPROM_MAX_ADDR > (TOTAL_EEPROM_BYTE_COUNT - 1)
# pragma message STR(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) " > " STR((TOTAL_EEPROM_BYTE_COUNT - 1))
# error DYNAMIC_KEYMAP_EEPROM_MAX_ADDR is configured to use more space than what is available for the selected EEPROM driver
#endif
// Due to usage of uint16_t check for max 65535
#if DYNAMIC_KEYMAP_EEPROM_MAX_ADDR > 65535
# pragma message STR(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) " > 65535"
# error DYNAMIC_KEYMAP_EEPROM_MAX_ADDR must be less than 65536
#endif
// If DYNAMIC_KEYMAP_EEPROM_ADDR not explicitly defined in config.h,
#ifndef DYNAMIC_KEYMAP_EEPROM_ADDR
# define DYNAMIC_KEYMAP_EEPROM_ADDR DYNAMIC_KEYMAP_EEPROM_START
#endif
// Dynamic encoders starts after dynamic keymaps
#ifndef DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR
# define DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR (DYNAMIC_KEYMAP_EEPROM_ADDR + (DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2))
#endif
// Dynamic macro starts after dynamic encoders, but only when using ENCODER_MAP
#ifdef ENCODER_MAP_ENABLE
# ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR
# define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR (DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR + (DYNAMIC_KEYMAP_LAYER_COUNT * NUM_ENCODERS * 2 * 2))
# endif // DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR
#else // ENCODER_MAP_ENABLE
# ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR
# define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR (DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR)
# endif // DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR
#endif // ENCODER_MAP_ENABLE
// Sanity check that dynamic keymaps fit in available EEPROM
// If there's not 100 bytes available for macros, then something is wrong.
// The keyboard should override DYNAMIC_KEYMAP_LAYER_COUNT to reduce it,
// or DYNAMIC_KEYMAP_EEPROM_MAX_ADDR to increase it, *only if* the microcontroller has
// more than the default.
_Static_assert((DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) - (DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR) >= 100, "Dynamic keymaps are configured to use more EEPROM than is available.");
#ifndef TOTAL_EEPROM_BYTE_COUNT
# error Unknown total EEPROM size. Cannot derive maximum for dynamic keymaps.
#endif
// Dynamic macros are stored after the keymaps and use what is available
// up to and including DYNAMIC_KEYMAP_EEPROM_MAX_ADDR.
#ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE
# define DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE (DYNAMIC_KEYMAP_EEPROM_MAX_ADDR - DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + 1)
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void nvm_dynamic_keymap_erase(void) {
// No-op, nvm_eeconfig_erase() will have already erased EEPROM if necessary.
}
void nvm_dynamic_keymap_macro_erase(void) {
// No-op, nvm_eeconfig_erase() will have already erased EEPROM if necessary.
}
static inline void *dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t column) {
return ((void *)DYNAMIC_KEYMAP_EEPROM_ADDR) + (layer * MATRIX_ROWS * MATRIX_COLS * 2) + (row * MATRIX_COLS * 2) + (column * 2);
}
uint16_t nvm_dynamic_keymap_read_keycode(uint8_t layer, uint8_t row, uint8_t column) {
if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || row >= MATRIX_ROWS || column >= MATRIX_COLS) return KC_NO;
void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column);
// Big endian, so we can read/write EEPROM directly from host if we want
uint16_t keycode = eeprom_read_byte(address) << 8;
keycode |= eeprom_read_byte(address + 1);
return keycode;
}
void nvm_dynamic_keymap_update_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode) {
if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || row >= MATRIX_ROWS || column >= MATRIX_COLS) return;
void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column);
// Big endian, so we can read/write EEPROM directly from host if we want
eeprom_update_byte(address, (uint8_t)(keycode >> 8));
eeprom_update_byte(address + 1, (uint8_t)(keycode & 0xFF));
}
#ifdef ENCODER_MAP_ENABLE
static void *dynamic_keymap_encoder_to_eeprom_address(uint8_t layer, uint8_t encoder_id) {
return ((void *)DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR) + (layer * NUM_ENCODERS * 2 * 2) + (encoder_id * 2 * 2);
}
uint16_t nvm_dynamic_keymap_read_encoder(uint8_t layer, uint8_t encoder_id, bool clockwise) {
if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || encoder_id >= NUM_ENCODERS) return KC_NO;
void *address = dynamic_keymap_encoder_to_eeprom_address(layer, encoder_id);
// Big endian, so we can read/write EEPROM directly from host if we want
uint16_t keycode = ((uint16_t)eeprom_read_byte(address + (clockwise ? 0 : 2))) << 8;
keycode |= eeprom_read_byte(address + (clockwise ? 0 : 2) + 1);
return keycode;
}
void nvm_dynamic_keymap_update_encoder(uint8_t layer, uint8_t encoder_id, bool clockwise, uint16_t keycode) {
if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || encoder_id >= NUM_ENCODERS) return;
void *address = dynamic_keymap_encoder_to_eeprom_address(layer, encoder_id);
// Big endian, so we can read/write EEPROM directly from host if we want
eeprom_update_byte(address + (clockwise ? 0 : 2), (uint8_t)(keycode >> 8));
eeprom_update_byte(address + (clockwise ? 0 : 2) + 1, (uint8_t)(keycode & 0xFF));
}
#endif // ENCODER_MAP_ENABLE
void nvm_dynamic_keymap_read_buffer(uint32_t offset, uint32_t size, uint8_t *data) {
uint32_t dynamic_keymap_eeprom_size = DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2;
void * source = (void *)(uintptr_t)(DYNAMIC_KEYMAP_EEPROM_ADDR + offset);
uint8_t *target = data;
for (uint32_t i = 0; i < size; i++) {
if (offset + i < dynamic_keymap_eeprom_size) {
*target = eeprom_read_byte(source);
} else {
*target = 0x00;
}
source++;
target++;
}
}
void nvm_dynamic_keymap_update_buffer(uint32_t offset, uint32_t size, uint8_t *data) {
uint32_t dynamic_keymap_eeprom_size = DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2;
void * target = (void *)(uintptr_t)(DYNAMIC_KEYMAP_EEPROM_ADDR + offset);
uint8_t *source = data;
for (uint32_t i = 0; i < size; i++) {
if (offset + i < dynamic_keymap_eeprom_size) {
eeprom_update_byte(target, *source);
}
source++;
target++;
}
}
uint32_t nvm_dynamic_keymap_macro_size(void) {
return DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE;
}
void nvm_dynamic_keymap_macro_read_buffer(uint32_t offset, uint32_t size, uint8_t *data) {
void * source = (void *)(uintptr_t)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + offset);
uint8_t *target = data;
for (uint16_t i = 0; i < size; i++) {
if (offset + i < DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE) {
*target = eeprom_read_byte(source);
} else {
*target = 0x00;
}
source++;
target++;
}
}
void nvm_dynamic_keymap_macro_update_buffer(uint32_t offset, uint32_t size, uint8_t *data) {
void * target = (void *)(uintptr_t)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + offset);
uint8_t *source = data;
for (uint16_t i = 0; i < size; i++) {
if (offset + i < DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE) {
eeprom_update_byte(target, *source);
}
source++;
target++;
}
}
void nvm_dynamic_keymap_macro_reset(void) {
void * start = (void *)(uintptr_t)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR);
void * end = (void *)(uintptr_t)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE);
long remaining = end - start;
uint8_t dummy[16] = {0};
for (int i = 0; i < DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE; i += sizeof(dummy)) {
int this_loop = remaining < sizeof(dummy) ? remaining : sizeof(dummy);
eeprom_update_block(dummy, start, this_loop);
start += this_loop;
remaining -= this_loop;
}
}

View File

@ -0,0 +1,278 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#include <string.h>
#include "nvm_eeconfig.h"
#include "nvm_eeprom_eeconfig_internal.h"
#include "util.h"
#include "eeconfig.h"
#include "debug.h"
#include "eeprom.h"
#include "keycode_config.h"
#ifdef EEPROM_DRIVER
# include "eeprom_driver.h"
#endif
#ifdef AUDIO_ENABLE
# include "audio.h"
#endif
#ifdef BACKLIGHT_ENABLE
# include "backlight.h"
#endif
#ifdef RGBLIGHT_ENABLE
# include "rgblight.h"
#endif
#ifdef RGB_MATRIX_ENABLE
# include "rgb_matrix_types.h"
#endif
#ifdef LED_MATRIX_ENABLE
# include "led_matrix_types.h"
#endif
#ifdef UNICODE_COMMON_ENABLE
# include "unicode.h"
#endif
#ifdef HAPTIC_ENABLE
# include "haptic.h"
#endif
void nvm_eeconfig_erase(void) {
#ifdef EEPROM_DRIVER
eeprom_driver_format(false);
#endif // EEPROM_DRIVER
}
bool nvm_eeconfig_is_enabled(void) {
return eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER;
}
bool nvm_eeconfig_is_disabled(void) {
return eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF;
}
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);
}
void nvm_eeconfig_read_debug(debug_config_t *debug_config) {
debug_config->raw = eeprom_read_byte(EECONFIG_DEBUG);
}
void nvm_eeconfig_update_debug(const debug_config_t *debug_config) {
eeprom_update_byte(EECONFIG_DEBUG, debug_config->raw);
}
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);
}
void nvm_eeconfig_read_keymap(keymap_config_t *keymap_config) {
keymap_config->raw = eeprom_read_word(EECONFIG_KEYMAP);
}
void nvm_eeconfig_update_keymap(const keymap_config_t *keymap_config) {
eeprom_update_word(EECONFIG_KEYMAP, keymap_config->raw);
}
#ifdef AUDIO_ENABLE
void nvm_eeconfig_read_audio(audio_config_t *audio_config) {
audio_config->raw = eeprom_read_byte(EECONFIG_AUDIO);
}
void nvm_eeconfig_update_audio(const audio_config_t *audio_config) {
eeprom_update_byte(EECONFIG_AUDIO, audio_config->raw);
}
#endif // AUDIO_ENABLE
#ifdef UNICODE_COMMON_ENABLE
void nvm_eeconfig_read_unicode_mode(unicode_config_t *unicode_config) {
unicode_config->raw = eeprom_read_byte(EECONFIG_UNICODEMODE);
}
void nvm_eeconfig_update_unicode_mode(const unicode_config_t *unicode_config) {
eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config->raw);
}
#endif // UNICODE_COMMON_ENABLE
#ifdef BACKLIGHT_ENABLE
void nvm_eeconfig_read_backlight(backlight_config_t *backlight_config) {
backlight_config->raw = eeprom_read_byte(EECONFIG_BACKLIGHT);
}
void nvm_eeconfig_update_backlight(const backlight_config_t *backlight_config) {
eeprom_update_byte(EECONFIG_BACKLIGHT, backlight_config->raw);
}
#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
void nvm_eeconfig_read_haptic(haptic_config_t *haptic_config) {
haptic_config->raw = eeprom_read_dword(EECONFIG_HAPTIC);
}
void nvm_eeconfig_update_haptic(const haptic_config_t *haptic_config) {
eeprom_update_dword(EECONFIG_HAPTIC, haptic_config->raw);
}
#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);
}
uint32_t nvm_eeconfig_read_kb_datablock(void *data, uint32_t offset, uint32_t length) {
if (eeconfig_is_kb_datablock_valid()) {
void *ee_start = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK + offset);
void *ee_end = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK + MIN(EECONFIG_KB_DATA_SIZE, offset + length));
eeprom_read_block(data, ee_start, ee_end - ee_start);
return ee_end - ee_start;
} else {
memset(data, 0, length);
return length;
}
}
uint32_t nvm_eeconfig_update_kb_datablock(const void *data, uint32_t offset, uint32_t length) {
eeprom_update_dword(EECONFIG_KEYBOARD, (EECONFIG_KB_DATA_VERSION));
void *ee_start = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK + offset);
void *ee_end = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK + MIN(EECONFIG_KB_DATA_SIZE, offset + length));
eeprom_update_block(data, ee_start, ee_end - ee_start);
return ee_end - ee_start;
}
void nvm_eeconfig_init_kb_datablock(void) {
eeprom_update_dword(EECONFIG_KEYBOARD, (EECONFIG_KB_DATA_VERSION));
void * start = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK);
void * end = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK + EECONFIG_KB_DATA_SIZE);
long remaining = end - start;
uint8_t dummy[16] = {0};
for (int i = 0; i < EECONFIG_KB_DATA_SIZE; i += sizeof(dummy)) {
int this_loop = remaining < sizeof(dummy) ? remaining : sizeof(dummy);
eeprom_update_block(dummy, start, this_loop);
start += this_loop;
remaining -= this_loop;
}
}
#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);
}
uint32_t nvm_eeconfig_read_user_datablock(void *data, uint32_t offset, uint32_t length) {
if (eeconfig_is_user_datablock_valid()) {
void *ee_start = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK + offset);
void *ee_end = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK + MIN(EECONFIG_USER_DATA_SIZE, offset + length));
eeprom_read_block(data, ee_start, ee_end - ee_start);
return ee_end - ee_start;
} else {
memset(data, 0, length);
return length;
}
}
uint32_t nvm_eeconfig_update_user_datablock(const void *data, uint32_t offset, uint32_t length) {
eeprom_update_dword(EECONFIG_USER, (EECONFIG_USER_DATA_VERSION));
void *ee_start = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK + offset);
void *ee_end = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK + MIN(EECONFIG_USER_DATA_SIZE, offset + length));
eeprom_update_block(data, ee_start, ee_end - ee_start);
return ee_end - ee_start;
}
void nvm_eeconfig_init_user_datablock(void) {
eeprom_update_dword(EECONFIG_USER, (EECONFIG_USER_DATA_VERSION));
void * start = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK);
void * end = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK + EECONFIG_USER_DATA_SIZE);
long remaining = end - start;
uint8_t dummy[16] = {0};
for (int i = 0; i < EECONFIG_USER_DATA_SIZE; i += sizeof(dummy)) {
int this_loop = remaining < sizeof(dummy) ? remaining : sizeof(dummy);
eeprom_update_block(dummy, start, this_loop);
start += this_loop;
remaining -= this_loop;
}
}
#endif // (EECONFIG_USER_DATA_SIZE) > 0

View File

@ -0,0 +1,58 @@
// 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"
// 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,22 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
// 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)

View File

@ -0,0 +1,77 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#include "eeprom.h"
#include "util.h"
#include "via.h"
#include "nvm_via.h"
#include "nvm_eeprom_eeconfig_internal.h"
#include "nvm_eeprom_via_internal.h"
void nvm_via_erase(void) {
// No-op, nvm_eeconfig_erase() will have already erased EEPROM if necessary.
}
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));
eeprom_read_block(buf, ee_start, ee_end - ee_start);
return ee_end - ee_start;
#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));
eeprom_update_block(buf, ee_start, ee_end - ee_start);
return ee_end - ee_start;
#else
return 0;
#endif
}

View File

@ -0,0 +1,27 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <stdint.h>
#include <stdbool.h>
void nvm_dynamic_keymap_erase(void);
void nvm_dynamic_keymap_macro_erase(void);
uint16_t nvm_dynamic_keymap_read_keycode(uint8_t layer, uint8_t row, uint8_t column);
void nvm_dynamic_keymap_update_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode);
#ifdef ENCODER_MAP_ENABLE
uint16_t nvm_dynamic_keymap_read_encoder(uint8_t layer, uint8_t encoder_id, bool clockwise);
void nvm_dynamic_keymap_update_encoder(uint8_t layer, uint8_t encoder_id, bool clockwise, uint16_t keycode);
#endif // ENCODER_MAP_ENABLE
void nvm_dynamic_keymap_read_buffer(uint32_t offset, uint32_t size, uint8_t *data);
void nvm_dynamic_keymap_update_buffer(uint32_t offset, uint32_t size, uint8_t *data);
uint32_t nvm_dynamic_keymap_macro_size(void);
void nvm_dynamic_keymap_macro_read_buffer(uint32_t offset, uint32_t size, uint8_t *data);
void nvm_dynamic_keymap_macro_update_buffer(uint32_t offset, uint32_t size, uint8_t *data);
void nvm_dynamic_keymap_macro_reset(void);

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

@ -0,0 +1,104 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <stdint.h>
#include <stdbool.h>
#ifndef EECONFIG_MAGIC_NUMBER
# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEE3 // When changing, decrement this value to avoid future re-init issues
#endif
#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF
void nvm_eeconfig_erase(void);
bool nvm_eeconfig_is_enabled(void);
bool nvm_eeconfig_is_disabled(void);
void nvm_eeconfig_enable(void);
void nvm_eeconfig_disable(void);
typedef union debug_config_t debug_config_t;
void nvm_eeconfig_read_debug(debug_config_t *debug_config);
void nvm_eeconfig_update_debug(const debug_config_t *debug_config);
uint8_t nvm_eeconfig_read_default_layer(void);
void nvm_eeconfig_update_default_layer(uint8_t val);
typedef union keymap_config_t keymap_config_t;
void nvm_eeconfig_read_keymap(keymap_config_t *keymap_config);
void nvm_eeconfig_update_keymap(const keymap_config_t *keymap_config);
#ifdef AUDIO_ENABLE
typedef union audio_config_t audio_config_t;
void nvm_eeconfig_read_audio(audio_config_t *audio_config);
void nvm_eeconfig_update_audio(const audio_config_t *audio_config);
#endif // AUDIO_ENABLE
#ifdef UNICODE_COMMON_ENABLE
typedef union unicode_config_t unicode_config_t;
void nvm_eeconfig_read_unicode_mode(unicode_config_t *unicode_config);
void nvm_eeconfig_update_unicode_mode(const unicode_config_t *unicode_config);
#endif // UNICODE_COMMON_ENABLE
#ifdef BACKLIGHT_ENABLE
typedef union backlight_config_t backlight_config_t;
void nvm_eeconfig_read_backlight(backlight_config_t *backlight_config);
void nvm_eeconfig_update_backlight(const backlight_config_t *backlight_config);
#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
typedef union rgb_config_t rgb_config_t;
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
typedef union led_eeconfig_t led_eeconfig_t;
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
typedef union rgblight_config_t rgblight_config_t;
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
typedef union haptic_config_t haptic_config_t;
void nvm_eeconfig_read_haptic(haptic_config_t *haptic_config);
void nvm_eeconfig_update_haptic(const haptic_config_t *haptic_config);
#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);
uint32_t nvm_eeconfig_read_kb_datablock(void *data, uint32_t offset, uint32_t length);
uint32_t nvm_eeconfig_update_kb_datablock(const void *data, uint32_t offset, uint32_t length);
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);
uint32_t nvm_eeconfig_read_user_datablock(void *data, uint32_t offset, uint32_t length);
uint32_t nvm_eeconfig_update_user_datablock(const void *data, uint32_t offset, uint32_t length);
void nvm_eeconfig_init_user_datablock(void);
#endif // (EECONFIG_USER_DATA_SIZE) > 0

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

@ -0,0 +1,17 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <stdint.h>
#include <stdbool.h>
void nvm_via_erase(void);
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);

30
quantum/nvm/readme.md Normal file
View File

@ -0,0 +1,30 @@
# Non-volatile Memory - Data Repositories
This area is intentionally structured in the following way:
```
╰- quantum
╰- nvm
├- readme.md
├- rules.mk
|
├- nvm_eeconfig.h
├- nvm_<<system>>.h
|
├- eeprom
| ├- nvm_eeconfig.c
| ├- nvm_<<system>>.c
| ╰- ...
|
├- <<another provider>>
| ├- nvm_eeconfig.c
| ├- nvm_<<system>>.c
| ╰- ...
╰- ...
```
At the base `nvm` level, for every QMK core system which requires persistence there must be a corresponding `nvm_<<system>>.h` header file. This provides the data repository API to the "owner" system, and allows the underlying data persistence mechanism to be abstracted away from upper code. Any conversion to/from a `.raw` field should occur inside the `nvm_<<system>>.c` layer, with the API using values, such as structs or unions exposed to the rest of QMK.
Each `nvm` "provider" is a corresponding child directory consisting of its name, such as `eeprom`, and corresponding `nvm_<<system>>.c` implementation files which provide the concrete implementation of the upper `nvm_<<system>>.h`.
New systems requiring persistence can add the corresponding `nvm_<<system>>.h` file, and in most circumstances must also implement equivalent `nvm_<<system>>.c` files for every `nvm` provider. If persistence is not possible for that system, a `nvm_<<system>>.c` file with simple stubs which ignore writes and provide sane defaults must be used instead.

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

@ -0,0 +1,31 @@
# 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))","")
COMMON_VPATH += $(QUANTUM_DIR)/nvm/$(NVM_DRIVER_LOWER)
endif
QUANTUM_SRC += nvm_eeconfig.c
endif

View File

@ -43,6 +43,9 @@ void slave_update_detected_host_os(os_variant_t os);
#endif #endif
#ifdef OS_DETECTION_DEBUG_ENABLE #ifdef OS_DETECTION_DEBUG_ENABLE
# if defined(DYNAMIC_KEYMAP_ENABLE) || defined(VIA_ENABLE)
# error Cannot enable OS Detection debug mode simultaneously with DYNAMIC_KEYMAP or VIA
# endif
void print_stored_setups(void); void print_stored_setups(void);
void store_setups_in_eeprom(void); void store_setups_in_eeprom(void);
#endif #endif

View File

@ -38,7 +38,7 @@ bool autocorrect_is_enabled(void) {
*/ */
void autocorrect_enable(void) { void autocorrect_enable(void) {
keymap_config.autocorrect_enable = true; keymap_config.autocorrect_enable = true;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
/** /**
@ -48,7 +48,7 @@ void autocorrect_enable(void) {
void autocorrect_disable(void) { void autocorrect_disable(void) {
keymap_config.autocorrect_enable = false; keymap_config.autocorrect_enable = false;
typo_buffer_size = 0; typo_buffer_size = 0;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
/** /**
@ -58,7 +58,7 @@ void autocorrect_disable(void) {
void autocorrect_toggle(void) { void autocorrect_toggle(void) {
keymap_config.autocorrect_enable = !keymap_config.autocorrect_enable; keymap_config.autocorrect_enable = !keymap_config.autocorrect_enable;
typo_buffer_size = 0; typo_buffer_size = 0;
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
} }
/** /**

View File

@ -66,17 +66,17 @@ void clicky_freq_reset(void) {
void clicky_toggle(void) { void clicky_toggle(void) {
audio_config.clicky_enable ^= 1; audio_config.clicky_enable ^= 1;
eeconfig_update_audio(audio_config.raw); eeconfig_update_audio(&audio_config);
} }
void clicky_on(void) { void clicky_on(void) {
audio_config.clicky_enable = 1; audio_config.clicky_enable = 1;
eeconfig_update_audio(audio_config.raw); eeconfig_update_audio(&audio_config);
} }
void clicky_off(void) { void clicky_off(void) {
audio_config.clicky_enable = 0; audio_config.clicky_enable = 0;
eeconfig_update_audio(audio_config.raw); eeconfig_update_audio(&audio_config);
} }
bool is_clicky_on(void) { bool is_clicky_on(void) {

View File

@ -47,7 +47,7 @@ bool process_magic(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) { if (record->event.pressed) {
if (IS_MAGIC_KEYCODE(keycode)) { if (IS_MAGIC_KEYCODE(keycode)) {
/* keymap config */ /* keymap config */
keymap_config.raw = eeconfig_read_keymap(); eeconfig_read_keymap(&keymap_config);
switch (keycode) { switch (keycode) {
case QK_MAGIC_SWAP_CONTROL_CAPS_LOCK: case QK_MAGIC_SWAP_CONTROL_CAPS_LOCK:
keymap_config.swap_control_capslock = true; keymap_config.swap_control_capslock = true;
@ -187,7 +187,7 @@ bool process_magic(uint16_t keycode, keyrecord_t *record) {
break; break;
} }
eeconfig_update_keymap(keymap_config.raw); eeconfig_update_keymap(&keymap_config);
clear_keyboard(); // clear to prevent stuck keys clear_keyboard(); // clear to prevent stuck keys
return false; return false;

View File

@ -20,9 +20,6 @@
#ifdef VIRTSER_ENABLE #ifdef VIRTSER_ENABLE
# include "virtser.h" # include "virtser.h"
#endif #endif
#ifdef STENO_ENABLE_ALL
# include "eeprom.h"
#endif
// All steno keys that have been pressed to form this chord, // All steno keys that have been pressed to form this chord,
// stored in MAX_STROKE_SIZE groups of 8-bit arrays. // 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 #ifdef STENO_ENABLE_ALL
void steno_init(void) { void steno_init(void) {
mode = eeprom_read_byte(EECONFIG_STENOMODE); mode = eeconfig_read_steno_mode();
} }
void steno_set_mode(steno_mode_t new_mode) { void steno_set_mode(steno_mode_t new_mode) {
steno_clear_chord(); steno_clear_chord();
mode = new_mode; mode = new_mode;
eeprom_update_byte(EECONFIG_STENOMODE, mode); eeconfig_update_steno_mode(mode);
} }
#endif // STENO_ENABLE_ALL #endif // STENO_ENABLE_ALL

View File

@ -88,9 +88,9 @@ static last_hit_t last_hit_buffer;
const uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT; const uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT;
#endif #endif
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); 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_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_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); uint8_t rgb_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i);
@ -215,7 +215,7 @@ void rgb_matrix_set_flags_noeeprom(led_flags_t flags);
void rgb_matrix_update_pwm_buffers(void); void rgb_matrix_update_pwm_buffers(void);
#ifndef RGBLIGHT_ENABLE #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_reload_from_eeprom rgb_matrix_reload_from_eeprom
# define rgblight_toggle rgb_matrix_toggle # define rgblight_toggle rgb_matrix_toggle
# define rgblight_toggle_noeeprom rgb_matrix_toggle_noeeprom # define rgblight_toggle_noeeprom rgb_matrix_toggle_noeeprom

View File

@ -73,7 +73,7 @@ typedef struct PACKED {
uint8_t flags[RGB_MATRIX_LED_COUNT]; uint8_t flags[RGB_MATRIX_LED_COUNT];
} led_config_t; } led_config_t;
typedef union { typedef union rgb_config_t {
uint64_t raw; uint64_t raw;
struct PACKED { struct PACKED {
uint8_t enable : 2; uint8_t enable : 2;

View File

@ -24,9 +24,7 @@
#include "util.h" #include "util.h"
#include "led_tables.h" #include "led_tables.h"
#include <lib/lib8tion/lib8tion.h> #include <lib/lib8tion/lib8tion.h>
#ifdef EEPROM_ENABLE #include "eeconfig.h"
# include "eeprom.h"
#endif
#ifdef RGBLIGHT_SPLIT #ifdef RGBLIGHT_SPLIT
/* for split keyboard */ /* for split keyboard */
@ -176,24 +174,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) { 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) { void eeconfig_update_rgblight_default(void) {
@ -205,7 +188,7 @@ void eeconfig_update_rgblight_default(void) {
rgblight_config.val = RGBLIGHT_DEFAULT_VAL; rgblight_config.val = RGBLIGHT_DEFAULT_VAL;
rgblight_config.speed = RGBLIGHT_DEFAULT_SPD; rgblight_config.speed = RGBLIGHT_DEFAULT_SPD;
RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS; RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS;
eeconfig_update_rgblight(rgblight_config.raw); eeconfig_update_rgblight(&rgblight_config);
} }
void eeconfig_debug_rgblight(void) { void eeconfig_debug_rgblight(void) {
@ -228,12 +211,12 @@ void rgblight_init(void) {
} }
dprintf("rgblight_init start!\n"); dprintf("rgblight_init start!\n");
rgblight_config.raw = eeconfig_read_rgblight(); eeconfig_read_rgblight(&rgblight_config);
RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS; RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS;
if (!rgblight_config.mode) { if (!rgblight_config.mode) {
dprintf("rgblight_init rgblight_config.mode = 0. Write default values to EEPROM.\n"); dprintf("rgblight_init rgblight_config.mode = 0. Write default values to EEPROM.\n");
eeconfig_update_rgblight_default(); eeconfig_update_rgblight_default();
rgblight_config.raw = eeconfig_read_rgblight(); eeconfig_read_rgblight(&rgblight_config);
} }
rgblight_check_config(); rgblight_check_config();
@ -252,7 +235,7 @@ void rgblight_init(void) {
void rgblight_reload_from_eeprom(void) { void rgblight_reload_from_eeprom(void) {
/* Reset back to what we have in eeprom */ /* 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_SPLIT_SET_CHANGE_MODEHSVS;
rgblight_check_config(); rgblight_check_config();
eeconfig_debug_rgblight(); // display current eeprom values eeconfig_debug_rgblight(); // display current eeprom values
@ -341,7 +324,7 @@ void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
} }
RGBLIGHT_SPLIT_SET_CHANGE_MODE; RGBLIGHT_SPLIT_SET_CHANGE_MODE;
if (write_to_eeprom) { if (write_to_eeprom) {
eeconfig_update_rgblight(rgblight_config.raw); eeconfig_update_rgblight(&rgblight_config);
dprintf("rgblight mode [EEPROM]: %u\n", rgblight_config.mode); dprintf("rgblight mode [EEPROM]: %u\n", rgblight_config.mode);
} else { } else {
dprintf("rgblight mode [NOEEPROM]: %u\n", rgblight_config.mode); dprintf("rgblight mode [NOEEPROM]: %u\n", rgblight_config.mode);
@ -386,7 +369,7 @@ void rgblight_toggle_noeeprom(void) {
void rgblight_enable(void) { void rgblight_enable(void) {
rgblight_config.enable = 1; rgblight_config.enable = 1;
// No need to update EEPROM here. rgblight_mode() will do that, actually // 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); dprintf("rgblight enable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
rgblight_mode(rgblight_config.mode); rgblight_mode(rgblight_config.mode);
} }
@ -399,7 +382,7 @@ void rgblight_enable_noeeprom(void) {
void rgblight_disable(void) { void rgblight_disable(void) {
rgblight_config.enable = 0; 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); dprintf("rgblight disable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
rgblight_timer_disable(); rgblight_timer_disable();
RGBLIGHT_SPLIT_SET_CHANGE_MODE; RGBLIGHT_SPLIT_SET_CHANGE_MODE;
@ -487,7 +470,7 @@ void rgblight_increase_speed_helper(bool write_to_eeprom) {
if (rgblight_config.speed < 3) rgblight_config.speed++; if (rgblight_config.speed < 3) rgblight_config.speed++;
// RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED? // RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED?
if (write_to_eeprom) { if (write_to_eeprom) {
eeconfig_update_rgblight(rgblight_config.raw); eeconfig_update_rgblight(&rgblight_config);
} }
} }
void rgblight_increase_speed(void) { void rgblight_increase_speed(void) {
@ -501,7 +484,7 @@ void rgblight_decrease_speed_helper(bool write_to_eeprom) {
if (rgblight_config.speed > 0) rgblight_config.speed--; if (rgblight_config.speed > 0) rgblight_config.speed--;
// RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED?? // RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED??
if (write_to_eeprom) { if (write_to_eeprom) {
eeconfig_update_rgblight(rgblight_config.raw); eeconfig_update_rgblight(&rgblight_config);
} }
} }
void rgblight_decrease_speed(void) { void rgblight_decrease_speed(void) {
@ -585,7 +568,7 @@ void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool w
rgblight_config.sat = sat; rgblight_config.sat = sat;
rgblight_config.val = val; rgblight_config.val = val;
if (write_to_eeprom) { 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); dprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
} else { } else {
dprintf("rgblight set hsv [NOEEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); dprintf("rgblight set hsv [NOEEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
@ -608,7 +591,7 @@ uint8_t rgblight_get_speed(void) {
void rgblight_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) { void rgblight_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) {
rgblight_config.speed = speed; rgblight_config.speed = speed;
if (write_to_eeprom) { 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); dprintf("rgblight set speed [EEPROM]: %u\n", rgblight_config.speed);
} else { } else {
dprintf("rgblight set speed [NOEEPROM]: %u\n", rgblight_config.speed); dprintf("rgblight set speed [NOEEPROM]: %u\n", rgblight_config.speed);

View File

@ -168,7 +168,6 @@ enum RGBLIGHT_EFFECT_MODE {
#include <stdbool.h> #include <stdbool.h>
#include "rgblight_drivers.h" #include "rgblight_drivers.h"
#include "progmem.h" #include "progmem.h"
#include "eeconfig.h"
#include "color.h" #include "color.h"
#ifdef RGBLIGHT_LAYERS #ifdef RGBLIGHT_LAYERS
@ -248,7 +247,7 @@ extern const uint16_t RGBLED_RGBTEST_INTERVALS[1] PROGMEM;
extern const uint8_t RGBLED_TWINKLE_INTERVALS[3] PROGMEM; extern const uint8_t RGBLED_TWINKLE_INTERVALS[3] PROGMEM;
extern bool is_rgblight_initialized; extern bool is_rgblight_initialized;
typedef union { typedef union rgblight_config_t {
uint64_t raw; uint64_t raw;
struct { struct {
bool enable : 1; bool enable : 1;
@ -370,8 +369,6 @@ void rgblight_suspend(void);
void rgblight_wakeup(void); void rgblight_wakeup(void);
uint64_t rgblight_read_qword(void); uint64_t rgblight_read_qword(void);
void rgblight_update_qword(uint64_t qword); 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_current(void);
void eeconfig_update_rgblight_default(void); void eeconfig_update_rgblight_default(void);
void eeconfig_debug_rgblight(void); void eeconfig_debug_rgblight(void);

View File

@ -136,7 +136,7 @@ static void unicode_play_song(uint8_t mode) {
#endif #endif
void unicode_input_mode_init(void) { void unicode_input_mode_init(void) {
unicode_config.raw = eeprom_read_byte(EECONFIG_UNICODEMODE); eeconfig_read_unicode_mode(&unicode_config);
#if UNICODE_SELECTED_MODES != -1 #if UNICODE_SELECTED_MODES != -1
# if UNICODE_CYCLE_PERSIST # if UNICODE_CYCLE_PERSIST
// Find input_mode in selected modes // Find input_mode in selected modes
@ -165,7 +165,7 @@ uint8_t get_unicode_input_mode(void) {
} }
static void persist_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);
} }
void set_unicode_input_mode(uint8_t mode) { void set_unicode_input_mode(uint8_t mode) {

View File

@ -26,7 +26,7 @@
* \{ * \{
*/ */
typedef union { typedef union unicode_config_t {
uint8_t raw; uint8_t raw;
struct { struct {
uint8_t input_mode : 8; uint8_t input_mode : 8;

View File

@ -32,6 +32,7 @@
#include "timer.h" #include "timer.h"
#include "wait.h" #include "wait.h"
#include "version.h" // for QMK_BUILDDATE used in EEPROM magic #include "version.h" // for QMK_BUILDDATE used in EEPROM magic
#include "nvm_via.h"
#if defined(AUDIO_ENABLE) #if defined(AUDIO_ENABLE)
# include "audio.h" # 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 magic1 = ((p[5] & 0x0F) << 4) | (p[6] & 0x0F);
uint8_t magic2 = ((p[8] & 0x0F) << 4) | (p[9] & 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 // Sets VIA/keyboard level usage of EEPROM to valid/invalid
// Keyboard level code (eg. via_init_kb()) should not call this // Keyboard level code (eg. via_init_kb()) should not call this
void via_eeprom_set_valid(bool valid) { void via_eeprom_set_valid(bool valid) {
if (valid) {
char * p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54" char * p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54"
uint8_t magic0 = ((p[2] & 0x0F) << 4) | (p[3] & 0x0F); uint8_t magic0 = ((p[2] & 0x0F) << 4) | (p[3] & 0x0F);
uint8_t magic1 = ((p[5] & 0x0F) << 4) | (p[6] & 0x0F); uint8_t magic1 = ((p[5] & 0x0F) << 4) | (p[6] & 0x0F);
uint8_t magic2 = ((p[8] & 0x0F) << 4) | (p[9] & 0x0F); uint8_t magic2 = ((p[8] & 0x0F) << 4) | (p[9] & 0x0F);
nvm_via_update_magic(magic0, magic1, magic2);
eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 0, valid ? magic0 : 0xFF); } else {
eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 1, valid ? magic1 : 0xFF); nvm_via_update_magic(0xFF, 0xFF, 0xFF);
eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 2, valid ? magic2 : 0xFF); }
} }
// Override this at the keyboard code level to check // Override this at the keyboard code level to check
@ -104,6 +111,8 @@ void via_init(void) {
} }
void eeconfig_init_via(void) { void eeconfig_init_via(void) {
// Erase any NVM storage if necessary
nvm_via_erase();
// set the magic number to false, in case this gets interrupted // set the magic number to false, in case this gets interrupted
via_eeprom_set_valid(false); via_eeprom_set_valid(false);
// This resets the layout options // This resets the layout options
@ -119,30 +128,25 @@ void eeconfig_init_via(void) {
// This is generalized so the layout options EEPROM usage can be // This is generalized so the layout options EEPROM usage can be
// variable, between 1 and 4 bytes. // variable, between 1 and 4 bytes.
uint32_t via_get_layout_options(void) { uint32_t via_get_layout_options(void) {
uint32_t value = 0; return nvm_via_read_layout_options();
// 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;
} }
__attribute__((weak)) void via_set_layout_options_kb(uint32_t value) {} __attribute__((weak)) void via_set_layout_options_kb(uint32_t value) {}
void via_set_layout_options(uint32_t value) { void via_set_layout_options(uint32_t value) {
via_set_layout_options_kb(value); via_set_layout_options_kb(value);
// Start at the least significant byte nvm_via_update_layout_options(value);
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--;
}
} }
#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) #if defined(AUDIO_ENABLE)
float via_device_indication_song[][2] = SONG(STARTUP_SOUND); float via_device_indication_song[][2] = SONG(STARTUP_SOUND);
#endif // AUDIO_ENABLE #endif // AUDIO_ENABLE
@ -715,7 +719,7 @@ void via_qmk_rgb_matrix_set_value(uint8_t *data) {
} }
void via_qmk_rgb_matrix_save(void) { void via_qmk_rgb_matrix_save(void) {
eeconfig_update_rgb_matrix(); eeconfig_force_flush_rgb_matrix();
} }
#endif // RGB_MATRIX_ENABLE #endif // RGB_MATRIX_ENABLE
@ -794,7 +798,7 @@ void via_qmk_led_matrix_set_value(uint8_t *data) {
} }
void via_qmk_led_matrix_save(void) { void via_qmk_led_matrix_save(void) {
eeconfig_update_led_matrix(); eeconfig_force_flush_led_matrix();
} }
#endif // LED_MATRIX_ENABLE #endif // LED_MATRIX_ENABLE
@ -861,7 +865,7 @@ void via_qmk_audio_set_value(uint8_t *data) {
} }
void via_qmk_audio_save(void) { void via_qmk_audio_save(void) {
eeconfig_update_audio(audio_config.raw); eeconfig_update_audio(&audio_config);
} }
#endif // QMK_AUDIO_ENABLE #endif // QMK_AUDIO_ENABLE

View File

@ -16,21 +16,8 @@
#pragma once #pragma once
#include "eeconfig.h" // for EECONFIG_SIZE
#include "action.h" #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, // Changing the layout options size after release will invalidate EEPROM,
// but this is something that should be set correctly on initial implementation. // 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 ) // 1 byte is enough for most uses (i.e. 8 binary states, or 6 binary + 1 ternary/quaternary )
@ -46,17 +33,10 @@
# define VIA_EEPROM_LAYOUT_OPTIONS_DEFAULT 0x00000000 # define VIA_EEPROM_LAYOUT_OPTIONS_DEFAULT 0x00000000
#endif #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 #ifndef VIA_EEPROM_CUSTOM_CONFIG_SIZE
# define VIA_EEPROM_CUSTOM_CONFIG_SIZE 0 # define VIA_EEPROM_CUSTOM_CONFIG_SIZE 0
#endif #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, // This is changed only when the command IDs change,
// so VIA Configurator can detect compatible firmware. // so VIA Configurator can detect compatible firmware.
#define VIA_PROTOCOL_VERSION 0x000C #define VIA_PROTOCOL_VERSION 0x000C
@ -160,6 +140,11 @@ uint32_t via_get_layout_options(void);
void via_set_layout_options(uint32_t value); void via_set_layout_options(uint32_t value);
void via_set_layout_options_kb(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 // 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 // device becomes the active device being configured, on startup or switching
// between devices. // between devices.

View File

@ -45,7 +45,7 @@ void TestFixture::SetUpTestCase() {
// The following is enough to bootstrap the values set in main // The following is enough to bootstrap the values set in main
eeconfig_init_quantum(); eeconfig_init_quantum();
eeconfig_update_debug(debug_config.raw); eeconfig_update_debug(&debug_config);
TestDriver driver; TestDriver driver;
keyboard_init(); keyboard_init();