aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrashna Jaelre <drashna@live.com>2020-09-30 16:52:47 -0700
committerGitHub <noreply@github.com>2020-09-30 16:52:47 -0700
commit11c308d436180974b7719ce78cdffdd83a1302c0 (patch)
tree4c798a48b13e328bba01b66459775511e0131493
parent482c9fbbf28c7e871145cacd01f22c9edf7d1ddf (diff)
downloadqmk_firmware-11c308d436180974b7719ce78cdffdd83a1302c0.tar.gz
qmk_firmware-11c308d436180974b7719ce78cdffdd83a1302c0.zip
[Keyboard] Convert ErgoDox EZ to Matrix Lite (#10189)
* Convert ErgoDox EZ to lite matrix * Add initial config from Dactyl config Based on ErinCall's work to generalize the mcp i/o expander matrix code * formatting * Fix number of pins * Remove unused defines
-rw-r--r--keyboards/ergodox_ez/config.h10
-rw-r--r--keyboards/ergodox_ez/ergodox_ez.c2
-rw-r--r--keyboards/ergodox_ez/ergodox_ez.h4
-rw-r--r--keyboards/ergodox_ez/matrix.c333
-rw-r--r--keyboards/ergodox_ez/rules.mk20
5 files changed, 151 insertions, 218 deletions
diff --git a/keyboards/ergodox_ez/config.h b/keyboards/ergodox_ez/config.h
index 8ef600b08..eb0f2066d 100644
--- a/keyboards/ergodox_ez/config.h
+++ b/keyboards/ergodox_ez/config.h
@@ -32,6 +32,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
32#define MATRIX_ROWS_PER_SIDE (MATRIX_ROWS / 2) 32#define MATRIX_ROWS_PER_SIDE (MATRIX_ROWS / 2)
33#define MATRIX_COLS 6 33#define MATRIX_COLS 6
34 34
35#define COL_EXPANDED { true, true, true, true, true, true, true, false, false, false, false, false, false, false }
36#define MATRIX_ONBOARD_ROW_PINS { 0, 0, 0, 0, 0, 0, 0, B0, B1, B2, B3, D2, D3, C6 }
37#define MATRIX_ONBOARD_COL_PINS { F0, F1, F4, F5, F6, F7 }
38#define DIODE_DIRECTION COL2ROW
39#define EXPANDER_COL_REGISTER GPIOB
40#define EXPANDER_ROW_REGISTER GPIOA
41#define MATRIX_EXPANDER_COL_PINS { 5, 4, 3, 2, 1, 0 }
42#define MATRIX_EXPANDER_ROW_PINS { 0, 1, 2, 3, 4, 5, 6 }
43
44
35#define MOUSEKEY_INTERVAL 20 45#define MOUSEKEY_INTERVAL 20
36#define MOUSEKEY_DELAY 0 46#define MOUSEKEY_DELAY 0
37#define MOUSEKEY_TIME_TO_MAX 60 47#define MOUSEKEY_TIME_TO_MAX 60
diff --git a/keyboards/ergodox_ez/ergodox_ez.c b/keyboards/ergodox_ez/ergodox_ez.c
index d313f7d5d..6c0b74ec4 100644
--- a/keyboards/ergodox_ez/ergodox_ez.c
+++ b/keyboards/ergodox_ez/ergodox_ez.c
@@ -1,4 +1,4 @@
1#include QMK_KEYBOARD_H 1#include "ergodox_ez.h"
2 2
3extern inline void ergodox_board_led_on(void); 3extern inline void ergodox_board_led_on(void);
4extern inline void ergodox_right_led_1_on(void); 4extern inline void ergodox_right_led_1_on(void);
diff --git a/keyboards/ergodox_ez/ergodox_ez.h b/keyboards/ergodox_ez/ergodox_ez.h
index 88a0a2ee9..a8b02a96b 100644
--- a/keyboards/ergodox_ez/ergodox_ez.h
+++ b/keyboards/ergodox_ez/ergodox_ez.h
@@ -4,10 +4,6 @@
4#include <stdint.h> 4#include <stdint.h>
5#include <stdbool.h> 5#include <stdbool.h>
6#include "i2c_master.h" 6#include "i2c_master.h"
7#include <util/delay.h>
8
9#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
10#define CPU_16MHz 0x00
11 7
12// I2C aliases and register addresses (see "mcp23018.md") 8// I2C aliases and register addresses (see "mcp23018.md")
13#define I2C_ADDR 0b0100000 9#define I2C_ADDR 0b0100000
diff --git a/keyboards/ergodox_ez/matrix.c b/keyboards/ergodox_ez/matrix.c
index 28dc37a09..cfa76c1c3 100644
--- a/keyboards/ergodox_ez/matrix.c
+++ b/keyboards/ergodox_ez/matrix.c
@@ -30,7 +30,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
30#include "util.h" 30#include "util.h"
31#include "matrix.h" 31#include "matrix.h"
32#include "debounce.h" 32#include "debounce.h"
33#include QMK_KEYBOARD_H 33#include "ergodox_ez.h"
34
34 35
35/* 36/*
36 * This constant define not debouncing time in msecs, assuming eager_pr. 37 * This constant define not debouncing time in msecs, assuming eager_pr.
@@ -45,8 +46,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
45 */ 46 */
46 47
47/* matrix state(1:on, 0:off) */ 48/* matrix state(1:on, 0:off) */
48static matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values 49extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values
49static matrix_row_t matrix[MATRIX_ROWS]; // debounced values 50extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values
50 51
51static matrix_row_t read_cols(uint8_t row); 52static matrix_row_t read_cols(uint8_t row);
52static void init_cols(void); 53static void init_cols(void);
@@ -54,132 +55,62 @@ static void unselect_rows(void);
54static void select_row(uint8_t row); 55static void select_row(uint8_t row);
55 56
56static uint8_t mcp23018_reset_loop; 57static uint8_t mcp23018_reset_loop;
57// static uint16_t mcp23018_reset_loop;
58
59__attribute__((weak)) void matrix_init_user(void) {}
60
61__attribute__((weak)) void matrix_scan_user(void) {}
62
63__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); }
64
65__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); }
66 58
67inline uint8_t matrix_rows(void) { return MATRIX_ROWS; } 59void matrix_init_custom(void) {
60 // initialize row and col
68 61
69inline uint8_t matrix_cols(void) { return MATRIX_COLS; } 62 mcp23018_status = init_mcp23018();
70 63
71void matrix_init(void) { 64 unselect_rows();
72 // initialize row and col 65 init_cols();
73
74 mcp23018_status = init_mcp23018();
75
76 unselect_rows();
77 init_cols();
78
79 // initialize matrix state: all keys off
80 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
81 matrix[i] = 0;
82 raw_matrix[i] = 0;
83 }
84
85 debounce_init(MATRIX_ROWS);
86 matrix_init_quantum();
87}
88
89void matrix_power_up(void) {
90 mcp23018_status = init_mcp23018();
91
92 unselect_rows();
93 init_cols();
94
95 // initialize matrix state: all keys off
96 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
97 matrix[i] = 0;
98 }
99} 66}
100 67
101// Reads and stores a row, returning 68// Reads and stores a row, returning
102// whether a change occurred. 69// whether a change occurred.
103static inline bool store_raw_matrix_row(uint8_t index) { 70static inline bool store_raw_matrix_row(uint8_t index) {
104 matrix_row_t temp = read_cols(index); 71 matrix_row_t temp = read_cols(index);
105 if (raw_matrix[index] != temp) { 72 if (raw_matrix[index] != temp) {
106 raw_matrix[index] = temp; 73 raw_matrix[index] = temp;
107 return true; 74 return true;
108 } 75 }
109 return false; 76 return false;
110} 77}
111 78
112uint8_t matrix_scan(void) { 79bool matrix_scan_custom(matrix_row_t current_matrix[]) {
113 if (mcp23018_status) { // if there was an error 80 if (mcp23018_status) { // if there was an error
114 if (++mcp23018_reset_loop == 0) { 81 if (++mcp23018_reset_loop == 0) {
115 // if (++mcp23018_reset_loop >= 1300) { 82 print("trying to reset mcp23018\n");
116 // since mcp23018_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans 83 mcp23018_status = init_mcp23018();
117 // this will be approx bit more frequent than once per second 84 if (mcp23018_status) {
118 print("trying to reset mcp23018\n"); 85 print("left side not responding\n");
119 mcp23018_status = init_mcp23018(); 86 } else {
120 if (mcp23018_status) { 87 print("left side attached\n");
121 print("left side not responding\n"); 88 ergodox_blink_all_leds();
122 } else {
123 print("left side attached\n");
124 ergodox_blink_all_leds();
125#ifdef RGB_MATRIX_ENABLE 89#ifdef RGB_MATRIX_ENABLE
126 rgb_matrix_init(); // re-init driver on reconnect 90 rgb_matrix_init(); // re-init driver on reconnect
127#endif 91#endif
128 } 92 }
93 }
129 } 94 }
130 }
131 95
132#ifdef LEFT_LEDS 96#ifdef LEFT_LEDS
133 mcp23018_status = ergodox_left_leds_update(); 97 mcp23018_status = ergodox_left_leds_update();
134#endif // LEFT_LEDS 98#endif // LEFT_LEDS
135 bool changed = false; 99 bool changed = false;
136 for (uint8_t i = 0; i < MATRIX_ROWS_PER_SIDE; i++) { 100 for (uint8_t i = 0; i < MATRIX_ROWS_PER_SIDE; i++) {
137 // select rows from left and right hands 101 // select rows from left and right hands
138 uint8_t left_index = i; 102 uint8_t left_index = i;
139 uint8_t right_index = i + MATRIX_ROWS_PER_SIDE; 103 uint8_t right_index = i + MATRIX_ROWS_PER_SIDE;
140 select_row(left_index); 104 select_row(left_index);
141 select_row(right_index); 105 select_row(right_index);
142 106
143 // we don't need a 30us delay anymore, because selecting a 107 changed |= store_raw_matrix_row(left_index);
144 // left-hand row requires more than 30us for i2c. 108 changed |= store_raw_matrix_row(right_index);
145 109
146 changed |= store_raw_matrix_row(left_index); 110 unselect_rows();
147 changed |= store_raw_matrix_row(right_index); 111 }
148
149 unselect_rows();
150 }
151
152 debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
153 matrix_scan_quantum();
154
155 return 1;
156}
157
158bool matrix_is_modified(void) // deprecated and evidently not called.
159{
160 return true;
161}
162
163inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); }
164
165inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; }
166
167void matrix_print(void) {
168 print("\nr/c 0123456789ABCDEF\n");
169 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
170 phex(row);
171 print(": ");
172 pbin_reverse16(matrix_get_row(row));
173 print("\n");
174 }
175}
176 112
177uint8_t matrix_key_count(void) { 113 return changed;
178 uint8_t count = 0;
179 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
180 count += bitpop16(matrix[i]);
181 }
182 return count;
183} 114}
184 115
185/* Column pin configuration 116/* Column pin configuration
@@ -193,42 +124,43 @@ uint8_t matrix_key_count(void) {
193 * pin: B5 B4 B3 B2 B1 B0 124 * pin: B5 B4 B3 B2 B1 B0
194 */ 125 */
195static void init_cols(void) { 126static void init_cols(void) {
196 // init on mcp23018 127 // init on mcp23018
197 // not needed, already done as part of init_mcp23018() 128 // not needed, already done as part of init_mcp23018()
198 129
199 // init on teensy 130 // init on teensy
200 // Input with pull-up(DDR:0, PORT:1) 131 setPinInputHigh(F0);
201 DDRF &= ~(1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 1 | 1 << 0); 132 setPinInputHigh(F1);
202 PORTF |= (1 << 7 | 1 << 6 | 1 << 5 | 1 << 4 | 1 << 1 | 1 << 0); 133 setPinInputHigh(F4);
134 setPinInputHigh(F5);
135 setPinInputHigh(F6);
136 setPinInputHigh(F7);
203} 137}
204 138
205static matrix_row_t read_cols(uint8_t row) { 139static matrix_row_t read_cols(uint8_t row) {
206 if (row < 7) { 140 if (row < 7) {
207 if (mcp23018_status) { // if there was an error 141 if (mcp23018_status) { // if there was an error
208 return 0; 142 return 0;
143 } else {
144 uint8_t data = 0;
145 // reading GPIOB (column port) since in mcp23018's sequential mode
146 // it is addressed directly after writing to GPIOA in select_row()
147 mcp23018_status = i2c_start(I2C_ADDR_READ, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
148 mcp23018_status = i2c_read_nack(ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status < 0) goto out;
149 data = ~((uint8_t)mcp23018_status);
150 mcp23018_status = I2C_STATUS_SUCCESS;
151 out:
152 i2c_stop();
153 return data;
154 }
209 } else { 155 } else {
210 uint8_t data = 0; 156 /* read from teensy
211 // reading GPIOB (column port) since in mcp23018's sequential mode 157 * bitmask is 0b11110011, but we want those all
212 // it is addressed directly after writing to GPIOA in select_row() 158 * in the lower six bits.
213 mcp23018_status = i2c_start(I2C_ADDR_READ, ERGODOX_EZ_I2C_TIMEOUT); 159 * we'll return 1s for the top two, but that's harmless.
214 if (mcp23018_status) goto out; 160 */
215 mcp23018_status = i2c_read_nack(ERGODOX_EZ_I2C_TIMEOUT);
216 if (mcp23018_status < 0) goto out;
217 data = ~((uint8_t)mcp23018_status);
218 mcp23018_status = I2C_STATUS_SUCCESS;
219 out:
220 i2c_stop();
221 return data;
222 }
223 } else {
224 /* read from teensy
225 * bitmask is 0b11110011, but we want those all
226 * in the lower six bits.
227 * we'll return 1s for the top two, but that's harmless.
228 */
229 161
230 return ~((PINF & 0x03) | ((PINF & 0xF0) >> 2)); 162 return ~((PINF & 0x03) | ((PINF & 0xF0) >> 2));
231 } 163 }
232} 164}
233 165
234/* Row pin configuration 166/* Row pin configuration
@@ -242,69 +174,64 @@ static matrix_row_t read_cols(uint8_t row) {
242 * pin: A0 A1 A2 A3 A4 A5 A6 174 * pin: A0 A1 A2 A3 A4 A5 A6
243 */ 175 */
244static void unselect_rows(void) { 176static void unselect_rows(void) {
245 // no need to unselect on mcp23018, because the select step sets all 177 // no need to unselect on mcp23018, because the select step sets all
246 // the other row bits high, and it's not changing to a different 178 // the other row bits high, and it's not changing to a different
247 // direction 179 // direction
248 180
249 // unselect on teensy 181 // unselect on teensy
250 // Hi-Z(DDR:0, PORT:0) to unselect 182 setPinInput(B0);
251 DDRB &= ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3); 183 setPinInput(B1);
252 PORTB &= ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3); 184 setPinInput(B2);
253 DDRD &= ~(1 << 2 | 1 << 3); 185 setPinInput(B3);
254 PORTD &= ~(1 << 2 | 1 << 3); 186 setPinInput(D2);
255 DDRC &= ~(1 << 6); 187 setPinInput(D3);
256 PORTC &= ~(1 << 6); 188 setPinInput(C6);
257} 189}
258 190
259static void select_row(uint8_t row) { 191static void select_row(uint8_t row) {
260 if (row < 7) { 192 if (row < 7) {
261 // select on mcp23018 193 // select on mcp23018
262 if (mcp23018_status) { // if there was an error 194 if (!mcp23018_status) {
263 // do nothing 195 // set active row low : 0
196 // set other rows hi-Z : 1
197 mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
198 mcp23018_status = i2c_write(GPIOA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
199 mcp23018_status = i2c_write(0xFF & ~(1 << row), ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
200 out:
201 i2c_stop();
202 }
264 } else { 203 } else {
265 // set active row low : 0 204 // select on teensy
266 // set other rows hi-Z : 1 205 // Output low(DDR:1, PORT:0) to select
267 mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); 206 switch (row) {
268 if (mcp23018_status) goto out; 207 case 7:
269 mcp23018_status = i2c_write(GPIOA, ERGODOX_EZ_I2C_TIMEOUT); 208 setPinOutput(B0);
270 if (mcp23018_status) goto out; 209 writePinLow(B0);
271 mcp23018_status = i2c_write(0xFF & ~(1 << row), ERGODOX_EZ_I2C_TIMEOUT); 210 break;
272 if (mcp23018_status) goto out; 211 case 8:
273 out: 212 setPinOutput(B1);
274 i2c_stop(); 213 writePinLow(B1);
275 } 214 break;
276 } else { 215 case 9:
277 // select on teensy 216 setPinOutput(B2);
278 // Output low(DDR:1, PORT:0) to select 217 writePinLow(B2);
279 switch (row) { 218 break;
280 case 7: 219 case 10:
281 DDRB |= (1 << 0); 220 setPinOutput(B3);
282 PORTB &= ~(1 << 0); 221 writePinLow(B3);
283 break; 222 break;
284 case 8: 223 case 11:
285 DDRB |= (1 << 1); 224 setPinOutput(D2);
286 PORTB &= ~(1 << 1); 225 writePinLow(D2);
287 break; 226 break;
288 case 9: 227 case 12:
289 DDRB |= (1 << 2); 228 setPinOutput(D3);
290 PORTB &= ~(1 << 2); 229 writePinLow(D3);
291 break; 230 break;
292 case 10: 231 case 13:
293 DDRB |= (1 << 3); 232 setPinOutput(C6);
294 PORTB &= ~(1 << 3); 233 writePinLow(C6);
295 break; 234 break;
296 case 11: 235 }
297 DDRD |= (1 << 2);
298 PORTD &= ~(1 << 2);
299 break;
300 case 12:
301 DDRD |= (1 << 3);
302 PORTD &= ~(1 << 3);
303 break;
304 case 13:
305 DDRC |= (1 << 6);
306 PORTC &= ~(1 << 6);
307 break;
308 } 236 }
309 }
310} 237}
diff --git a/keyboards/ergodox_ez/rules.mk b/keyboards/ergodox_ez/rules.mk
index 579e4f59d..9ad4eaa18 100644
--- a/keyboards/ergodox_ez/rules.mk
+++ b/keyboards/ergodox_ez/rules.mk
@@ -19,20 +19,20 @@ BOOTLOADER = halfkay
19# Build Options 19# Build Options
20# comment out to disable the options. 20# comment out to disable the options.
21# 21#
22BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration 22BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration
23MOUSEKEY_ENABLE = yes # Mouse keys 23MOUSEKEY_ENABLE = yes # Mouse keys
24EXTRAKEY_ENABLE = yes # Audio control and System control 24EXTRAKEY_ENABLE = yes # Audio control and System control
25CONSOLE_ENABLE = no # Console for debug 25CONSOLE_ENABLE = no # Console for debug
26COMMAND_ENABLE = yes # Commands for debug and configuration 26COMMAND_ENABLE = yes # Commands for debug and configuration
27CUSTOM_MATRIX = yes # Custom matrix file for the ErgoDox EZ 27CUSTOM_MATRIX = lite # Custom matrix file for the ErgoDox EZ
28NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work 28NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
29UNICODE_ENABLE = yes # Unicode 29UNICODE_ENABLE = yes # Unicode
30SWAP_HANDS_ENABLE= yes # Allow swapping hands of keyboard 30SWAP_HANDS_ENABLE= yes # Allow swapping hands of keyboard
31SLEEP_LED_ENABLE = no 31SLEEP_LED_ENABLE = no
32API_SYSEX_ENABLE = no 32API_SYSEX_ENABLE = no
33RGBLIGHT_ENABLE = yes 33RGBLIGHT_ENABLE = yes
34 34
35RGB_MATRIX_ENABLE = no # enable later 35RGB_MATRIX_ENABLE = no # enable later
36DEBOUNCE_TYPE = eager_pr 36DEBOUNCE_TYPE = eager_pr
37 37
38# project specific files 38# project specific files