diff options
| author | Jack Humbert <jack.humb@gmail.com> | 2016-07-04 11:45:58 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-07-04 11:45:58 -0400 |
| commit | 8e88d55bfd7c88cb15845e0c6415e4e892532861 (patch) | |
| tree | 281f82e47a34c9c7176537cdd85c76c387a8286d /tmk_core/common/keyboard.c | |
| parent | 21ee3eb569caffdf2ad581c668682c0109c978e5 (diff) | |
| download | qmk_firmware-8e88d55bfd7c88cb15845e0c6415e4e892532861.tar.gz qmk_firmware-8e88d55bfd7c88cb15845e0c6415e4e892532861.zip | |
reverts #343 for the most part (#474)
Diffstat (limited to 'tmk_core/common/keyboard.c')
| -rw-r--r-- | tmk_core/common/keyboard.c | 107 |
1 files changed, 62 insertions, 45 deletions
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c index 34e1ceeca..81df8eb73 100644 --- a/tmk_core/common/keyboard.c +++ b/tmk_core/common/keyboard.c | |||
| @@ -51,17 +51,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 51 | #endif | 51 | #endif |
| 52 | 52 | ||
| 53 | #ifdef MATRIX_HAS_GHOST | 53 | #ifdef MATRIX_HAS_GHOST |
| 54 | static bool is_row_ghosting(uint8_t row){ | 54 | static bool has_ghost_in_row(uint8_t row) |
| 55 | matrix_row_t state = matrix_get_row(row); | 55 | { |
| 56 | /* no ghosting happens when only one key in the row is pressed */ | 56 | matrix_row_t matrix_row = matrix_get_row(row); |
| 57 | if (!(state - 1 & state)) return false; | 57 | // No ghost exists when less than 2 keys are down on the row |
| 58 | /* ghosting occurs when two keys in the same column are pressed */ | 58 | if (((matrix_row - 1) & matrix_row) == 0) |
| 59 | for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { | 59 | return false; |
| 60 | if (r != row && matrix_get_row(r) & state) return true; | 60 | |
| 61 | // Ghost occurs when the row shares column line with other row | ||
| 62 | for (uint8_t i=0; i < MATRIX_ROWS; i++) { | ||
| 63 | if (i != row && (matrix_get_row(i) & matrix_row)) | ||
| 64 | return true; | ||
| 61 | } | 65 | } |
| 62 | return false; | 66 | return false; |
| 63 | } | 67 | } |
| 64 | |||
| 65 | #endif | 68 | #endif |
| 66 | 69 | ||
| 67 | __attribute__ ((weak)) | 70 | __attribute__ ((weak)) |
| @@ -100,72 +103,86 @@ void keyboard_init(void) { | |||
| 100 | #endif | 103 | #endif |
| 101 | } | 104 | } |
| 102 | 105 | ||
| 103 | /* does routine keyboard jobs */ | 106 | /* |
| 104 | void keyboard_task(void) { | 107 | * Do keyboard routine jobs: scan mantrix, light LEDs, ... |
| 105 | static uint8_t led_status; | 108 | * This is repeatedly called as fast as possible. |
| 109 | */ | ||
| 110 | void keyboard_task(void) | ||
| 111 | { | ||
| 112 | static matrix_row_t matrix_prev[MATRIX_ROWS]; | ||
| 113 | #ifdef MATRIX_HAS_GHOST | ||
| 114 | static matrix_row_t matrix_ghost[MATRIX_ROWS]; | ||
| 115 | #endif | ||
| 116 | static uint8_t led_status = 0; | ||
| 117 | matrix_row_t matrix_row = 0; | ||
| 118 | matrix_row_t matrix_change = 0; | ||
| 119 | |||
| 106 | matrix_scan(); | 120 | matrix_scan(); |
| 107 | for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { | 121 | for (uint8_t r = 0; r < MATRIX_ROWS; r++) { |
| 108 | static matrix_row_t previous_matrix[MATRIX_ROWS]; | 122 | matrix_row = matrix_get_row(r); |
| 109 | matrix_row_t state = matrix_get_row(r); | 123 | matrix_change = matrix_row ^ matrix_prev[r]; |
| 110 | matrix_row_t changes = state ^ previous_matrix[r]; | 124 | if (matrix_change) { |
| 111 | if (changes) { | ||
| 112 | #ifdef MATRIX_HAS_GHOST | 125 | #ifdef MATRIX_HAS_GHOST |
| 113 | static matrix_row_t deghosting_matrix[MATRIX_ROWS]; | 126 | if (has_ghost_in_row(r)) { |
| 114 | if (is_row_ghosting(r)) { | 127 | /* Keep track of whether ghosted status has changed for |
| 115 | /* debugs the deghosting mechanism */ | 128 | * debugging. But don't update matrix_prev until un-ghosted, or |
| 116 | /* doesn't update previous_matrix until the ghosting has stopped | 129 | * the last key would be lost. |
| 117 | * in order to prevent the last key from being lost | ||
| 118 | */ | 130 | */ |
| 119 | if (debug_matrix && deghosting_matrix[r] != state) { | 131 | if (debug_matrix && matrix_ghost[r] != matrix_row) { |
| 120 | matrix_print(); | 132 | matrix_print(); |
| 121 | } | 133 | } |
| 122 | deghosting_matrix[r] = state; | 134 | matrix_ghost[r] = matrix_row; |
| 123 | continue; | 135 | continue; |
| 124 | } | 136 | } |
| 125 | deghosting_matrix[r] = state; | 137 | matrix_ghost[r] = matrix_row; |
| 126 | #endif | 138 | #endif |
| 127 | if (debug_matrix) matrix_print(); | 139 | if (debug_matrix) matrix_print(); |
| 128 | for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { | 140 | for (uint8_t c = 0; c < MATRIX_COLS; c++) { |
| 129 | matrix_row_t mask = (matrix_row_t)1 << c; | 141 | if (matrix_change & ((matrix_row_t)1<<c)) { |
| 130 | if (changes & mask) { | 142 | action_exec((keyevent_t){ |
| 131 | keyevent_t event; | 143 | .key = (keypos_t){ .row = r, .col = c }, |
| 132 | event.key = (keypos_t){ .row = r, .col = c }; | 144 | .pressed = (matrix_row & ((matrix_row_t)1<<c)), |
| 133 | event.pressed = state & mask; | 145 | .time = (timer_read() | 1) /* time should not be 0 */ |
| 134 | /* the time should not be 0 */ | 146 | }); |
| 135 | event.time = timer_read() | 1; | 147 | // record a processed key |
| 136 | action_exec(event); | 148 | matrix_prev[r] ^= ((matrix_row_t)1<<c); |
| 137 | /* records the processed key event */ | 149 | // process a key per task call |
| 138 | previous_matrix[r] ^= mask; | 150 | goto MATRIX_LOOP_END; |
| 139 | /* processes one key event per call */ | ||
| 140 | goto event_processed; | ||
| 141 | } | 151 | } |
| 142 | } | 152 | } |
| 143 | } | 153 | } |
| 144 | } | 154 | } |
| 145 | /* sends tick events when the keyboard is idle */ | 155 | // call with pseudo tick event when no real key event. |
| 146 | action_exec(TICK); | 156 | action_exec(TICK); |
| 147 | event_processed: | 157 | |
| 158 | MATRIX_LOOP_END: | ||
| 159 | |||
| 148 | #ifdef MOUSEKEY_ENABLE | 160 | #ifdef MOUSEKEY_ENABLE |
| 149 | /* repeats and accelerates the mouse keys */ | 161 | // mousekey repeat & acceleration |
| 150 | mousekey_task(); | 162 | mousekey_task(); |
| 151 | #endif | 163 | #endif |
| 164 | |||
| 152 | #ifdef PS2_MOUSE_ENABLE | 165 | #ifdef PS2_MOUSE_ENABLE |
| 153 | ps2_mouse_task(); | 166 | ps2_mouse_task(); |
| 154 | #endif | 167 | #endif |
| 168 | |||
| 155 | #ifdef SERIAL_MOUSE_ENABLE | 169 | #ifdef SERIAL_MOUSE_ENABLE |
| 156 | serial_mouse_task(); | 170 | serial_mouse_task(); |
| 157 | #endif | 171 | #endif |
| 172 | |||
| 158 | #ifdef ADB_MOUSE_ENABLE | 173 | #ifdef ADB_MOUSE_ENABLE |
| 159 | adb_mouse_task(); | 174 | adb_mouse_task(); |
| 160 | #endif | 175 | #endif |
| 161 | /* updates the LEDs */ | 176 | |
| 177 | // update LED | ||
| 162 | if (led_status != host_keyboard_leds()) { | 178 | if (led_status != host_keyboard_leds()) { |
| 163 | led_status = host_keyboard_leds(); | 179 | led_status = host_keyboard_leds(); |
| 164 | keyboard_set_leds(led_status); | 180 | keyboard_set_leds(led_status); |
| 165 | } | 181 | } |
| 166 | } | 182 | } |
| 167 | 183 | ||
| 168 | void keyboard_set_leds(uint8_t leds) { | 184 | void keyboard_set_leds(uint8_t leds) |
| 169 | if (debug_keyboard) dprintf("Keyboard LEDs state: %x\n", leds); | 185 | { |
| 186 | if (debug_keyboard) { debug("keyboard_set_led: "); debug_hex8(leds); debug("\n"); } | ||
| 170 | led_set(leds); | 187 | led_set(leds); |
| 171 | } | 188 | } |
