aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/internals_gpio_control.md23
-rw-r--r--quantum/config_common.h199
-rw-r--r--quantum/matrix.c49
-rw-r--r--quantum/quantum.h69
4 files changed, 244 insertions, 96 deletions
diff --git a/docs/internals_gpio_control.md b/docs/internals_gpio_control.md
new file mode 100644
index 000000000..21643d30c
--- /dev/null
+++ b/docs/internals_gpio_control.md
@@ -0,0 +1,23 @@
1# GPIO Control
2
3QMK has a GPIO control abstraction layer which is micro-controller agnostic. This is done to allow easy access to pin control across different platforms.
4
5## Functions
6
7The following functions can provide basic control of GPIOs and are found in `quantum/quantum.h`.
8
9|Function |Description |
10|----------------------|------------------------------------------------------------------|
11|`setPinInput(pin)` |Set pin as input with high impedance (High-Z) |
12|`setPinInputHigh(pin)`|Set pin as input with build in pull-up |
13|`setPinInputLow(pin)` |Set pin as input with build in pull-down (Supported only on STM32)|
14|`setPinOutput(pin)` |Set pin as output |
15|`writePinHige(pin)` |Set pin level as high, assuming it is an output |
16|`writePinLow(pin)` |Set pin level as low, assuming it is an output |
17|`writePin(pin, level)`|Set pin level, assuming it is an output |
18|`readPin(pin)` |Returns the level of the pin |
19
20## Advance settings
21
22Each micro-controller can have multiple advance settings regarding its GPIO. This abstraction layer does not limit the use of architecture specific functions. Advance users should consult the datasheet of there desired device and include any needed libraries. For AVR the standard avr/io.h library is used and for STM32 the Chibios [PAL library](http://chibios.sourceforge.net/docs3/hal/group___p_a_l.html) is used.
23
diff --git a/quantum/config_common.h b/quantum/config_common.h
index f6f51b367..288617255 100644
--- a/quantum/config_common.h
+++ b/quantum/config_common.h
@@ -23,57 +23,154 @@
23#define CUSTOM_MATRIX 2 /* Disables built-in matrix scanning code */ 23#define CUSTOM_MATRIX 2 /* Disables built-in matrix scanning code */
24 24
25#ifdef __AVR__ 25#ifdef __AVR__
26 /* I/O pins */ 26 /* I/O pins */
27 #ifndef F0 27 #ifndef F0
28 #define B0 0x30 28 #define B0 0x30
29 #define B1 0x31 29 #define B1 0x31
30 #define B2 0x32 30 #define B2 0x32
31 #define B3 0x33 31 #define B3 0x33
32 #define B4 0x34 32 #define B4 0x34
33 #define B5 0x35 33 #define B5 0x35
34 #define B6 0x36 34 #define B6 0x36
35 #define B7 0x37 35 #define B7 0x37
36 #define C0 0x60 36 #define C0 0x60
37 #define C1 0x61 37 #define C1 0x61
38 #define C2 0x62 38 #define C2 0x62
39 #define C3 0x63 39 #define C3 0x63
40 #define C4 0x64 40 #define C4 0x64
41 #define C5 0x65 41 #define C5 0x65
42 #define C6 0x66 42 #define C6 0x66
43 #define C7 0x67 43 #define C7 0x67
44 #define D0 0x90 44 #define D0 0x90
45 #define D1 0x91 45 #define D1 0x91
46 #define D2 0x92 46 #define D2 0x92
47 #define D3 0x93 47 #define D3 0x93
48 #define D4 0x94 48 #define D4 0x94
49 #define D5 0x95 49 #define D5 0x95
50 #define D6 0x96 50 #define D6 0x96
51 #define D7 0x97 51 #define D7 0x97
52 #define E0 0xC0 52 #define E0 0xC0
53 #define E1 0xC1 53 #define E1 0xC1
54 #define E2 0xC2 54 #define E2 0xC2
55 #define E3 0xC3 55 #define E3 0xC3
56 #define E4 0xC4 56 #define E4 0xC4
57 #define E5 0xC5 57 #define E5 0xC5
58 #define E6 0xC6 58 #define E6 0xC6
59 #define E7 0xC7 59 #define E7 0xC7
60 #define F0 0xF0 60 #define F0 0xF0
61 #define F1 0xF1 61 #define F1 0xF1
62 #define F2 0xF2 62 #define F2 0xF2
63 #define F3 0xF3 63 #define F3 0xF3
64 #define F4 0xF4 64 #define F4 0xF4
65 #define F5 0xF5 65 #define F5 0xF5
66 #define F6 0xF6 66 #define F6 0xF6
67 #define F7 0xF7 67 #define F7 0xF7
68 #define A0 0x00 68 #define A0 0x00
69 #define A1 0x01 69 #define A1 0x01
70 #define A2 0x02 70 #define A2 0x02
71 #define A3 0x03 71 #define A3 0x03
72 #define A4 0x04 72 #define A4 0x04
73 #define A5 0x05 73 #define A5 0x05
74 #define A6 0x06 74 #define A6 0x06
75 #define A7 0x07 75 #define A7 0x07
76 #endif 76 #endif
77#elif defined(PROTOCOL_CHIBIOS)
78 #define A0 PAL_LINE(GPIOA, 0)
79 #define A1 PAL_LINE(GPIOA, 1)
80 #define A2 PAL_LINE(GPIOA, 2)
81 #define A3 PAL_LINE(GPIOA, 3)
82 #define A4 PAL_LINE(GPIOA, 4)
83 #define A5 PAL_LINE(GPIOA, 5)
84 #define A6 PAL_LINE(GPIOA, 6)
85 #define A7 PAL_LINE(GPIOA, 7)
86 #define A8 PAL_LINE(GPIOA, 8)
87 #define A9 PAL_LINE(GPIOA, 9)
88 #define A10 PAL_LINE(GPIOA, 10)
89 #define A11 PAL_LINE(GPIOA, 11)
90 #define A12 PAL_LINE(GPIOA, 12)
91 #define A13 PAL_LINE(GPIOA, 13)
92 #define A14 PAL_LINE(GPIOA, 14)
93 #define A15 PAL_LINE(GPIOA, 15)
94 #define B0 PAL_LINE(GPIOB, 0)
95 #define B1 PAL_LINE(GPIOB, 1)
96 #define B2 PAL_LINE(GPIOB, 2)
97 #define B3 PAL_LINE(GPIOB, 3)
98 #define B4 PAL_LINE(GPIOB, 4)
99 #define B5 PAL_LINE(GPIOB, 5)
100 #define B6 PAL_LINE(GPIOB, 6)
101 #define B7 PAL_LINE(GPIOB, 7)
102 #define B8 PAL_LINE(GPIOB, 8)
103 #define B9 PAL_LINE(GPIOB, 9)
104 #define B10 PAL_LINE(GPIOB, 10)
105 #define B11 PAL_LINE(GPIOB, 11)
106 #define B12 PAL_LINE(GPIOB, 12)
107 #define B13 PAL_LINE(GPIOB, 13)
108 #define B14 PAL_LINE(GPIOB, 14)
109 #define B15 PAL_LINE(GPIOB, 15)
110 #define C0 PAL_LINE(GPIOC, 0)
111 #define C1 PAL_LINE(GPIOC, 1)
112 #define C2 PAL_LINE(GPIOC, 2)
113 #define C3 PAL_LINE(GPIOC, 3)
114 #define C4 PAL_LINE(GPIOC, 4)
115 #define C5 PAL_LINE(GPIOC, 5)
116 #define C6 PAL_LINE(GPIOC, 6)
117 #define C7 PAL_LINE(GPIOC, 7)
118 #define C8 PAL_LINE(GPIOC, 8)
119 #define C9 PAL_LINE(GPIOC, 9)
120 #define C10 PAL_LINE(GPIOC, 10)
121 #define C11 PAL_LINE(GPIOC, 11)
122 #define C12 PAL_LINE(GPIOC, 12)
123 #define C13 PAL_LINE(GPIOC, 13)
124 #define C14 PAL_LINE(GPIOC, 14)
125 #define C15 PAL_LINE(GPIOC, 15)
126 #define D0 PAL_LINE(GPIOD, 0)
127 #define D1 PAL_LINE(GPIOD, 1)
128 #define D2 PAL_LINE(GPIOD, 2)
129 #define D3 PAL_LINE(GPIOD, 3)
130 #define D4 PAL_LINE(GPIOD, 4)
131 #define D5 PAL_LINE(GPIOD, 5)
132 #define D6 PAL_LINE(GPIOD, 6)
133 #define D7 PAL_LINE(GPIOD, 7)
134 #define D8 PAL_LINE(GPIOD, 8)
135 #define D9 PAL_LINE(GPIOD, 9)
136 #define D10 PAL_LINE(GPIOD, 10)
137 #define D11 PAL_LINE(GPIOD, 11)
138 #define D12 PAL_LINE(GPIOD, 12)
139 #define D13 PAL_LINE(GPIOD, 13)
140 #define D14 PAL_LINE(GPIOD, 14)
141 #define D15 PAL_LINE(GPIOD, 15)
142 #define E0 PAL_LINE(GPIOE, 0)
143 #define E1 PAL_LINE(GPIOE, 1)
144 #define E2 PAL_LINE(GPIOE, 2)
145 #define E3 PAL_LINE(GPIOE, 3)
146 #define E4 PAL_LINE(GPIOE, 4)
147 #define E5 PAL_LINE(GPIOE, 5)
148 #define E6 PAL_LINE(GPIOE, 6)
149 #define E7 PAL_LINE(GPIOE, 7)
150 #define E8 PAL_LINE(GPIOE, 8)
151 #define E9 PAL_LINE(GPIOE, 9)
152 #define E10 PAL_LINE(GPIOE, 10)
153 #define E11 PAL_LINE(GPIOE, 11)
154 #define E12 PAL_LINE(GPIOE, 12)
155 #define E13 PAL_LINE(GPIOE, 13)
156 #define E14 PAL_LINE(GPIOE, 14)
157 #define E15 PAL_LINE(GPIOE, 15)
158 #define F0 PAL_LINE(GPIOF, 0)
159 #define F1 PAL_LINE(GPIOF, 1)
160 #define F2 PAL_LINE(GPIOF, 2)
161 #define F3 PAL_LINE(GPIOF, 3)
162 #define F4 PAL_LINE(GPIOF, 4)
163 #define F5 PAL_LINE(GPIOF, 5)
164 #define F6 PAL_LINE(GPIOF, 6)
165 #define F7 PAL_LINE(GPIOF, 7)
166 #define F8 PAL_LINE(GPIOF, 8)
167 #define F9 PAL_LINE(GPIOF, 9)
168 #define F10 PAL_LINE(GPIOF, 10)
169 #define F11 PAL_LINE(GPIOF, 11)
170 #define F12 PAL_LINE(GPIOF, 12)
171 #define F13 PAL_LINE(GPIOF, 13)
172 #define F14 PAL_LINE(GPIOF, 14)
173 #define F15 PAL_LINE(GPIOF, 15)
77#endif 174#endif
78 175
79/* USART configuration */ 176/* USART configuration */
diff --git a/quantum/matrix.c b/quantum/matrix.c
index 3600d4e7b..9b5ce33d2 100644
--- a/quantum/matrix.c
+++ b/quantum/matrix.c
@@ -1,5 +1,5 @@
1/* 1/*
2Copyright 2012-2017 Jun Wako, Jack Humbert 2Copyright 2012-2018 Jun Wako, Jack Humbert, Yiancar
3 3
4This program is free software: you can redistribute it and/or modify 4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by 5it under the terms of the GNU General Public License as published by
@@ -16,15 +16,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17#include <stdint.h> 17#include <stdint.h>
18#include <stdbool.h> 18#include <stdbool.h>
19#if defined(__AVR__)
20#include <avr/io.h>
21#endif
22#include "wait.h" 19#include "wait.h"
23#include "print.h" 20#include "print.h"
24#include "debug.h" 21#include "debug.h"
25#include "util.h" 22#include "util.h"
26#include "matrix.h" 23#include "matrix.h"
27#include "timer.h" 24#include "timer.h"
25#include "quantum.h"
28 26
29 27
30/* Set 0 if debouncing isn't needed */ 28/* Set 0 if debouncing isn't needed */
@@ -60,8 +58,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
60#endif 58#endif
61 59
62#if (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW) 60#if (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW)
63static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; 61static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
64static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; 62static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
65#endif 63#endif
66 64
67/* matrix state(1:on, 0:off) */ 65/* matrix state(1:on, 0:off) */
@@ -271,9 +269,7 @@ uint8_t matrix_key_count(void)
271static void init_cols(void) 269static void init_cols(void)
272{ 270{
273 for(uint8_t x = 0; x < MATRIX_COLS; x++) { 271 for(uint8_t x = 0; x < MATRIX_COLS; x++) {
274 uint8_t pin = col_pins[x]; 272 setPinInputHigh(col_pins[x]);
275 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
276 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
277 } 273 }
278} 274}
279 275
@@ -293,8 +289,7 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
293 for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { 289 for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
294 290
295 // Select the col pin to read (active low) 291 // Select the col pin to read (active low)
296 uint8_t pin = col_pins[col_index]; 292 uint8_t pin_state = readPin(col_pins[col_index]);
297 uint8_t pin_state = (_SFR_IO8(pin >> 4) & _BV(pin & 0xF));
298 293
299 // Populate the matrix row with the state of the col pin 294 // Populate the matrix row with the state of the col pin
300 current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index); 295 current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index);
@@ -308,24 +303,19 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
308 303
309static void select_row(uint8_t row) 304static void select_row(uint8_t row)
310{ 305{
311 uint8_t pin = row_pins[row]; 306 setPinOutput(row_pins[row]);
312 _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT 307 writePinLow(row_pins[row]);
313 _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
314} 308}
315 309
316static void unselect_row(uint8_t row) 310static void unselect_row(uint8_t row)
317{ 311{
318 uint8_t pin = row_pins[row]; 312 setPinInputHigh(row_pins[row]);
319 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
320 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
321} 313}
322 314
323static void unselect_rows(void) 315static void unselect_rows(void)
324{ 316{
325 for(uint8_t x = 0; x < MATRIX_ROWS; x++) { 317 for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
326 uint8_t pin = row_pins[x]; 318 setPinInput(row_pins[x]);
327 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
328 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
329 } 319 }
330} 320}
331 321
@@ -334,9 +324,7 @@ static void unselect_rows(void)
334static void init_rows(void) 324static void init_rows(void)
335{ 325{
336 for(uint8_t x = 0; x < MATRIX_ROWS; x++) { 326 for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
337 uint8_t pin = row_pins[x]; 327 setPinInputHigh(row_pins[x]);
338 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
339 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
340 } 328 }
341} 329}
342 330
@@ -356,7 +344,7 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
356 matrix_row_t last_row_value = current_matrix[row_index]; 344 matrix_row_t last_row_value = current_matrix[row_index];
357 345
358 // Check row pin state 346 // Check row pin state
359 if ((_SFR_IO8(row_pins[row_index] >> 4) & _BV(row_pins[row_index] & 0xF)) == 0) 347 if (readPin(row_pins[row_index]) == 0)
360 { 348 {
361 // Pin LO, set col bit 349 // Pin LO, set col bit
362 current_matrix[row_index] |= (ROW_SHIFTER << current_col); 350 current_matrix[row_index] |= (ROW_SHIFTER << current_col);
@@ -382,24 +370,19 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
382 370
383static void select_col(uint8_t col) 371static void select_col(uint8_t col)
384{ 372{
385 uint8_t pin = col_pins[col]; 373 setPinOutput(col_pins[col]);
386 _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT 374 writePinLow(col_pins[col]);
387 _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
388} 375}
389 376
390static void unselect_col(uint8_t col) 377static void unselect_col(uint8_t col)
391{ 378{
392 uint8_t pin = col_pins[col]; 379 setPinInputHigh(col_pins[col]);
393 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
394 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
395} 380}
396 381
397static void unselect_cols(void) 382static void unselect_cols(void)
398{ 383{
399 for(uint8_t x = 0; x < MATRIX_COLS; x++) { 384 for(uint8_t x = 0; x < MATRIX_COLS; x++) {
400 uint8_t pin = col_pins[x]; 385 setPinInputHigh(col_pins[x]);
401 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
402 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
403 } 386 }
404} 387}
405 388
diff --git a/quantum/quantum.h b/quantum/quantum.h
index 7cf16d81e..683333211 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -1,4 +1,4 @@
1/* Copyright 2016-2017 Erez Zukerman, Jack Humbert 1/* Copyright 2016-2018 Erez Zukerman, Jack Humbert, Yiancar
2 * 2 *
3 * This program is free software: you can redistribute it and/or modify 3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by 4 * it under the terms of the GNU General Public License as published by
@@ -17,9 +17,12 @@
17#define QUANTUM_H 17#define QUANTUM_H
18 18
19#if defined(__AVR__) 19#if defined(__AVR__)
20#include <avr/pgmspace.h> 20 #include <avr/pgmspace.h>
21#include <avr/io.h> 21 #include <avr/io.h>
22#include <avr/interrupt.h> 22 #include <avr/interrupt.h>
23#endif
24#if defined(PROTOCOL_CHIBIOS)
25 #include "hal.h"
23#endif 26#endif
24#include "wait.h" 27#include "wait.h"
25#include "matrix.h" 28#include "matrix.h"
@@ -33,11 +36,11 @@
33#ifdef RGBLIGHT_ENABLE 36#ifdef RGBLIGHT_ENABLE
34 #include "rgblight.h" 37 #include "rgblight.h"
35#else 38#else
36 #ifdef RGB_MATRIX_ENABLE 39 #ifdef RGB_MATRIX_ENABLE
37 /* dummy define RGBLIGHT_MODE_xxxx */ 40 /* dummy define RGBLIGHT_MODE_xxxx */
38 #define RGBLIGHT_H_DUMMY_DEFINE 41 #define RGBLIGHT_H_DUMMY_DEFINE
39 #include "rgblight.h" 42 #include "rgblight.h"
40 #endif 43 #endif
41#endif 44#endif
42 45
43#ifdef SPLIT_KEYBOARD 46#ifdef SPLIT_KEYBOARD
@@ -76,9 +79,9 @@ extern uint32_t default_layer_state;
76#ifdef AUDIO_ENABLE 79#ifdef AUDIO_ENABLE
77 #include "audio.h" 80 #include "audio.h"
78 #include "process_audio.h" 81 #include "process_audio.h"
79 #ifdef AUDIO_CLICKY 82 #ifdef AUDIO_CLICKY
80 #include "process_clicky.h" 83 #include "process_clicky.h"
81 #endif // AUDIO_CLICKY 84 #endif // AUDIO_CLICKY
82#endif 85#endif
83 86
84#ifdef STENO_ENABLE 87#ifdef STENO_ENABLE
@@ -133,6 +136,48 @@ extern uint32_t default_layer_state;
133 #include "hd44780.h" 136 #include "hd44780.h"
134#endif 137#endif
135 138
139//Function substitutions to ease GPIO manipulation
140#ifdef __AVR__
141 #define pin_t uint8_t
142 #define setPinInput(pin) _SFR_IO8((pin >> 4) + 1) &= ~ _BV(pin & 0xF)
143 #define setPinInputHigh(pin) ({\
144 _SFR_IO8((pin >> 4) + 1) &= ~ _BV(pin & 0xF);\
145 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF);\
146 })
147 #define setPinInputLow(pin) _Static_assert(0, "AVR Processors cannot impliment an input as pull low")
148 #define setPinOutput(pin) _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF)
149
150 #define writePinHigh(pin) _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF)
151 #define writePinLow(pin) _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF)
152 static inline void writePin(pin_t pin, uint8_t level){
153 if (level){
154 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF);
155 } else {
156 _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF);
157 }
158 }
159
160 #define readPin(pin) (_SFR_IO8(pin >> 4) & _BV(pin & 0xF))
161#elif defined(PROTOCOL_CHIBIOS)
162 #define pin_t ioline_t
163 #define setPinInput(pin) palSetLineMode(pin, PAL_MODE_INPUT)
164 #define setPinInputHigh(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)
165 #define setPinInputLow(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)
166 #define setPinOutput(pin) palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)
167
168 #define writePinHigh(pin) palSetLine(pin)
169 #define writePinLow(pin) palClearLine(pin)
170 static inline void writePin(pin_t pin, uint8_t level){
171 if (level){
172 palSetLine(pin);
173 } else {
174 palClearLine(pin);
175 }
176 }
177
178 #define readPin(pin) palReadLine(pin)
179#endif
180
136#define STRINGIZE(z) #z 181#define STRINGIZE(z) #z
137#define ADD_SLASH_X(y) STRINGIZE(\x ## y) 182#define ADD_SLASH_X(y) STRINGIZE(\x ## y)
138#define SYMBOL_STR(x) ADD_SLASH_X(x) 183#define SYMBOL_STR(x) ADD_SLASH_X(x)