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.c58
1 files changed, 43 insertions, 15 deletions
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c
index eac1f1dd8..97a8f1cd8 100644
--- a/tmk_core/common/keyboard.c
+++ b/tmk_core/common/keyboard.c
@@ -61,23 +61,51 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
61# include "visualizer/visualizer.h" 61# include "visualizer/visualizer.h"
62#endif 62#endif
63 63
64#ifdef MATRIX_HAS_GHOST
65extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
66static matrix_row_t get_real_keys(uint8_t row, matrix_row_t rowdata){
67 matrix_row_t out = 0;
68 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
69 //read each key in the row data and check if the keymap defines it as a real key
70 if (pgm_read_byte(&keymaps[0][row][col]) && (rowdata & (1<<col))){
71 //this creates new row data, if a key is defined in the keymap, it will be set here
72 out |= 1<<col;
73 }
74 }
75 return out;
76}
64 77
78static inline bool popcount_more_than_one(matrix_row_t rowdata)
79{
80 rowdata &= rowdata-1; //if there are less than two bits (keys) set, rowdata will become zero
81 return rowdata;
82}
65 83
66#ifdef MATRIX_HAS_GHOST 84static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata)
67static bool has_ghost_in_row(uint8_t row)
68{ 85{
69 matrix_row_t matrix_row = matrix_get_row(row); 86 /* No ghost exists when less than 2 keys are down on the row.
70 // No ghost exists when less than 2 keys are down on the row 87 If there are "active" blanks in the matrix, the key can't be pressed by the user,
71 if (((matrix_row - 1) & matrix_row) == 0) 88 there is no doubt as to which keys are really being pressed.
89 The ghosts will be ignored, they are KC_NO. */
90 rowdata = get_real_keys(row, rowdata);
91 if ((popcount_more_than_one(rowdata)) == 0){
72 return false; 92 return false;
73 93 }
74 // Ghost occurs when the row shares column line with other row 94 /* Ghost occurs when the row shares a column line with other row,
95 and two columns are read on each row. Blanks in the matrix don't matter,
96 so they are filtered out.
97 If there are two or more real keys pressed and they match columns with
98 at least two of another row's real keys, the row will be ignored. Keep in mind,
99 we are checking one row at a time, not all of them at once.
100 */
75 for (uint8_t i=0; i < MATRIX_ROWS; i++) { 101 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
76 if (i != row && (matrix_get_row(i) & matrix_row)) 102 if (i != row && popcount_more_than_one(get_real_keys(i, matrix_get_row(i)) & rowdata)){
77 return true; 103 return true;
104 }
78 } 105 }
79 return false; 106 return false;
80} 107}
108
81#endif 109#endif
82 110
83__attribute__ ((weak)) 111__attribute__ ((weak))
@@ -127,7 +155,7 @@ void keyboard_task(void)
127{ 155{
128 static matrix_row_t matrix_prev[MATRIX_ROWS]; 156 static matrix_row_t matrix_prev[MATRIX_ROWS];
129#ifdef MATRIX_HAS_GHOST 157#ifdef MATRIX_HAS_GHOST
130 static matrix_row_t matrix_ghost[MATRIX_ROWS]; 158 // static matrix_row_t matrix_ghost[MATRIX_ROWS];
131#endif 159#endif
132 static uint8_t led_status = 0; 160 static uint8_t led_status = 0;
133 matrix_row_t matrix_row = 0; 161 matrix_row_t matrix_row = 0;
@@ -139,18 +167,18 @@ void keyboard_task(void)
139 matrix_change = matrix_row ^ matrix_prev[r]; 167 matrix_change = matrix_row ^ matrix_prev[r];
140 if (matrix_change) { 168 if (matrix_change) {
141#ifdef MATRIX_HAS_GHOST 169#ifdef MATRIX_HAS_GHOST
142 if (has_ghost_in_row(r)) { 170 if (has_ghost_in_row(r, matrix_row)) {
143 /* Keep track of whether ghosted status has changed for 171 /* Keep track of whether ghosted status has changed for
144 * debugging. But don't update matrix_prev until un-ghosted, or 172 * debugging. But don't update matrix_prev until un-ghosted, or
145 * the last key would be lost. 173 * the last key would be lost.
146 */ 174 */
147 if (debug_matrix && matrix_ghost[r] != matrix_row) { 175 //if (debug_matrix && matrix_ghost[r] != matrix_row) {
148 matrix_print(); 176 // matrix_print();
149 } 177 //}
150 matrix_ghost[r] = matrix_row; 178 //matrix_ghost[r] = matrix_row;
151 continue; 179 continue;
152 } 180 }
153 matrix_ghost[r] = matrix_row; 181 //matrix_ghost[r] = matrix_row;
154#endif 182#endif
155 if (debug_matrix) matrix_print(); 183 if (debug_matrix) matrix_print();
156 for (uint8_t c = 0; c < MATRIX_COLS; c++) { 184 for (uint8_t c = 0; c < MATRIX_COLS; c++) {