794a9152fbeb749c0e588864137e4de33ae2821f
[jackhill/qmk/firmware.git] / tmk_core / common / keyboard.c
1 /*
2 Copyright 2011, 2012, 2013 Jun Wako <wakojun@gmail.com>
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <stdint.h>
19 #include "keyboard.h"
20 #include "matrix.h"
21 #include "keymap.h"
22 #include "host.h"
23 #include "led.h"
24 #include "keycode.h"
25 #include "timer.h"
26 #include "print.h"
27 #include "debug.h"
28 #include "command.h"
29 #include "util.h"
30 #include "sendchar.h"
31 #include "eeconfig.h"
32 #include "action_layer.h"
33 #ifdef BACKLIGHT_ENABLE
34 # include "backlight.h"
35 #endif
36 #ifdef BOOTMAGIC_ENABLE
37 # include "bootmagic.h"
38 #else
39 # include "magic.h"
40 #endif
41 #ifdef MOUSEKEY_ENABLE
42 # include "mousekey.h"
43 #endif
44 #ifdef PS2_MOUSE_ENABLE
45 # include "ps2_mouse.h"
46 #endif
47 #ifdef SERIAL_MOUSE_ENABLE
48 # include "serial_mouse.h"
49 #endif
50 #ifdef ADB_MOUSE_ENABLE
51 # include "adb.h"
52 #endif
53 #ifdef RGBLIGHT_ENABLE
54 # include "rgblight.h"
55 #endif
56 #ifdef STENO_ENABLE
57 # include "process_steno.h"
58 #endif
59 #ifdef FAUXCLICKY_ENABLE
60 # include "fauxclicky.h"
61 #endif
62 #ifdef SERIAL_LINK_ENABLE
63 # include "serial_link/system/serial_link.h"
64 #endif
65 #ifdef VISUALIZER_ENABLE
66 # include "visualizer/visualizer.h"
67 #endif
68 #ifdef POINTING_DEVICE_ENABLE
69 # include "pointing_device.h"
70 #endif
71 #ifdef MIDI_ENABLE
72 # include "process_midi.h"
73 #endif
74 #ifdef HD44780_ENABLE
75 # include "hd44780.h"
76 #endif
77 #ifdef QWIIC_ENABLE
78 # include "qwiic.h"
79 #endif
80 #ifdef OLED_DRIVER_ENABLE
81 # include "oled_driver.h"
82 #endif
83 #ifdef VELOCIKEY_ENABLE
84 # include "velocikey.h"
85 #endif
86 #ifdef VIA_ENABLE
87 # include "via.h"
88 #endif
89
90 // Only enable this if console is enabled to print to
91 #if defined(DEBUG_MATRIX_SCAN_RATE) && defined(CONSOLE_ENABLE)
92 static uint32_t matrix_timer = 0;
93 static uint32_t matrix_scan_count = 0;
94
95 void matrix_scan_perf_task(void) {
96 matrix_scan_count++;
97
98 uint32_t timer_now = timer_read32();
99 if (TIMER_DIFF_32(timer_now, matrix_timer) > 1000) {
100 dprintf("matrix scan frequency: %d\n", matrix_scan_count);
101
102 matrix_timer = timer_now;
103 matrix_scan_count = 0;
104 }
105 }
106 #else
107 # define matrix_scan_perf_task()
108 #endif
109
110 #ifdef MATRIX_HAS_GHOST
111 extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
112 static matrix_row_t get_real_keys(uint8_t row, matrix_row_t rowdata) {
113 matrix_row_t out = 0;
114 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
115 // read each key in the row data and check if the keymap defines it as a real key
116 if (pgm_read_byte(&keymaps[0][row][col]) && (rowdata & (1 << col))) {
117 // this creates new row data, if a key is defined in the keymap, it will be set here
118 out |= 1 << col;
119 }
120 }
121 return out;
122 }
123
124 static inline bool popcount_more_than_one(matrix_row_t rowdata) {
125 rowdata &= rowdata - 1; // if there are less than two bits (keys) set, rowdata will become zero
126 return rowdata;
127 }
128
129 static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata) {
130 /* No ghost exists when less than 2 keys are down on the row.
131 If there are "active" blanks in the matrix, the key can't be pressed by the user,
132 there is no doubt as to which keys are really being pressed.
133 The ghosts will be ignored, they are KC_NO. */
134 rowdata = get_real_keys(row, rowdata);
135 if ((popcount_more_than_one(rowdata)) == 0) {
136 return false;
137 }
138 /* Ghost occurs when the row shares a column line with other row,
139 and two columns are read on each row. Blanks in the matrix don't matter,
140 so they are filtered out.
141 If there are two or more real keys pressed and they match columns with
142 at least two of another row's real keys, the row will be ignored. Keep in mind,
143 we are checking one row at a time, not all of them at once.
144 */
145 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
146 if (i != row && popcount_more_than_one(get_real_keys(i, matrix_get_row(i)) & rowdata)) {
147 return true;
148 }
149 }
150 return false;
151 }
152
153 #endif
154
155 void disable_jtag(void) {
156 // To use PF4-7 (PC2-5 on ATmega32A), disable JTAG by writing JTD bit twice within four cycles.
157 #if (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
158 MCUCR |= _BV(JTD);
159 MCUCR |= _BV(JTD);
160 #elif defined(__AVR_ATmega32A__)
161 MCUCSR |= _BV(JTD);
162 MCUCSR |= _BV(JTD);
163 #endif
164 }
165
166 /** \brief matrix_setup
167 *
168 * FIXME: needs doc
169 */
170 __attribute__((weak)) void matrix_setup(void) {}
171
172 /** \brief keyboard_pre_init_user
173 *
174 * FIXME: needs doc
175 */
176 __attribute__((weak)) void keyboard_pre_init_user(void) {}
177
178 /** \brief keyboard_pre_init_kb
179 *
180 * FIXME: needs doc
181 */
182 __attribute__((weak)) void keyboard_pre_init_kb(void) { keyboard_pre_init_user(); }
183
184 /** \brief keyboard_post_init_user
185 *
186 * FIXME: needs doc
187 */
188
189 __attribute__((weak)) void keyboard_post_init_user() {}
190
191 /** \brief keyboard_post_init_kb
192 *
193 * FIXME: needs doc
194 */
195
196 __attribute__((weak)) void keyboard_post_init_kb(void) { keyboard_post_init_user(); }
197
198 /** \brief keyboard_setup
199 *
200 * FIXME: needs doc
201 */
202 void keyboard_setup(void) {
203 #ifndef NO_JTAG_DISABLE
204 disable_jtag();
205 #endif
206 matrix_setup();
207 keyboard_pre_init_kb();
208 }
209
210 /** \brief is_keyboard_master
211 *
212 * FIXME: needs doc
213 */
214 __attribute__((weak)) bool is_keyboard_master(void) { return true; }
215
216 /** \brief keyboard_init
217 *
218 * FIXME: needs doc
219 */
220 void keyboard_init(void) {
221 timer_init();
222 matrix_init();
223 #ifdef VIA_ENABLE
224 via_init();
225 #endif
226 #ifdef QWIIC_ENABLE
227 qwiic_init();
228 #endif
229 #ifdef OLED_DRIVER_ENABLE
230 oled_init(OLED_ROTATION_0);
231 #endif
232 #ifdef PS2_MOUSE_ENABLE
233 ps2_mouse_init();
234 #endif
235 #ifdef SERIAL_MOUSE_ENABLE
236 serial_mouse_init();
237 #endif
238 #ifdef ADB_MOUSE_ENABLE
239 adb_mouse_init();
240 #endif
241 #ifdef BOOTMAGIC_ENABLE
242 bootmagic();
243 #else
244 magic();
245 #endif
246 #ifdef BACKLIGHT_ENABLE
247 backlight_init();
248 #endif
249 #ifdef RGBLIGHT_ENABLE
250 rgblight_init();
251 #endif
252 #ifdef STENO_ENABLE
253 steno_init();
254 #endif
255 #ifdef FAUXCLICKY_ENABLE
256 fauxclicky_init();
257 #endif
258 #ifdef POINTING_DEVICE_ENABLE
259 pointing_device_init();
260 #endif
261 #if defined(NKRO_ENABLE) && defined(FORCE_NKRO)
262 keymap_config.nkro = 1;
263 eeconfig_update_keymap(keymap_config.raw);
264 #endif
265 keyboard_post_init_kb(); /* Always keep this last */
266 }
267
268 /** \brief Keyboard task: Do keyboard routine jobs
269 *
270 * Do routine keyboard jobs:
271 *
272 * * scan matrix
273 * * handle mouse movements
274 * * run visualizer code
275 * * handle midi commands
276 * * light LEDs
277 *
278 * This is repeatedly called as fast as possible.
279 */
280 void keyboard_task(void) {
281 static matrix_row_t matrix_prev[MATRIX_ROWS];
282 static uint8_t led_status = 0;
283 matrix_row_t matrix_row = 0;
284 matrix_row_t matrix_change = 0;
285 #ifdef QMK_KEYS_PER_SCAN
286 uint8_t keys_processed = 0;
287 #endif
288
289 #if defined(OLED_DRIVER_ENABLE) && !defined(OLED_DISABLE_TIMEOUT)
290 uint8_t ret = matrix_scan();
291 #else
292 matrix_scan();
293 #endif
294
295 if (is_keyboard_master()) {
296 for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
297 matrix_row = matrix_get_row(r);
298 matrix_change = matrix_row ^ matrix_prev[r];
299 if (matrix_change) {
300 #ifdef MATRIX_HAS_GHOST
301 if (has_ghost_in_row(r, matrix_row)) {
302 continue;
303 }
304 #endif
305 if (debug_matrix) matrix_print();
306 matrix_row_t col_mask = 1;
307 for (uint8_t c = 0; c < MATRIX_COLS; c++, col_mask <<= 1) {
308 if (matrix_change & col_mask) {
309 action_exec((keyevent_t){
310 .key = (keypos_t){.row = r, .col = c}, .pressed = (matrix_row & col_mask), .time = (timer_read() | 1) /* time should not be 0 */
311 });
312 // record a processed key
313 matrix_prev[r] ^= col_mask;
314 #ifdef QMK_KEYS_PER_SCAN
315 // only jump out if we have processed "enough" keys.
316 if (++keys_processed >= QMK_KEYS_PER_SCAN)
317 #endif
318 // process a key per task call
319 goto MATRIX_LOOP_END;
320 }
321 }
322 }
323 }
324 }
325 // call with pseudo tick event when no real key event.
326 #ifdef QMK_KEYS_PER_SCAN
327 // we can get here with some keys processed now.
328 if (!keys_processed)
329 #endif
330 action_exec(TICK);
331
332 MATRIX_LOOP_END:
333
334 #ifdef DEBUG_MATRIX_SCAN_RATE
335 matrix_scan_perf_task();
336 #endif
337
338 #ifdef QWIIC_ENABLE
339 qwiic_task();
340 #endif
341
342 #ifdef OLED_DRIVER_ENABLE
343 oled_task();
344 # ifndef OLED_DISABLE_TIMEOUT
345 // Wake up oled if user is using those fabulous keys!
346 if (ret) oled_on();
347 # endif
348 #endif
349
350 #ifdef MOUSEKEY_ENABLE
351 // mousekey repeat & acceleration
352 mousekey_task();
353 #endif
354
355 #ifdef PS2_MOUSE_ENABLE
356 ps2_mouse_task();
357 #endif
358
359 #ifdef SERIAL_MOUSE_ENABLE
360 serial_mouse_task();
361 #endif
362
363 #ifdef ADB_MOUSE_ENABLE
364 adb_mouse_task();
365 #endif
366
367 #ifdef SERIAL_LINK_ENABLE
368 serial_link_update();
369 #endif
370
371 #ifdef VISUALIZER_ENABLE
372 visualizer_update(default_layer_state, layer_state, visualizer_get_mods(), host_keyboard_leds());
373 #endif
374
375 #ifdef POINTING_DEVICE_ENABLE
376 pointing_device_task();
377 #endif
378
379 #ifdef MIDI_ENABLE
380 midi_task();
381 #endif
382
383 #ifdef VELOCIKEY_ENABLE
384 if (velocikey_enabled()) {
385 velocikey_decelerate();
386 }
387 #endif
388
389 // update LED
390 if (led_status != host_keyboard_leds()) {
391 led_status = host_keyboard_leds();
392 keyboard_set_leds(led_status);
393 }
394 }
395
396 /** \brief keyboard set leds
397 *
398 * FIXME: needs doc
399 */
400 void keyboard_set_leds(uint8_t leds) {
401 if (debug_keyboard) {
402 debug("keyboard_set_led: ");
403 debug_hex8(leds);
404 debug("\n");
405 }
406 led_set(leds);
407 }