]> git.donarmstrong.com Git - qmk_firmware.git/commitdiff
Update quantum matrix to support both AVR and Chibios ARM (#3968)
authoryiancar <yiangosyiangou@cytanet.com.cy>
Fri, 28 Sep 2018 16:33:11 +0000 (17:33 +0100)
committerJack Humbert <jack.humb@gmail.com>
Fri, 28 Sep 2018 16:33:11 +0000 (12:33 -0400)
* Update quantum matrix to support both AVR and Chibios ARM

- Addition of STM32 pin definitions
- Created abstruction layer defines to control GPIO (This is a bit pointless for Chibios as we are creating a PAL ontop of a PAL but it is necessary for uniformity with AVR)
- Modified matrix.c to use the above functions

* minor ifdef fix

* Rename of functions and docs

- Added documentation.
- Renamed functions according to Jack's spec.

* Massdrop fix

* Update matrix.c

* Update quantum.h

* Update quantum.h

* Update quantum.h

* Update internals_gpio_control.md

docs/internals_gpio_control.md [new file with mode: 0644]
quantum/config_common.h
quantum/matrix.c
quantum/quantum.h

diff --git a/docs/internals_gpio_control.md b/docs/internals_gpio_control.md
new file mode 100644 (file)
index 0000000..21643d3
--- /dev/null
@@ -0,0 +1,23 @@
+# GPIO Control
+
+QMK has a GPIO control abstraction layer which is micro-controller agnostic. This is done to allow easy access to pin control across different platforms.
+
+## Functions
+
+The following functions can provide basic control of GPIOs and are found in `quantum/quantum.h`.
+
+|Function              |Description                                                       |
+|----------------------|------------------------------------------------------------------|
+|`setPinInput(pin)`    |Set pin as input with high impedance (High-Z)                     |
+|`setPinInputHigh(pin)`|Set pin as input with build in pull-up                            |
+|`setPinInputLow(pin)` |Set pin as input with build in pull-down (Supported only on STM32)|
+|`setPinOutput(pin)`   |Set pin as output                                                 |
+|`writePinHige(pin)`   |Set pin level as high, assuming it is an output                   |
+|`writePinLow(pin)`    |Set pin level as low, assuming it is an output                    |
+|`writePin(pin, level)`|Set pin level, assuming it is an output                           |
+|`readPin(pin)`        |Returns the level of the pin                                      |
+
+## Advance settings
+
+Each 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.
+
index f6f51b367da194182d029497b3cf93791a3dc580..288617255f51ad8324a1b163e7af610947b71cf2 100644 (file)
 #define CUSTOM_MATRIX 2 /* Disables built-in matrix scanning code */
 
 #ifdef __AVR__
-  /* I/O pins */
-  #ifndef F0
-      #define B0 0x30
-      #define B1 0x31
-      #define B2 0x32
-      #define B3 0x33
-      #define B4 0x34
-      #define B5 0x35
-      #define B6 0x36
-      #define B7 0x37
-      #define C0 0x60
-      #define C1 0x61
-      #define C2 0x62
-      #define C3 0x63
-      #define C4 0x64
-      #define C5 0x65
-      #define C6 0x66
-      #define C7 0x67
-      #define D0 0x90
-      #define D1 0x91
-      #define D2 0x92
-      #define D3 0x93
-      #define D4 0x94
-      #define D5 0x95
-      #define D6 0x96
-      #define D7 0x97
-      #define E0 0xC0
-      #define E1 0xC1
-      #define E2 0xC2
-      #define E3 0xC3
-      #define E4 0xC4
-      #define E5 0xC5
-      #define E6 0xC6
-      #define E7 0xC7
-      #define F0 0xF0
-      #define F1 0xF1
-      #define F2 0xF2
-      #define F3 0xF3
-      #define F4 0xF4
-      #define F5 0xF5
-      #define F6 0xF6
-      #define F7 0xF7
-      #define A0 0x00
-      #define A1 0x01
-      #define A2 0x02
-      #define A3 0x03
-      #define A4 0x04
-      #define A5 0x05
-      #define A6 0x06
-      #define A7 0x07
-  #endif
+    /* I/O pins */
+    #ifndef F0
+        #define B0 0x30
+        #define B1 0x31
+        #define B2 0x32
+        #define B3 0x33
+        #define B4 0x34
+        #define B5 0x35
+        #define B6 0x36
+        #define B7 0x37
+        #define C0 0x60
+        #define C1 0x61
+        #define C2 0x62
+        #define C3 0x63
+        #define C4 0x64
+        #define C5 0x65
+        #define C6 0x66
+        #define C7 0x67
+        #define D0 0x90
+        #define D1 0x91
+        #define D2 0x92
+        #define D3 0x93
+        #define D4 0x94
+        #define D5 0x95
+        #define D6 0x96
+        #define D7 0x97
+        #define E0 0xC0
+        #define E1 0xC1
+        #define E2 0xC2
+        #define E3 0xC3
+        #define E4 0xC4
+        #define E5 0xC5
+        #define E6 0xC6
+        #define E7 0xC7
+        #define F0 0xF0
+        #define F1 0xF1
+        #define F2 0xF2
+        #define F3 0xF3
+        #define F4 0xF4
+        #define F5 0xF5
+        #define F6 0xF6
+        #define F7 0xF7
+        #define A0 0x00
+        #define A1 0x01
+        #define A2 0x02
+        #define A3 0x03
+        #define A4 0x04
+        #define A5 0x05
+        #define A6 0x06
+        #define A7 0x07
+    #endif
+#elif defined(PROTOCOL_CHIBIOS)
+    #define A0  PAL_LINE(GPIOA, 0)
+    #define A1  PAL_LINE(GPIOA, 1)
+    #define A2  PAL_LINE(GPIOA, 2)
+    #define A3  PAL_LINE(GPIOA, 3)
+    #define A4  PAL_LINE(GPIOA, 4)
+    #define A5  PAL_LINE(GPIOA, 5)
+    #define A6  PAL_LINE(GPIOA, 6)
+    #define A7  PAL_LINE(GPIOA, 7)
+    #define A8  PAL_LINE(GPIOA, 8)
+    #define A9  PAL_LINE(GPIOA, 9)
+    #define A10 PAL_LINE(GPIOA, 10)
+    #define A11 PAL_LINE(GPIOA, 11)
+    #define A12 PAL_LINE(GPIOA, 12)
+    #define A13 PAL_LINE(GPIOA, 13)
+    #define A14 PAL_LINE(GPIOA, 14)
+    #define A15 PAL_LINE(GPIOA, 15)
+    #define B0  PAL_LINE(GPIOB, 0)
+    #define B1  PAL_LINE(GPIOB, 1)
+    #define B2  PAL_LINE(GPIOB, 2)
+    #define B3  PAL_LINE(GPIOB, 3)
+    #define B4  PAL_LINE(GPIOB, 4)
+    #define B5  PAL_LINE(GPIOB, 5)
+    #define B6  PAL_LINE(GPIOB, 6)
+    #define B7  PAL_LINE(GPIOB, 7)
+    #define B8  PAL_LINE(GPIOB, 8)
+    #define B9  PAL_LINE(GPIOB, 9)
+    #define B10 PAL_LINE(GPIOB, 10)
+    #define B11 PAL_LINE(GPIOB, 11)
+    #define B12 PAL_LINE(GPIOB, 12)
+    #define B13 PAL_LINE(GPIOB, 13)
+    #define B14 PAL_LINE(GPIOB, 14)
+    #define B15 PAL_LINE(GPIOB, 15)
+    #define C0  PAL_LINE(GPIOC, 0)
+    #define C1  PAL_LINE(GPIOC, 1)
+    #define C2  PAL_LINE(GPIOC, 2)
+    #define C3  PAL_LINE(GPIOC, 3)
+    #define C4  PAL_LINE(GPIOC, 4)
+    #define C5  PAL_LINE(GPIOC, 5)
+    #define C6  PAL_LINE(GPIOC, 6)
+    #define C7  PAL_LINE(GPIOC, 7)
+    #define C8  PAL_LINE(GPIOC, 8)
+    #define C9  PAL_LINE(GPIOC, 9)
+    #define C10 PAL_LINE(GPIOC, 10)
+    #define C11 PAL_LINE(GPIOC, 11)
+    #define C12 PAL_LINE(GPIOC, 12)
+    #define C13 PAL_LINE(GPIOC, 13)
+    #define C14 PAL_LINE(GPIOC, 14)
+    #define C15 PAL_LINE(GPIOC, 15)
+    #define D0  PAL_LINE(GPIOD, 0)
+    #define D1  PAL_LINE(GPIOD, 1)
+    #define D2  PAL_LINE(GPIOD, 2)
+    #define D3  PAL_LINE(GPIOD, 3)
+    #define D4  PAL_LINE(GPIOD, 4)
+    #define D5  PAL_LINE(GPIOD, 5)
+    #define D6  PAL_LINE(GPIOD, 6)
+    #define D7  PAL_LINE(GPIOD, 7)
+    #define D8  PAL_LINE(GPIOD, 8)
+    #define D9  PAL_LINE(GPIOD, 9)
+    #define D10 PAL_LINE(GPIOD, 10)
+    #define D11 PAL_LINE(GPIOD, 11)
+    #define D12 PAL_LINE(GPIOD, 12)
+    #define D13 PAL_LINE(GPIOD, 13)
+    #define D14 PAL_LINE(GPIOD, 14)
+    #define D15 PAL_LINE(GPIOD, 15)
+    #define E0  PAL_LINE(GPIOE, 0)
+    #define E1  PAL_LINE(GPIOE, 1)
+    #define E2  PAL_LINE(GPIOE, 2)
+    #define E3  PAL_LINE(GPIOE, 3)
+    #define E4  PAL_LINE(GPIOE, 4)
+    #define E5  PAL_LINE(GPIOE, 5)
+    #define E6  PAL_LINE(GPIOE, 6)
+    #define E7  PAL_LINE(GPIOE, 7)
+    #define E8  PAL_LINE(GPIOE, 8)
+    #define E9  PAL_LINE(GPIOE, 9)
+    #define E10 PAL_LINE(GPIOE, 10)
+    #define E11 PAL_LINE(GPIOE, 11)
+    #define E12 PAL_LINE(GPIOE, 12)
+    #define E13 PAL_LINE(GPIOE, 13)
+    #define E14 PAL_LINE(GPIOE, 14)
+    #define E15 PAL_LINE(GPIOE, 15)
+    #define F0  PAL_LINE(GPIOF, 0)
+    #define F1  PAL_LINE(GPIOF, 1)
+    #define F2  PAL_LINE(GPIOF, 2)
+    #define F3  PAL_LINE(GPIOF, 3)
+    #define F4  PAL_LINE(GPIOF, 4)
+    #define F5  PAL_LINE(GPIOF, 5)
+    #define F6  PAL_LINE(GPIOF, 6)
+    #define F7  PAL_LINE(GPIOF, 7)
+    #define F8  PAL_LINE(GPIOF, 8)
+    #define F9  PAL_LINE(GPIOF, 9)
+    #define F10 PAL_LINE(GPIOF, 10)
+    #define F11 PAL_LINE(GPIOF, 11)
+    #define F12 PAL_LINE(GPIOF, 12)
+    #define F13 PAL_LINE(GPIOF, 13)
+    #define F14 PAL_LINE(GPIOF, 14)
+    #define F15 PAL_LINE(GPIOF, 15)
 #endif
 
 /* USART configuration */
index 3600d4e7b54ce42a8e8483dc9b5119e7a83f32e2..9b5ce33d239599779bd597b53c689b8fcc2cc768 100644 (file)
@@ -1,5 +1,5 @@
 /*
-Copyright 2012-2017 Jun Wako, Jack Humbert
+Copyright 2012-2018 Jun Wako, Jack Humbert, Yiancar
 
 This program is free software: you can redistribute it and/or modify
 it 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/>.
 */
 #include <stdint.h>
 #include <stdbool.h>
-#if defined(__AVR__)
-#include <avr/io.h>
-#endif
 #include "wait.h"
 #include "print.h"
 #include "debug.h"
 #include "util.h"
 #include "matrix.h"
 #include "timer.h"
+#include "quantum.h"
 
 
 /* Set 0 if debouncing isn't needed */
@@ -60,8 +58,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #endif
 
 #if (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW)
-static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
-static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
+static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
+static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
 #endif
 
 /* matrix state(1:on, 0:off) */
@@ -271,9 +269,7 @@ uint8_t matrix_key_count(void)
 static void init_cols(void)
 {
     for(uint8_t x = 0; x < MATRIX_COLS; x++) {
-        uint8_t pin = col_pins[x];
-        _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
-        _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI
+        setPinInputHigh(col_pins[x]);
     }
 }
 
@@ -293,8 +289,7 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
     for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
 
         // Select the col pin to read (active low)
-        uint8_t pin = col_pins[col_index];
-        uint8_t pin_state = (_SFR_IO8(pin >> 4) & _BV(pin & 0xF));
+        uint8_t pin_state = readPin(col_pins[col_index]);
 
         // Populate the matrix row with the state of the col pin
         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)
 
 static void select_row(uint8_t row)
 {
-    uint8_t pin = row_pins[row];
-    _SFR_IO8((pin >> 4) + 1) |=  _BV(pin & 0xF); // OUT
-    _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
+    setPinOutput(row_pins[row]);
+    writePinLow(row_pins[row]);
 }
 
 static void unselect_row(uint8_t row)
 {
-    uint8_t pin = row_pins[row];
-    _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
-    _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI
+    setPinInputHigh(row_pins[row]);
 }
 
 static void unselect_rows(void)
 {
     for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
-        uint8_t pin = row_pins[x];
-        _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
-        _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI
+        setPinInput(row_pins[x]);
     }
 }
 
@@ -334,9 +324,7 @@ static void unselect_rows(void)
 static void init_rows(void)
 {
     for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
-        uint8_t pin = row_pins[x];
-        _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
-        _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI
+        setPinInputHigh(row_pins[x]);
     }
 }
 
@@ -356,7 +344,7 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
         matrix_row_t last_row_value = current_matrix[row_index];
 
         // Check row pin state
-        if ((_SFR_IO8(row_pins[row_index] >> 4) & _BV(row_pins[row_index] & 0xF)) == 0)
+        if (readPin(row_pins[row_index]) == 0)
         {
             // Pin LO, set col bit
             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)
 
 static void select_col(uint8_t col)
 {
-    uint8_t pin = col_pins[col];
-    _SFR_IO8((pin >> 4) + 1) |=  _BV(pin & 0xF); // OUT
-    _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
+    setPinOutput(col_pins[col]);
+    writePinLow(col_pins[col]);
 }
 
 static void unselect_col(uint8_t col)
 {
-    uint8_t pin = col_pins[col];
-    _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
-    _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI
+    setPinInputHigh(col_pins[col]);
 }
 
 static void unselect_cols(void)
 {
     for(uint8_t x = 0; x < MATRIX_COLS; x++) {
-        uint8_t pin = col_pins[x];
-        _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
-        _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI
+        setPinInputHigh(col_pins[x]);
     }
 }
 
index 7cf16d81e68bcd1e5b96af34c542e79db81b65c3..6833332117b8563ea13fe35f50259245aeec5f18 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright 2016-2017 Erez Zukerman, Jack Humbert
+/* Copyright 2016-2018 Erez Zukerman, Jack Humbert, Yiancar
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #define QUANTUM_H
 
 #if defined(__AVR__)
-#include <avr/pgmspace.h>
-#include <avr/io.h>
-#include <avr/interrupt.h>
+    #include <avr/pgmspace.h>
+    #include <avr/io.h>
+    #include <avr/interrupt.h>
+#endif
+#if defined(PROTOCOL_CHIBIOS)
+    #include "hal.h"
 #endif
 #include "wait.h"
 #include "matrix.h"
 #ifdef RGBLIGHT_ENABLE
   #include "rgblight.h"
 #else
-  #ifdef RGB_MATRIX_ENABLE
-    /* dummy define RGBLIGHT_MODE_xxxx */
-    #define RGBLIGHT_H_DUMMY_DEFINE
-    #include "rgblight.h"
-  #endif
+    #ifdef RGB_MATRIX_ENABLE
+        /* dummy define RGBLIGHT_MODE_xxxx */
+        #define RGBLIGHT_H_DUMMY_DEFINE
+        #include "rgblight.h"
+    #endif
 #endif
 
 #ifdef SPLIT_KEYBOARD
@@ -76,9 +79,9 @@ extern uint32_t default_layer_state;
 #ifdef AUDIO_ENABLE
     #include "audio.h"
     #include "process_audio.h"
-  #ifdef AUDIO_CLICKY
-    #include "process_clicky.h"
-  #endif // AUDIO_CLICKY
+    #ifdef AUDIO_CLICKY
+        #include "process_clicky.h"
+    #endif // AUDIO_CLICKY
 #endif
 
 #ifdef STENO_ENABLE
@@ -133,6 +136,48 @@ extern uint32_t default_layer_state;
     #include "hd44780.h"
 #endif
 
+//Function substitutions to ease GPIO manipulation
+#ifdef __AVR__
+    #define pin_t uint8_t
+    #define setPinInput(pin) _SFR_IO8((pin >> 4) + 1) &= ~ _BV(pin & 0xF)
+    #define setPinInputHigh(pin) ({\
+            _SFR_IO8((pin >> 4) + 1) &= ~ _BV(pin & 0xF);\
+            _SFR_IO8((pin >> 4) + 2) |=   _BV(pin & 0xF);\
+            })
+    #define setPinInputLow(pin) _Static_assert(0, "AVR Processors cannot impliment an input as pull low")
+    #define setPinOutput(pin) _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF)
+
+    #define writePinHigh(pin) _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF)
+    #define writePinLow(pin) _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF)
+    static inline void writePin(pin_t pin, uint8_t level){
+        if (level){
+            _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF);
+        } else {
+            _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF);
+        }
+    }
+
+    #define readPin(pin) (_SFR_IO8(pin >> 4) & _BV(pin & 0xF))
+#elif defined(PROTOCOL_CHIBIOS)
+    #define pin_t ioline_t
+    #define setPinInput(pin) palSetLineMode(pin, PAL_MODE_INPUT)
+    #define setPinInputHigh(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)
+    #define setPinInputLow(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)
+    #define setPinOutput(pin) palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)
+
+    #define writePinHigh(pin) palSetLine(pin)
+    #define writePinLow(pin) palClearLine(pin)
+    static inline void writePin(pin_t pin, uint8_t level){
+        if (level){
+            palSetLine(pin);
+        } else {
+            palClearLine(pin);
+        }
+    }
+
+    #define readPin(pin) palReadLine(pin)
+#endif
+
 #define STRINGIZE(z) #z
 #define ADD_SLASH_X(y) STRINGIZE(\x ## y)
 #define SYMBOL_STR(x) ADD_SLASH_X(x)