diff options
| author | Jeremiah <barrar@users.noreply.github.com> | 2017-05-13 16:57:23 -0700 |
|---|---|---|
| committer | Jeremiah <barrar@users.noreply.github.com> | 2017-05-13 16:57:23 -0700 |
| commit | 99877cdff3f891127e806a9bde7105e6250f3737 (patch) | |
| tree | fee011cba7e7176d6c782d8e4d80a5e20c4bd08e /tmk_core | |
| parent | b9895771edb4cca2bb17f5872a0e6ee068c91500 (diff) | |
| download | qmk_firmware-99877cdff3f891127e806a9bde7105e6250f3737.tar.gz qmk_firmware-99877cdff3f891127e806a9bde7105e6250f3737.zip | |
a bit smaller
Diffstat (limited to 'tmk_core')
| -rw-r--r-- | tmk_core/common/keyboard.c | 53 |
1 files changed, 35 insertions, 18 deletions
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c index 116914e1a..d1794c887 100644 --- a/tmk_core/common/keyboard.c +++ b/tmk_core/common/keyboard.c | |||
| @@ -63,40 +63,54 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 63 | 63 | ||
| 64 | 64 | ||
| 65 | #ifdef MATRIX_HAS_GHOST | 65 | #ifdef MATRIX_HAS_GHOST |
| 66 | extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; | 66 | static uint16_t matrix_ghost_check[MATRIX_ROWS]; |
| 67 | // bit map of true keys and empty spots in matrix, each row is reversed | 67 | |
| 68 | static uint16_t get_row_ghost_check(uint16_t row){ | 68 | static inline bool countones(uint16_t data) |
| 69 | { | ||
| 70 | int count = 0; | ||
| 69 | for (int col = 0; col < MATRIX_COLS; col++) { | 71 | for (int col = 0; col < MATRIX_COLS; col++) { |
| 70 | if (keymaps[0][row][col]) | 72 | if (data & (1<<col)) |
| 71 | row &= 1<<col; | 73 | count++; |
| 72 | else | 74 | } |
| 73 | row &= 0<<col; | 75 | if (count > 1){ |
| 76 | return true; | ||
| 74 | } | 77 | } |
| 75 | return row; | 78 | return false; |
| 76 | } | 79 | } |
| 77 | static bool has_ghost_in_row(uint8_t row) | 80 | static inline bool has_ghost_in_row(uint8_t row, uint16_t rowdata) |
| 78 | { | 81 | { |
| 79 | matrix_row_t matrix_row = (get_row_ghost_check(matrix_get_row(row))); | 82 | rowdata &= matrix_ghost_check[row]; |
| 83 | if (((rowdata - 1) & rowdata) == 0){ | ||
| 84 | return false; | ||
| 85 | } | ||
| 80 | /* No ghost exists when less than 2 keys are down on the row. | 86 | /* No ghost exists when less than 2 keys are down on the row. |
| 81 | If there are "active" blanks in the matrix, the key can't be pressed by the user, | 87 | If there are "active" blanks in the matrix, the key can't be pressed by the user, |
| 82 | there is no doubt as to which keys are really being pressed. | 88 | there is no doubt as to which keys are really being pressed. |
| 83 | The ghosts will be ignored, they are KC_NO. */ | 89 | The ghosts will be ignored, they are KC_NO. */ |
| 84 | if (((matrix_row - 1) & matrix_row) == 0){ | ||
| 85 | return false; | ||
| 86 | } | ||
| 87 | // Ghost occurs when the row shares column line with other row, blanks in the matrix don't matter | 90 | // Ghost occurs when the row shares column line with other row, blanks in the matrix don't matter |
| 88 | // If there are two or more real keys pressed and they match another row's real keys, the row will be ignored. | 91 | // If there are more than two real keys pressed and they match another row's real keys, the row will be ignored. |
| 89 | for (uint8_t i=0; i < MATRIX_ROWS; i++) { | 92 | for (uint8_t i=0; i < MATRIX_ROWS; i++) { |
| 90 | if (i != row && __builtin_popcount( | 93 | if (i != row && countones((matrix_get_row(i) & matrix_ghost_check[i]) & rowdata)){ |
| 91 | get_row_ghost_check(matrix_get_row(i)) & matrix_row | ||
| 92 | ) > 1){ | ||
| 93 | return true; | 94 | return true; |
| 94 | } | 95 | } |
| 95 | } | 96 | } |
| 96 | return false; | 97 | return false; |
| 97 | } | 98 | } |
| 99 | |||
| 100 | extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; | ||
| 101 | // bit map of true keys and empty spots in matrix, each row is reversed | ||
| 102 | static inline void make_ghost_check_array(void){ | ||
| 103 | for (int row = 0; row < MATRIX_ROWS; row++) { | ||
| 104 | for (int col = 0; col < MATRIX_COLS; col++) { | ||
| 105 | if (pgm_read_byte(&keymaps[0][row][col]) != 0) | ||
| 106 | matrix_ghost_check[row] |= 1<<col; | ||
| 107 | } | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 98 | #endif | 111 | #endif |
| 99 | 112 | ||
| 113 | |||
| 100 | __attribute__ ((weak)) | 114 | __attribute__ ((weak)) |
| 101 | void matrix_setup(void) { | 115 | void matrix_setup(void) { |
| 102 | } | 116 | } |
| @@ -134,6 +148,9 @@ void keyboard_init(void) { | |||
| 134 | #if defined(NKRO_ENABLE) && defined(FORCE_NKRO) | 148 | #if defined(NKRO_ENABLE) && defined(FORCE_NKRO) |
| 135 | keymap_config.nkro = 1; | 149 | keymap_config.nkro = 1; |
| 136 | #endif | 150 | #endif |
| 151 | #ifdef MATRIX_HAS_GHOST | ||
| 152 | make_ghost_check_array(); | ||
| 153 | #endif | ||
| 137 | } | 154 | } |
| 138 | 155 | ||
| 139 | /* | 156 | /* |
| @@ -156,7 +173,7 @@ void keyboard_task(void) | |||
| 156 | matrix_change = matrix_row ^ matrix_prev[r]; | 173 | matrix_change = matrix_row ^ matrix_prev[r]; |
| 157 | if (matrix_change) { | 174 | if (matrix_change) { |
| 158 | #ifdef MATRIX_HAS_GHOST | 175 | #ifdef MATRIX_HAS_GHOST |
| 159 | if (has_ghost_in_row(r)) { | 176 | if (has_ghost_in_row(r, matrix_row)) { |
| 160 | /* Keep track of whether ghosted status has changed for | 177 | /* Keep track of whether ghosted status has changed for |
| 161 | * debugging. But don't update matrix_prev until un-ghosted, or | 178 | * debugging. But don't update matrix_prev until un-ghosted, or |
| 162 | * the last key would be lost. | 179 | * the last key would be lost. |
