Port DIRECT_PINS from split_common/matrix.c to matrix.c (#5091)

* Port DIRECT_PINS from split_common/matrix.c to matrix.c

* Reorder matrix.c to remove foward declaration and match split_common/matrix.c

* Refactor nano to use DIRECT_PINS

* Reorder matrix.c to remove foward declaration and match split_common/matrix.c

* Add DIRECT_PINS documentation

* Reorder matrix.c to remove foward declaration and match split_common/matrix.c - fix logic from inherited from split_common

* Add DIRECT_PINS documentation - review comments
This commit is contained in:
zvecr 2019-04-11 19:51:55 +01:00 committed by MechMerlin
parent dc570b0b38
commit 0137b02319
8 changed files with 159 additions and 272 deletions

View file

@ -59,6 +59,8 @@ This is a C header file that is one of the first things included, and will persi
* define is matrix has ghost (unlikely) * define is matrix has ghost (unlikely)
* `#define DIODE_DIRECTION COL2ROW` * `#define DIODE_DIRECTION COL2ROW`
* 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. * 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.
* `#define DIRECT_PINS { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }`
* pins mapped to rows and columns, from left to right. Defines a matrix where each switch is connected to a separate pin and ground.
* `#define AUDIO_VOICES` * `#define AUDIO_VOICES`
* turns on the alternate audio voices (to cycle through) * turns on the alternate audio voices (to cycle through)
* `#define C4_AUDIO` * `#define C4_AUDIO`

View file

@ -93,6 +93,24 @@ Finally, you can specify the direction your diodes point. This can be `COL2ROW`
#define DIODE_DIRECTION COL2ROW #define DIODE_DIRECTION COL2ROW
``` ```
#### Direct Pin Matrix
To 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`.
```c
// #define MATRIX_ROW_PINS { D0, D5 }
// #define MATRIX_COL_PINS { F1, F0, B0 }
#define DIRECT_PINS { \
{ F1, E6, B0, B2, B3 }, \
{ F5, F0, B1, B7, D2 }, \
{ F6, F7, C7, D5, D3 }, \
{ B5, C6, B6, NO_PIN, NO_PIN } \
}
#define UNUSED_PINS
/* COL2ROW, ROW2COL */
//#define DIODE_DIRECTION
```
### Backlight Configuration ### Backlight Configuration
By 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). By 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).

View file

@ -22,6 +22,8 @@ The `MATRIX_ROW_PINS` and `MATRIX_COL_PINS` are the pins your MCU uses on each r
For 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. For 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.
To 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`.
`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. `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.
`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. `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.

View file

@ -31,12 +31,29 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define MATRIX_ROWS 2 #define MATRIX_ROWS 2
#define MATRIX_COLS 4 #define MATRIX_COLS 4
/*
* Keyboard Matrix Assignments
*
* Change this to how you wired your keyboard
* COLS: AVR pins used for columns, left to right
* ROWS: AVR pins used for rows, top to bottom
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
* NO_DIODE = switches are directly connected to AVR pins
*
*/
// #define MATRIX_ROW_PINS { D0, D5 }
// #define MATRIX_COL_PINS { F1, F0, B0 }
#define DIRECT_PINS { \
{ F4, F5, F6, F7 }, \
{ D1, D0, D4, C6 }, \
}
#define UNUSED_PINS
/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */
//#define DIODE_DIRECTION CUSTOM_MATRIX
/* ws2812 RGB LED */ /* ws2812 RGB LED */
#define RGB_DI_PIN D3 #define RGB_DI_PIN D3
#define RGBLIGHT_ANIMATIONS #define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 6 // Number of LEDs #define RGBLED_NUM 6 // Number of LEDs
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
#define TAPPING_TERM 200

View file

@ -1,159 +0,0 @@
/*
Note for ErgoDox EZ customizers: Here be dragons!
This is not a file you want to be messing with.
All of the interesting stuff for you is under keymaps/ :)
Love, Erez
Copyright 2013 Oleg Kostyuk <cub.uanic@gmail.com>
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
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* scan matrix
*/
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include <util/delay.h>
#include "action_layer.h"
#include "print.h"
#include "debug.h"
#include "util.h"
#include "matrix.h"
#include "nano.h"
#include <string.h>
/* matrix state(1:on, 0:off) */
static matrix_row_t matrix[MATRIX_ROWS];
static matrix_row_t matrix_stage[MATRIX_ROWS];
static matrix_row_t matrix_debouncing[MATRIX_ROWS];
static uint16_t debouncing_time;
static bool debouncing = false;
__attribute__ ((weak))
void matrix_init_kb(void) {
matrix_init_user();
}
__attribute__ ((weak))
void matrix_scan_kb(void) {
matrix_scan_user();
}
__attribute__ ((weak))
void matrix_init_user(void) {
}
__attribute__ ((weak))
void matrix_scan_user(void) {
}
inline
uint8_t matrix_rows(void)
{
return MATRIX_ROWS;
}
inline
uint8_t matrix_cols(void)
{
return MATRIX_COLS;
}
void matrix_init(void)
{
DDRF &= ~(1<<4 | 1<<5 | 1<<6 | 1<<7);
PORTF |= (1<<4 | 1<<5 | 1<<6 | 1<<7);
DDRC &= ~(1<<6);
PORTC |= (1<<6);
DDRD &= ~(1<<0 | 1<<1 | 1<<4);
PORTD |= (1<<0 | 1<<1 | 1<<4);
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
matrix[i] = 0;
matrix_debouncing[i] = 0;
matrix_stage[i] = 0;
}
matrix_init_quantum();
}
uint8_t matrix_scan(void)
{
matrix_stage[0] =
(PINF&(1<<4) ? 0 : (1<<0)) |
(PINF&(1<<5) ? 0 : (1<<1)) |
(PINF&(1<<6) ? 0 : (1<<2)) |
(PINF&(1<<7) ? 0 : (1<<3));
matrix_stage[1] =
(PIND&(1<<1) ? 0 : (1<<0)) |
(PIND&(1<<0) ? 0 : (1<<1)) |
(PIND&(1<<4) ? 0 : (1<<2)) |
(PINC&(1<<6) ? 0 : (1<<3));
if (memcmp(matrix_debouncing, matrix_stage, sizeof(matrix)) != 0) {
debouncing = true;
debouncing_time = timer_read();
}
matrix_debouncing[0] = matrix_stage[0];
matrix_debouncing[1] = matrix_stage[1];
if (debouncing && (timer_elapsed(debouncing_time) > 20)) {
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
matrix[i] = matrix_debouncing[i];
}
debouncing = false;
}
matrix_scan_quantum();
return 1;
}
bool matrix_is_modified(void)
{
return true;
}
inline
bool matrix_is_on(uint8_t row, uint8_t col)
{
return (matrix[row] & ((matrix_row_t)1<<col));
}
inline
matrix_row_t matrix_get_row(uint8_t row)
{
return matrix[row];
}
void matrix_print(void)
{
}
uint8_t matrix_key_count(void)
{
uint8_t count = 0;
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
count += bitpop16(matrix[i]);
}
return count;
}

View file

@ -2,10 +2,12 @@
#include "quantum.h" #include "quantum.h"
#define LAYOUT( \ #define LAYOUT_ortho_2x4( \
k01, k02, k03, k04, \ k01, k02, k03, k04, \
k05, k06, k07, k08 \ k05, k06, k07, k08 \
) { \ ) { \
{ k01, k02, k03, k04 }, \ { k01, k02, k03, k04 }, \
{ k05, k06, k07, k08 } \ { k05, k06, k07, k08 } \
} }
#define LAYOUT LAYOUT_ortho_2x4

View file

@ -76,7 +76,3 @@ RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight.
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
# custom matrix setup
SRC = matrix.c
CUSTOM_MATRIX = yes

View file

@ -45,7 +45,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
extern const matrix_row_t matrix_mask[]; extern const matrix_row_t matrix_mask[];
#endif #endif
#if (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW) #ifdef DIRECT_PINS
static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS;
#elif (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW)
static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
#endif #endif
@ -54,20 +56,6 @@ static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
static matrix_row_t raw_matrix[MATRIX_ROWS]; //raw values static matrix_row_t raw_matrix[MATRIX_ROWS]; //raw values
static matrix_row_t matrix[MATRIX_ROWS]; //debounced values static matrix_row_t matrix[MATRIX_ROWS]; //debounced values
#if (DIODE_DIRECTION == COL2ROW)
static void init_cols(void);
static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row);
static void unselect_rows(void);
static void select_row(uint8_t row);
static void unselect_row(uint8_t row);
#elif (DIODE_DIRECTION == ROW2COL)
static void init_rows(void);
static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col);
static void unselect_cols(void);
static void unselect_col(uint8_t col);
static void select_col(uint8_t col);
#endif
__attribute__ ((weak)) __attribute__ ((weak))
void matrix_init_quantum(void) { void matrix_init_quantum(void) {
matrix_init_kb(); matrix_init_kb();
@ -106,49 +94,6 @@ uint8_t matrix_cols(void) {
return MATRIX_COLS; return MATRIX_COLS;
} }
void matrix_init(void) {
// initialize row and col
#if (DIODE_DIRECTION == COL2ROW)
unselect_rows();
init_cols();
#elif (DIODE_DIRECTION == ROW2COL)
unselect_cols();
init_rows();
#endif
// initialize matrix state: all keys off
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
raw_matrix[i] = 0;
matrix[i] = 0;
}
debounce_init(MATRIX_ROWS);
matrix_init_quantum();
}
uint8_t matrix_scan(void)
{
bool changed = false;
#if (DIODE_DIRECTION == COL2ROW)
// Set row, read cols
for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
changed |= read_cols_on_row(raw_matrix, current_row);
}
#elif (DIODE_DIRECTION == ROW2COL)
// Set col, read rows
for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
changed |= read_rows_on_col(raw_matrix, current_col);
}
#endif
debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
matrix_scan_quantum();
return 1;
}
//Deprecated. //Deprecated.
bool matrix_is_modified(void) bool matrix_is_modified(void)
{ {
@ -195,11 +140,55 @@ uint8_t matrix_key_count(void)
} }
#ifdef DIRECT_PINS
#if (DIODE_DIRECTION == COL2ROW) static void init_pins(void) {
for (int row = 0; row < MATRIX_ROWS; row++) {
for (int col = 0; col < MATRIX_COLS; col++) {
pin_t pin = direct_pins[row][col];
if (pin != NO_PIN) {
setPinInputHigh(pin);
}
}
}
}
static void init_cols(void) static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
matrix_row_t last_row_value = current_matrix[current_row];
current_matrix[current_row] = 0;
for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
pin_t pin = direct_pins[current_row][col_index];
if (pin != NO_PIN) {
current_matrix[current_row] |= readPin(pin) ? 0 : (ROW_SHIFTER << col_index);
}
}
return (last_row_value != current_matrix[current_row]);
}
#elif (DIODE_DIRECTION == COL2ROW)
static void select_row(uint8_t row)
{ {
setPinOutput(row_pins[row]);
writePinLow(row_pins[row]);
}
static void unselect_row(uint8_t row)
{
setPinInputHigh(row_pins[row]);
}
static void unselect_rows(void)
{
for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
setPinInput(row_pins[x]);
}
}
static void init_pins(void) {
unselect_rows();
for (uint8_t x = 0; x < MATRIX_COLS; x++) { for (uint8_t x = 0; x < MATRIX_COLS; x++) {
setPinInputHigh(col_pins[x]); setPinInputHigh(col_pins[x]);
} }
@ -233,28 +222,28 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
return (last_row_value != current_matrix[current_row]); return (last_row_value != current_matrix[current_row]);
} }
static void select_row(uint8_t row)
{
setPinOutput(row_pins[row]);
writePinLow(row_pins[row]);
}
static void unselect_row(uint8_t row)
{
setPinInputHigh(row_pins[row]);
}
static void unselect_rows(void)
{
for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
setPinInput(row_pins[x]);
}
}
#elif (DIODE_DIRECTION == ROW2COL) #elif (DIODE_DIRECTION == ROW2COL)
static void init_rows(void) static void select_col(uint8_t col)
{ {
setPinOutput(col_pins[col]);
writePinLow(col_pins[col]);
}
static void unselect_col(uint8_t col)
{
setPinInputHigh(col_pins[col]);
}
static void unselect_cols(void)
{
for(uint8_t x = 0; x < MATRIX_COLS; x++) {
setPinInputHigh(col_pins[x]);
}
}
static void init_pins(void) {
unselect_cols();
for (uint8_t x = 0; x < MATRIX_ROWS; x++) { for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
setPinInputHigh(row_pins[x]); setPinInputHigh(row_pins[x]);
} }
@ -300,22 +289,42 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
return matrix_changed; return matrix_changed;
} }
static void select_col(uint8_t col)
{
setPinOutput(col_pins[col]);
writePinLow(col_pins[col]);
}
static void unselect_col(uint8_t col)
{
setPinInputHigh(col_pins[col]);
}
static void unselect_cols(void)
{
for(uint8_t x = 0; x < MATRIX_COLS; x++) {
setPinInputHigh(col_pins[x]);
}
}
#endif #endif
void matrix_init(void) {
// initialize key pins
init_pins();
// initialize matrix state: all keys off
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
raw_matrix[i] = 0;
matrix[i] = 0;
}
debounce_init(MATRIX_ROWS);
matrix_init_quantum();
}
uint8_t matrix_scan(void)
{
bool changed = false;
#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW)
// Set row, read cols
for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
changed |= read_cols_on_row(raw_matrix, current_row);
}
#elif (DIODE_DIRECTION == ROW2COL)
// Set col, read rows
for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
changed |= read_rows_on_col(raw_matrix, current_col);
}
#endif
debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
matrix_scan_quantum();
return 1;
}