2 Copyright 2012-2019 Jun Wako, Jack Humbert, Yiancar
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.
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.
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/>.
26 #include "i2c_master.h"
28 #if (MATRIX_COLS <= 8)
29 # define print_matrix_header() print("\nr/c 01234567\n")
30 # define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
31 # define matrix_bitpop(i) bitpop(matrix[i])
32 # define ROW_SHIFTER ((uint8_t)1)
33 #elif (MATRIX_COLS <= 16)
34 # define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
35 # define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
36 # define matrix_bitpop(i) bitpop16(matrix[i])
37 # define ROW_SHIFTER ((uint16_t)1)
38 #elif (MATRIX_COLS <= 32)
39 # define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
40 # define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
41 # define matrix_bitpop(i) bitpop32(matrix[i])
42 # define ROW_SHIFTER ((uint32_t)1)
46 extern const matrix_row_t matrix_mask[];
49 static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
50 static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
52 /* matrix state(1:on, 0:off) */
53 static matrix_row_t raw_matrix[MATRIX_ROWS]; //raw values
54 static matrix_row_t matrix[MATRIX_ROWS]; //debounced values
56 __attribute__ ((weak))
57 void matrix_init_quantum(void) {
61 __attribute__ ((weak))
62 void matrix_scan_quantum(void) {
66 __attribute__ ((weak))
67 void matrix_init_kb(void) {
71 __attribute__ ((weak))
72 void matrix_scan_kb(void) {
76 __attribute__ ((weak))
77 void matrix_init_user(void) {
80 __attribute__ ((weak))
81 void matrix_scan_user(void) {
85 uint8_t matrix_rows(void) {
90 uint8_t matrix_cols(void) {
95 bool matrix_is_modified(void)
97 if (debounce_active()) return false;
102 bool matrix_is_on(uint8_t row, uint8_t col)
104 return (matrix[row] & ((matrix_row_t)1<<col));
108 matrix_row_t matrix_get_row(uint8_t row)
110 // Matrix mask lets you disable switches in the returned matrix data. For example, if you have a
111 // switch blocker installed and the switch is always pressed.
113 return matrix[row] & matrix_mask[row];
119 void matrix_print(void)
121 print_matrix_header();
123 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
124 phex(row); print(": ");
125 print_matrix_row(row);
130 uint8_t matrix_key_count(void)
133 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
134 count += matrix_bitpop(i);
139 static void select_row(uint8_t row)
141 setPinOutput(row_pins[row]);
142 writePinLow(row_pins[row]);
145 static void unselect_row(uint8_t row)
147 setPinInputHigh(row_pins[row]);
150 static void unselect_rows(void)
152 for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
153 setPinInput(row_pins[x]);
157 static void init_pins(void) {
160 uint8_t send_data = 0x07;
161 i2c_writeReg((PORT_EXPANDER_ADDRESS << 1), 0x00, &send_data, 1, 20);
163 i2c_writeReg((PORT_EXPANDER_ADDRESS << 1), 0x06, &send_data, 1, 20);
165 for (uint8_t x = 0; x < MATRIX_COLS; x++) {
166 if ( (x > 0) && (x < 12) ) {
167 setPinInputHigh(col_pins[x]);
172 static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
174 // Store last value of row prior to reading
175 matrix_row_t last_row_value = current_matrix[current_row];
177 // Clear data in matrix row
178 current_matrix[current_row] = 0;
180 // Select row and wait for row selecton to stabilize
181 select_row(current_row);
185 for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
187 // Select the col pin to read (active low)
190 i2c_readReg((PORT_EXPANDER_ADDRESS << 1), 0x09, &pin_state, 1, 20);
191 pin_state = pin_state & 0x01;
194 i2c_readReg((PORT_EXPANDER_ADDRESS << 1), 0x09, &pin_state, 1, 20);
195 pin_state = pin_state & (1 << 2);
198 i2c_readReg((PORT_EXPANDER_ADDRESS << 1), 0x09, &pin_state, 1, 20);
199 pin_state = pin_state & (1 << 1);
202 pin_state = readPin(col_pins[col_index]);
205 // Populate the matrix row with the state of the col pin
206 current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index);
210 unselect_row(current_row);
212 return (last_row_value != current_matrix[current_row]);
215 void matrix_init(void) {
220 // initialize key pins
223 // initialize matrix state: all keys off
224 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
229 debounce_init(MATRIX_ROWS);
231 matrix_init_quantum();
234 uint8_t matrix_scan(void)
236 bool changed = false;
238 // Set row, read cols
239 for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
240 changed |= read_cols_on_row(raw_matrix, current_row);
243 debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
245 matrix_scan_quantum();
246 return (uint8_t)changed;