aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/config_options.md2
-rw-r--r--docs/hardware_avr.md18
-rw-r--r--docs/porting_your_keyboard_to_qmk_(arm_and_other_chibios_cpus).md2
-rw-r--r--keyboards/40percentclub/nano/config.h27
-rw-r--r--keyboards/40percentclub/nano/matrix.c159
-rw-r--r--keyboards/40percentclub/nano/nano.h4
-rw-r--r--keyboards/40percentclub/nano/rules.mk4
-rw-r--r--quantum/matrix.c189
8 files changed, 146 insertions, 259 deletions
diff --git a/docs/config_options.md b/docs/config_options.md
index c5131a841..bc2a89058 100644
--- a/docs/config_options.md
+++ b/docs/config_options.md
@@ -59,6 +59,8 @@ This is a C header file that is one of the first things included, and will persi
59 * define is matrix has ghost (unlikely) 59 * define is matrix has ghost (unlikely)
60* `#define DIODE_DIRECTION COL2ROW` 60* `#define DIODE_DIRECTION COL2ROW`
61 * COL2ROW or ROW2COL - how your matrix is configured. COL2ROW means the black mark on your diode is facing to the rows, and between the switch and the rows. 61 * COL2ROW or ROW2COL - how your matrix is configured. COL2ROW means the black mark on your diode is facing to the rows, and between the switch and the rows.
62* `#define DIRECT_PINS { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }`
63 * pins mapped to rows and columns, from left to right. Defines a matrix where each switch is connected to a separate pin and ground.
62* `#define AUDIO_VOICES` 64* `#define AUDIO_VOICES`
63 * turns on the alternate audio voices (to cycle through) 65 * turns on the alternate audio voices (to cycle through)
64* `#define C4_AUDIO` 66* `#define C4_AUDIO`
diff --git a/docs/hardware_avr.md b/docs/hardware_avr.md
index 12a0059c3..acf7088a3 100644
--- a/docs/hardware_avr.md
+++ b/docs/hardware_avr.md
@@ -93,6 +93,24 @@ Finally, you can specify the direction your diodes point. This can be `COL2ROW`
93#define DIODE_DIRECTION COL2ROW 93#define DIODE_DIRECTION COL2ROW
94``` 94```
95 95
96#### Direct Pin Matrix
97To configure a keyboard where each switch is connected to a separate pin and ground instead of sharing row and column pins, use `DIRECT_PINS`. The mapping defines the pins of each switch in rows and columns, from left to right. Must conform to the sizes within `MATRIX_ROWS` and `MATRIX_COLS`, use `NO_PIN` to fill in blank spaces. Overrides the behaviour of `DIODE_DIRECTION`, `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`.
98
99```c
100// #define MATRIX_ROW_PINS { D0, D5 }
101// #define MATRIX_COL_PINS { F1, F0, B0 }
102#define DIRECT_PINS { \
103 { F1, E6, B0, B2, B3 }, \
104 { F5, F0, B1, B7, D2 }, \
105 { F6, F7, C7, D5, D3 }, \
106 { B5, C6, B6, NO_PIN, NO_PIN } \
107}
108#define UNUSED_PINS
109
110/* COL2ROW, ROW2COL */
111//#define DIODE_DIRECTION
112```
113
96### Backlight Configuration 114### Backlight Configuration
97 115
98By default QMK supports backlighting on pins `B5`, `B6`, and `B7`. If you are using one of those you can simply enable it here. For more details see the [Backlight Documentation](feature_backlight.md). 116By default QMK supports backlighting on pins `B5`, `B6`, and `B7`. If you are using one of those you can simply enable it here. For more details see the [Backlight Documentation](feature_backlight.md).
diff --git a/docs/porting_your_keyboard_to_qmk_(arm_and_other_chibios_cpus).md b/docs/porting_your_keyboard_to_qmk_(arm_and_other_chibios_cpus).md
index c32c428cf..d8e084f46 100644
--- a/docs/porting_your_keyboard_to_qmk_(arm_and_other_chibios_cpus).md
+++ b/docs/porting_your_keyboard_to_qmk_(arm_and_other_chibios_cpus).md
@@ -22,6 +22,8 @@ The `MATRIX_ROW_PINS` and `MATRIX_COL_PINS` are the pins your MCU uses on each r
22 22
23For the `DIODE_DIRECTION`, most hand-wiring guides will instruct you to wire the diodes in the `COL2ROW` position, but it's possible that they are in the other - people coming from EasyAVR often use `ROW2COL`. Nothing will function if this is incorrect. 23For the `DIODE_DIRECTION`, most hand-wiring guides will instruct you to wire the diodes in the `COL2ROW` position, but it's possible that they are in the other - people coming from EasyAVR often use `ROW2COL`. Nothing will function if this is incorrect.
24 24
25To configure a keyboard where each switch is connected to a separate pin and ground instead of sharing row and column pins, use `DIRECT_PINS`. The mapping defines the pins of each switch in rows and columns, from left to right. Must conform to the sizes within `MATRIX_ROWS` and `MATRIX_COLS`, use `NO_PIN` to fill in blank spaces. Overrides the behaviour of `DIODE_DIRECTION`, `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`.
26
25`BACKLIGHT_PIN` is the pin that your PWM-controlled backlight (if one exists) is hooked-up to. Currently only B5, B6, and B7 are supported. 27`BACKLIGHT_PIN` is the pin that your PWM-controlled backlight (if one exists) is hooked-up to. Currently only B5, B6, and B7 are supported.
26 28
27`BACKLIGHT_BREATHING` is a fancier backlight feature that adds breathing/pulsing/fading effects to the backlight. It uses the same timer as the normal backlight. These breathing effects must be called by code in your keymap. 29`BACKLIGHT_BREATHING` is a fancier backlight feature that adds breathing/pulsing/fading effects to the backlight. It uses the same timer as the normal backlight. These breathing effects must be called by code in your keymap.
diff --git a/keyboards/40percentclub/nano/config.h b/keyboards/40percentclub/nano/config.h
index 36840d2f6..5eb65c74a 100644
--- a/keyboards/40percentclub/nano/config.h
+++ b/keyboards/40percentclub/nano/config.h
@@ -31,12 +31,29 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
31#define MATRIX_ROWS 2 31#define MATRIX_ROWS 2
32#define MATRIX_COLS 4 32#define MATRIX_COLS 4
33 33
34/*
35 * Keyboard Matrix Assignments
36 *
37 * Change this to how you wired your keyboard
38 * COLS: AVR pins used for columns, left to right
39 * ROWS: AVR pins used for rows, top to bottom
40 * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
41 * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
42 * NO_DIODE = switches are directly connected to AVR pins
43 *
44*/
45// #define MATRIX_ROW_PINS { D0, D5 }
46// #define MATRIX_COL_PINS { F1, F0, B0 }
47#define DIRECT_PINS { \
48 { F4, F5, F6, F7 }, \
49 { D1, D0, D4, C6 }, \
50}
51#define UNUSED_PINS
52
53/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */
54//#define DIODE_DIRECTION CUSTOM_MATRIX
55
34/* ws2812 RGB LED */ 56/* ws2812 RGB LED */
35#define RGB_DI_PIN D3 57#define RGB_DI_PIN D3
36#define RGBLIGHT_ANIMATIONS 58#define RGBLIGHT_ANIMATIONS
37#define RGBLED_NUM 6 // Number of LEDs 59#define RGBLED_NUM 6 // Number of LEDs
38
39/* COL2ROW or ROW2COL */
40#define DIODE_DIRECTION COL2ROW
41
42#define TAPPING_TERM 200
diff --git a/keyboards/40percentclub/nano/matrix.c b/keyboards/40percentclub/nano/matrix.c
deleted file mode 100644
index fa2461af5..000000000
--- a/keyboards/40percentclub/nano/matrix.c
+++ /dev/null
@@ -1,159 +0,0 @@
1/*
2
3Note for ErgoDox EZ customizers: Here be dragons!
4This is not a file you want to be messing with.
5All of the interesting stuff for you is under keymaps/ :)
6Love, Erez
7
8Copyright 2013 Oleg Kostyuk <cub.uanic@gmail.com>
9
10This program is free software: you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation, either version 2 of the License, or
13(at your option) any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program. If not, see <http://www.gnu.org/licenses/>.
22*/
23
24/*
25 * scan matrix
26 */
27#include <stdint.h>
28#include <stdbool.h>
29#include <avr/io.h>
30#include <util/delay.h>
31#include "action_layer.h"
32#include "print.h"
33#include "debug.h"
34#include "util.h"
35#include "matrix.h"
36#include "nano.h"
37#include <string.h>
38
39/* matrix state(1:on, 0:off) */
40static matrix_row_t matrix[MATRIX_ROWS];
41static matrix_row_t matrix_stage[MATRIX_ROWS];
42static matrix_row_t matrix_debouncing[MATRIX_ROWS];
43
44static uint16_t debouncing_time;
45static bool debouncing = false;
46
47__attribute__ ((weak))
48void matrix_init_kb(void) {
49 matrix_init_user();
50}
51
52__attribute__ ((weak))
53void matrix_scan_kb(void) {
54 matrix_scan_user();
55}
56
57__attribute__ ((weak))
58void matrix_init_user(void) {
59}
60
61__attribute__ ((weak))
62void matrix_scan_user(void) {
63}
64
65inline
66uint8_t matrix_rows(void)
67{
68 return MATRIX_ROWS;
69}
70
71inline
72uint8_t matrix_cols(void)
73{
74 return MATRIX_COLS;
75}
76
77void matrix_init(void)
78{
79
80 DDRF &= ~(1<<4 | 1<<5 | 1<<6 | 1<<7);
81 PORTF |= (1<<4 | 1<<5 | 1<<6 | 1<<7);
82 DDRC &= ~(1<<6);
83 PORTC |= (1<<6);
84 DDRD &= ~(1<<0 | 1<<1 | 1<<4);
85 PORTD |= (1<<0 | 1<<1 | 1<<4);
86
87 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
88 matrix[i] = 0;
89 matrix_debouncing[i] = 0;
90 matrix_stage[i] = 0;
91 }
92
93 matrix_init_quantum();
94
95}
96
97uint8_t matrix_scan(void)
98{
99 matrix_stage[0] =
100 (PINF&(1<<4) ? 0 : (1<<0)) |
101 (PINF&(1<<5) ? 0 : (1<<1)) |
102 (PINF&(1<<6) ? 0 : (1<<2)) |
103 (PINF&(1<<7) ? 0 : (1<<3));
104 matrix_stage[1] =
105 (PIND&(1<<1) ? 0 : (1<<0)) |
106 (PIND&(1<<0) ? 0 : (1<<1)) |
107 (PIND&(1<<4) ? 0 : (1<<2)) |
108 (PINC&(1<<6) ? 0 : (1<<3));
109
110 if (memcmp(matrix_debouncing, matrix_stage, sizeof(matrix)) != 0) {
111 debouncing = true;
112 debouncing_time = timer_read();
113 }
114
115 matrix_debouncing[0] = matrix_stage[0];
116 matrix_debouncing[1] = matrix_stage[1];
117
118 if (debouncing && (timer_elapsed(debouncing_time) > 20)) {
119 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
120 matrix[i] = matrix_debouncing[i];
121 }
122 debouncing = false;
123 }
124
125 matrix_scan_quantum();
126
127 return 1;
128}
129
130bool matrix_is_modified(void)
131{
132 return true;
133}
134
135inline
136bool matrix_is_on(uint8_t row, uint8_t col)
137{
138 return (matrix[row] & ((matrix_row_t)1<<col));
139}
140
141inline
142matrix_row_t matrix_get_row(uint8_t row)
143{
144 return matrix[row];
145}
146
147void matrix_print(void)
148{
149}
150
151uint8_t matrix_key_count(void)
152{
153 uint8_t count = 0;
154 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
155 count += bitpop16(matrix[i]);
156 }
157 return count;
158}
159
diff --git a/keyboards/40percentclub/nano/nano.h b/keyboards/40percentclub/nano/nano.h
index ae297ac12..881309738 100644
--- a/keyboards/40percentclub/nano/nano.h
+++ b/keyboards/40percentclub/nano/nano.h
@@ -2,10 +2,12 @@
2 2
3#include "quantum.h" 3#include "quantum.h"
4 4
5#define LAYOUT( \ 5#define LAYOUT_ortho_2x4( \
6 k01, k02, k03, k04, \ 6 k01, k02, k03, k04, \
7 k05, k06, k07, k08 \ 7 k05, k06, k07, k08 \
8 ) { \ 8 ) { \
9 { k01, k02, k03, k04 }, \ 9 { k01, k02, k03, k04 }, \
10 { k05, k06, k07, k08 } \ 10 { k05, k06, k07, k08 } \
11} 11}
12
13#define LAYOUT LAYOUT_ortho_2x4
diff --git a/keyboards/40percentclub/nano/rules.mk b/keyboards/40percentclub/nano/rules.mk
index 66ad3ffc6..e3c97e0d4 100644
--- a/keyboards/40percentclub/nano/rules.mk
+++ b/keyboards/40percentclub/nano/rules.mk
@@ -76,7 +76,3 @@ RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight.
76 76
77# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE 77# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
78SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend 78SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
79
80# custom matrix setup
81SRC = matrix.c
82CUSTOM_MATRIX = yes
diff --git a/quantum/matrix.c b/quantum/matrix.c
index f7cad1a0f..ca63f50f2 100644
--- a/quantum/matrix.c
+++ b/quantum/matrix.c
@@ -45,7 +45,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
45 extern const matrix_row_t matrix_mask[]; 45 extern const matrix_row_t matrix_mask[];
46#endif 46#endif
47 47
48#if (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW) 48#ifdef DIRECT_PINS
49static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS;
50#elif (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW)
49static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; 51static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
50static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; 52static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
51#endif 53#endif
@@ -54,20 +56,6 @@ static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
54static matrix_row_t raw_matrix[MATRIX_ROWS]; //raw values 56static matrix_row_t raw_matrix[MATRIX_ROWS]; //raw values
55static matrix_row_t matrix[MATRIX_ROWS]; //debounced values 57static matrix_row_t matrix[MATRIX_ROWS]; //debounced values
56 58
57#if (DIODE_DIRECTION == COL2ROW)
58 static void init_cols(void);
59 static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row);
60 static void unselect_rows(void);
61 static void select_row(uint8_t row);
62 static void unselect_row(uint8_t row);
63#elif (DIODE_DIRECTION == ROW2COL)
64 static void init_rows(void);
65 static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col);
66 static void unselect_cols(void);
67 static void unselect_col(uint8_t col);
68 static void select_col(uint8_t col);
69#endif
70
71__attribute__ ((weak)) 59__attribute__ ((weak))
72void matrix_init_quantum(void) { 60void matrix_init_quantum(void) {
73 matrix_init_kb(); 61 matrix_init_kb();
@@ -106,49 +94,6 @@ uint8_t matrix_cols(void) {
106 return MATRIX_COLS; 94 return MATRIX_COLS;
107} 95}
108 96
109void matrix_init(void) {
110
111 // initialize row and col
112#if (DIODE_DIRECTION == COL2ROW)
113 unselect_rows();
114 init_cols();
115#elif (DIODE_DIRECTION == ROW2COL)
116 unselect_cols();
117 init_rows();
118#endif
119
120 // initialize matrix state: all keys off
121 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
122 raw_matrix[i] = 0;
123 matrix[i] = 0;
124 }
125 debounce_init(MATRIX_ROWS);
126
127 matrix_init_quantum();
128}
129
130uint8_t matrix_scan(void)
131{
132 bool changed = false;
133
134#if (DIODE_DIRECTION == COL2ROW)
135 // Set row, read cols
136 for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
137 changed |= read_cols_on_row(raw_matrix, current_row);
138 }
139#elif (DIODE_DIRECTION == ROW2COL)
140 // Set col, read rows
141 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
142 changed |= read_rows_on_col(raw_matrix, current_col);
143 }
144#endif
145
146 debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
147
148 matrix_scan_quantum();
149 return 1;
150}
151
152//Deprecated. 97//Deprecated.
153bool matrix_is_modified(void) 98bool matrix_is_modified(void)
154{ 99{
@@ -195,16 +140,60 @@ uint8_t matrix_key_count(void)
195} 140}
196 141
197 142
143#ifdef DIRECT_PINS
144
145static void init_pins(void) {
146 for (int row = 0; row < MATRIX_ROWS; row++) {
147 for (int col = 0; col < MATRIX_COLS; col++) {
148 pin_t pin = direct_pins[row][col];
149 if (pin != NO_PIN) {
150 setPinInputHigh(pin);
151 }
152 }
153 }
154}
198 155
199#if (DIODE_DIRECTION == COL2ROW) 156static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
157 matrix_row_t last_row_value = current_matrix[current_row];
158 current_matrix[current_row] = 0;
200 159
201static void init_cols(void) 160 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
161 pin_t pin = direct_pins[current_row][col_index];
162 if (pin != NO_PIN) {
163 current_matrix[current_row] |= readPin(pin) ? 0 : (ROW_SHIFTER << col_index);
164 }
165 }
166
167 return (last_row_value != current_matrix[current_row]);
168}
169
170#elif (DIODE_DIRECTION == COL2ROW)
171
172static void select_row(uint8_t row)
202{ 173{
203 for(uint8_t x = 0; x < MATRIX_COLS; x++) { 174 setPinOutput(row_pins[row]);
204 setPinInputHigh(col_pins[x]); 175 writePinLow(row_pins[row]);
176}
177
178static void unselect_row(uint8_t row)
179{
180 setPinInputHigh(row_pins[row]);
181}
182
183static void unselect_rows(void)
184{
185 for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
186 setPinInput(row_pins[x]);
205 } 187 }
206} 188}
207 189
190static void init_pins(void) {
191 unselect_rows();
192 for (uint8_t x = 0; x < MATRIX_COLS; x++) {
193 setPinInputHigh(col_pins[x]);
194 }
195}
196
208static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) 197static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
209{ 198{
210 // Store last value of row prior to reading 199 // Store last value of row prior to reading
@@ -233,31 +222,31 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
233 return (last_row_value != current_matrix[current_row]); 222 return (last_row_value != current_matrix[current_row]);
234} 223}
235 224
236static void select_row(uint8_t row) 225#elif (DIODE_DIRECTION == ROW2COL)
226
227static void select_col(uint8_t col)
237{ 228{
238 setPinOutput(row_pins[row]); 229 setPinOutput(col_pins[col]);
239 writePinLow(row_pins[row]); 230 writePinLow(col_pins[col]);
240} 231}
241 232
242static void unselect_row(uint8_t row) 233static void unselect_col(uint8_t col)
243{ 234{
244 setPinInputHigh(row_pins[row]); 235 setPinInputHigh(col_pins[col]);
245} 236}
246 237
247static void unselect_rows(void) 238static void unselect_cols(void)
248{ 239{
249 for(uint8_t x = 0; x < MATRIX_ROWS; x++) { 240 for(uint8_t x = 0; x < MATRIX_COLS; x++) {
250 setPinInput(row_pins[x]); 241 setPinInputHigh(col_pins[x]);
251 } 242 }
252} 243}
253 244
254#elif (DIODE_DIRECTION == ROW2COL) 245static void init_pins(void) {
255 246 unselect_cols();
256static void init_rows(void) 247 for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
257{ 248 setPinInputHigh(row_pins[x]);
258 for(uint8_t x = 0; x < MATRIX_ROWS; x++) { 249 }
259 setPinInputHigh(row_pins[x]);
260 }
261} 250}
262 251
263static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) 252static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
@@ -300,22 +289,42 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
300 return matrix_changed; 289 return matrix_changed;
301} 290}
302 291
303static void select_col(uint8_t col) 292#endif
304{
305 setPinOutput(col_pins[col]);
306 writePinLow(col_pins[col]);
307}
308 293
309static void unselect_col(uint8_t col) 294void matrix_init(void) {
310{
311 setPinInputHigh(col_pins[col]);
312}
313 295
314static void unselect_cols(void) 296 // initialize key pins
315{ 297 init_pins();
316 for(uint8_t x = 0; x < MATRIX_COLS; x++) { 298
317 setPinInputHigh(col_pins[x]); 299 // initialize matrix state: all keys off
300 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
301 raw_matrix[i] = 0;
302 matrix[i] = 0;
318 } 303 }
304
305 debounce_init(MATRIX_ROWS);
306
307 matrix_init_quantum();
319} 308}
320 309
310uint8_t matrix_scan(void)
311{
312 bool changed = false;
313
314#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW)
315 // Set row, read cols
316 for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
317 changed |= read_cols_on_row(raw_matrix, current_row);
318 }
319#elif (DIODE_DIRECTION == ROW2COL)
320 // Set col, read rows
321 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
322 changed |= read_rows_on_col(raw_matrix, current_col);
323 }
321#endif 324#endif
325
326 debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
327
328 matrix_scan_quantum();
329 return 1;
330}