diff --git a/quantum/dynamic_keymap.c b/quantum/dynamic_keymap.c index 5f2f4d5f22..bb4d91bf38 100644 --- a/quantum/dynamic_keymap.c +++ b/quantum/dynamic_keymap.c @@ -76,9 +76,19 @@ static pin_t encoders_pad_a[] = ENCODERS_PAD_A; #define VIAL_ENCODERS_SIZE 0 #endif +#define VIAL_QMK_SETTINGS_EEPROM_ADDR (VIAL_ENCODERS_EEPROM_ADDR + VIAL_ENCODERS_SIZE) + +// QMK settings area is just past encoders, or dynamic keymaps if encoders aren't enabled +#ifdef QMK_SETTINGS +#include "qmk_settings.h" +#define VIAL_QMK_SETTINGS_SIZE (sizeof(qmk_settings_t)) +#else +#define VIAL_QMK_SETTINGS_SIZE 0 +#endif + // Dynamic macro starts after encoders, or dynamic keymaps if encoders aren't enabled #ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR -# define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR (VIAL_ENCODERS_EEPROM_ADDR + VIAL_ENCODERS_SIZE) +# define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR (VIAL_QMK_SETTINGS_EEPROM_ADDR + VIAL_QMK_SETTINGS_SIZE) #endif // Sanity check that dynamic keymaps fit in available EEPROM @@ -157,6 +167,24 @@ void dynamic_keymap_set_encoder(uint8_t layer, uint8_t idx, uint8_t dir, uint16_ } #endif +#ifdef QMK_SETTINGS +uint8_t dynamic_keymap_get_qmk_settings(uint16_t offset) { + if (offset >= VIAL_QMK_SETTINGS_SIZE) + return 0; + + void *address = (void*)(VIAL_QMK_SETTINGS_EEPROM_ADDR + offset); + return eeprom_read_byte(address); +} + +void dynamic_keymap_set_qmk_settings(uint16_t offset, uint8_t value) { + if (offset >= VIAL_QMK_SETTINGS_SIZE) + return; + + void *address = (void*)(VIAL_QMK_SETTINGS_EEPROM_ADDR + offset); + eeprom_update_byte(address, value); +} +#endif + #if defined(VIAL_ENCODERS_ENABLE) && defined(VIAL_ENCODER_DEFAULT) static const uint16_t PROGMEM vial_encoder_default[] = VIAL_ENCODER_DEFAULT; _Static_assert(sizeof(vial_encoder_default)/sizeof(*vial_encoder_default) == 2 * DYNAMIC_KEYMAP_LAYER_COUNT * NUMBER_OF_ENCODERS, @@ -193,6 +221,10 @@ void dynamic_keymap_reset(void) { #endif } +#ifdef QMK_SETTINGS + qmk_settings_reset(); +#endif + #ifdef VIAL_ENABLE /* re-lock the keyboard */ vial_unlocked = vial_unlocked_prev; diff --git a/quantum/dynamic_keymap.h b/quantum/dynamic_keymap.h index a6bcdd878b..e7bf8b462d 100644 --- a/quantum/dynamic_keymap.h +++ b/quantum/dynamic_keymap.h @@ -30,6 +30,10 @@ void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t dynamic_keymap_get_encoder(uint8_t layer, uint8_t idx, uint8_t dir); void dynamic_keymap_set_encoder(uint8_t layer, uint8_t idx, uint8_t dir, uint16_t keycode); #endif +#ifdef QMK_SETTINGS +uint8_t dynamic_keymap_get_qmk_settings(uint16_t offset); +void dynamic_keymap_set_qmk_settings(uint16_t offset, uint8_t value); +#endif void dynamic_keymap_reset(void); // These get/set the keycodes as stored in the EEPROM buffer // Data is big-endian 16-bit values (the keycodes) diff --git a/quantum/qmk_settings.c b/quantum/qmk_settings.c index 346cd8023c..50c4e39395 100644 --- a/quantum/qmk_settings.c +++ b/quantum/qmk_settings.c @@ -1,9 +1,11 @@ #include "qmk_settings.h" #include -#include "progmem.h" #include +#include "progmem.h" +#include "dynamic_keymap.h" + qmk_settings_t QS; #define DECLARE_SETTING(id, field) { .qsid=id, .ptr=&QS.field, .sz=sizeof(QS.field) } @@ -26,6 +28,42 @@ static const qmk_settings_proto_t *find_setting(uint16_t qsid) { return NULL; } +static void load_settings(void) { + for (size_t i = 0; i < sizeof(qmk_settings_t); ++i) { + uint8_t byte; + byte = dynamic_keymap_get_qmk_settings(i); + memcpy((char*)&QS + i, &byte, 1); + } +} + +static void save_settings(void) { + for (size_t i = 0; i < sizeof(qmk_settings_t); ++i) { + uint8_t old_byte, new_byte; + old_byte = dynamic_keymap_get_qmk_settings(i); + memcpy(&new_byte, (char*)&QS + i, 1); + if (old_byte != new_byte) + dynamic_keymap_set_qmk_settings(i, new_byte); + } +} + +void qmk_settings_init(void) { + load_settings(); +} + +void qmk_settings_reset(void) { + /* TODO: this should take values from various #define's */ + QS.grave_esc_override = 0; + QS.debounce_time = 5; + QS.auto_shift = 0; + QS.auto_shift_timeout = 175; + QS.osk_tap_toggle = 0; + QS.osk_timeout = 5000; + QS.tapping_term = 200; + QS.tap_hold = 0; + + save_settings(); +} + int qmk_settings_get(uint16_t qsid, void *setting, size_t maxsz) { const qmk_settings_proto_t *proto = find_setting(qsid); if (!proto || pgm_read_word(&proto->sz) > maxsz) @@ -39,5 +77,6 @@ int qmk_settings_set(uint16_t qsid, const void *setting, size_t maxsz) { if (!proto || pgm_read_word(&proto->sz) > maxsz) return -1; memcpy(pgm_read_ptr(&proto->ptr), setting, pgm_read_word(&proto->sz)); + save_settings(); return 0; } diff --git a/quantum/qmk_settings.h b/quantum/qmk_settings.h index 86c075abc0..5aaed68d6b 100644 --- a/quantum/qmk_settings.h +++ b/quantum/qmk_settings.h @@ -56,6 +56,8 @@ typedef struct { void *ptr; } qmk_settings_proto_t; +void qmk_settings_init(void); +void qmk_settings_reset(void); int qmk_settings_get(uint16_t qsid, void *setting, size_t maxsz); int qmk_settings_set(uint16_t qsid, const void *setting, size_t maxsz); diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c index 3d6092e71c..ad3bd6ad55 100644 --- a/tmk_core/common/keyboard.c +++ b/tmk_core/common/keyboard.c @@ -100,6 +100,9 @@ along with this program. If not, see . #ifdef EEPROM_DRIVER # include "eeprom_driver.h" #endif +#ifdef QMK_SETTINGS +# include "qmk_settings.h" +#endif static uint32_t last_input_modification_time = 0; uint32_t last_input_activity_time(void) { return last_input_modification_time; } @@ -242,6 +245,9 @@ void keyboard_setup(void) { #endif #ifdef EEPROM_DRIVER eeprom_driver_init(); +#endif +#ifdef QMK_SETTINGS + qmk_settings_init(); #endif matrix_setup(); keyboard_pre_init_kb();