diff options
Diffstat (limited to 'keyboards/barleycorn_smd/matrix.c')
-rw-r--r-- | keyboards/barleycorn_smd/matrix.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/keyboards/barleycorn_smd/matrix.c b/keyboards/barleycorn_smd/matrix.c new file mode 100644 index 000000000..b717452f3 --- /dev/null +++ b/keyboards/barleycorn_smd/matrix.c | |||
@@ -0,0 +1,138 @@ | |||
1 | /* | ||
2 | Copyright 2021 Matthew Dias | ||
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 <stdbool.h> | ||
19 | #include "wait.h" | ||
20 | #include "quantum.h" | ||
21 | #include "i2c_master.h" | ||
22 | |||
23 | static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; | ||
24 | static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; | ||
25 | |||
26 | static void unselect_rows(void) { | ||
27 | for(uint8_t x = 0; x < MATRIX_ROWS; x++) { | ||
28 | setPinInputHigh(row_pins[x]); | ||
29 | } | ||
30 | } | ||
31 | |||
32 | static void select_row(uint8_t row) { | ||
33 | setPinOutput(row_pins[row]); | ||
34 | writePinLow(row_pins[row]); | ||
35 | } | ||
36 | |||
37 | static void unselect_row(uint8_t row) { | ||
38 | setPinInputHigh(row_pins[row]); | ||
39 | } | ||
40 | |||
41 | static void init_pins(void) { | ||
42 | unselect_rows(); | ||
43 | // Set I/O | ||
44 | uint8_t send_data[2] = { 0xFF, 0x03}; | ||
45 | i2c_writeReg((PORT_EXPANDER_ADDRESS << 1), 0x00, &send_data[0], 2, 20); | ||
46 | // Set Pull-up | ||
47 | i2c_writeReg((PORT_EXPANDER_ADDRESS << 1), 0x0C, &send_data[0], 2, 20); | ||
48 | |||
49 | for (uint8_t x = 0; x < MATRIX_COLS; x++) { | ||
50 | if ( x < 8 ) { | ||
51 | setPinInputHigh(col_pins[x]); | ||
52 | } | ||
53 | } | ||
54 | } | ||
55 | |||
56 | void matrix_init_custom(void) { | ||
57 | // TODO: initialize hardware here | ||
58 | // Initialize I2C | ||
59 | i2c_init(); | ||
60 | |||
61 | // initialize key pins | ||
62 | init_pins(); | ||
63 | wait_ms(50); | ||
64 | } | ||
65 | |||
66 | static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { | ||
67 | // Store last value of row prior to reading | ||
68 | matrix_row_t last_row_value = current_matrix[current_row]; | ||
69 | |||
70 | // Clear data in matrix row | ||
71 | current_matrix[current_row] = 0; | ||
72 | |||
73 | // Select row and wait for row selecton to stabilize | ||
74 | select_row(current_row); | ||
75 | matrix_io_delay(); | ||
76 | |||
77 | uint8_t port_expander_col_buffer[2]; | ||
78 | i2c_readReg((PORT_EXPANDER_ADDRESS << 1), 0x12, &port_expander_col_buffer[0], 2, 20); | ||
79 | |||
80 | // For each col... | ||
81 | for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { | ||
82 | uint8_t pin_state; | ||
83 | // Select the col pin to read (active low) | ||
84 | switch (col_index) { | ||
85 | case 8 : | ||
86 | pin_state = port_expander_col_buffer[0] & (1 << 0); | ||
87 | break; | ||
88 | case 9 : | ||
89 | pin_state = port_expander_col_buffer[0] & (1 << 1); | ||
90 | break; | ||
91 | case 10 : | ||
92 | pin_state = port_expander_col_buffer[0] & (1 << 2); | ||
93 | break; | ||
94 | case 11 : | ||
95 | pin_state = port_expander_col_buffer[0] & (1 << 3); | ||
96 | break; | ||
97 | case 12 : | ||
98 | pin_state = port_expander_col_buffer[0] & (1 << 4); | ||
99 | break; | ||
100 | case 13 : | ||
101 | pin_state = port_expander_col_buffer[0] & (1 << 5); | ||
102 | break; | ||
103 | case 14 : | ||
104 | pin_state = port_expander_col_buffer[0] & (1 << 6); | ||
105 | break; | ||
106 | case 15 : | ||
107 | pin_state = port_expander_col_buffer[0] & (1 << 7); | ||
108 | break; | ||
109 | case 16 : | ||
110 | pin_state = port_expander_col_buffer[1] & (1 << 0); | ||
111 | break; | ||
112 | case 17 : | ||
113 | pin_state = port_expander_col_buffer[1] & (1 << 1); | ||
114 | break; | ||
115 | default : | ||
116 | pin_state = readPin(col_pins[col_index]); | ||
117 | } | ||
118 | |||
119 | // Populate the matrix row with the state of the col pin | ||
120 | current_matrix[current_row] |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index); | ||
121 | } | ||
122 | |||
123 | // Unselect row | ||
124 | unselect_row(current_row); | ||
125 | |||
126 | return (last_row_value != current_matrix[current_row]); | ||
127 | } | ||
128 | |||
129 | bool matrix_scan_custom(matrix_row_t current_matrix[]) { | ||
130 | bool matrix_has_changed = false; | ||
131 | |||
132 | // Set row, read cols | ||
133 | for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) { | ||
134 | matrix_has_changed |= read_cols_on_row(current_matrix, current_row); | ||
135 | } | ||
136 | |||
137 | return matrix_has_changed; | ||
138 | } | ||