]> git.donarmstrong.com Git - qmk_firmware.git/blob - tmk_core/common/keyboard.c
fix typos
[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 #include <stdint.h>
18 #include "keyboard.h"
19 #include "matrix.h"
20 #include "keymap.h"
21 #include "host.h"
22 #include "led.h"
23 #include "keycode.h"
24 #include "timer.h"
25 #include "print.h"
26 #include "debug.h"
27 #include "command.h"
28 #include "util.h"
29 #include "sendchar.h"
30 #include "eeconfig.h"
31 #include "backlight.h"
32 #ifdef BOOTMAGIC_ENABLE
33 #   include "bootmagic.h"
34 #else
35 #   include "magic.h"
36 #endif
37 #ifdef MOUSEKEY_ENABLE
38 #   include "mousekey.h"
39 #endif
40 #ifdef PS2_MOUSE_ENABLE
41 #   include "ps2_mouse.h"
42 #endif
43 #ifdef SERIAL_MOUSE_ENABLE
44 #   include "serial_mouse.h"
45 #endif
46 #ifdef ADB_MOUSE_ENABLE
47 #   include "adb.h"
48 #endif
49 #ifdef RGBLIGHT_ENABLE
50 #   include "rgblight.h"
51 #endif
52
53 #ifdef MATRIX_HAS_GHOST
54 static bool is_row_ghosting(uint8_t row){
55     matrix_row_t state = matrix_get_row(row);
56     /* no ghosting happens when only one key in the row is pressed */
57     if (!(state - 1 & state)) return false;
58     /* ghosting occurs when two keys in the same column are pressed */
59     for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
60         if (r != row && matrix_get_row(r) & state) return true;
61     }
62     return false;
63 }
64
65 #endif
66
67 __attribute__ ((weak))
68 void matrix_setup(void) {
69 }
70
71 void keyboard_setup(void) {
72     matrix_setup();
73 }
74
75 void keyboard_init(void) {
76     timer_init();
77     matrix_init();
78 #ifdef PS2_MOUSE_ENABLE
79     ps2_mouse_init();
80 #endif
81 #ifdef SERIAL_MOUSE_ENABLE
82     serial_mouse_init();
83 #endif
84 #ifdef ADB_MOUSE_ENABLE
85     adb_mouse_init();
86 #endif
87 #ifdef BOOTMAGIC_ENABLE
88     bootmagic();
89 #else
90     magic();
91 #endif
92 #ifdef BACKLIGHT_ENABLE
93     backlight_init();
94 #endif
95 #ifdef RGBLIGHT_ENABLE
96     rgblight_init();
97 #endif
98 #if defined(NKRO_ENABLE) && defined(FORCE_NKRO)
99         keyboard_nkro = true;
100 #endif
101 }
102
103 /* does routine keyboard jobs */
104 void keyboard_task(void) {
105     static uint8_t led_status;
106     matrix_scan();
107     for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
108         static matrix_row_t previous_matrix[MATRIX_ROWS];
109         matrix_row_t state = matrix_get_row(r);
110         matrix_row_t changes = state ^ previous_matrix[r];
111         if (changes) {
112 #ifdef MATRIX_HAS_GHOST
113             static matrix_row_t deghosting_matrix[MATRIX_ROWS];
114             if (is_row_ghosting(r)) {
115                 /* debugs the deghosting mechanism */
116                 /* doesn't update previous_matrix until the ghosting has stopped
117                  * in order to prevent the last key from being lost
118                  */
119                 if (debug_matrix && deghosting_matrix[r] != state) {
120                     matrix_print();
121                 }
122                 deghosting_matrix[r] = state;
123                 continue;
124             }
125             deghosting_matrix[r] = state;
126 #endif
127             if (debug_matrix) matrix_print();
128             for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
129                 matrix_row_t mask = (matrix_row_t)1 << c;
130                 if (changes & mask) {
131                     keyevent_t event;
132                     event.key = (keypos_t){ .row = r, .col = c };
133                     event.pressed = state & mask;
134                     /* the time should not be 0 */
135                     event.time = timer_read() | 1;
136                     action_exec(event);
137                     /* records the processed key event */
138                     previous_matrix[r] ^= mask;
139                     /* processes one key event per call */
140                     goto event_processed;
141                 }
142             }
143         }
144     }
145     /* sends tick events when the keyboard is idle */
146     action_exec(TICK);
147 event_processed:
148 #ifdef MOUSEKEY_ENABLE
149     /* repeats and accelerates the mouse keys */
150     mousekey_task();
151 #endif
152 #ifdef PS2_MOUSE_ENABLE
153     ps2_mouse_task();
154 #endif
155 #ifdef SERIAL_MOUSE_ENABLE
156     serial_mouse_task();
157 #endif
158 #ifdef ADB_MOUSE_ENABLE
159     adb_mouse_task();
160 #endif
161     /* updates the LEDs */
162     if (led_status != host_keyboard_leds()) {
163         led_status = host_keyboard_leds();
164         keyboard_set_leds(led_status);
165     }
166 }
167
168 void keyboard_set_leds(uint8_t leds) {
169     if (debug_keyboard) dprintf("Keyboard LEDs state: %x\n", leds);
170     led_set(leds);
171 }