aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/common/keyboard.c
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/common/keyboard.c')
-rw-r--r--tmk_core/common/keyboard.c138
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
86extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; 86extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
87static matrix_row_t get_real_keys(uint8_t row, matrix_row_t rowdata){ 87static 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
99static inline bool popcount_more_than_one(matrix_row_t rowdata) 99static 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
105static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata) 104static 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
132void disable_jtag(void) { 130void 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) {}
150void 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) {}
158void 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(); }
165void 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() {}
175void 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(); }
183void 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; }
204bool 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 */
268void keyboard_task(void) 251void 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
320MATRIX_LOOP_END: 302MATRIX_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 */
383void keyboard_set_leds(uint8_t leds) 366void 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}