diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk index 86ced309029..40c27d6ade1 100644 --- a/builddefs/common_features.mk +++ b/builddefs/common_features.mk @@ -29,6 +29,8 @@ QUANTUM_SRC += \ $(QUANTUM_DIR)/logging/debug.c \ $(QUANTUM_DIR)/logging/sendchar.c \ +include $(QUANTUM_DIR)/nvm/rules.mk + VPATH += $(QUANTUM_DIR)/logging # Fall back to lib/printf if there is no platform provided print ifeq ("$(wildcard $(PLATFORM_PATH)/$(PLATFORM_KEY)/printf.mk)","") diff --git a/builddefs/generic_features.mk b/builddefs/generic_features.mk index f14f4408770..9f2bb3f917a 100644 --- a/builddefs/generic_features.mk +++ b/builddefs/generic_features.mk @@ -60,6 +60,7 @@ define HANDLE_GENERIC_FEATURE SRC += $$(wildcard $$(QUANTUM_DIR)/process_keycode/process_$2.c) SRC += $$(wildcard $$(QUANTUM_DIR)/$2/$2.c) SRC += $$(wildcard $$(QUANTUM_DIR)/$2.c) + SRC += $$(wildcard $$(QUANTUM_DIR)/nvm/$$(NVM_DRIVER_LOWER)/nvm_$2.c) VPATH += $$(wildcard $$(QUANTUM_DIR)/$2/) OPT_DEFS += -D$1_ENABLE endef diff --git a/drivers/eeprom/eeprom_transient.h b/drivers/eeprom/eeprom_transient.h index 687b8619fe5..0483fd58b9c 100644 --- a/drivers/eeprom/eeprom_transient.h +++ b/drivers/eeprom/eeprom_transient.h @@ -20,6 +20,6 @@ The size of the transient EEPROM buffer 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 #endif diff --git a/keyboards/akko/5087/5087.c b/keyboards/akko/5087/5087.c index 996f8c25850..27439c20ef7 100644 --- a/keyboards/akko/5087/5087.c +++ b/keyboards/akko/5087/5087.c @@ -164,7 +164,7 @@ bool process_record_kb(uint16_t keycode, keyrecord_t* record) { if (record->event.pressed) { set_single_persistent_default_layer(MAC_B); keymap_config.no_gui = 0; - eeconfig_update_keymap(keymap_config.raw); + eeconfig_update_keymap(&keymap_config); } return false; case QK_RGB_MATRIX_TOGGLE: diff --git a/keyboards/cannonkeys/lib/satisfaction75/satisfaction_core.c b/keyboards/cannonkeys/lib/satisfaction75/satisfaction_core.c index 6f76582e4b2..a410480d7d9 100644 --- a/keyboards/cannonkeys/lib/satisfaction75/satisfaction_core.c +++ b/keyboards/cannonkeys/lib/satisfaction75/satisfaction_core.c @@ -53,10 +53,26 @@ void board_init(void) { 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) { /* This is a workaround to some really weird behavior - Without this code, the OLED will turn on, but not when you initially plug the keyboard in. + Without this code, the OLED will turn on, but not when you initially plug the keyboard in. You have to manually trigger a user reset to get the OLED to initialize properly I'm not sure what the root cause is at this time, but this workaround fixes it. */ @@ -74,11 +90,11 @@ void keyboard_post_init_kb(void) { void custom_set_value(uint8_t *data) { uint8_t *value_id = &(data[0]); uint8_t *value_data = &(data[1]); - + switch ( *value_id ) { 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; } case id_oled_mode: @@ -92,7 +108,7 @@ void custom_set_value(uint8_t *data) { uint8_t index = value_data[0]; uint8_t enable = value_data[1]; enabled_encoder_modes = (enabled_encoder_modes & ~(1< #include +#include + #include "via.h" // only for EEPROM address #include "satisfaction_keycodes.h" -#define EEPROM_ENABLED_ENCODER_MODES (VIA_EEPROM_CUSTOM_CONFIG_ADDR) -#define EEPROM_DEFAULT_OLED (VIA_EEPROM_CUSTOM_CONFIG_ADDR+1) -#define EEPROM_CUSTOM_ENCODER (VIA_EEPROM_CUSTOM_CONFIG_ADDR+2) +#define EEPROM_ENABLED_ENCODER_MODES_OFFSET 0 +#define EEPROM_DEFAULT_OLED_OFFSET 1 +#define EEPROM_CUSTOM_ENCODER_OFFSET 2 enum s75_keyboard_value_id { id_encoder_modes = 1, @@ -94,3 +96,6 @@ void oled_request_repaint(void); bool oled_task_needs_to_repaint(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); diff --git a/keyboards/cannonkeys/lib/satisfaction75/satisfaction_encoder.c b/keyboards/cannonkeys/lib/satisfaction75/satisfaction_encoder.c index 7e0b82e9e7a..87ff87ea66d 100644 --- a/keyboards/cannonkeys/lib/satisfaction75/satisfaction_encoder.c +++ b/keyboards/cannonkeys/lib/satisfaction75/satisfaction_encoder.c @@ -215,10 +215,13 @@ uint16_t handle_encoder_press(void){ uint16_t retrieve_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior){ #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 - uint16_t keycode = eeprom_read_byte(addr) << 8; - keycode |= eeprom_read_byte(addr + 1); + uint8_t hi, lo; + read_custom_config(&hi, offset+0, 1); + read_custom_config(&lo, offset+1, 1); + uint16_t keycode = hi << 8; + keycode |= lo; return keycode; #else 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){ #ifdef DYNAMIC_KEYMAP_ENABLE - void* addr = (void*)(EEPROM_CUSTOM_ENCODER + (encoder_idx * 6) + (behavior * 2)); - eeprom_update_byte(addr, (uint8_t)(new_code >> 8)); - eeprom_update_byte(addr + 1, (uint8_t)(new_code & 0xFF)); + uint32_t offset = EEPROM_CUSTOM_ENCODER_OFFSET + (encoder_idx * 6) + (behavior * 2); + uint8_t hi = new_code >> 8; + uint8_t lo = new_code & 0xFF; + write_custom_config(&hi, offset+0, 1); + write_custom_config(&lo, offset+1, 1); #endif } diff --git a/keyboards/cannonkeys/lib/satisfaction75/satisfaction_oled.c b/keyboards/cannonkeys/lib/satisfaction75/satisfaction_oled.c index 0361453c52b..815e84901df 100644 --- a/keyboards/cannonkeys/lib/satisfaction75/satisfaction_oled.c +++ b/keyboards/cannonkeys/lib/satisfaction75/satisfaction_oled.c @@ -8,7 +8,6 @@ #include "matrix.h" #include "led.h" #include "host.h" -#include "oled_driver.h" #include "progmem.h" #include @@ -16,6 +15,7 @@ void draw_default(void); void draw_clock(void); #ifdef OLED_ENABLE +#include "oled_driver.h" oled_rotation_t oled_init_kb(oled_rotation_t rotation) { return OLED_ROTATION_0; } diff --git a/keyboards/cannonkeys/satisfaction75/config.h b/keyboards/cannonkeys/satisfaction75/config.h index 969206b19a3..28bc6b286a6 100644 --- a/keyboards/cannonkeys/satisfaction75/config.h +++ b/keyboards/cannonkeys/satisfaction75/config.h @@ -42,4 +42,7 @@ // 6 for 3x custom encoder settings, left, right, and press (18 bytes) #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 diff --git a/keyboards/cannonkeys/satisfaction75_hs/config.h b/keyboards/cannonkeys/satisfaction75_hs/config.h index 658babd3c08..26c3e4080c4 100644 --- a/keyboards/cannonkeys/satisfaction75_hs/config.h +++ b/keyboards/cannonkeys/satisfaction75_hs/config.h @@ -40,5 +40,10 @@ // 6 for 3x custom encoder settings, left, right, and press (18 bytes) #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 #define VIA_CUSTOM_LIGHTING_ENABLE diff --git a/keyboards/cipulot/common/ec_board.c b/keyboards/cipulot/common/ec_board.c index 0ccb9f6d3c3..b15543e49e8 100644 --- a/keyboards/cipulot/common/ec_board.c +++ b/keyboards/cipulot/common/ec_board.c @@ -36,7 +36,7 @@ void eeconfig_init_kb(void) { } } // 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(); } @@ -44,7 +44,7 @@ void eeconfig_init_kb(void) { // On Keyboard startup void keyboard_post_init_kb(void) { // 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 ec_config.actuation_mode = eeprom_ec_config.actuation_mode; diff --git a/keyboards/cipulot/common/eeprom_tools.h b/keyboards/cipulot/common/eeprom_tools.h deleted file mode 100644 index b3c90d87592..00000000000 --- a/keyboards/cipulot/common/eeprom_tools.h +++ /dev/null @@ -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 . - */ -#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 diff --git a/keyboards/cipulot/common/via_ec.c b/keyboards/cipulot/common/via_ec.c index ed34a579b22..0bd04809d57 100644 --- a/keyboards/cipulot/common/via_ec.c +++ b/keyboards/cipulot/common/via_ec.c @@ -73,7 +73,7 @@ void via_config_set_value(uint8_t *data) { uprintf("# Actuation Mode: Rapid Trigger #\n"); uprintf("#################################\n"); } - EEPROM_KB_PARTIAL_UPDATE(eeprom_ec_config, actuation_mode); + eeconfig_update_kb_datablock_field(eeprom_ec_config, actuation_mode); break; } 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(4); } - eeconfig_update_kb_datablock(&eeprom_ec_config); + eeconfig_update_kb_datablock(&eeprom_ec_config, 0, EECONFIG_KB_DATA_SIZE); uprintf("####################################\n"); uprintf("# New thresholds applied and saved #\n"); uprintf("####################################\n"); @@ -321,7 +321,7 @@ void ec_save_bottoming_reading(void) { ec_rescale_values(2); ec_rescale_values(3); 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 diff --git a/keyboards/cipulot/ec_980c/ec_980c.c b/keyboards/cipulot/ec_980c/ec_980c.c index eaa636ede6a..7a2062a4e48 100644 --- a/keyboards/cipulot/ec_980c/ec_980c.c +++ b/keyboards/cipulot/ec_980c/ec_980c.c @@ -44,7 +44,7 @@ void eeconfig_init_kb(void) { } } // 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(); } @@ -52,7 +52,7 @@ void eeconfig_init_kb(void) { // On Keyboard startup void keyboard_post_init_kb(void) { // 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 ec_config.actuation_mode = eeprom_ec_config.actuation_mode; diff --git a/keyboards/cipulot/ec_typek/ec_typek.c b/keyboards/cipulot/ec_typek/ec_typek.c index d4241f66f1e..31616afc02b 100644 --- a/keyboards/cipulot/ec_typek/ec_typek.c +++ b/keyboards/cipulot/ec_typek/ec_typek.c @@ -44,7 +44,7 @@ void eeconfig_init_kb(void) { } } // 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(); } @@ -52,7 +52,7 @@ void eeconfig_init_kb(void) { // On Keyboard startup void keyboard_post_init_kb(void) { // 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 ec_config.actuation_mode = eeprom_ec_config.actuation_mode; diff --git a/keyboards/contra/keymaps/default/keymap.c b/keyboards/contra/keymaps/default/keymap.c index 29f98033d61..06e96caafad 100644 --- a/keyboards/contra/keymaps/default/keymap.c +++ b/keyboards/contra/keymaps/default/keymap.c @@ -240,9 +240,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (!eeconfig_is_enabled()) { eeconfig_init(); } - keymap_config.raw = eeconfig_read_keymap(); + eeconfig_read_keymap(&keymap_config); keymap_config.nkro = 1; - eeconfig_update_keymap(keymap_config.raw); + eeconfig_update_keymap(&keymap_config); } return false; break; diff --git a/keyboards/dm9records/plaid/keymaps/default/keymap.c b/keyboards/dm9records/plaid/keymaps/default/keymap.c index 2b366f49309..42b5a297559 100644 --- a/keyboards/dm9records/plaid/keymaps/default/keymap.c +++ b/keyboards/dm9records/plaid/keymaps/default/keymap.c @@ -329,9 +329,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (!eeconfig_is_enabled()) { eeconfig_init(); } - keymap_config.raw = eeconfig_read_keymap(); + eeconfig_read_keymap(&keymap_config); keymap_config.nkro = 1; - eeconfig_update_keymap(keymap_config.raw); + eeconfig_update_keymap(&keymap_config); } return false; break; diff --git a/keyboards/handwired/ortho_brass/keymaps/default/keymap.c b/keyboards/handwired/ortho_brass/keymaps/default/keymap.c index d5ab0ba3985..e4690385c9e 100644 --- a/keyboards/handwired/ortho_brass/keymaps/default/keymap.c +++ b/keyboards/handwired/ortho_brass/keymaps/default/keymap.c @@ -199,9 +199,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (!eeconfig_is_enabled()) { eeconfig_init(); } - keymap_config.raw = eeconfig_read_keymap(); + eeconfig_read_keymap(&keymap_config); keymap_config.nkro = 1; - eeconfig_update_keymap(keymap_config.raw); + eeconfig_update_keymap(&keymap_config); } return false; break; diff --git a/keyboards/helix/rev2/rev2.c b/keyboards/helix/rev2/rev2.c index ded22bbe933..7502ad0552f 100644 --- a/keyboards/helix/rev2/rev2.c +++ b/keyboards/helix/rev2/rev2.c @@ -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 */ 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) { diff --git a/keyboards/helix/rev3_4rows/rev3_4rows.c b/keyboards/helix/rev3_4rows/rev3_4rows.c index ff61027a961..7f655b6852d 100644 --- a/keyboards/helix/rev3_4rows/rev3_4rows.c +++ b/keyboards/helix/rev3_4rows/rev3_4rows.c @@ -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 */ 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 diff --git a/keyboards/helix/rev3_5rows/rev3_5rows.c b/keyboards/helix/rev3_5rows/rev3_5rows.c index 28fa314a7ba..af7276a2b52 100644 --- a/keyboards/helix/rev3_5rows/rev3_5rows.c +++ b/keyboards/helix/rev3_5rows/rev3_5rows.c @@ -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 */ 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 diff --git a/keyboards/horrortroll/nyx/rev1/lib/startup_swirl_anim.h b/keyboards/horrortroll/nyx/rev1/lib/startup_swirl_anim.h index f26f07fe12f..87e2e813a4b 100644 --- a/keyboards/horrortroll/nyx/rev1/lib/startup_swirl_anim.h +++ b/keyboards/horrortroll/nyx/rev1/lib/startup_swirl_anim.h @@ -18,6 +18,7 @@ #include #include #include +#include "eeconfig.h" #define LED_TRAIL 10 @@ -105,7 +106,7 @@ static void swirl_set_color(hsv_t hsv) { traverse_matrix(); if (!(top <= bottom && left <= right)) { - eeprom_read_block(&rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_matrix_config)); + eeconfig_read_rgb_matrix(&rgb_matrix_config); rgb_matrix_mode_noeeprom(rgb_matrix_config.mode); return; } diff --git a/keyboards/inland/kb83/kb83.c b/keyboards/inland/kb83/kb83.c index 1052131a915..41a3ad8df72 100644 --- a/keyboards/inland/kb83/kb83.c +++ b/keyboards/inland/kb83/kb83.c @@ -317,7 +317,7 @@ bool dip_switch_update_kb(uint8_t index, bool active) { } if(active){ keymap_config.no_gui = 0; - eeconfig_update_keymap(keymap_config.raw); + eeconfig_update_keymap(&keymap_config); } return true; } diff --git a/keyboards/jian/keymaps/advanced/keymap.c b/keyboards/jian/keymaps/advanced/keymap.c index eaf57cdd78d..e3e58a0e9f2 100644 --- a/keyboards/jian/keymaps/advanced/keymap.c +++ b/keyboards/jian/keymaps/advanced/keymap.c @@ -472,9 +472,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (!eeconfig_is_enabled()) { eeconfig_init(); } - keymap_config.raw = eeconfig_read_keymap(); + eeconfig_read_keymap(&keymap_config); keymap_config.nkro = 1; - eeconfig_update_keymap(keymap_config.raw); + eeconfig_update_keymap(&keymap_config); } return false; case EXT_PLV: diff --git a/keyboards/monsgeek/m1/m1.c b/keyboards/monsgeek/m1/m1.c index 60479ab8017..2f7365e5622 100644 --- a/keyboards/monsgeek/m1/m1.c +++ b/keyboards/monsgeek/m1/m1.c @@ -190,7 +190,7 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) { set_single_persistent_default_layer(MAC_B); layer_state_set(1<event.pressed) { set_single_persistent_default_layer(MAC_B); keymap_config.no_gui = 0; - eeconfig_update_keymap(keymap_config.raw); + eeconfig_update_keymap(&keymap_config); } return false; case GU_TOGG: diff --git a/keyboards/omnikeyish/dynamic_macro.c b/keyboards/omnikeyish/dynamic_macro.c index b990a09a133..99b6d173b88 100644 --- a/keyboards/omnikeyish/dynamic_macro.c +++ b/keyboards/omnikeyish/dynamic_macro.c @@ -1,5 +1,6 @@ #include "omnikeyish.h" #include +#include "eeprom.h" dynamic_macro_t dynamic_macros[DYNAMIC_MACRO_COUNT]; diff --git a/keyboards/planck/keymaps/default/keymap.c b/keyboards/planck/keymaps/default/keymap.c index a1ad5c65d66..0a2bd220c6c 100644 --- a/keyboards/planck/keymaps/default/keymap.c +++ b/keyboards/planck/keymaps/default/keymap.c @@ -233,9 +233,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (!eeconfig_is_enabled()) { eeconfig_init(); } - keymap_config.raw = eeconfig_read_keymap(); + eeconfig_read_keymap(&keymap_config); keymap_config.nkro = 1; - eeconfig_update_keymap(keymap_config.raw); + eeconfig_update_keymap(&keymap_config); } return false; break; diff --git a/keyboards/planck/rev7/keymaps/default/keymap.c b/keyboards/planck/rev7/keymaps/default/keymap.c index 85f5097332c..385ae1089d7 100644 --- a/keyboards/planck/rev7/keymaps/default/keymap.c +++ b/keyboards/planck/rev7/keymaps/default/keymap.c @@ -270,9 +270,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (!eeconfig_is_enabled()) { eeconfig_init(); } - keymap_config.raw = eeconfig_read_keymap(); + eeconfig_read_keymap(&keymap_config); keymap_config.nkro = 1; - eeconfig_update_keymap(keymap_config.raw); + eeconfig_update_keymap(&keymap_config); } return false; break; diff --git a/keyboards/rocketboard_16/keycode_lookup.c b/keyboards/rocketboard_16/keycode_lookup.c index 41fd5c8537d..a29808d04d0 100644 --- a/keyboards/rocketboard_16/keycode_lookup.c +++ b/keyboards/rocketboard_16/keycode_lookup.c @@ -14,6 +14,7 @@ * along with this program. If not, see . */ +#include #include "keycode_lookup.h" #include "quantum_keycodes.h" #include "keymap_us.h" diff --git a/keyboards/splitography/keymaps/default/keymap.c b/keyboards/splitography/keymaps/default/keymap.c index 9c6c7d6b26e..5d26eb96825 100644 --- a/keyboards/splitography/keymaps/default/keymap.c +++ b/keyboards/splitography/keymaps/default/keymap.c @@ -214,9 +214,9 @@ void plover(keyrecord_t *record) { if (!eeconfig_is_enabled()) { eeconfig_init(); } - keymap_config.raw = eeconfig_read_keymap(); + eeconfig_read_keymap(&keymap_config); keymap_config.nkro = 1; - eeconfig_update_keymap(keymap_config.raw); + eeconfig_update_keymap(&keymap_config); } } diff --git a/keyboards/splitography/keymaps/default_with_ctl_shft_alt_switched/keymap.c b/keyboards/splitography/keymaps/default_with_ctl_shft_alt_switched/keymap.c index 787f448ffbe..a3cb1837589 100644 --- a/keyboards/splitography/keymaps/default_with_ctl_shft_alt_switched/keymap.c +++ b/keyboards/splitography/keymaps/default_with_ctl_shft_alt_switched/keymap.c @@ -214,9 +214,9 @@ void plover(keyrecord_t *record) { if (!eeconfig_is_enabled()) { eeconfig_init(); } - keymap_config.raw = eeconfig_read_keymap(); + eeconfig_read_keymap(&keymap_config); keymap_config.nkro = 1; - eeconfig_update_keymap(keymap_config.raw); + eeconfig_update_keymap(&keymap_config); } } diff --git a/keyboards/splitography/keymaps/dvorak/keymap.c b/keyboards/splitography/keymaps/dvorak/keymap.c index 992cfd0abb0..0edec7043c8 100644 --- a/keyboards/splitography/keymaps/dvorak/keymap.c +++ b/keyboards/splitography/keymaps/dvorak/keymap.c @@ -214,9 +214,9 @@ void plover(keyrecord_t *record) { if (!eeconfig_is_enabled()) { eeconfig_init(); } - keymap_config.raw = eeconfig_read_keymap(); + eeconfig_read_keymap(&keymap_config); keymap_config.nkro = 1; - eeconfig_update_keymap(keymap_config.raw); + eeconfig_update_keymap(&keymap_config); } } diff --git a/keyboards/system76/launch_1/launch_1.c b/keyboards/system76/launch_1/launch_1.c index c9af479bf59..c01fb7b01d1 100644 --- a/keyboards/system76/launch_1/launch_1.c +++ b/keyboards/system76/launch_1/launch_1.c @@ -16,6 +16,7 @@ */ #include "quantum.h" +#include "eeprom.h" #include "usb_mux.h" @@ -73,7 +74,7 @@ led_config_t g_led_config = { { } }; #endif // RGB_MATRIX_ENABLE -bool eeprom_is_valid(void) { +bool eeprom_is_valid(void) { return ( eeprom_read_word(((void *)EEPROM_MAGIC_ADDR)) == EEPROM_MAGIC && eeprom_read_byte(((void *)EEPROM_VERSION_ADDR)) == EEPROM_VERSION diff --git a/keyboards/vitamins_included/rev2/rev2.c b/keyboards/vitamins_included/rev2/rev2.c index e445a3da456..28bd73cc75a 100644 --- a/keyboards/vitamins_included/rev2/rev2.c +++ b/keyboards/vitamins_included/rev2/rev2.c @@ -12,7 +12,7 @@ bool is_keyboard_left(void) { gpio_set_pin_input(SPLIT_HAND_PIN); return x; #elif defined(EE_HANDS) - return eeprom_read_byte(EECONFIG_HANDEDNESS); + return eeconfig_read_handedness(); #endif return is_keyboard_master(); diff --git a/keyboards/wilba_tech/wt_main.c b/keyboards/wilba_tech/wt_main.c index 92c43c794da..7e56d98356c 100644 --- a/keyboards/wilba_tech/wt_main.c +++ b/keyboards/wilba_tech/wt_main.c @@ -33,7 +33,7 @@ // Called from via_init() if 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) // and also firmware build date (from via_eeprom_is_valid()) @@ -64,11 +64,9 @@ void via_init_kb(void) void matrix_init_kb(void) { // If VIA is disabled, we still need to load backlight settings. - // Call via_init_kb() the same way as via_init(), with setting - // EEPROM valid afterwards. + // Call via_init_kb() the same way as via_init_kb() does. #ifndef VIA_ENABLE - via_init_kb(); - via_eeprom_set_valid(true); + wt_main_init(); #endif // VIA_ENABLE 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 // for an intermittent compiler error for Atmel compiler. #ifdef VIA_ENABLE +void via_init_kb(void) { + wt_main_init(); +} + void via_custom_value_command_kb(uint8_t *data, uint8_t length) { uint8_t *command_id = &(data[0]); uint8_t *channel_id = &(data[1]); @@ -159,50 +161,3 @@ void via_set_device_indication(uint8_t value) } #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 diff --git a/keyboards/wilba_tech/wt_mono_backlight.c b/keyboards/wilba_tech/wt_mono_backlight.c index 01fefc8ecc1..8359aab1350 100644 --- a/keyboards/wilba_tech/wt_mono_backlight.c +++ b/keyboards/wilba_tech/wt_mono_backlight.c @@ -25,6 +25,8 @@ #include "progmem.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 #define MONO_BACKLIGHT_CONFIG_EEPROM_ADDR (VIA_EEPROM_CUSTOM_CONFIG_ADDR) diff --git a/keyboards/wilba_tech/wt_rgb_backlight.c b/keyboards/wilba_tech/wt_rgb_backlight.c index e52d002060a..744bcb262d3 100644 --- a/keyboards/wilba_tech/wt_rgb_backlight.c +++ b/keyboards/wilba_tech/wt_rgb_backlight.c @@ -66,6 +66,8 @@ #include "quantum/color.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 #define RGB_BACKLIGHT_CONFIG_EEPROM_ADDR (VIA_EEPROM_CUSTOM_CONFIG_ADDR) diff --git a/keyboards/xelus/la_plus/rgb_matrix_kb.inc b/keyboards/xelus/la_plus/rgb_matrix_kb.inc index 88dd2ab0a2f..93d52ec9d0c 100644 --- a/keyboards/xelus/la_plus/rgb_matrix_kb.inc +++ b/keyboards/xelus/la_plus/rgb_matrix_kb.inc @@ -31,7 +31,7 @@ static void startup_animation_setleds(effect_params_t* params, bool dots) { } else if (num == 0 || num == 1 || num == 2) { return; } 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); return; } diff --git a/quantum/action_util.c b/quantum/action_util.c index c0dc4f38228..9fe17f2124b 100644 --- a/quantum/action_util.c +++ b/quantum/action_util.c @@ -220,7 +220,7 @@ bool is_oneshot_layer_active(void) { void oneshot_set(bool active) { if (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); dprintf("Oneshot: active: %d\n", active); } diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index b2611c5f099..d61af17ad6a 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -149,14 +149,14 @@ void audio_driver_start(void) { } void eeconfig_update_audio_current(void) { - eeconfig_update_audio(audio_config.raw); + eeconfig_update_audio(&audio_config); } void eeconfig_update_audio_default(void) { audio_config.valid = true; audio_config.enable = AUDIO_DEFAULT_ON; audio_config.clicky_enable = AUDIO_DEFAULT_CLICKY_ON; - eeconfig_update_audio(audio_config.raw); + eeconfig_update_audio(&audio_config); } void audio_init(void) { @@ -164,7 +164,7 @@ void audio_init(void) { return; } - audio_config.raw = eeconfig_read_audio(); + eeconfig_read_audio(&audio_config); if (!audio_config.valid) { dprintf("audio_init audio_config.valid = 0. Write default values to EEPROM.\n"); eeconfig_update_audio_default(); @@ -196,7 +196,7 @@ void audio_toggle(void) { stop_all_notes(); } audio_config.enable ^= 1; - eeconfig_update_audio(audio_config.raw); + eeconfig_update_audio(&audio_config); if (audio_config.enable) { audio_on_user(); } else { @@ -206,7 +206,7 @@ void audio_toggle(void) { void audio_on(void) { audio_config.enable = 1; - eeconfig_update_audio(audio_config.raw); + eeconfig_update_audio(&audio_config); audio_on_user(); PLAY_SONG(audio_on_song); } @@ -217,7 +217,7 @@ void audio_off(void) { wait_ms(100); audio_stop_all(); audio_config.enable = 0; - eeconfig_update_audio(audio_config.raw); + eeconfig_update_audio(&audio_config); } bool audio_is_on(void) { diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 054331d6f33..93dc6f62b14 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -28,7 +28,7 @@ # include "audio_dac.h" #endif -typedef union { +typedef union audio_config_t { uint8_t raw; struct { bool enable : 1; diff --git a/quantum/backlight/backlight.c b/quantum/backlight/backlight.c index eb64dd71e8c..a7d2a45a515 100644 --- a/quantum/backlight/backlight.c +++ b/quantum/backlight/backlight.c @@ -16,7 +16,6 @@ along with this program. If not, see . */ #include "backlight.h" -#include "eeprom.h" #include "eeconfig.h" #include "debug.h" @@ -55,7 +54,7 @@ static void backlight_check_config(void) { * FIXME: needs doc */ void backlight_init(void) { - backlight_config.raw = eeconfig_read_backlight(); + eeconfig_read_backlight(&backlight_config); if (!backlight_config.valid) { dprintf("backlight_init backlight_config.valid = 0. Write default values to EEPROM.\n"); eeconfig_update_backlight_default(); @@ -74,7 +73,7 @@ void backlight_increase(void) { backlight_config.level++; } backlight_config.enable = 1; - eeconfig_update_backlight(backlight_config.raw); + eeconfig_update_backlight(&backlight_config); dprintf("backlight increase: %u\n", backlight_config.level); backlight_set(backlight_config.level); } @@ -87,7 +86,7 @@ void backlight_decrease(void) { if (backlight_config.level > 0) { 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); backlight_set(backlight_config.level); @@ -116,7 +115,7 @@ void backlight_enable(void) { backlight_config.enable = true; if (backlight_config.raw == 1) // enabled but level == 0 backlight_config.level = 1; - eeconfig_update_backlight(backlight_config.raw); + eeconfig_update_backlight(&backlight_config); dprintf("backlight enable\n"); 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 backlight_config.enable = false; - eeconfig_update_backlight(backlight_config.raw); + eeconfig_update_backlight(&backlight_config); dprintf("backlight disable\n"); backlight_set(0); } @@ -152,7 +151,7 @@ void backlight_step(void) { backlight_config.level = 0; } 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); backlight_set(backlight_config.level); } @@ -173,19 +172,11 @@ void backlight_level_noeeprom(uint8_t level) { */ void backlight_level(uint8_t level) { backlight_level_noeeprom(level); - eeconfig_update_backlight(backlight_config.raw); -} - -uint8_t eeconfig_read_backlight(void) { - return eeprom_read_byte(EECONFIG_BACKLIGHT); -} - -void eeconfig_update_backlight(uint8_t val) { - eeprom_update_byte(EECONFIG_BACKLIGHT, val); + eeconfig_update_backlight(&backlight_config); } void eeconfig_update_backlight_current(void) { - eeconfig_update_backlight(backlight_config.raw); + eeconfig_update_backlight(&backlight_config); } void eeconfig_update_backlight_default(void) { @@ -193,7 +184,7 @@ void eeconfig_update_backlight_default(void) { backlight_config.enable = BACKLIGHT_DEFAULT_ON; backlight_config.breathing = BACKLIGHT_DEFAULT_BREATHING; backlight_config.level = BACKLIGHT_DEFAULT_LEVEL; - eeconfig_update_backlight(backlight_config.raw); + eeconfig_update_backlight(&backlight_config); } /** \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 backlight_config.breathing = true; - eeconfig_update_backlight(backlight_config.raw); + eeconfig_update_backlight(&backlight_config); dprintf("backlight breathing enable\n"); breathing_enable(); } @@ -239,7 +230,7 @@ void backlight_disable_breathing(void) { if (!backlight_config.breathing) return; // do nothing if breathing is already off backlight_config.breathing = false; - eeconfig_update_backlight(backlight_config.raw); + eeconfig_update_backlight(&backlight_config); dprintf("backlight breathing disable\n"); breathing_disable(); } diff --git a/quantum/backlight/backlight.h b/quantum/backlight/backlight.h index c34fb5858d1..561c7f8a945 100644 --- a/quantum/backlight/backlight.h +++ b/quantum/backlight/backlight.h @@ -34,7 +34,7 @@ along with this program. If not, see . # define BREATHING_PERIOD 6 #endif -typedef union { +typedef union backlight_config_t { uint8_t raw; struct { bool enable : 1; @@ -58,10 +58,8 @@ void backlight_level_noeeprom(uint8_t level); void backlight_level(uint8_t level); 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_default(void); +void eeconfig_update_backlight_current(void); +void eeconfig_update_backlight_default(void); // implementation specific void backlight_init_ports(void); diff --git a/quantum/command.c b/quantum/command.c index 024d96917d7..96b637f8425 100644 --- a/quantum/command.c +++ b/quantum/command.c @@ -246,7 +246,7 @@ static void print_eeconfig(void) { xprintf("eeconfig:\ndefault_layer: %u\n", eeconfig_read_default_layer()); debug_config_t dc; - dc.raw = eeconfig_read_debug(); + eeconfig_read_debug(&dc); xprintf(/* clang-format off */ "debug_config.raw: %02X\n" @@ -263,7 +263,7 @@ static void print_eeconfig(void) { ); /* clang-format on */ keymap_config_t kc; - kc.raw = eeconfig_read_keymap(); + eeconfig_read_keymap(&kc); xprintf(/* clang-format off */ "keymap_config.raw: %02X\n" @@ -296,7 +296,7 @@ static void print_eeconfig(void) { # ifdef BACKLIGHT_ENABLE backlight_config_t bc; - bc.raw = eeconfig_read_backlight(); + eeconfig_read_backlight(&bc); xprintf(/* clang-format off */ "backlight_config" diff --git a/quantum/dynamic_keymap.c b/quantum/dynamic_keymap.c index 3c22bbd4457..537c31098d3 100644 --- a/quantum/dynamic_keymap.c +++ b/quantum/dynamic_keymap.c @@ -21,14 +21,7 @@ #include "progmem.h" #include "send_string.h" #include "keycodes.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 +#include "nvm_dynamic_keymap.h" #ifdef ENCODER_ENABLE # include "encoder.h" @@ -36,67 +29,6 @@ # define NUM_ENCODERS 0 #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 # define DYNAMIC_KEYMAP_MACRO_DELAY TAP_CODE_DELAY #endif @@ -105,52 +37,28 @@ uint8_t dynamic_keymap_get_layer_count(void) { 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) { - 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; + return nvm_dynamic_keymap_read_keycode(layer, row, column); } 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; - 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)); + nvm_dynamic_keymap_update_keycode(layer, row, column, keycode); } #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) { - 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; + return nvm_dynamic_keymap_read_encoder(layer, encoder_id, clockwise); } 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; - 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)); + nvm_dynamic_keymap_update_encoder(layer, encoder_id, clockwise, keycode); } #endif // ENCODER_MAP_ENABLE void dynamic_keymap_reset(void) { + // Erase the keymaps, if necessary. + nvm_dynamic_keymap_erase(); + // Reset the keymaps in EEPROM to what is in flash. for (int layer = 0; layer < DYNAMIC_KEYMAP_LAYER_COUNT; layer++) { 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) { - uint16_t dynamic_keymap_eeprom_size = DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2; - 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++; - } + nvm_dynamic_keymap_read_buffer(offset, size, 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; - 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++; - } + nvm_dynamic_keymap_update_buffer(offset, size, data); } 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) { - 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 * source = (void *)(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++; - } + nvm_dynamic_keymap_macro_read_buffer(offset, size, 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); - 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++; - } + nvm_dynamic_keymap_macro_update_buffer(offset, size, data); } void dynamic_keymap_macro_reset(void) { - void *p = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR); - void *end = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE); - while (p != end) { - eeprom_update_byte(p, 0); - ++p; - } + // Erase the macros, if necessary. + nvm_dynamic_keymap_macro_erase(); + nvm_dynamic_keymap_macro_reset(); +} + +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) { @@ -263,25 +136,24 @@ void dynamic_keymap_macro_send(uint8_t id) { // If it's not zero, then we are in the middle // of buffer writing, possibly an aborted buffer // write. So do nothing. - void *p = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE - 1); - if (eeprom_read_byte(p) != 0) { + if (dynamic_keymap_read_byte(nvm_dynamic_keymap_macro_size() - 1) != 0) { return; } // Skip N null characters // p will then point to the Nth macro - p = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR); - void *end = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE); + uint32_t offset = 0; + uint32_t end = nvm_dynamic_keymap_macro_size(); while (id > 0) { // If we are past the end of the buffer, then there is // no Nth macro in the buffer. - if (p == end) { + if (offset == end) { return; } - if (eeprom_read_byte(p) == 0) { + if (dynamic_keymap_read_byte(offset) == 0) { --id; } - ++p; + ++offset; } // 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 // the buffer, so this cannot go past the end while (1) { - data[0] = eeprom_read_byte(p++); + data[0] = dynamic_keymap_read_byte(offset++); data[1] = 0; // Stop at the null terminator of this macro string if (data[0] == 0) { @@ -297,14 +169,14 @@ void dynamic_keymap_macro_send(uint8_t id) { } if (data[0] == SS_QMK_PREFIX) { // Get the code - data[1] = eeprom_read_byte(p++); + data[1] = dynamic_keymap_read_byte(offset++); // Unexpected null, abort. if (data[1] == 0) { return; } if (data[1] == SS_TAP_CODE || data[1] == SS_DOWN_CODE || data[1] == SS_UP_CODE) { // Get the keycode - data[2] = eeprom_read_byte(p++); + data[2] = dynamic_keymap_read_byte(offset++); // Unexpected null, abort. if (data[2] == 0) { return; @@ -316,7 +188,7 @@ void dynamic_keymap_macro_send(uint8_t id) { // At most this is 4 digits plus '|' uint8_t i = 2; while (1) { - data[i] = eeprom_read_byte(p++); + data[i] = dynamic_keymap_read_byte(offset++); // Unexpected null, abort if (data[i] == 0) { return; diff --git a/quantum/dynamic_keymap.h b/quantum/dynamic_keymap.h index 806342efa3c..f1d8077b127 100644 --- a/quantum/dynamic_keymap.h +++ b/quantum/dynamic_keymap.h @@ -18,8 +18,15 @@ #include #include +#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); -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); void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode); #ifdef ENCODER_MAP_ENABLE diff --git a/quantum/eeconfig.c b/quantum/eeconfig.c index ffbbf43a95c..848139d16cd 100644 --- a/quantum/eeconfig.c +++ b/quantum/eeconfig.c @@ -1,340 +1,333 @@ #include #include #include +#include "debug.h" #include "eeprom.h" #include "eeconfig.h" #include "action_layer.h" +#include "nvm_eeconfig.h" +#include "keycode_config.h" -#if defined(EEPROM_DRIVER) +#ifdef EEPROM_DRIVER # 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" -#endif +#endif // HAPTIC_ENABLE -#if defined(VIA_ENABLE) +#ifdef VIA_ENABLE bool via_eeprom_is_valid(void); void via_eeprom_set_valid(bool valid); void eeconfig_init_via(void); -#endif +#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) { #if (EECONFIG_USER_DATA_SIZE) == 0 // Reset user EEPROM value to blank, rather than to a set value eeconfig_update_user(0); -#endif +#endif // (EECONFIG_USER_DATA_SIZE) == 0 } __attribute__((weak)) void eeconfig_init_kb(void) { #if (EECONFIG_KB_DATA_SIZE) == 0 // Reset Keyboard EEPROM value to blank, rather than to a set value eeconfig_update_kb(0); -#endif +#endif // (EECONFIG_KB_DATA_SIZE) == 0 eeconfig_init_user(); } -/* - * FIXME: needs doc - */ void eeconfig_init_quantum(void) { -#if defined(EEPROM_DRIVER) - eeprom_driver_format(false); + nvm_eeconfig_erase(); + + 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 - eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); - eeprom_update_byte(EECONFIG_DEBUG, 0); - default_layer_state = (layer_state_t)1 << 0; - eeprom_update_byte(EECONFIG_DEFAULT_LAYER, default_layer_state); - // Enable oneshot and autocorrect by default: 0b0001 0100 0000 0000 - eeprom_update_word(EECONFIG_KEYMAP, 0x1400); - eeprom_update_byte(EECONFIG_BACKLIGHT, 0); - eeprom_update_byte(EECONFIG_AUDIO, 0); - eeprom_update_dword(EECONFIG_RGBLIGHT, 0); - eeprom_update_byte(EECONFIG_RGBLIGHT_EXTENDED, 0); - eeprom_update_byte(EECONFIG_UNICODEMODE, 0); - eeprom_update_byte(EECONFIG_STENOMODE, 0); - eeprom_write_qword(EECONFIG_RGB_MATRIX, 0); - eeprom_update_dword(EECONFIG_HAPTIC, 0); -#if defined(HAPTIC_ENABLE) +#ifdef LED_MATRIX_ENABLE + led_eeconfig_t led_matrix_config = {0}; + eeconfig_update_led_matrix(&led_matrix_config); +#endif // LED_MATRIX_ENABLE + +#ifdef HAPTIC_ENABLE + haptic_config_t haptic_config = {0}; + eeconfig_update_haptic(&haptic_config); haptic_reset(); -#endif +#endif // HAPTIC_ENABLE #if (EECONFIG_KB_DATA_SIZE) > 0 eeconfig_init_kb_datablock(); -#endif +#endif // (EECONFIG_KB_DATA_SIZE) > 0 #if (EECONFIG_USER_DATA_SIZE) > 0 eeconfig_init_user_datablock(); -#endif +#endif // (EECONFIG_USER_DATA_SIZE) > 0 #if defined(VIA_ENABLE) // Invalidate VIA eeprom config, and then reset. - // 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. - via_eeprom_set_valid(false); eeconfig_init_via(); +#elif defined(DYNAMIC_KEYMAP_ENABLE) + dynamic_keymap_reset(); #endif eeconfig_init_kb(); } -/** \brief eeconfig initialization - * - * FIXME: needs doc - */ void eeconfig_init(void) { eeconfig_init_quantum(); } -/** \brief eeconfig enable - * - * FIXME: needs doc - */ void eeconfig_enable(void) { - eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); + nvm_eeconfig_enable(); } -/** \brief eeconfig disable - * - * FIXME: needs doc - */ void eeconfig_disable(void) { -#if defined(EEPROM_DRIVER) - eeprom_driver_format(false); -#endif - eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF); + nvm_eeconfig_disable(); } -/** \brief eeconfig is enabled - * - * FIXME: needs doc - */ bool eeconfig_is_enabled(void) { - bool is_eeprom_enabled = (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER); + bool is_eeprom_enabled = nvm_eeconfig_is_enabled(); #ifdef VIA_ENABLE if (is_eeprom_enabled) { is_eeprom_enabled = via_eeprom_is_valid(); } -#endif +#endif // VIA_ENABLE return is_eeprom_enabled; } -/** \brief eeconfig is disabled - * - * FIXME: needs doc - */ bool eeconfig_is_disabled(void) { - bool is_eeprom_disabled = (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF); + bool is_eeprom_disabled = nvm_eeconfig_is_disabled(); #ifdef VIA_ENABLE if (!is_eeprom_disabled) { is_eeprom_disabled = !via_eeprom_is_valid(); } -#endif +#endif // VIA_ENABLE return is_eeprom_disabled; } -/** \brief eeconfig read debug - * - * FIXME: needs doc - */ -uint8_t eeconfig_read_debug(void) { - return eeprom_read_byte(EECONFIG_DEBUG); +void eeconfig_read_debug(debug_config_t *debug_config) { + nvm_eeconfig_read_debug(debug_config); } -/** \brief eeconfig update debug - * - * FIXME: needs doc - */ -void eeconfig_update_debug(uint8_t val) { - eeprom_update_byte(EECONFIG_DEBUG, val); +void eeconfig_update_debug(const debug_config_t *debug_config) { + nvm_eeconfig_update_debug(debug_config); } -/** \brief eeconfig read default layer - * - * FIXME: needs doc - */ uint8_t eeconfig_read_default_layer(void) { - return eeprom_read_byte(EECONFIG_DEFAULT_LAYER); + return nvm_eeconfig_read_default_layer(); } -/** \brief eeconfig update default layer - * - * FIXME: needs doc - */ void eeconfig_update_default_layer(uint8_t val) { - eeprom_update_byte(EECONFIG_DEFAULT_LAYER, val); + nvm_eeconfig_update_default_layer(val); } -/** \brief eeconfig read keymap - * - * FIXME: needs doc - */ -uint16_t eeconfig_read_keymap(void) { - return eeprom_read_word(EECONFIG_KEYMAP); +void eeconfig_read_keymap(keymap_config_t *keymap_config) { + nvm_eeconfig_read_keymap(keymap_config); } -/** \brief eeconfig update keymap - * - * FIXME: needs doc - */ -void eeconfig_update_keymap(uint16_t val) { - eeprom_update_word(EECONFIG_KEYMAP, val); +void eeconfig_update_keymap(const keymap_config_t *keymap_config) { + nvm_eeconfig_update_keymap(keymap_config); } -/** \brief eeconfig read audio - * - * FIXME: needs doc - */ -uint8_t eeconfig_read_audio(void) { - return eeprom_read_byte(EECONFIG_AUDIO); +#ifdef AUDIO_ENABLE +void eeconfig_read_audio(audio_config_t *audio_config) { + nvm_eeconfig_read_audio(audio_config); } -/** \brief eeconfig update audio - * - * FIXME: needs doc - */ -void eeconfig_update_audio(uint8_t val) { - eeprom_update_byte(EECONFIG_AUDIO, val); +void eeconfig_update_audio(const audio_config_t *audio_config) { + nvm_eeconfig_update_audio(audio_config); } +#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 -/** \brief eeconfig read kb - * - * FIXME: needs doc - */ uint32_t eeconfig_read_kb(void) { - return eeprom_read_dword(EECONFIG_KEYBOARD); + return nvm_eeconfig_read_kb(); } -/** \brief eeconfig update kb - * - * FIXME: needs doc - */ void eeconfig_update_kb(uint32_t val) { - eeprom_update_dword(EECONFIG_KEYBOARD, val); + nvm_eeconfig_update_kb(val); } #endif // (EECONFIG_KB_DATA_SIZE) == 0 #if (EECONFIG_USER_DATA_SIZE) == 0 -/** \brief eeconfig read user - * - * FIXME: needs doc - */ uint32_t eeconfig_read_user(void) { - return eeprom_read_dword(EECONFIG_USER); + return nvm_eeconfig_read_user(); } -/** \brief eeconfig update user - * - * FIXME: needs doc - */ void eeconfig_update_user(uint32_t val) { - eeprom_update_dword(EECONFIG_USER, val); + nvm_eeconfig_update_user(val); } #endif // (EECONFIG_USER_DATA_SIZE) == 0 -/** \brief eeconfig read haptic - * - * FIXME: needs doc - */ -uint32_t eeconfig_read_haptic(void) { - return eeprom_read_dword(EECONFIG_HAPTIC); +#ifdef HAPTIC_ENABLE +void eeconfig_read_haptic(haptic_config_t *haptic_config) { + nvm_eeconfig_read_haptic(haptic_config); } -/** \brief eeconfig update haptic - * - * FIXME: needs doc - */ -void eeconfig_update_haptic(uint32_t val) { - eeprom_update_dword(EECONFIG_HAPTIC, val); +void eeconfig_update_haptic(const haptic_config_t *haptic_config) { + nvm_eeconfig_update_haptic(haptic_config); } +#endif // HAPTIC_ENABLE -/** \brief eeconfig read split handedness - * - * FIXME: needs doc - */ bool eeconfig_read_handedness(void) { - return !!eeprom_read_byte(EECONFIG_HANDEDNESS); + return nvm_eeconfig_read_handedness(); } -/** \brief eeconfig update split handedness - * - * FIXME: needs doc - */ void eeconfig_update_handedness(bool val) { - eeprom_update_byte(EECONFIG_HANDEDNESS, !!val); + nvm_eeconfig_update_handedness(val); } #if (EECONFIG_KB_DATA_SIZE) > 0 -/** \brief eeconfig assert keyboard data block version - * - * FIXME: needs doc - */ bool eeconfig_is_kb_datablock_valid(void) { - return eeprom_read_dword(EECONFIG_KEYBOARD) == (EECONFIG_KB_DATA_VERSION); + return nvm_eeconfig_is_kb_datablock_valid(); } -/** \brief eeconfig read keyboard data block - * - * FIXME: needs doc - */ -void eeconfig_read_kb_datablock(void *data) { - if (eeconfig_is_kb_datablock_valid()) { - eeprom_read_block(data, EECONFIG_KB_DATABLOCK, (EECONFIG_KB_DATA_SIZE)); - } else { - memset(data, 0, (EECONFIG_KB_DATA_SIZE)); - } +uint32_t eeconfig_read_kb_datablock(void *data, uint32_t offset, uint32_t length) { + return nvm_eeconfig_read_kb_datablock(data, offset, length); } -/** \brief eeconfig update keyboard data block - * - * FIXME: needs doc - */ -void eeconfig_update_kb_datablock(const void *data) { - eeprom_update_dword(EECONFIG_KEYBOARD, (EECONFIG_KB_DATA_VERSION)); - eeprom_update_block(data, EECONFIG_KB_DATABLOCK, (EECONFIG_KB_DATA_SIZE)); +uint32_t eeconfig_update_kb_datablock(const void *data, uint32_t offset, uint32_t length) { + return nvm_eeconfig_update_kb_datablock(data, offset, length); } -/** \brief eeconfig init keyboard data block - * - * FIXME: needs doc - */ __attribute__((weak)) void eeconfig_init_kb_datablock(void) { - uint8_t dummy_kb[(EECONFIG_KB_DATA_SIZE)] = {0}; - eeconfig_update_kb_datablock(dummy_kb); + nvm_eeconfig_init_kb_datablock(); } #endif // (EECONFIG_KB_DATA_SIZE) > 0 #if (EECONFIG_USER_DATA_SIZE) > 0 -/** \brief eeconfig assert user data block version - * - * FIXME: needs doc - */ bool eeconfig_is_user_datablock_valid(void) { - return eeprom_read_dword(EECONFIG_USER) == (EECONFIG_USER_DATA_VERSION); + return nvm_eeconfig_is_user_datablock_valid(); } -/** \brief eeconfig read user data block - * - * FIXME: needs doc - */ -void eeconfig_read_user_datablock(void *data) { - if (eeconfig_is_user_datablock_valid()) { - eeprom_read_block(data, EECONFIG_USER_DATABLOCK, (EECONFIG_USER_DATA_SIZE)); - } else { - memset(data, 0, (EECONFIG_USER_DATA_SIZE)); - } +uint32_t eeconfig_read_user_datablock(void *data, uint32_t offset, uint32_t length) { + return nvm_eeconfig_read_user_datablock(data, offset, length); } -/** \brief eeconfig update user data block - * - * FIXME: needs doc - */ -void eeconfig_update_user_datablock(const void *data) { - eeprom_update_dword(EECONFIG_USER, (EECONFIG_USER_DATA_VERSION)); - eeprom_update_block(data, EECONFIG_USER_DATABLOCK, (EECONFIG_USER_DATA_SIZE)); +uint32_t eeconfig_update_user_datablock(const void *data, uint32_t offset, uint32_t length) { + return nvm_eeconfig_update_user_datablock(data, offset, length); } -/** \brief eeconfig init user data block - * - * FIXME: needs doc - */ __attribute__((weak)) void eeconfig_init_user_datablock(void) { - uint8_t dummy_user[(EECONFIG_USER_DATA_SIZE)] = {0}; - eeconfig_update_user_datablock(dummy_user); + nvm_eeconfig_init_user_datablock(); } #endif // (EECONFIG_USER_DATA_SIZE) > 0 diff --git a/quantum/eeconfig.h b/quantum/eeconfig.h index fa0dd799d19..084abffe388 100644 --- a/quantum/eeconfig.h +++ b/quantum/eeconfig.h @@ -20,56 +20,6 @@ along with this program. If not, see . #include #include #include // 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 #ifndef EECONFIG_KB_DATA_SIZE @@ -85,12 +35,6 @@ typedef struct PACKED { # define EECONFIG_USER_DATA_VERSION (EECONFIG_USER_DATA_SIZE) #endif -#define EECONFIG_KB_DATABLOCK ((uint8_t *)(EECONFIG_BASE_SIZE)) -#define EECONFIG_USER_DATABLOCK ((uint8_t *)((EECONFIG_BASE_SIZE) + (EECONFIG_KB_DATA_SIZE))) - -// Size of EEPROM being used, other code can refer to this for available EEPROM -#define EECONFIG_SIZE ((EECONFIG_BASE_SIZE) + (EECONFIG_KB_DATA_SIZE) + (EECONFIG_USER_DATA_SIZE)) - /* debug bit */ #define EECONFIG_DEBUG_ENABLE (1 << 0) #define EECONFIG_DEBUG_MATRIX (1 << 1) @@ -116,22 +60,59 @@ void eeconfig_init_kb(void); void eeconfig_init_user(void); void eeconfig_enable(void); - void eeconfig_disable(void); -uint8_t eeconfig_read_debug(void); -void eeconfig_update_debug(uint8_t val); +typedef union debug_config_t debug_config_t; +void eeconfig_read_debug(debug_config_t *debug_config) __attribute__((nonnull)); +void eeconfig_update_debug(const debug_config_t *debug_config) __attribute__((nonnull)); uint8_t eeconfig_read_default_layer(void); void eeconfig_update_default_layer(uint8_t val); -uint16_t eeconfig_read_keymap(void); -void eeconfig_update_keymap(uint16_t val); +typedef union keymap_config_t keymap_config_t; +void eeconfig_read_keymap(keymap_config_t *keymap_config) __attribute__((nonnull)); +void eeconfig_update_keymap(const keymap_config_t *keymap_config) __attribute__((nonnull)); #ifdef AUDIO_ENABLE -uint8_t eeconfig_read_audio(void); -void eeconfig_update_audio(uint8_t val); -#endif +typedef union audio_config_t audio_config_t; +void eeconfig_read_audio(audio_config_t *audio_config) __attribute__((nonnull)); +void eeconfig_update_audio(const audio_config_t *audio_config) __attribute__((nonnull)); +#endif // AUDIO_ENABLE + +#ifdef UNICODE_COMMON_ENABLE +typedef union unicode_config_t unicode_config_t; +void eeconfig_read_unicode_mode(unicode_config_t *unicode_config) __attribute__((nonnull)); +void eeconfig_update_unicode_mode(const unicode_config_t *unicode_config) __attribute__((nonnull)); +#endif // UNICODE_COMMON_ENABLE + +#ifdef BACKLIGHT_ENABLE +typedef union backlight_config_t backlight_config_t; +void eeconfig_read_backlight(backlight_config_t *backlight_config) __attribute__((nonnull)); +void eeconfig_update_backlight(const backlight_config_t *backlight_config) __attribute__((nonnull)); +#endif // BACKLIGHT_ENABLE + +#ifdef STENO_ENABLE +uint8_t eeconfig_read_steno_mode(void); +void eeconfig_update_steno_mode(uint8_t val); +#endif // STENO_ENABLE + +#ifdef RGB_MATRIX_ENABLE +typedef union rgb_config_t rgb_config_t; +void eeconfig_read_rgb_matrix(rgb_config_t *rgb_matrix_config) __attribute__((nonnull)); +void eeconfig_update_rgb_matrix(const rgb_config_t *rgb_matrix_config) __attribute__((nonnull)); +#endif // RGB_MATRIX_ENABLE + +#ifdef LED_MATRIX_ENABLE +typedef union led_eeconfig_t led_eeconfig_t; +void eeconfig_read_led_matrix(led_eeconfig_t *led_matrix_config) __attribute__((nonnull)); +void eeconfig_update_led_matrix(const led_eeconfig_t *led_matrix_config) __attribute__((nonnull)); +#endif // LED_MATRIX_ENABLE + +#ifdef RGBLIGHT_ENABLE +typedef union rgblight_config_t rgblight_config_t; +void eeconfig_read_rgblight(rgblight_config_t *rgblight_config) __attribute__((nonnull)); +void eeconfig_update_rgblight(const rgblight_config_t *rgblight_config) __attribute__((nonnull)); +#endif // RGBLIGHT_ENABLE #if (EECONFIG_KB_DATA_SIZE) == 0 uint32_t eeconfig_read_kb(void); @@ -144,31 +125,36 @@ void eeconfig_update_user(uint32_t val); #endif // (EECONFIG_USER_DATA_SIZE) == 0 #ifdef HAPTIC_ENABLE -uint32_t eeconfig_read_haptic(void); -void eeconfig_update_haptic(uint32_t val); +typedef union haptic_config_t haptic_config_t; +void eeconfig_read_haptic(haptic_config_t *haptic_config) __attribute__((nonnull)); +void eeconfig_update_haptic(const haptic_config_t *haptic_config) __attribute__((nonnull)); #endif bool eeconfig_read_handedness(void); void eeconfig_update_handedness(bool val); #if (EECONFIG_KB_DATA_SIZE) > 0 -bool eeconfig_is_kb_datablock_valid(void); -void eeconfig_read_kb_datablock(void *data); -void eeconfig_update_kb_datablock(const void *data); -void eeconfig_init_kb_datablock(void); +bool eeconfig_is_kb_datablock_valid(void); +uint32_t eeconfig_read_kb_datablock(void *data, uint32_t offset, uint32_t length) __attribute__((nonnull)); +uint32_t eeconfig_update_kb_datablock(const void *data, uint32_t offset, uint32_t length) __attribute__((nonnull)); +void eeconfig_init_kb_datablock(void); +# define eeconfig_read_kb_datablock_field(__object, __field) eeconfig_read_kb_datablock(&(__object.__field), offsetof(__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 #if (EECONFIG_USER_DATA_SIZE) > 0 -bool eeconfig_is_user_datablock_valid(void); -void eeconfig_read_user_datablock(void *data); -void eeconfig_update_user_datablock(const void *data); -void eeconfig_init_user_datablock(void); +bool eeconfig_is_user_datablock_valid(void); +uint32_t eeconfig_read_user_datablock(void *data, uint32_t offset, uint32_t length) __attribute__((nonnull)); +uint32_t eeconfig_update_user_datablock(const void *data, uint32_t offset, uint32_t length) __attribute__((nonnull)); +void eeconfig_init_user_datablock(void); +# define eeconfig_read_user_datablock_field(__object, __field) eeconfig_read_user_datablock(&(__object.__field), offsetof(__object, __field), sizeof(__object.__field)) +# define eeconfig_update_user_datablock_field(__object, __field) eeconfig_update_user_datablock(&(__object.__field), offsetof(__object, __field), sizeof(__object.__field)) #endif // (EECONFIG_USER_DATA_SIZE) > 0 // Any "checked" debounce variant used requires implementation of: // -- bool eeconfig_check_valid_##name(void) // -- void eeconfig_post_flush_##name(void) -#define EECONFIG_DEBOUNCE_HELPER_CHECKED(name, offset, config) \ +#define EECONFIG_DEBOUNCE_HELPER_CHECKED(name, config) \ static uint8_t dirty_##name = false; \ \ bool eeconfig_check_valid_##name(void); \ @@ -177,13 +163,13 @@ void eeconfig_init_user_datablock(void); static inline void eeconfig_init_##name(void) { \ dirty_##name = true; \ if (eeconfig_check_valid_##name()) { \ - eeprom_read_block(&config, offset, sizeof(config)); \ + eeconfig_read_##name(&config); \ dirty_##name = false; \ } \ } \ static inline void eeconfig_flush_##name(bool force) { \ if (force || dirty_##name) { \ - eeprom_update_block(&config, offset, sizeof(config)); \ + eeconfig_update_##name(&config); \ eeconfig_post_flush_##name(); \ dirty_##name = false; \ } \ @@ -205,10 +191,10 @@ void eeconfig_init_user_datablock(void); } \ } -#define EECONFIG_DEBOUNCE_HELPER(name, offset, config) \ - EECONFIG_DEBOUNCE_HELPER_CHECKED(name, offset, config) \ - \ - bool eeconfig_check_valid_##name(void) { \ - return true; \ - } \ +#define EECONFIG_DEBOUNCE_HELPER(name, config) \ + EECONFIG_DEBOUNCE_HELPER_CHECKED(name, config) \ + \ + bool eeconfig_check_valid_##name(void) { \ + return true; \ + } \ void eeconfig_post_flush_##name(void) {} diff --git a/quantum/haptic.c b/quantum/haptic.c index 81bad469b37..8a743480ffb 100644 --- a/quantum/haptic.c +++ b/quantum/haptic.c @@ -67,7 +67,7 @@ void haptic_init(void) { if (!eeconfig_is_enabled()) { eeconfig_init(); } - haptic_config.raw = eeconfig_read_haptic(); + eeconfig_read_haptic(&haptic_config); #ifdef HAPTIC_SOLENOID solenoid_set_dwell(haptic_config.dwell); #endif @@ -122,13 +122,13 @@ void eeconfig_debug_haptic(void) { void haptic_enable(void) { set_haptic_config_enable(true); dprintf("haptic_config.enable = %u\n", haptic_config.enable); - eeconfig_update_haptic(haptic_config.raw); + eeconfig_update_haptic(&haptic_config); } void haptic_disable(void) { set_haptic_config_enable(false); dprintf("haptic_config.enable = %u\n", haptic_config.enable); - eeconfig_update_haptic(haptic_config.raw); + eeconfig_update_haptic(&haptic_config); } void haptic_toggle(void) { @@ -137,14 +137,14 @@ void haptic_toggle(void) { } else { haptic_enable(); } - eeconfig_update_haptic(haptic_config.raw); + eeconfig_update_haptic(&haptic_config); } void haptic_feedback_toggle(void) { haptic_config.feedback++; if (haptic_config.feedback >= HAPTIC_FEEDBACK_MAX) haptic_config.feedback = KEY_PRESS; 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) { @@ -225,26 +225,26 @@ void haptic_reset(void) { haptic_config.dwell = 0; haptic_config.buzz = 0; #endif - eeconfig_update_haptic(haptic_config.raw); + eeconfig_update_haptic(&haptic_config); dprintf("haptic_config.feedback = %u\n", haptic_config.feedback); dprintf("haptic_config.mode = %u\n", haptic_config.mode); } void haptic_set_feedback(uint8_t 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); } void haptic_set_mode(uint8_t 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); } void haptic_set_amplitude(uint8_t 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); #ifdef HAPTIC_DRV2605L drv2605l_amplitude(amp); @@ -253,13 +253,13 @@ void haptic_set_amplitude(uint8_t amp) { void haptic_set_buzz(uint8_t 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); } void haptic_set_dwell(uint8_t 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); } @@ -291,7 +291,7 @@ uint8_t haptic_get_dwell(void) { void haptic_enable_continuous(void) { haptic_config.cont = 1; dprintf("haptic_config.cont = %u\n", haptic_config.cont); - eeconfig_update_haptic(haptic_config.raw); + eeconfig_update_haptic(&haptic_config); #ifdef HAPTIC_DRV2605L drv2605l_rtp_init(); #endif @@ -300,7 +300,7 @@ void haptic_enable_continuous(void) { void haptic_disable_continuous(void) { haptic_config.cont = 0; dprintf("haptic_config.cont = %u\n", haptic_config.cont); - eeconfig_update_haptic(haptic_config.raw); + eeconfig_update_haptic(&haptic_config); #ifdef HAPTIC_DRV2605L drv2605l_write(DRV2605L_REG_MODE, 0x00); #endif diff --git a/quantum/haptic.h b/quantum/haptic.h index b283d5d2687..e27f546d408 100644 --- a/quantum/haptic.h +++ b/quantum/haptic.h @@ -28,7 +28,7 @@ #endif /* EEPROM config settings */ -typedef union { +typedef union haptic_config_t { uint32_t raw; struct { bool enable : 1; diff --git a/quantum/keyboard.c b/quantum/keyboard.c index 8db81a4b391..408ec2c888c 100644 --- a/quantum/keyboard.c +++ b/quantum/keyboard.c @@ -389,8 +389,8 @@ void quantum_init(void) { } /* init globals */ - debug_config.raw = eeconfig_read_debug(); - keymap_config.raw = eeconfig_read_keymap(); + eeconfig_read_debug(&debug_config); + eeconfig_read_keymap(&keymap_config); #ifdef BOOTMAGIC_ENABLE bootmagic(); @@ -461,7 +461,7 @@ void keyboard_init(void) { #endif #if defined(NKRO_ENABLE) && defined(FORCE_NKRO) keymap_config.nkro = 1; - eeconfig_update_keymap(keymap_config.raw); + eeconfig_update_keymap(&keymap_config); #endif #ifdef DIP_SWITCH_ENABLE dip_switch_init(); diff --git a/quantum/keycode_config.h b/quantum/keycode_config.h index d1352c302ea..529cd0e127a 100644 --- a/quantum/keycode_config.h +++ b/quantum/keycode_config.h @@ -28,7 +28,7 @@ uint16_t keycode_config(uint16_t keycode); uint8_t mod_config(uint8_t mod); /* NOTE: Not portable. Bit field order depends on implementation */ -typedef union { +typedef union keymap_config_t { uint16_t raw; struct { bool swap_control_capslock : 1; diff --git a/quantum/led_matrix/led_matrix.c b/quantum/led_matrix/led_matrix.c index 58263c62e37..2e107a66e96 100644 --- a/quantum/led_matrix/led_matrix.c +++ b/quantum/led_matrix/led_matrix.c @@ -86,9 +86,9 @@ static last_hit_t last_hit_buffer; const uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT; #endif -EECONFIG_DEBOUNCE_HELPER(led_matrix, EECONFIG_LED_MATRIX, led_matrix_eeconfig); +EECONFIG_DEBOUNCE_HELPER(led_matrix, led_matrix_eeconfig); -void eeconfig_update_led_matrix(void) { +void eeconfig_force_flush_led_matrix(void) { eeconfig_flush_led_matrix(true); } diff --git a/quantum/led_matrix/led_matrix.h b/quantum/led_matrix/led_matrix.h index a3468a20039..0006d487e9d 100644 --- a/quantum/led_matrix/led_matrix.h +++ b/quantum/led_matrix/led_matrix.h @@ -115,7 +115,7 @@ enum led_matrix_effects { }; void eeconfig_update_led_matrix_default(void); -void eeconfig_update_led_matrix(void); +void eeconfig_force_flush_led_matrix(void); void eeconfig_debug_led_matrix(void); uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i); diff --git a/quantum/led_matrix/led_matrix_types.h b/quantum/led_matrix/led_matrix_types.h index 5a516ceb102..810420f46fd 100644 --- a/quantum/led_matrix/led_matrix_types.h +++ b/quantum/led_matrix/led_matrix_types.h @@ -71,7 +71,7 @@ typedef struct PACKED { uint8_t flags[LED_MATRIX_LED_COUNT]; } led_config_t; -typedef union { +typedef union led_eeconfig_t { uint32_t raw; struct PACKED { uint8_t enable : 2; diff --git a/quantum/logging/debug.h b/quantum/logging/debug.h index b0d9b9a10ed..6675680ec7a 100644 --- a/quantum/logging/debug.h +++ b/quantum/logging/debug.h @@ -28,7 +28,7 @@ extern "C" { /* * Debug output control */ -typedef union { +typedef union debug_config_t { struct { bool enable : 1; bool matrix : 1; diff --git a/quantum/nvm/eeprom/nvm_dynamic_keymap.c b/quantum/nvm/eeprom/nvm_dynamic_keymap.c new file mode 100644 index 00000000000..b22b6908aa0 --- /dev/null +++ b/quantum/nvm/eeprom/nvm_dynamic_keymap.c @@ -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; + } +} diff --git a/quantum/nvm/eeprom/nvm_eeconfig.c b/quantum/nvm/eeprom/nvm_eeconfig.c new file mode 100644 index 00000000000..897675c1ae0 --- /dev/null +++ b/quantum/nvm/eeprom/nvm_eeconfig.c @@ -0,0 +1,278 @@ +// Copyright 2024 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later +#include +#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 diff --git a/quantum/nvm/eeprom/nvm_eeprom_eeconfig_internal.h b/quantum/nvm/eeprom/nvm_eeprom_eeconfig_internal.h new file mode 100644 index 00000000000..f4f45bbf87e --- /dev/null +++ b/quantum/nvm/eeprom/nvm_eeprom_eeconfig_internal.h @@ -0,0 +1,58 @@ +// Copyright 2024 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +#include +#include // 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"); diff --git a/quantum/nvm/eeprom/nvm_eeprom_via_internal.h b/quantum/nvm/eeprom/nvm_eeprom_via_internal.h new file mode 100644 index 00000000000..bf0d38e2ac3 --- /dev/null +++ b/quantum/nvm/eeprom/nvm_eeprom_via_internal.h @@ -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) diff --git a/quantum/nvm/eeprom/nvm_via.c b/quantum/nvm/eeprom/nvm_via.c new file mode 100644 index 00000000000..5372791fb7a --- /dev/null +++ b/quantum/nvm/eeprom/nvm_via.c @@ -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 +} diff --git a/quantum/nvm/nvm_dynamic_keymap.h b/quantum/nvm/nvm_dynamic_keymap.h new file mode 100644 index 00000000000..d6e4aaee51a --- /dev/null +++ b/quantum/nvm/nvm_dynamic_keymap.h @@ -0,0 +1,27 @@ +// Copyright 2024 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +#include +#include + +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); diff --git a/quantum/nvm/nvm_eeconfig.h b/quantum/nvm/nvm_eeconfig.h new file mode 100644 index 00000000000..dc0cfeb30b9 --- /dev/null +++ b/quantum/nvm/nvm_eeconfig.h @@ -0,0 +1,104 @@ +// Copyright 2024 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +#include +#include + +#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 diff --git a/quantum/nvm/nvm_via.h b/quantum/nvm/nvm_via.h new file mode 100644 index 00000000000..90c5e674217 --- /dev/null +++ b/quantum/nvm/nvm_via.h @@ -0,0 +1,17 @@ +// Copyright 2024 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +#include +#include + +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); diff --git a/quantum/nvm/readme.md b/quantum/nvm/readme.md new file mode 100644 index 00000000000..0731695e92f --- /dev/null +++ b/quantum/nvm/readme.md @@ -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_<>.h + | + ├- eeprom + | ├- nvm_eeconfig.c + | ├- nvm_<>.c + | ╰- ... + | + ├- <> + | ├- nvm_eeconfig.c + | ├- nvm_<>.c + | ╰- ... + ╰- ... +``` + +At the base `nvm` level, for every QMK core system which requires persistence there must be a corresponding `nvm_<>.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_<>.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_<>.c` implementation files which provide the concrete implementation of the upper `nvm_<>.h`. + +New systems requiring persistence can add the corresponding `nvm_<>.h` file, and in most circumstances must also implement equivalent `nvm_<>.c` files for every `nvm` provider. If persistence is not possible for that system, a `nvm_<>.c` file with simple stubs which ignore writes and provide sane defaults must be used instead. \ No newline at end of file diff --git a/quantum/nvm/rules.mk b/quantum/nvm/rules.mk new file mode 100644 index 00000000000..c9c1fabfd49 --- /dev/null +++ b/quantum/nvm/rules.mk @@ -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 diff --git a/quantum/os_detection.h b/quantum/os_detection.h index 98a8e805e4c..e9e7b25f1d2 100644 --- a/quantum/os_detection.h +++ b/quantum/os_detection.h @@ -43,6 +43,9 @@ void slave_update_detected_host_os(os_variant_t os); #endif #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 store_setups_in_eeprom(void); #endif diff --git a/quantum/process_keycode/process_autocorrect.c b/quantum/process_keycode/process_autocorrect.c index edc47718f32..5577b78f8ab 100644 --- a/quantum/process_keycode/process_autocorrect.c +++ b/quantum/process_keycode/process_autocorrect.c @@ -38,7 +38,7 @@ bool autocorrect_is_enabled(void) { */ void autocorrect_enable(void) { 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) { keymap_config.autocorrect_enable = false; 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) { keymap_config.autocorrect_enable = !keymap_config.autocorrect_enable; typo_buffer_size = 0; - eeconfig_update_keymap(keymap_config.raw); + eeconfig_update_keymap(&keymap_config); } /** diff --git a/quantum/process_keycode/process_clicky.c b/quantum/process_keycode/process_clicky.c index 82000db9b30..f50761268a7 100644 --- a/quantum/process_keycode/process_clicky.c +++ b/quantum/process_keycode/process_clicky.c @@ -66,17 +66,17 @@ void clicky_freq_reset(void) { void clicky_toggle(void) { audio_config.clicky_enable ^= 1; - eeconfig_update_audio(audio_config.raw); + eeconfig_update_audio(&audio_config); } void clicky_on(void) { audio_config.clicky_enable = 1; - eeconfig_update_audio(audio_config.raw); + eeconfig_update_audio(&audio_config); } void clicky_off(void) { audio_config.clicky_enable = 0; - eeconfig_update_audio(audio_config.raw); + eeconfig_update_audio(&audio_config); } bool is_clicky_on(void) { diff --git a/quantum/process_keycode/process_magic.c b/quantum/process_keycode/process_magic.c index 3b35884d68a..d5280105de3 100644 --- a/quantum/process_keycode/process_magic.c +++ b/quantum/process_keycode/process_magic.c @@ -47,7 +47,7 @@ bool process_magic(uint16_t keycode, keyrecord_t *record) { if (record->event.pressed) { if (IS_MAGIC_KEYCODE(keycode)) { /* keymap config */ - keymap_config.raw = eeconfig_read_keymap(); + eeconfig_read_keymap(&keymap_config); switch (keycode) { case QK_MAGIC_SWAP_CONTROL_CAPS_LOCK: keymap_config.swap_control_capslock = true; @@ -187,7 +187,7 @@ bool process_magic(uint16_t keycode, keyrecord_t *record) { break; } - eeconfig_update_keymap(keymap_config.raw); + eeconfig_update_keymap(&keymap_config); clear_keyboard(); // clear to prevent stuck keys return false; diff --git a/quantum/process_keycode/process_steno.c b/quantum/process_keycode/process_steno.c index c491d6f1d8c..47894613523 100644 --- a/quantum/process_keycode/process_steno.c +++ b/quantum/process_keycode/process_steno.c @@ -20,9 +20,6 @@ #ifdef VIRTSER_ENABLE # include "virtser.h" #endif -#ifdef STENO_ENABLE_ALL -# include "eeprom.h" -#endif // All steno keys that have been pressed to form this chord, // stored in MAX_STROKE_SIZE groups of 8-bit arrays. @@ -128,13 +125,13 @@ static const uint16_t combinedmap_second[] PROGMEM = {STN_S2, STN_KL, STN_WL, ST #ifdef STENO_ENABLE_ALL void steno_init(void) { - mode = eeprom_read_byte(EECONFIG_STENOMODE); + mode = eeconfig_read_steno_mode(); } void steno_set_mode(steno_mode_t new_mode) { steno_clear_chord(); mode = new_mode; - eeprom_update_byte(EECONFIG_STENOMODE, mode); + eeconfig_update_steno_mode(mode); } #endif // STENO_ENABLE_ALL diff --git a/quantum/rgb_matrix/rgb_matrix.c b/quantum/rgb_matrix/rgb_matrix.c index 484d177546a..a18105c9b35 100644 --- a/quantum/rgb_matrix/rgb_matrix.c +++ b/quantum/rgb_matrix/rgb_matrix.c @@ -88,9 +88,9 @@ static last_hit_t last_hit_buffer; const uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT; #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); } diff --git a/quantum/rgb_matrix/rgb_matrix.h b/quantum/rgb_matrix/rgb_matrix.h index 33f7e06a639..e00e3927c76 100644 --- a/quantum/rgb_matrix/rgb_matrix.h +++ b/quantum/rgb_matrix/rgb_matrix.h @@ -140,7 +140,7 @@ enum rgb_matrix_effects { }; void eeconfig_update_rgb_matrix_default(void); -void eeconfig_update_rgb_matrix(void); +void eeconfig_force_flush_rgb_matrix(void); uint8_t rgb_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i); uint8_t rgb_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i); @@ -215,7 +215,7 @@ void rgb_matrix_set_flags_noeeprom(led_flags_t flags); void rgb_matrix_update_pwm_buffers(void); #ifndef RGBLIGHT_ENABLE -# define eeconfig_update_rgblight_current eeconfig_update_rgb_matrix +# define eeconfig_update_rgblight_current eeconfig_force_flush_rgb_matrix # define rgblight_reload_from_eeprom rgb_matrix_reload_from_eeprom # define rgblight_toggle rgb_matrix_toggle # define rgblight_toggle_noeeprom rgb_matrix_toggle_noeeprom diff --git a/quantum/rgb_matrix/rgb_matrix_types.h b/quantum/rgb_matrix/rgb_matrix_types.h index 0834a7067c4..62005ebea9f 100644 --- a/quantum/rgb_matrix/rgb_matrix_types.h +++ b/quantum/rgb_matrix/rgb_matrix_types.h @@ -73,7 +73,7 @@ typedef struct PACKED { uint8_t flags[RGB_MATRIX_LED_COUNT]; } led_config_t; -typedef union { +typedef union rgb_config_t { uint64_t raw; struct PACKED { uint8_t enable : 2; diff --git a/quantum/rgblight/rgblight.c b/quantum/rgblight/rgblight.c index ddccc9bae36..83f97c81143 100644 --- a/quantum/rgblight/rgblight.c +++ b/quantum/rgblight/rgblight.c @@ -24,9 +24,7 @@ #include "util.h" #include "led_tables.h" #include -#ifdef EEPROM_ENABLE -# include "eeprom.h" -#endif +#include "eeconfig.h" #ifdef RGBLIGHT_SPLIT /* 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) { - eeconfig_update_rgblight(rgblight_config.raw); + rgblight_check_config(); + eeconfig_update_rgblight(&rgblight_config); } void eeconfig_update_rgblight_default(void) { @@ -205,7 +188,7 @@ void eeconfig_update_rgblight_default(void) { rgblight_config.val = RGBLIGHT_DEFAULT_VAL; rgblight_config.speed = RGBLIGHT_DEFAULT_SPD; RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS; - eeconfig_update_rgblight(rgblight_config.raw); + eeconfig_update_rgblight(&rgblight_config); } void eeconfig_debug_rgblight(void) { @@ -228,12 +211,12 @@ void rgblight_init(void) { } dprintf("rgblight_init start!\n"); - rgblight_config.raw = eeconfig_read_rgblight(); + eeconfig_read_rgblight(&rgblight_config); RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS; if (!rgblight_config.mode) { dprintf("rgblight_init rgblight_config.mode = 0. Write default values to EEPROM.\n"); eeconfig_update_rgblight_default(); - rgblight_config.raw = eeconfig_read_rgblight(); + eeconfig_read_rgblight(&rgblight_config); } rgblight_check_config(); @@ -252,7 +235,7 @@ void rgblight_init(void) { void rgblight_reload_from_eeprom(void) { /* Reset back to what we have in eeprom */ - rgblight_config.raw = eeconfig_read_rgblight(); + eeconfig_read_rgblight(&rgblight_config); RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS; rgblight_check_config(); eeconfig_debug_rgblight(); // display current eeprom values @@ -341,7 +324,7 @@ void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) { } RGBLIGHT_SPLIT_SET_CHANGE_MODE; if (write_to_eeprom) { - eeconfig_update_rgblight(rgblight_config.raw); + eeconfig_update_rgblight(&rgblight_config); dprintf("rgblight mode [EEPROM]: %u\n", rgblight_config.mode); } else { dprintf("rgblight mode [NOEEPROM]: %u\n", rgblight_config.mode); @@ -386,7 +369,7 @@ void rgblight_toggle_noeeprom(void) { void rgblight_enable(void) { rgblight_config.enable = 1; // No need to update EEPROM here. rgblight_mode() will do that, actually - // eeconfig_update_rgblight(rgblight_config.raw); + // eeconfig_update_rgblight(&rgblight_config); dprintf("rgblight enable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); rgblight_mode(rgblight_config.mode); } @@ -399,7 +382,7 @@ void rgblight_enable_noeeprom(void) { void rgblight_disable(void) { rgblight_config.enable = 0; - eeconfig_update_rgblight(rgblight_config.raw); + eeconfig_update_rgblight(&rgblight_config); dprintf("rgblight disable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); rgblight_timer_disable(); RGBLIGHT_SPLIT_SET_CHANGE_MODE; @@ -487,7 +470,7 @@ void rgblight_increase_speed_helper(bool write_to_eeprom) { if (rgblight_config.speed < 3) rgblight_config.speed++; // RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED? if (write_to_eeprom) { - eeconfig_update_rgblight(rgblight_config.raw); + eeconfig_update_rgblight(&rgblight_config); } } void rgblight_increase_speed(void) { @@ -501,7 +484,7 @@ void rgblight_decrease_speed_helper(bool write_to_eeprom) { if (rgblight_config.speed > 0) rgblight_config.speed--; // RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED?? if (write_to_eeprom) { - eeconfig_update_rgblight(rgblight_config.raw); + eeconfig_update_rgblight(&rgblight_config); } } void rgblight_decrease_speed(void) { @@ -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.val = val; if (write_to_eeprom) { - eeconfig_update_rgblight(rgblight_config.raw); + eeconfig_update_rgblight(&rgblight_config); dprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } else { dprintf("rgblight set hsv [NOEEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); @@ -608,7 +591,7 @@ uint8_t rgblight_get_speed(void) { void rgblight_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) { rgblight_config.speed = speed; if (write_to_eeprom) { - eeconfig_update_rgblight(rgblight_config.raw); + eeconfig_update_rgblight(&rgblight_config); dprintf("rgblight set speed [EEPROM]: %u\n", rgblight_config.speed); } else { dprintf("rgblight set speed [NOEEPROM]: %u\n", rgblight_config.speed); diff --git a/quantum/rgblight/rgblight.h b/quantum/rgblight/rgblight.h index f4b6e621e40..f5fd450d4cf 100644 --- a/quantum/rgblight/rgblight.h +++ b/quantum/rgblight/rgblight.h @@ -168,7 +168,6 @@ enum RGBLIGHT_EFFECT_MODE { #include #include "rgblight_drivers.h" #include "progmem.h" -#include "eeconfig.h" #include "color.h" #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 bool is_rgblight_initialized; -typedef union { +typedef union rgblight_config_t { uint64_t raw; struct { bool enable : 1; @@ -370,8 +369,6 @@ void rgblight_suspend(void); void rgblight_wakeup(void); uint64_t rgblight_read_qword(void); void rgblight_update_qword(uint64_t qword); -uint64_t eeconfig_read_rgblight(void); -void eeconfig_update_rgblight(uint64_t val); void eeconfig_update_rgblight_current(void); void eeconfig_update_rgblight_default(void); void eeconfig_debug_rgblight(void); diff --git a/quantum/unicode/unicode.c b/quantum/unicode/unicode.c index 78a4cad5859..b0729335f07 100644 --- a/quantum/unicode/unicode.c +++ b/quantum/unicode/unicode.c @@ -136,7 +136,7 @@ static void unicode_play_song(uint8_t mode) { #endif void unicode_input_mode_init(void) { - unicode_config.raw = eeprom_read_byte(EECONFIG_UNICODEMODE); + eeconfig_read_unicode_mode(&unicode_config); #if UNICODE_SELECTED_MODES != -1 # if UNICODE_CYCLE_PERSIST // Find input_mode in selected modes @@ -165,7 +165,7 @@ uint8_t get_unicode_input_mode(void) { } static void persist_unicode_input_mode(void) { - eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config.input_mode); + eeconfig_update_unicode_mode(&unicode_config); } void set_unicode_input_mode(uint8_t mode) { diff --git a/quantum/unicode/unicode.h b/quantum/unicode/unicode.h index 90a54c8b18b..f19d8033354 100644 --- a/quantum/unicode/unicode.h +++ b/quantum/unicode/unicode.h @@ -26,7 +26,7 @@ * \{ */ -typedef union { +typedef union unicode_config_t { uint8_t raw; struct { uint8_t input_mode : 8; diff --git a/quantum/via.c b/quantum/via.c index 643d7aa3c39..c746d9a6082 100644 --- a/quantum/via.c +++ b/quantum/via.c @@ -32,6 +32,7 @@ #include "timer.h" #include "wait.h" #include "version.h" // for QMK_BUILDDATE used in EEPROM magic +#include "nvm_via.h" #if defined(AUDIO_ENABLE) # include "audio.h" @@ -65,20 +66,26 @@ bool via_eeprom_is_valid(void) { uint8_t magic1 = ((p[5] & 0x0F) << 4) | (p[6] & 0x0F); uint8_t magic2 = ((p[8] & 0x0F) << 4) | (p[9] & 0x0F); - return (eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 0) == magic0 && eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 1) == magic1 && eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 2) == magic2); + uint8_t ee_magic0; + uint8_t ee_magic1; + uint8_t ee_magic2; + nvm_via_read_magic(&ee_magic0, &ee_magic1, &ee_magic2); + + return ee_magic0 == magic0 && ee_magic1 == magic1 && ee_magic2 == magic2; } // Sets VIA/keyboard level usage of EEPROM to valid/invalid // Keyboard level code (eg. via_init_kb()) should not call this void via_eeprom_set_valid(bool valid) { - char * p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54" - uint8_t magic0 = ((p[2] & 0x0F) << 4) | (p[3] & 0x0F); - uint8_t magic1 = ((p[5] & 0x0F) << 4) | (p[6] & 0x0F); - uint8_t magic2 = ((p[8] & 0x0F) << 4) | (p[9] & 0x0F); - - eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 0, valid ? magic0 : 0xFF); - eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 1, valid ? magic1 : 0xFF); - eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 2, valid ? magic2 : 0xFF); + if (valid) { + char * p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54" + uint8_t magic0 = ((p[2] & 0x0F) << 4) | (p[3] & 0x0F); + uint8_t magic1 = ((p[5] & 0x0F) << 4) | (p[6] & 0x0F); + uint8_t magic2 = ((p[8] & 0x0F) << 4) | (p[9] & 0x0F); + nvm_via_update_magic(magic0, magic1, magic2); + } else { + nvm_via_update_magic(0xFF, 0xFF, 0xFF); + } } // Override this at the keyboard code level to check @@ -104,6 +111,8 @@ void via_init(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 via_eeprom_set_valid(false); // 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 // variable, between 1 and 4 bytes. uint32_t via_get_layout_options(void) { - uint32_t value = 0; - // Start at the most significant byte - void *source = (void *)(VIA_EEPROM_LAYOUT_OPTIONS_ADDR); - for (uint8_t i = 0; i < VIA_EEPROM_LAYOUT_OPTIONS_SIZE; i++) { - value = value << 8; - value |= eeprom_read_byte(source); - source++; - } - return value; + return nvm_via_read_layout_options(); } __attribute__((weak)) void via_set_layout_options_kb(uint32_t value) {} void via_set_layout_options(uint32_t value) { via_set_layout_options_kb(value); - // Start at the least significant byte - void *target = (void *)(VIA_EEPROM_LAYOUT_OPTIONS_ADDR + VIA_EEPROM_LAYOUT_OPTIONS_SIZE - 1); - for (uint8_t i = 0; i < VIA_EEPROM_LAYOUT_OPTIONS_SIZE; i++) { - eeprom_update_byte(target, value & 0xFF); - value = value >> 8; - target--; - } + nvm_via_update_layout_options(value); } +#if VIA_EEPROM_CUSTOM_CONFIG_SIZE > 0 +uint32_t via_read_custom_config(void *buf, uint32_t offset, uint32_t length) { + return nvm_via_read_custom_config(buf, offset, length); +} +uint32_t via_update_custom_config(const void *buf, uint32_t offset, uint32_t length) { + return nvm_via_update_custom_config(buf, offset, length); +} +#endif + #if defined(AUDIO_ENABLE) float via_device_indication_song[][2] = SONG(STARTUP_SOUND); #endif // AUDIO_ENABLE @@ -715,7 +719,7 @@ void via_qmk_rgb_matrix_set_value(uint8_t *data) { } void via_qmk_rgb_matrix_save(void) { - eeconfig_update_rgb_matrix(); + eeconfig_force_flush_rgb_matrix(); } #endif // RGB_MATRIX_ENABLE @@ -794,7 +798,7 @@ void via_qmk_led_matrix_set_value(uint8_t *data) { } void via_qmk_led_matrix_save(void) { - eeconfig_update_led_matrix(); + eeconfig_force_flush_led_matrix(); } #endif // LED_MATRIX_ENABLE @@ -861,7 +865,7 @@ void via_qmk_audio_set_value(uint8_t *data) { } void via_qmk_audio_save(void) { - eeconfig_update_audio(audio_config.raw); + eeconfig_update_audio(&audio_config); } #endif // QMK_AUDIO_ENABLE diff --git a/quantum/via.h b/quantum/via.h index 01d4c48b374..9f0eef10f75 100644 --- a/quantum/via.h +++ b/quantum/via.h @@ -16,21 +16,8 @@ #pragma once -#include "eeconfig.h" // for EECONFIG_SIZE #include "action.h" -// Keyboard level code can change where VIA stores the magic. -// The magic is the build date YYMMDD encoded as BCD in 3 bytes, -// thus installing firmware built on a different date to the one -// already installed can be detected and the EEPROM data is reset. -// The only reason this is important is in case EEPROM usage changes -// and the EEPROM was not explicitly reset by bootmagic lite. -#ifndef VIA_EEPROM_MAGIC_ADDR -# define VIA_EEPROM_MAGIC_ADDR (EECONFIG_SIZE) -#endif - -#define VIA_EEPROM_LAYOUT_OPTIONS_ADDR (VIA_EEPROM_MAGIC_ADDR + 3) - // Changing the layout options size after release will invalidate EEPROM, // but this is something that should be set correctly on initial implementation. // 1 byte is enough for most uses (i.e. 8 binary states, or 6 binary + 1 ternary/quaternary ) @@ -46,17 +33,10 @@ # define VIA_EEPROM_LAYOUT_OPTIONS_DEFAULT 0x00000000 #endif -// The end of the EEPROM memory used by VIA -// By default, dynamic keymaps will start at this if there is no -// custom config -#define VIA_EEPROM_CUSTOM_CONFIG_ADDR (VIA_EEPROM_LAYOUT_OPTIONS_ADDR + VIA_EEPROM_LAYOUT_OPTIONS_SIZE) - #ifndef VIA_EEPROM_CUSTOM_CONFIG_SIZE # define VIA_EEPROM_CUSTOM_CONFIG_SIZE 0 #endif -#define VIA_EEPROM_CONFIG_END (VIA_EEPROM_CUSTOM_CONFIG_ADDR + VIA_EEPROM_CUSTOM_CONFIG_SIZE) - // This is changed only when the command IDs change, // so VIA Configurator can detect compatible firmware. #define VIA_PROTOCOL_VERSION 0x000C @@ -160,6 +140,11 @@ uint32_t via_get_layout_options(void); void via_set_layout_options(uint32_t value); void via_set_layout_options_kb(uint32_t value); +#if VIA_EEPROM_CUSTOM_CONFIG_SIZE > 0 +uint32_t via_read_custom_config(void *buf, uint32_t offset, uint32_t length); +uint32_t via_update_custom_config(const void *buf, uint32_t offset, uint32_t length); +#endif + // Used by VIA to tell a device to flash LEDs (or do something else) when that // device becomes the active device being configured, on startup or switching // between devices. @@ -202,4 +187,4 @@ void via_qmk_audio_command(uint8_t *data, uint8_t length); void via_qmk_audio_set_value(uint8_t *data); void via_qmk_audio_get_value(uint8_t *data); void via_qmk_audio_save(void); -#endif \ No newline at end of file +#endif diff --git a/tests/test_common/test_fixture.cpp b/tests/test_common/test_fixture.cpp index 3cfb2cb4c29..21457f7f532 100644 --- a/tests/test_common/test_fixture.cpp +++ b/tests/test_common/test_fixture.cpp @@ -45,7 +45,7 @@ void TestFixture::SetUpTestCase() { // The following is enough to bootstrap the values set in main eeconfig_init_quantum(); - eeconfig_update_debug(debug_config.raw); + eeconfig_update_debug(&debug_config); TestDriver driver; keyboard_init();