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

View File

@ -29,6 +29,8 @@ QUANTUM_SRC += \
$(QUANTUM_DIR)/logging/debug.c \
$(QUANTUM_DIR)/logging/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)","")

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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<<index)) | (enable<<index);
eeprom_update_byte((uint8_t*)EEPROM_ENABLED_ENCODER_MODES, enabled_encoder_modes);
write_custom_config(&enabled_encoder_modes, EEPROM_ENABLED_ENCODER_MODES_OFFSET, 1);
break;
}
case id_encoder_custom:
@ -109,11 +125,12 @@ void custom_set_value(uint8_t *data) {
void custom_get_value(uint8_t *data) {
uint8_t *value_id = &(data[0]);
uint8_t *value_data = &(data[1]);
switch ( *value_id ) {
case id_oled_default_mode:
{
uint8_t default_oled = eeprom_read_byte((uint8_t*)EEPROM_DEFAULT_OLED);
uint8_t default_oled;
read_custom_config(&default_oled, EEPROM_DEFAULT_OLED_OFFSET, 1);
value_data[0] = default_oled;
break;
}
@ -179,7 +196,6 @@ void via_custom_value_command_kb(uint8_t *data, uint8_t length) {
}
#endif
void read_host_led_state(void) {
led_t led_state = host_keyboard_led_state();
if (led_state.num_lock) {
@ -290,25 +306,25 @@ bool encoder_update_kb(uint8_t index, bool clockwise) {
}
void custom_config_reset(void){
void *p = (void*)(VIA_EEPROM_CUSTOM_CONFIG_ADDR);
void *end = (void*)(VIA_EEPROM_CUSTOM_CONFIG_ADDR+VIA_EEPROM_CUSTOM_CONFIG_SIZE);
while ( p != end ) {
eeprom_update_byte(p, 0);
++p;
for(int i = 0; i < VIA_EEPROM_CUSTOM_CONFIG_SIZE; ++i) {
uint8_t dummy = 0;
write_custom_config(&dummy, i, 1);
}
eeprom_update_byte((uint8_t*)EEPROM_ENABLED_ENCODER_MODES, 0x1F);
uint8_t encoder_modes = 0x1F;
write_custom_config(&encoder_modes, EEPROM_ENABLED_ENCODER_MODES_OFFSET, 1);
}
void custom_config_load(void){
#ifdef DYNAMIC_KEYMAP_ENABLE
oled_mode = eeprom_read_byte((uint8_t*)EEPROM_DEFAULT_OLED);
enabled_encoder_modes = eeprom_read_byte((uint8_t*)EEPROM_ENABLED_ENCODER_MODES);
read_custom_config(&oled_mode, EEPROM_DEFAULT_OLED_OFFSET, 1);
read_custom_config(&enabled_encoder_modes, EEPROM_ENABLED_ENCODER_MODES_OFFSET, 1);
#endif
}
// Called from via_init() if VIA_ENABLE
// Called from matrix_init_kb() if not VIA_ENABLE
void via_init_kb(void)
void satisfaction_core_init(void)
{
// This checks both an EEPROM reset (from bootmagic lite, keycodes)
// and also firmware build date (from via_eeprom_is_valid())
@ -326,8 +342,7 @@ void via_init_kb(void)
void matrix_init_kb(void)
{
#ifndef VIA_ENABLE
via_init_kb();
via_eeprom_set_valid(true);
satisfaction_core_init();
#endif // VIA_ENABLE
rtcGetTime(&RTCD1, &last_timespec);
@ -335,6 +350,11 @@ void matrix_init_kb(void)
oled_request_wakeup();
}
#ifdef VIA_ENABLE
void via_init_kb(void) {
satisfaction_core_init();
}
#endif // VIA_ENABLE
void housekeeping_task_kb(void) {
rtcGetTime(&RTCD1, &last_timespec);
@ -345,52 +365,3 @@ void housekeeping_task_kb(void) {
oled_request_repaint();
}
}
//
// In the case of VIA being disabled, we still need to check if
// keyboard level EEPROM memory is valid before loading.
// Thus these are copies of the same functions in VIA, since
// the backlight settings reuse VIA's EEPROM magic/version,
// and the ones in via.c won't be compiled in.
//
// Yes, this is sub-optimal, and is only here for completeness
// (i.e. catering to the 1% of people that want wilba.tech LED bling
// AND want persistent settings BUT DON'T want to use dynamic keymaps/VIA).
//
#ifndef VIA_ENABLE
bool via_eeprom_is_valid(void)
{
char *p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54"
uint8_t magic0 = ( ( p[2] & 0x0F ) << 4 ) | ( p[3] & 0x0F );
uint8_t magic1 = ( ( p[5] & 0x0F ) << 4 ) | ( p[6] & 0x0F );
uint8_t magic2 = ( ( p[8] & 0x0F ) << 4 ) | ( p[9] & 0x0F );
return (eeprom_read_byte( (void*)VIA_EEPROM_MAGIC_ADDR+0 ) == magic0 &&
eeprom_read_byte( (void*)VIA_EEPROM_MAGIC_ADDR+1 ) == magic1 &&
eeprom_read_byte( (void*)VIA_EEPROM_MAGIC_ADDR+2 ) == magic2 );
}
// Sets VIA/keyboard level usage of EEPROM to valid/invalid
// Keyboard level code (eg. via_init_kb()) should not call this
void via_eeprom_set_valid(bool valid)
{
char *p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54"
uint8_t magic0 = ( ( p[2] & 0x0F ) << 4 ) | ( p[3] & 0x0F );
uint8_t magic1 = ( ( p[5] & 0x0F ) << 4 ) | ( p[6] & 0x0F );
uint8_t magic2 = ( ( p[8] & 0x0F ) << 4 ) | ( p[9] & 0x0F );
eeprom_update_byte( (void*)VIA_EEPROM_MAGIC_ADDR+0, valid ? magic0 : 0xFF);
eeprom_update_byte( (void*)VIA_EEPROM_MAGIC_ADDR+1, valid ? magic1 : 0xFF);
eeprom_update_byte( (void*)VIA_EEPROM_MAGIC_ADDR+2, valid ? magic2 : 0xFF);
}
void via_eeprom_reset(void)
{
// Set the VIA specific EEPROM state as invalid.
via_eeprom_set_valid(false);
// Set the TMK/QMK EEPROM state as invalid.
eeconfig_disable();
}
#endif // VIA_ENABLE

View File

@ -6,12 +6,14 @@
#include <stdint.h>
#include <stdbool.h>
#include <hal.h>
#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);

View File

@ -215,10 +215,13 @@ uint16_t handle_encoder_press(void){
uint16_t retrieve_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior){
#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
}

View File

@ -8,7 +8,6 @@
#include "matrix.h"
#include "led.h"
#include "host.h"
#include "oled_driver.h"
#include "progmem.h"
#include <stdio.h>
@ -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; }

View File

@ -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

View File

@ -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

View File

@ -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;

View File

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

View File

@ -73,7 +73,7 @@ void via_config_set_value(uint8_t *data) {
uprintf("# Actuation Mode: Rapid Trigger #\n");
uprintf("#################################\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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -32,7 +32,7 @@ void set_mac_mode_kb(bool macmode) {
* https://github.com/qmk/qmk_firmware/blob/fb4a6ad30ea7a648acd59793ed4a30c3a8d8dc32/quantum/process_keycode/process_magic.c#L80-L81
*/
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) {

View File

@ -27,7 +27,7 @@ void set_mac_mode(bool macmode) {
* https://github.com/qmk/qmk_firmware/blob/fb4a6ad30ea7a648acd59793ed4a30c3a8d8dc32/quantum/process_keycode/process_magic.c#L80-L81
*/
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

View File

@ -27,7 +27,7 @@ void set_mac_mode(bool macmode) {
* https://github.com/qmk/qmk_firmware/blob/fb4a6ad30ea7a648acd59793ed4a30c3a8d8dc32/quantum/process_keycode/process_magic.c#L80-L81
*/
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

View File

@ -18,6 +18,7 @@
#include <string.h>
#include <math.h>
#include <lib/lib8tion/lib8tion.h>
#include "eeconfig.h"
#define LED_TRAIL 10
@ -105,7 +106,7 @@ static void swirl_set_color(hsv_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;
}

View File

@ -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;
}

View File

@ -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:

View File

@ -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<<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:

View File

@ -163,7 +163,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 GU_TOGG:

View File

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

View File

@ -233,9 +233,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!eeconfig_is_enabled()) {
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;

View File

@ -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;

View File

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

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

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

View File

@ -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);
}

View File

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

View File

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

View File

@ -16,7 +16,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backlight.h"
#include "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();
}

View File

@ -34,7 +34,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# 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);

View File

@ -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"

View File

@ -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;

View File

@ -18,8 +18,15 @@
#include <stdint.h>
#include <stdbool.h>
#ifndef DYNAMIC_KEYMAP_LAYER_COUNT
# define DYNAMIC_KEYMAP_LAYER_COUNT 4
#endif
#ifndef DYNAMIC_KEYMAP_MACRO_COUNT
# define DYNAMIC_KEYMAP_MACRO_COUNT 16
#endif
uint8_t dynamic_keymap_get_layer_count(void);
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

View File

@ -1,340 +1,333 @@
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#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

View File

@ -20,56 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h> // offsetof
#include "eeprom.h"
#include "util.h"
#ifndef EECONFIG_MAGIC_NUMBER
# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEE5 // When changing, decrement this value to avoid future re-init issues
#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) {}

View File

@ -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

View File

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

View File

@ -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();

View File

@ -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;

View File

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

View File

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

View File

@ -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;

View File

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

View File

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

View File

@ -0,0 +1,278 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#include <string.h>
#include "nvm_eeconfig.h"
#include "nvm_eeprom_eeconfig_internal.h"
#include "util.h"
#include "eeconfig.h"
#include "debug.h"
#include "eeprom.h"
#include "keycode_config.h"
#ifdef EEPROM_DRIVER
# include "eeprom_driver.h"
#endif
#ifdef AUDIO_ENABLE
# include "audio.h"
#endif
#ifdef BACKLIGHT_ENABLE
# include "backlight.h"
#endif
#ifdef RGBLIGHT_ENABLE
# include "rgblight.h"
#endif
#ifdef RGB_MATRIX_ENABLE
# include "rgb_matrix_types.h"
#endif
#ifdef LED_MATRIX_ENABLE
# include "led_matrix_types.h"
#endif
#ifdef UNICODE_COMMON_ENABLE
# include "unicode.h"
#endif
#ifdef HAPTIC_ENABLE
# include "haptic.h"
#endif
void nvm_eeconfig_erase(void) {
#ifdef EEPROM_DRIVER
eeprom_driver_format(false);
#endif // EEPROM_DRIVER
}
bool nvm_eeconfig_is_enabled(void) {
return eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER;
}
bool nvm_eeconfig_is_disabled(void) {
return eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF;
}
void nvm_eeconfig_enable(void) {
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
}
void nvm_eeconfig_disable(void) {
#if defined(EEPROM_DRIVER)
eeprom_driver_format(false);
#endif
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF);
}
void nvm_eeconfig_read_debug(debug_config_t *debug_config) {
debug_config->raw = eeprom_read_byte(EECONFIG_DEBUG);
}
void nvm_eeconfig_update_debug(const debug_config_t *debug_config) {
eeprom_update_byte(EECONFIG_DEBUG, debug_config->raw);
}
uint8_t nvm_eeconfig_read_default_layer(void) {
return eeprom_read_byte(EECONFIG_DEFAULT_LAYER);
}
void nvm_eeconfig_update_default_layer(uint8_t val) {
eeprom_update_byte(EECONFIG_DEFAULT_LAYER, val);
}
void nvm_eeconfig_read_keymap(keymap_config_t *keymap_config) {
keymap_config->raw = eeprom_read_word(EECONFIG_KEYMAP);
}
void nvm_eeconfig_update_keymap(const keymap_config_t *keymap_config) {
eeprom_update_word(EECONFIG_KEYMAP, keymap_config->raw);
}
#ifdef AUDIO_ENABLE
void nvm_eeconfig_read_audio(audio_config_t *audio_config) {
audio_config->raw = eeprom_read_byte(EECONFIG_AUDIO);
}
void nvm_eeconfig_update_audio(const audio_config_t *audio_config) {
eeprom_update_byte(EECONFIG_AUDIO, audio_config->raw);
}
#endif // AUDIO_ENABLE
#ifdef UNICODE_COMMON_ENABLE
void nvm_eeconfig_read_unicode_mode(unicode_config_t *unicode_config) {
unicode_config->raw = eeprom_read_byte(EECONFIG_UNICODEMODE);
}
void nvm_eeconfig_update_unicode_mode(const unicode_config_t *unicode_config) {
eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config->raw);
}
#endif // UNICODE_COMMON_ENABLE
#ifdef BACKLIGHT_ENABLE
void nvm_eeconfig_read_backlight(backlight_config_t *backlight_config) {
backlight_config->raw = eeprom_read_byte(EECONFIG_BACKLIGHT);
}
void nvm_eeconfig_update_backlight(const backlight_config_t *backlight_config) {
eeprom_update_byte(EECONFIG_BACKLIGHT, backlight_config->raw);
}
#endif // BACKLIGHT_ENABLE
#ifdef STENO_ENABLE
uint8_t nvm_eeconfig_read_steno_mode(void) {
return eeprom_read_byte(EECONFIG_STENOMODE);
}
void nvm_eeconfig_update_steno_mode(uint8_t val) {
eeprom_update_byte(EECONFIG_STENOMODE, val);
}
#endif // STENO_ENABLE
#ifdef RGBLIGHT_ENABLE
#endif // RGBLIGHT_ENABLE
#ifdef RGB_MATRIX_ENABLE
void nvm_eeconfig_read_rgb_matrix(rgb_config_t *rgb_matrix_config) {
eeprom_read_block(rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_config_t));
}
void nvm_eeconfig_update_rgb_matrix(const rgb_config_t *rgb_matrix_config) {
eeprom_update_block(rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_config_t));
}
#endif // RGB_MATRIX_ENABLE
#ifdef LED_MATRIX_ENABLE
void nvm_eeconfig_read_led_matrix(led_eeconfig_t *led_matrix_config) {
eeprom_read_block(led_matrix_config, EECONFIG_LED_MATRIX, sizeof(led_eeconfig_t));
}
void nvm_eeconfig_update_led_matrix(const led_eeconfig_t *led_matrix_config) {
eeprom_update_block(led_matrix_config, EECONFIG_LED_MATRIX, sizeof(led_eeconfig_t));
}
#endif // LED_MATRIX_ENABLE
#ifdef RGBLIGHT_ENABLE
void nvm_eeconfig_read_rgblight(rgblight_config_t *rgblight_config) {
rgblight_config->raw = eeprom_read_dword(EECONFIG_RGBLIGHT);
rgblight_config->raw |= ((uint64_t)eeprom_read_byte(EECONFIG_RGBLIGHT_EXTENDED) << 32);
}
void nvm_eeconfig_update_rgblight(const rgblight_config_t *rgblight_config) {
eeprom_update_dword(EECONFIG_RGBLIGHT, rgblight_config->raw & 0xFFFFFFFF);
eeprom_update_byte(EECONFIG_RGBLIGHT_EXTENDED, (rgblight_config->raw >> 32) & 0xFF);
}
#endif // RGBLIGHT_ENABLE
#if (EECONFIG_KB_DATA_SIZE) == 0
uint32_t nvm_eeconfig_read_kb(void) {
return eeprom_read_dword(EECONFIG_KEYBOARD);
}
void nvm_eeconfig_update_kb(uint32_t val) {
eeprom_update_dword(EECONFIG_KEYBOARD, val);
}
#endif // (EECONFIG_KB_DATA_SIZE) == 0
#if (EECONFIG_USER_DATA_SIZE) == 0
uint32_t nvm_eeconfig_read_user(void) {
return eeprom_read_dword(EECONFIG_USER);
}
void nvm_eeconfig_update_user(uint32_t val) {
eeprom_update_dword(EECONFIG_USER, val);
}
#endif // (EECONFIG_USER_DATA_SIZE) == 0
#ifdef HAPTIC_ENABLE
void nvm_eeconfig_read_haptic(haptic_config_t *haptic_config) {
haptic_config->raw = eeprom_read_dword(EECONFIG_HAPTIC);
}
void nvm_eeconfig_update_haptic(const haptic_config_t *haptic_config) {
eeprom_update_dword(EECONFIG_HAPTIC, haptic_config->raw);
}
#endif // HAPTIC_ENABLE
bool nvm_eeconfig_read_handedness(void) {
return !!eeprom_read_byte(EECONFIG_HANDEDNESS);
}
void nvm_eeconfig_update_handedness(bool val) {
eeprom_update_byte(EECONFIG_HANDEDNESS, !!val);
}
#if (EECONFIG_KB_DATA_SIZE) > 0
bool nvm_eeconfig_is_kb_datablock_valid(void) {
return eeprom_read_dword(EECONFIG_KEYBOARD) == (EECONFIG_KB_DATA_VERSION);
}
uint32_t nvm_eeconfig_read_kb_datablock(void *data, uint32_t offset, uint32_t length) {
if (eeconfig_is_kb_datablock_valid()) {
void *ee_start = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK + offset);
void *ee_end = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK + MIN(EECONFIG_KB_DATA_SIZE, offset + length));
eeprom_read_block(data, ee_start, ee_end - ee_start);
return ee_end - ee_start;
} else {
memset(data, 0, length);
return length;
}
}
uint32_t nvm_eeconfig_update_kb_datablock(const void *data, uint32_t offset, uint32_t length) {
eeprom_update_dword(EECONFIG_KEYBOARD, (EECONFIG_KB_DATA_VERSION));
void *ee_start = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK + offset);
void *ee_end = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK + MIN(EECONFIG_KB_DATA_SIZE, offset + length));
eeprom_update_block(data, ee_start, ee_end - ee_start);
return ee_end - ee_start;
}
void nvm_eeconfig_init_kb_datablock(void) {
eeprom_update_dword(EECONFIG_KEYBOARD, (EECONFIG_KB_DATA_VERSION));
void * start = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK);
void * end = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK + EECONFIG_KB_DATA_SIZE);
long remaining = end - start;
uint8_t dummy[16] = {0};
for (int i = 0; i < EECONFIG_KB_DATA_SIZE; i += sizeof(dummy)) {
int this_loop = remaining < sizeof(dummy) ? remaining : sizeof(dummy);
eeprom_update_block(dummy, start, this_loop);
start += this_loop;
remaining -= this_loop;
}
}
#endif // (EECONFIG_KB_DATA_SIZE) > 0
#if (EECONFIG_USER_DATA_SIZE) > 0
bool nvm_eeconfig_is_user_datablock_valid(void) {
return eeprom_read_dword(EECONFIG_USER) == (EECONFIG_USER_DATA_VERSION);
}
uint32_t nvm_eeconfig_read_user_datablock(void *data, uint32_t offset, uint32_t length) {
if (eeconfig_is_user_datablock_valid()) {
void *ee_start = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK + offset);
void *ee_end = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK + MIN(EECONFIG_USER_DATA_SIZE, offset + length));
eeprom_read_block(data, ee_start, ee_end - ee_start);
return ee_end - ee_start;
} else {
memset(data, 0, length);
return length;
}
}
uint32_t nvm_eeconfig_update_user_datablock(const void *data, uint32_t offset, uint32_t length) {
eeprom_update_dword(EECONFIG_USER, (EECONFIG_USER_DATA_VERSION));
void *ee_start = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK + offset);
void *ee_end = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK + MIN(EECONFIG_USER_DATA_SIZE, offset + length));
eeprom_update_block(data, ee_start, ee_end - ee_start);
return ee_end - ee_start;
}
void nvm_eeconfig_init_user_datablock(void) {
eeprom_update_dword(EECONFIG_USER, (EECONFIG_USER_DATA_VERSION));
void * start = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK);
void * end = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK + EECONFIG_USER_DATA_SIZE);
long remaining = end - start;
uint8_t dummy[16] = {0};
for (int i = 0; i < EECONFIG_USER_DATA_SIZE; i += sizeof(dummy)) {
int this_loop = remaining < sizeof(dummy) ? remaining : sizeof(dummy);
eeprom_update_block(dummy, start, this_loop);
start += this_loop;
remaining -= this_loop;
}
}
#endif // (EECONFIG_USER_DATA_SIZE) > 0

View File

@ -0,0 +1,58 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <stdint.h>
#include <stddef.h> // offsetof
#include "eeconfig.h"
// Dummy struct only used to calculate offsets
typedef struct PACKED {
uint16_t magic;
uint8_t debug;
uint8_t default_layer;
uint16_t keymap;
uint8_t backlight;
uint8_t audio;
uint32_t rgblight;
uint8_t unicode;
uint8_t steno;
uint8_t handedness;
uint32_t keyboard;
uint32_t user;
union { // Mutually exclusive
uint32_t led_matrix;
uint64_t rgb_matrix;
};
uint32_t haptic;
uint8_t rgblight_ext;
} eeprom_core_t;
/* EEPROM parameter address */
#define EECONFIG_MAGIC (uint16_t *)(offsetof(eeprom_core_t, magic))
#define EECONFIG_DEBUG (uint8_t *)(offsetof(eeprom_core_t, debug))
#define EECONFIG_DEFAULT_LAYER (uint8_t *)(offsetof(eeprom_core_t, default_layer))
#define EECONFIG_KEYMAP (uint16_t *)(offsetof(eeprom_core_t, keymap))
#define EECONFIG_BACKLIGHT (uint8_t *)(offsetof(eeprom_core_t, backlight))
#define EECONFIG_AUDIO (uint8_t *)(offsetof(eeprom_core_t, audio))
#define EECONFIG_RGBLIGHT (uint32_t *)(offsetof(eeprom_core_t, rgblight))
#define EECONFIG_UNICODEMODE (uint8_t *)(offsetof(eeprom_core_t, unicode))
#define EECONFIG_STENOMODE (uint8_t *)(offsetof(eeprom_core_t, steno))
#define EECONFIG_HANDEDNESS (uint8_t *)(offsetof(eeprom_core_t, handedness))
#define EECONFIG_KEYBOARD (uint32_t *)(offsetof(eeprom_core_t, keyboard))
#define EECONFIG_USER (uint32_t *)(offsetof(eeprom_core_t, user))
#define EECONFIG_LED_MATRIX (uint32_t *)(offsetof(eeprom_core_t, led_matrix))
#define EECONFIG_RGB_MATRIX (uint64_t *)(offsetof(eeprom_core_t, rgb_matrix))
#define EECONFIG_HAPTIC (uint32_t *)(offsetof(eeprom_core_t, haptic))
#define EECONFIG_RGBLIGHT_EXTENDED (uint8_t *)(offsetof(eeprom_core_t, rgblight_ext))
// Size of EEPROM being used for core data storage
#define EECONFIG_BASE_SIZE ((uint8_t)sizeof(eeprom_core_t))
#define EECONFIG_KB_DATABLOCK ((uint8_t *)(EECONFIG_BASE_SIZE))
#define EECONFIG_USER_DATABLOCK ((uint8_t *)((EECONFIG_BASE_SIZE) + (EECONFIG_KB_DATA_SIZE)))
// Size of EEPROM being used, other code can refer to this for available EEPROM
#define EECONFIG_SIZE ((EECONFIG_BASE_SIZE) + (EECONFIG_KB_DATA_SIZE) + (EECONFIG_USER_DATA_SIZE))
_Static_assert((intptr_t)EECONFIG_HANDEDNESS == 14, "EEPROM handedness offset is incorrect");

View File

@ -0,0 +1,22 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
// Keyboard level code can change where VIA stores the magic.
// The magic is the build date YYMMDD encoded as BCD in 3 bytes,
// thus installing firmware built on a different date to the one
// already installed can be detected and the EEPROM data is reset.
// The only reason this is important is in case EEPROM usage changes
// and the EEPROM was not explicitly reset by bootmagic lite.
#ifndef VIA_EEPROM_MAGIC_ADDR
# define VIA_EEPROM_MAGIC_ADDR (EECONFIG_SIZE)
#endif
#define VIA_EEPROM_LAYOUT_OPTIONS_ADDR (VIA_EEPROM_MAGIC_ADDR + 3)
// The end of the EEPROM memory used by VIA
// By default, dynamic keymaps will start at this if there is no
// custom config
#define VIA_EEPROM_CUSTOM_CONFIG_ADDR (VIA_EEPROM_LAYOUT_OPTIONS_ADDR + VIA_EEPROM_LAYOUT_OPTIONS_SIZE)
#define VIA_EEPROM_CONFIG_END (VIA_EEPROM_CUSTOM_CONFIG_ADDR + VIA_EEPROM_CUSTOM_CONFIG_SIZE)

View File

@ -0,0 +1,77 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#include "eeprom.h"
#include "util.h"
#include "via.h"
#include "nvm_via.h"
#include "nvm_eeprom_eeconfig_internal.h"
#include "nvm_eeprom_via_internal.h"
void nvm_via_erase(void) {
// No-op, nvm_eeconfig_erase() will have already erased EEPROM if necessary.
}
void nvm_via_read_magic(uint8_t *magic0, uint8_t *magic1, uint8_t *magic2) {
if (magic0) {
*magic0 = eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 0);
}
if (magic1) {
*magic1 = eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 1);
}
if (magic2) {
*magic2 = eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 2);
}
}
void nvm_via_update_magic(uint8_t magic0, uint8_t magic1, uint8_t magic2) {
eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 0, magic0);
eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 1, magic1);
eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 2, magic2);
}
uint32_t nvm_via_read_layout_options(void) {
uint32_t value = 0;
// Start at the most significant byte
void *source = (void *)(VIA_EEPROM_LAYOUT_OPTIONS_ADDR);
for (uint8_t i = 0; i < VIA_EEPROM_LAYOUT_OPTIONS_SIZE; i++) {
value = value << 8;
value |= eeprom_read_byte(source);
source++;
}
return value;
}
void nvm_via_update_layout_options(uint32_t val) {
// Start at the least significant byte
void *target = (void *)(VIA_EEPROM_LAYOUT_OPTIONS_ADDR + VIA_EEPROM_LAYOUT_OPTIONS_SIZE - 1);
for (uint8_t i = 0; i < VIA_EEPROM_LAYOUT_OPTIONS_SIZE; i++) {
eeprom_update_byte(target, val & 0xFF);
val = val >> 8;
target--;
}
}
uint32_t nvm_via_read_custom_config(void *buf, uint32_t offset, uint32_t length) {
#if VIA_EEPROM_CUSTOM_CONFIG_SIZE > 0
void *ee_start = (void *)(uintptr_t)(VIA_EEPROM_CUSTOM_CONFIG_ADDR + offset);
void *ee_end = (void *)(uintptr_t)(VIA_EEPROM_CUSTOM_CONFIG_ADDR + MIN(VIA_EEPROM_CUSTOM_CONFIG_SIZE, offset + length));
eeprom_read_block(buf, ee_start, ee_end - ee_start);
return ee_end - ee_start;
#else
return 0;
#endif
}
uint32_t nvm_via_update_custom_config(const void *buf, uint32_t offset, uint32_t length) {
#if VIA_EEPROM_CUSTOM_CONFIG_SIZE > 0
void *ee_start = (void *)(uintptr_t)(VIA_EEPROM_CUSTOM_CONFIG_ADDR + offset);
void *ee_end = (void *)(uintptr_t)(VIA_EEPROM_CUSTOM_CONFIG_ADDR + MIN(VIA_EEPROM_CUSTOM_CONFIG_SIZE, offset + length));
eeprom_update_block(buf, ee_start, ee_end - ee_start);
return ee_end - ee_start;
#else
return 0;
#endif
}

View File

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

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

@ -0,0 +1,104 @@
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <stdint.h>
#include <stdbool.h>
#ifndef EECONFIG_MAGIC_NUMBER
# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEE3 // When changing, decrement this value to avoid future re-init issues
#endif
#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF
void nvm_eeconfig_erase(void);
bool nvm_eeconfig_is_enabled(void);
bool nvm_eeconfig_is_disabled(void);
void nvm_eeconfig_enable(void);
void nvm_eeconfig_disable(void);
typedef union debug_config_t debug_config_t;
void nvm_eeconfig_read_debug(debug_config_t *debug_config);
void nvm_eeconfig_update_debug(const debug_config_t *debug_config);
uint8_t nvm_eeconfig_read_default_layer(void);
void nvm_eeconfig_update_default_layer(uint8_t val);
typedef union keymap_config_t keymap_config_t;
void nvm_eeconfig_read_keymap(keymap_config_t *keymap_config);
void nvm_eeconfig_update_keymap(const keymap_config_t *keymap_config);
#ifdef AUDIO_ENABLE
typedef union audio_config_t audio_config_t;
void nvm_eeconfig_read_audio(audio_config_t *audio_config);
void nvm_eeconfig_update_audio(const audio_config_t *audio_config);
#endif // AUDIO_ENABLE
#ifdef UNICODE_COMMON_ENABLE
typedef union unicode_config_t unicode_config_t;
void nvm_eeconfig_read_unicode_mode(unicode_config_t *unicode_config);
void nvm_eeconfig_update_unicode_mode(const unicode_config_t *unicode_config);
#endif // UNICODE_COMMON_ENABLE
#ifdef BACKLIGHT_ENABLE
typedef union backlight_config_t backlight_config_t;
void nvm_eeconfig_read_backlight(backlight_config_t *backlight_config);
void nvm_eeconfig_update_backlight(const backlight_config_t *backlight_config);
#endif // BACKLIGHT_ENABLE
#ifdef STENO_ENABLE
uint8_t nvm_eeconfig_read_steno_mode(void);
void nvm_eeconfig_update_steno_mode(uint8_t val);
#endif // STENO_ENABLE
#ifdef RGB_MATRIX_ENABLE
typedef union rgb_config_t rgb_config_t;
void nvm_eeconfig_read_rgb_matrix(rgb_config_t *rgb_matrix_config);
void nvm_eeconfig_update_rgb_matrix(const rgb_config_t *rgb_matrix_config);
#endif
#ifdef LED_MATRIX_ENABLE
typedef union led_eeconfig_t led_eeconfig_t;
void nvm_eeconfig_read_led_matrix(led_eeconfig_t *led_matrix_config);
void nvm_eeconfig_update_led_matrix(const led_eeconfig_t *led_matrix_config);
#endif // LED_MATRIX_ENABLE
#ifdef RGBLIGHT_ENABLE
typedef union rgblight_config_t rgblight_config_t;
void nvm_eeconfig_read_rgblight(rgblight_config_t *rgblight_config);
void nvm_eeconfig_update_rgblight(const rgblight_config_t *rgblight_config);
#endif // RGBLIGHT_ENABLE
#if (EECONFIG_KB_DATA_SIZE) == 0
uint32_t nvm_eeconfig_read_kb(void);
void nvm_eeconfig_update_kb(uint32_t val);
#endif // (EECONFIG_KB_DATA_SIZE) == 0
#if (EECONFIG_USER_DATA_SIZE) == 0
uint32_t nvm_eeconfig_read_user(void);
void nvm_eeconfig_update_user(uint32_t val);
#endif // (EECONFIG_USER_DATA_SIZE) == 0
#ifdef HAPTIC_ENABLE
typedef union haptic_config_t haptic_config_t;
void nvm_eeconfig_read_haptic(haptic_config_t *haptic_config);
void nvm_eeconfig_update_haptic(const haptic_config_t *haptic_config);
#endif // HAPTIC_ENABLE
bool nvm_eeconfig_read_handedness(void);
void nvm_eeconfig_update_handedness(bool val);
#if (EECONFIG_KB_DATA_SIZE) > 0
bool nvm_eeconfig_is_kb_datablock_valid(void);
uint32_t nvm_eeconfig_read_kb_datablock(void *data, uint32_t offset, uint32_t length);
uint32_t nvm_eeconfig_update_kb_datablock(const void *data, uint32_t offset, uint32_t length);
void nvm_eeconfig_init_kb_datablock(void);
#endif // (EECONFIG_KB_DATA_SIZE) > 0
#if (EECONFIG_USER_DATA_SIZE) > 0
bool nvm_eeconfig_is_user_datablock_valid(void);
uint32_t nvm_eeconfig_read_user_datablock(void *data, uint32_t offset, uint32_t length);
uint32_t nvm_eeconfig_update_user_datablock(const void *data, uint32_t offset, uint32_t length);
void nvm_eeconfig_init_user_datablock(void);
#endif // (EECONFIG_USER_DATA_SIZE) > 0

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

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

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

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

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

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

View File

@ -43,6 +43,9 @@ void slave_update_detected_host_os(os_variant_t os);
#endif
#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

View File

@ -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);
}
/**

View File

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

View File

@ -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;

View File

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

View File

@ -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);
}

View File

@ -140,7 +140,7 @@ enum rgb_matrix_effects {
};
void eeconfig_update_rgb_matrix_default(void);
void eeconfig_update_rgb_matrix(void);
void eeconfig_force_flush_rgb_matrix(void);
uint8_t rgb_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i);
uint8_t rgb_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i);
@ -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

View File

@ -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;

View File

@ -24,9 +24,7 @@
#include "util.h"
#include "led_tables.h"
#include <lib/lib8tion/lib8tion.h>
#ifdef EEPROM_ENABLE
# include "eeprom.h"
#endif
#include "eeconfig.h"
#ifdef RGBLIGHT_SPLIT
/* for split keyboard */
@ -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);

View File

@ -168,7 +168,6 @@ enum RGBLIGHT_EFFECT_MODE {
#include <stdbool.h>
#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);

View File

@ -136,7 +136,7 @@ static void unicode_play_song(uint8_t mode) {
#endif
void unicode_input_mode_init(void) {
unicode_config.raw = eeprom_read_byte(EECONFIG_UNICODEMODE);
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) {

View File

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

View File

@ -32,6 +32,7 @@
#include "timer.h"
#include "wait.h"
#include "version.h" // for QMK_BUILDDATE used in EEPROM magic
#include "nvm_via.h"
#if defined(AUDIO_ENABLE)
# include "audio.h"
@ -65,20 +66,26 @@ bool via_eeprom_is_valid(void) {
uint8_t magic1 = ((p[5] & 0x0F) << 4) | (p[6] & 0x0F);
uint8_t magic2 = ((p[8] & 0x0F) << 4) | (p[9] & 0x0F);
return (eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 0) == magic0 && eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 1) == magic1 && eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 2) == magic2);
uint8_t ee_magic0;
uint8_t ee_magic1;
uint8_t ee_magic2;
nvm_via_read_magic(&ee_magic0, &ee_magic1, &ee_magic2);
return ee_magic0 == magic0 && ee_magic1 == magic1 && ee_magic2 == magic2;
}
// Sets VIA/keyboard level usage of EEPROM to valid/invalid
// Keyboard level code (eg. via_init_kb()) should not call this
void via_eeprom_set_valid(bool valid) {
char * p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54"
uint8_t magic0 = ((p[2] & 0x0F) << 4) | (p[3] & 0x0F);
uint8_t magic1 = ((p[5] & 0x0F) << 4) | (p[6] & 0x0F);
uint8_t magic2 = ((p[8] & 0x0F) << 4) | (p[9] & 0x0F);
eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 0, valid ? magic0 : 0xFF);
eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 1, valid ? magic1 : 0xFF);
eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 2, valid ? magic2 : 0xFF);
if (valid) {
char * p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54"
uint8_t magic0 = ((p[2] & 0x0F) << 4) | (p[3] & 0x0F);
uint8_t magic1 = ((p[5] & 0x0F) << 4) | (p[6] & 0x0F);
uint8_t magic2 = ((p[8] & 0x0F) << 4) | (p[9] & 0x0F);
nvm_via_update_magic(magic0, magic1, magic2);
} else {
nvm_via_update_magic(0xFF, 0xFF, 0xFF);
}
}
// Override this at the keyboard code level to check
@ -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

View File

@ -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
#endif

View File

@ -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();