summaryrefslogtreecommitdiff
path: root/quantum/dynamic_keymap.c
diff options
context:
space:
mode:
authorNick Brassel <nick@tzarc.org>2022-03-09 19:29:00 +1100
committerGitHub <noreply@github.com>2022-03-09 19:29:00 +1100
commit8d5eacb7dd76bfd45444ceb1efa9a9f840173552 (patch)
treeb6b8b641dd61f5de0c5b7ee1bf251f6a84043656 /quantum/dynamic_keymap.c
parent7121a228eb204a0d697c97503ac7a28b762ab598 (diff)
Add support for encoder mapping. (#13286)
Diffstat (limited to 'quantum/dynamic_keymap.c')
-rw-r--r--quantum/dynamic_keymap.c50
1 files changed, 46 insertions, 4 deletions
diff --git a/quantum/dynamic_keymap.c b/quantum/dynamic_keymap.c
index f070375ff3..c0859ca35f 100644
--- a/quantum/dynamic_keymap.c
+++ b/quantum/dynamic_keymap.c
@@ -58,9 +58,14 @@
58# endif 58# endif
59#endif 59#endif
60 60
61// Dynamic macro starts after dynamic keymaps 61// Dynamic encoders starts after dynamic keymaps
62#ifndef DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR
63# define DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR (DYNAMIC_KEYMAP_EEPROM_ADDR + (DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2))
64#endif
65
66// Dynamic macro starts after dynamic encoders
62#ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR 67#ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR
63# define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR (DYNAMIC_KEYMAP_EEPROM_ADDR + (DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2)) 68# define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR (DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR + (DYNAMIC_KEYMAP_LAYER_COUNT * NUM_ENCODERS * 2 * 2))
64#endif 69#endif
65 70
66// Sanity check that dynamic keymaps fit in available EEPROM 71// Sanity check that dynamic keymaps fit in available EEPROM
@@ -89,6 +94,7 @@ void *dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t c
89} 94}
90 95
91uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column) { 96uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column) {
97 if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || row >= MATRIX_ROWS || column >= MATRIX_COLS) return KC_NO;
92 void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column); 98 void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column);
93 // Big endian, so we can read/write EEPROM directly from host if we want 99 // Big endian, so we can read/write EEPROM directly from host if we want
94 uint16_t keycode = eeprom_read_byte(address) << 8; 100 uint16_t keycode = eeprom_read_byte(address) << 8;
@@ -97,12 +103,36 @@ uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column)
97} 103}
98 104
99void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode) { 105void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode) {
106 if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || row >= MATRIX_ROWS || column >= MATRIX_COLS) return;
100 void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column); 107 void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column);
101 // Big endian, so we can read/write EEPROM directly from host if we want 108 // Big endian, so we can read/write EEPROM directly from host if we want
102 eeprom_update_byte(address, (uint8_t)(keycode >> 8)); 109 eeprom_update_byte(address, (uint8_t)(keycode >> 8));
103 eeprom_update_byte(address + 1, (uint8_t)(keycode & 0xFF)); 110 eeprom_update_byte(address + 1, (uint8_t)(keycode & 0xFF));
104} 111}
105 112
113#ifdef ENCODER_MAP_ENABLE
114void *dynamic_keymap_encoder_to_eeprom_address(uint8_t layer, uint8_t encoder_id) {
115 return ((void *)DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR) + (layer * NUM_ENCODERS * 2 * 2) + (encoder_id * 2 * 2);
116}
117
118uint16_t dynamic_keymap_get_encoder(uint8_t layer, uint8_t encoder_id, bool clockwise) {
119 if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || encoder_id >= NUM_ENCODERS) return KC_NO;
120 void *address = dynamic_keymap_encoder_to_eeprom_address(layer, encoder_id);
121 // Big endian, so we can read/write EEPROM directly from host if we want
122 uint16_t keycode = ((uint16_t)eeprom_read_byte(address + (clockwise ? 0 : 2))) << 8;
123 keycode |= eeprom_read_byte(address + (clockwise ? 0 : 2) + 1);
124 return keycode;
125}
126
127void dynamic_keymap_set_encoder(uint8_t layer, uint8_t encoder_id, bool clockwise, uint16_t keycode) {
128 if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || encoder_id >= NUM_ENCODERS) return;
129 void *address = dynamic_keymap_encoder_to_eeprom_address(layer, encoder_id);
130 // Big endian, so we can read/write EEPROM directly from host if we want
131 eeprom_update_byte(address + (clockwise ? 0 : 2), (uint8_t)(keycode >> 8));
132 eeprom_update_byte(address + (clockwise ? 0 : 2) + 1, (uint8_t)(keycode & 0xFF));
133}
134#endif // ENCODER_MAP_ENABLE
135
106void dynamic_keymap_reset(void) { 136void dynamic_keymap_reset(void) {
107 // Reset the keymaps in EEPROM to what is in flash. 137 // Reset the keymaps in EEPROM to what is in flash.
108 // All keyboards using dynamic keymaps should define a layout 138 // All keyboards using dynamic keymaps should define a layout
@@ -113,6 +143,12 @@ void dynamic_keymap_reset(void) {
113 dynamic_keymap_set_keycode(layer, row, column, pgm_read_word(&keymaps[layer][row][column])); 143 dynamic_keymap_set_keycode(layer, row, column, pgm_read_word(&keymaps[layer][row][column]));
114 } 144 }
115 } 145 }
146#ifdef ENCODER_MAP_ENABLE
147 for (int encoder = 0; encoder < NUM_ENCODERS; encoder++) {
148 dynamic_keymap_set_encoder(layer, encoder, true, pgm_read_word(&encoder_map[layer][encoder][0]));
149 dynamic_keymap_set_encoder(layer, encoder, false, pgm_read_word(&encoder_map[layer][encoder][1]));
150 }
151#endif // ENCODER_MAP_ENABLE
116 } 152 }
117} 153}
118 154
@@ -148,9 +184,15 @@ void dynamic_keymap_set_buffer(uint16_t offset, uint16_t size, uint8_t *data) {
148uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) { 184uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) {
149 if (layer < DYNAMIC_KEYMAP_LAYER_COUNT && key.row < MATRIX_ROWS && key.col < MATRIX_COLS) { 185 if (layer < DYNAMIC_KEYMAP_LAYER_COUNT && key.row < MATRIX_ROWS && key.col < MATRIX_COLS) {
150 return dynamic_keymap_get_keycode(layer, key.row, key.col); 186 return dynamic_keymap_get_keycode(layer, key.row, key.col);
151 } else {
152 return KC_NO;
153 } 187 }
188#ifdef ENCODER_MAP_ENABLE
189 else if (layer < DYNAMIC_KEYMAP_LAYER_COUNT && key.row == KEYLOC_ENCODER_CW && key.col < NUM_ENCODERS) {
190 return dynamic_keymap_get_encoder(layer, key.col, true);
191 } else if (layer < DYNAMIC_KEYMAP_LAYER_COUNT && key.row == KEYLOC_ENCODER_CCW && key.col < NUM_ENCODERS) {
192 return dynamic_keymap_get_encoder(layer, key.col, false);
193 }
194#endif // ENCODER_MAP_ENABLE
195 return KC_NO;
154} 196}
155 197
156uint8_t dynamic_keymap_macro_get_count(void) { 198uint8_t dynamic_keymap_macro_get_count(void) {