diff options
Diffstat (limited to 'tmk_core/common/keyboard.c')
-rw-r--r-- | tmk_core/common/keyboard.c | 138 |
1 files changed, 62 insertions, 76 deletions
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c index 8f0257cf6..f4d2cd738 100644 --- a/tmk_core/common/keyboard.c +++ b/tmk_core/common/keyboard.c | |||
@@ -32,84 +32,82 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
32 | #include "backlight.h" | 32 | #include "backlight.h" |
33 | #include "action_layer.h" | 33 | #include "action_layer.h" |
34 | #ifdef BOOTMAGIC_ENABLE | 34 | #ifdef BOOTMAGIC_ENABLE |
35 | # include "bootmagic.h" | 35 | # include "bootmagic.h" |
36 | #else | 36 | #else |
37 | # include "magic.h" | 37 | # include "magic.h" |
38 | #endif | 38 | #endif |
39 | #ifdef MOUSEKEY_ENABLE | 39 | #ifdef MOUSEKEY_ENABLE |
40 | # include "mousekey.h" | 40 | # include "mousekey.h" |
41 | #endif | 41 | #endif |
42 | #ifdef PS2_MOUSE_ENABLE | 42 | #ifdef PS2_MOUSE_ENABLE |
43 | # include "ps2_mouse.h" | 43 | # include "ps2_mouse.h" |
44 | #endif | 44 | #endif |
45 | #ifdef SERIAL_MOUSE_ENABLE | 45 | #ifdef SERIAL_MOUSE_ENABLE |
46 | # include "serial_mouse.h" | 46 | # include "serial_mouse.h" |
47 | #endif | 47 | #endif |
48 | #ifdef ADB_MOUSE_ENABLE | 48 | #ifdef ADB_MOUSE_ENABLE |
49 | # include "adb.h" | 49 | # include "adb.h" |
50 | #endif | 50 | #endif |
51 | #ifdef RGBLIGHT_ENABLE | 51 | #ifdef RGBLIGHT_ENABLE |
52 | # include "rgblight.h" | 52 | # include "rgblight.h" |
53 | #endif | 53 | #endif |
54 | #ifdef STENO_ENABLE | 54 | #ifdef STENO_ENABLE |
55 | # include "process_steno.h" | 55 | # include "process_steno.h" |
56 | #endif | 56 | #endif |
57 | #ifdef FAUXCLICKY_ENABLE | 57 | #ifdef FAUXCLICKY_ENABLE |
58 | # include "fauxclicky.h" | 58 | # include "fauxclicky.h" |
59 | #endif | 59 | #endif |
60 | #ifdef SERIAL_LINK_ENABLE | 60 | #ifdef SERIAL_LINK_ENABLE |
61 | # include "serial_link/system/serial_link.h" | 61 | # include "serial_link/system/serial_link.h" |
62 | #endif | 62 | #endif |
63 | #ifdef VISUALIZER_ENABLE | 63 | #ifdef VISUALIZER_ENABLE |
64 | # include "visualizer/visualizer.h" | 64 | # include "visualizer/visualizer.h" |
65 | #endif | 65 | #endif |
66 | #ifdef POINTING_DEVICE_ENABLE | 66 | #ifdef POINTING_DEVICE_ENABLE |
67 | # include "pointing_device.h" | 67 | # include "pointing_device.h" |
68 | #endif | 68 | #endif |
69 | #ifdef MIDI_ENABLE | 69 | #ifdef MIDI_ENABLE |
70 | # include "process_midi.h" | 70 | # include "process_midi.h" |
71 | #endif | 71 | #endif |
72 | #ifdef HD44780_ENABLE | 72 | #ifdef HD44780_ENABLE |
73 | # include "hd44780.h" | 73 | # include "hd44780.h" |
74 | #endif | 74 | #endif |
75 | #ifdef QWIIC_ENABLE | 75 | #ifdef QWIIC_ENABLE |
76 | # include "qwiic.h" | 76 | # include "qwiic.h" |
77 | #endif | 77 | #endif |
78 | #ifdef OLED_DRIVER_ENABLE | 78 | #ifdef OLED_DRIVER_ENABLE |
79 | #include "oled_driver.h" | 79 | # include "oled_driver.h" |
80 | #endif | 80 | #endif |
81 | #ifdef VELOCIKEY_ENABLE | 81 | #ifdef VELOCIKEY_ENABLE |
82 | #include "velocikey.h" | 82 | # include "velocikey.h" |
83 | #endif | 83 | #endif |
84 | 84 | ||
85 | #ifdef MATRIX_HAS_GHOST | 85 | #ifdef MATRIX_HAS_GHOST |
86 | extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; | 86 | extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; |
87 | static matrix_row_t get_real_keys(uint8_t row, matrix_row_t rowdata){ | 87 | static matrix_row_t get_real_keys(uint8_t row, matrix_row_t rowdata) { |
88 | matrix_row_t out = 0; | 88 | matrix_row_t out = 0; |
89 | for (uint8_t col = 0; col < MATRIX_COLS; col++) { | 89 | for (uint8_t col = 0; col < MATRIX_COLS; col++) { |
90 | //read each key in the row data and check if the keymap defines it as a real key | 90 | // read each key in the row data and check if the keymap defines it as a real key |
91 | if (pgm_read_byte(&keymaps[0][row][col]) && (rowdata & (1<<col))){ | 91 | if (pgm_read_byte(&keymaps[0][row][col]) && (rowdata & (1 << col))) { |
92 | //this creates new row data, if a key is defined in the keymap, it will be set here | 92 | // this creates new row data, if a key is defined in the keymap, it will be set here |
93 | out |= 1<<col; | 93 | out |= 1 << col; |
94 | } | 94 | } |
95 | } | 95 | } |
96 | return out; | 96 | return out; |
97 | } | 97 | } |
98 | 98 | ||
99 | static inline bool popcount_more_than_one(matrix_row_t rowdata) | 99 | static inline bool popcount_more_than_one(matrix_row_t rowdata) { |
100 | { | 100 | rowdata &= rowdata - 1; // if there are less than two bits (keys) set, rowdata will become zero |
101 | rowdata &= rowdata-1; //if there are less than two bits (keys) set, rowdata will become zero | ||
102 | return rowdata; | 101 | return rowdata; |
103 | } | 102 | } |
104 | 103 | ||
105 | static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata) | 104 | static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata) { |
106 | { | ||
107 | /* No ghost exists when less than 2 keys are down on the row. | 105 | /* No ghost exists when less than 2 keys are down on the row. |
108 | If there are "active" blanks in the matrix, the key can't be pressed by the user, | 106 | If there are "active" blanks in the matrix, the key can't be pressed by the user, |
109 | there is no doubt as to which keys are really being pressed. | 107 | there is no doubt as to which keys are really being pressed. |
110 | The ghosts will be ignored, they are KC_NO. */ | 108 | The ghosts will be ignored, they are KC_NO. */ |
111 | rowdata = get_real_keys(row, rowdata); | 109 | rowdata = get_real_keys(row, rowdata); |
112 | if ((popcount_more_than_one(rowdata)) == 0){ | 110 | if ((popcount_more_than_one(rowdata)) == 0) { |
113 | return false; | 111 | return false; |
114 | } | 112 | } |
115 | /* Ghost occurs when the row shares a column line with other row, | 113 | /* Ghost occurs when the row shares a column line with other row, |
@@ -119,8 +117,8 @@ static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata) | |||
119 | at least two of another row's real keys, the row will be ignored. Keep in mind, | 117 | at least two of another row's real keys, the row will be ignored. Keep in mind, |
120 | we are checking one row at a time, not all of them at once. | 118 | we are checking one row at a time, not all of them at once. |
121 | */ | 119 | */ |
122 | for (uint8_t i=0; i < MATRIX_ROWS; i++) { | 120 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { |
123 | if (i != row && popcount_more_than_one(get_real_keys(i, matrix_get_row(i)) & rowdata)){ | 121 | if (i != row && popcount_more_than_one(get_real_keys(i, matrix_get_row(i)) & rowdata)) { |
124 | return true; | 122 | return true; |
125 | } | 123 | } |
126 | } | 124 | } |
@@ -131,9 +129,7 @@ static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata) | |||
131 | 129 | ||
132 | void disable_jtag(void) { | 130 | void disable_jtag(void) { |
133 | // To use PF4-7 (PC2-5 on ATmega32A), disable JTAG by writing JTD bit twice within four cycles. | 131 | // To use PF4-7 (PC2-5 on ATmega32A), disable JTAG by writing JTD bit twice within four cycles. |
134 | #if (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || \ | 132 | #if (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) |
135 | defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || \ | ||
136 | defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) | ||
137 | MCUCR |= _BV(JTD); | 133 | MCUCR |= _BV(JTD); |
138 | MCUCR |= _BV(JTD); | 134 | MCUCR |= _BV(JTD); |
139 | #elif defined(__AVR_ATmega32A__) | 135 | #elif defined(__AVR_ATmega32A__) |
@@ -146,43 +142,33 @@ void disable_jtag(void) { | |||
146 | * | 142 | * |
147 | * FIXME: needs doc | 143 | * FIXME: needs doc |
148 | */ | 144 | */ |
149 | __attribute__ ((weak)) | 145 | __attribute__((weak)) void matrix_setup(void) {} |
150 | void matrix_setup(void) { | ||
151 | } | ||
152 | 146 | ||
153 | /** \brief keyboard_pre_init_user | 147 | /** \brief keyboard_pre_init_user |
154 | * | 148 | * |
155 | * FIXME: needs doc | 149 | * FIXME: needs doc |
156 | */ | 150 | */ |
157 | __attribute__ ((weak)) | 151 | __attribute__((weak)) void keyboard_pre_init_user(void) {} |
158 | void keyboard_pre_init_user(void) { } | ||
159 | 152 | ||
160 | /** \brief keyboard_pre_init_kb | 153 | /** \brief keyboard_pre_init_kb |
161 | * | 154 | * |
162 | * FIXME: needs doc | 155 | * FIXME: needs doc |
163 | */ | 156 | */ |
164 | __attribute__ ((weak)) | 157 | __attribute__((weak)) void keyboard_pre_init_kb(void) { keyboard_pre_init_user(); } |
165 | void keyboard_pre_init_kb(void) { | ||
166 | keyboard_pre_init_user(); | ||
167 | } | ||
168 | 158 | ||
169 | /** \brief keyboard_post_init_user | 159 | /** \brief keyboard_post_init_user |
170 | * | 160 | * |
171 | * FIXME: needs doc | 161 | * FIXME: needs doc |
172 | */ | 162 | */ |
173 | 163 | ||
174 | __attribute__ ((weak)) | 164 | __attribute__((weak)) void keyboard_post_init_user() {} |
175 | void keyboard_post_init_user() {} | ||
176 | 165 | ||
177 | /** \brief keyboard_post_init_kb | 166 | /** \brief keyboard_post_init_kb |
178 | * | 167 | * |
179 | * FIXME: needs doc | 168 | * FIXME: needs doc |
180 | */ | 169 | */ |
181 | 170 | ||
182 | __attribute__ ((weak)) | 171 | __attribute__((weak)) void keyboard_post_init_kb(void) { keyboard_post_init_user(); } |
183 | void keyboard_post_init_kb(void) { | ||
184 | keyboard_post_init_user(); | ||
185 | } | ||
186 | 172 | ||
187 | /** \brief keyboard_setup | 173 | /** \brief keyboard_setup |
188 | * | 174 | * |
@@ -200,10 +186,7 @@ void keyboard_setup(void) { | |||
200 | * | 186 | * |
201 | * FIXME: needs doc | 187 | * FIXME: needs doc |
202 | */ | 188 | */ |
203 | __attribute__((weak)) | 189 | __attribute__((weak)) bool is_keyboard_master(void) { return true; } |
204 | bool is_keyboard_master(void) { | ||
205 | return true; | ||
206 | } | ||
207 | 190 | ||
208 | /** \brief keyboard_init | 191 | /** \brief keyboard_init |
209 | * | 192 | * |
@@ -265,12 +248,11 @@ void keyboard_init(void) { | |||
265 | * | 248 | * |
266 | * This is repeatedly called as fast as possible. | 249 | * This is repeatedly called as fast as possible. |
267 | */ | 250 | */ |
268 | void keyboard_task(void) | 251 | void keyboard_task(void) { |
269 | { | ||
270 | static matrix_row_t matrix_prev[MATRIX_ROWS]; | 252 | static matrix_row_t matrix_prev[MATRIX_ROWS]; |
271 | static uint8_t led_status = 0; | 253 | static uint8_t led_status = 0; |
272 | matrix_row_t matrix_row = 0; | 254 | matrix_row_t matrix_row = 0; |
273 | matrix_row_t matrix_change = 0; | 255 | matrix_row_t matrix_change = 0; |
274 | #ifdef QMK_KEYS_PER_SCAN | 256 | #ifdef QMK_KEYS_PER_SCAN |
275 | uint8_t keys_processed = 0; | 257 | uint8_t keys_processed = 0; |
276 | #endif | 258 | #endif |
@@ -283,28 +265,28 @@ void keyboard_task(void) | |||
283 | 265 | ||
284 | if (is_keyboard_master()) { | 266 | if (is_keyboard_master()) { |
285 | for (uint8_t r = 0; r < MATRIX_ROWS; r++) { | 267 | for (uint8_t r = 0; r < MATRIX_ROWS; r++) { |
286 | matrix_row = matrix_get_row(r); | 268 | matrix_row = matrix_get_row(r); |
287 | matrix_change = matrix_row ^ matrix_prev[r]; | 269 | matrix_change = matrix_row ^ matrix_prev[r]; |
288 | if (matrix_change) { | 270 | if (matrix_change) { |
289 | #ifdef MATRIX_HAS_GHOST | 271 | #ifdef MATRIX_HAS_GHOST |
290 | if (has_ghost_in_row(r, matrix_row)) { continue; } | 272 | if (has_ghost_in_row(r, matrix_row)) { |
273 | continue; | ||
274 | } | ||
291 | #endif | 275 | #endif |
292 | if (debug_matrix) matrix_print(); | 276 | if (debug_matrix) matrix_print(); |
293 | for (uint8_t c = 0; c < MATRIX_COLS; c++) { | 277 | for (uint8_t c = 0; c < MATRIX_COLS; c++) { |
294 | if (matrix_change & ((matrix_row_t)1<<c)) { | 278 | if (matrix_change & ((matrix_row_t)1 << c)) { |
295 | action_exec((keyevent_t){ | 279 | action_exec((keyevent_t){ |
296 | .key = (keypos_t){ .row = r, .col = c }, | 280 | .key = (keypos_t){.row = r, .col = c}, .pressed = (matrix_row & ((matrix_row_t)1 << c)), .time = (timer_read() | 1) /* time should not be 0 */ |
297 | .pressed = (matrix_row & ((matrix_row_t)1<<c)), | ||
298 | .time = (timer_read() | 1) /* time should not be 0 */ | ||
299 | }); | 281 | }); |
300 | // record a processed key | 282 | // record a processed key |
301 | matrix_prev[r] ^= ((matrix_row_t)1<<c); | 283 | matrix_prev[r] ^= ((matrix_row_t)1 << c); |
302 | #ifdef QMK_KEYS_PER_SCAN | 284 | #ifdef QMK_KEYS_PER_SCAN |
303 | // only jump out if we have processed "enough" keys. | 285 | // only jump out if we have processed "enough" keys. |
304 | if (++keys_processed >= QMK_KEYS_PER_SCAN) | 286 | if (++keys_processed >= QMK_KEYS_PER_SCAN) |
305 | #endif | 287 | #endif |
306 | // process a key per task call | 288 | // process a key per task call |
307 | goto MATRIX_LOOP_END; | 289 | goto MATRIX_LOOP_END; |
308 | } | 290 | } |
309 | } | 291 | } |
310 | } | 292 | } |
@@ -315,7 +297,7 @@ void keyboard_task(void) | |||
315 | // we can get here with some keys processed now. | 297 | // we can get here with some keys processed now. |
316 | if (!keys_processed) | 298 | if (!keys_processed) |
317 | #endif | 299 | #endif |
318 | action_exec(TICK); | 300 | action_exec(TICK); |
319 | 301 | ||
320 | MATRIX_LOOP_END: | 302 | MATRIX_LOOP_END: |
321 | 303 | ||
@@ -325,11 +307,10 @@ MATRIX_LOOP_END: | |||
325 | 307 | ||
326 | #ifdef OLED_DRIVER_ENABLE | 308 | #ifdef OLED_DRIVER_ENABLE |
327 | oled_task(); | 309 | oled_task(); |
328 | #ifndef OLED_DISABLE_TIMEOUT | 310 | # ifndef OLED_DISABLE_TIMEOUT |
329 | // Wake up oled if user is using those fabulous keys! | 311 | // Wake up oled if user is using those fabulous keys! |
330 | if (ret) | 312 | if (ret) oled_on(); |
331 | oled_on(); | 313 | # endif |
332 | #endif | ||
333 | #endif | 314 | #endif |
334 | 315 | ||
335 | #ifdef MOUSEKEY_ENABLE | 316 | #ifdef MOUSEKEY_ENABLE |
@@ -350,7 +331,7 @@ MATRIX_LOOP_END: | |||
350 | #endif | 331 | #endif |
351 | 332 | ||
352 | #ifdef SERIAL_LINK_ENABLE | 333 | #ifdef SERIAL_LINK_ENABLE |
353 | serial_link_update(); | 334 | serial_link_update(); |
354 | #endif | 335 | #endif |
355 | 336 | ||
356 | #ifdef VISUALIZER_ENABLE | 337 | #ifdef VISUALIZER_ENABLE |
@@ -366,7 +347,9 @@ MATRIX_LOOP_END: | |||
366 | #endif | 347 | #endif |
367 | 348 | ||
368 | #ifdef VELOCIKEY_ENABLE | 349 | #ifdef VELOCIKEY_ENABLE |
369 | if (velocikey_enabled()) { velocikey_decelerate(); } | 350 | if (velocikey_enabled()) { |
351 | velocikey_decelerate(); | ||
352 | } | ||
370 | #endif | 353 | #endif |
371 | 354 | ||
372 | // update LED | 355 | // update LED |
@@ -380,8 +363,11 @@ MATRIX_LOOP_END: | |||
380 | * | 363 | * |
381 | * FIXME: needs doc | 364 | * FIXME: needs doc |
382 | */ | 365 | */ |
383 | void keyboard_set_leds(uint8_t leds) | 366 | void keyboard_set_leds(uint8_t leds) { |
384 | { | 367 | if (debug_keyboard) { |
385 | if (debug_keyboard) { debug("keyboard_set_led: "); debug_hex8(leds); debug("\n"); } | 368 | debug("keyboard_set_led: "); |
369 | debug_hex8(leds); | ||
370 | debug("\n"); | ||
371 | } | ||
386 | led_set(leds); | 372 | led_set(leds); |
387 | } | 373 | } |