diff options
author | Takeshi ISHII <2170248+mtei@users.noreply.github.com> | 2021-07-13 18:14:27 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-13 18:14:27 +0900 |
commit | b89abc402bdc70362dbb6d938eafaa8716b5d4ac (patch) | |
tree | f0370521b4492de9ba6fa1b6082f995639597d30 /keyboards/handwired/symmetric70_proto/matrix_fast/matrix.c | |
parent | 6b6ee5fa286c067fbea7da2b5274d47aac84d253 (diff) | |
download | qmk_firmware-b89abc402bdc70362dbb6d938eafaa8716b5d4ac.tar.gz qmk_firmware-b89abc402bdc70362dbb6d938eafaa8716b5d4ac.zip |
[Keyboard] Update Symmetric70 keyboard prototype (#12707)
* update handwired/symmetric70_proto/matrix.c
* make keyboards/handwired/symmetric70_proto/promicro/
* add symmetric70_proto/debug_config.h, update symmetric70_proto/local_features.mk etc.
set MATRIX_IO_DELAY macro
make MTEST=mdelay0 symmetric70_proto/promicro:default:flash
make MTEST=mdelay1 symmetric70_proto/promicro:default:flash
make MTEST=mdelay10 symmetric70_proto/promicro:default:flash
make MTEST=mdelay30 symmetric70_proto/promicro:default:flash
set DEBUG_MATRIX_SCAN_RATE_ENABLE yes
make MTEST=scan symmetric70_proto/promicro:default:flash
set MATRIX_DEBUG_DELAY and MATRIX_IO_DELAY macro
make MTEST=matrix_debug_delay,mdelay0 symmetric70_proto/promicro:default:flash
set MATRIX_DEBUG_SCAN
make MTEST=matrix_debug_scan symmetric70_proto/promicro:default:flash
* add symmetric70_proto/matrix_debug/readme.md
* update symmetric70_proto/matrix_debug/readme.md
* update handwired/symmetric70_proto/readme.md
* update handwired/symmetric70_proto/readme.md
* update handwired/symmetric70_proto/*/readme.md
* add handwired/symmetric70_proto/matrix_fast/
* update handwired/symmetric70_proto/matrix_fast/readme.md
* fix typo in handwired/symmetric70_proto/matrix_fast/readme.md
* update config.h under handwired/symmetric70_proto/promicro
* add Proton C support to handwired/symmetric70_proto
* add handwired/symmetric70_proto/proton_c/readme.md
* add promicro/*/readme.md proton_c/*/readme.md
* update handwired/symmetric70_proto/proton_c/proton_c.c
support MATRIX_IO_DELAY_DEFAULT for testing.
* Added another implementation of 'adaptive_delay'.
* update symmetric70_proto/local_features.mk
* update symmetric70_proto/matrix_fast/gpio_extr.h
* add matrix_output_unselect_delay_ports()
* add MTEST=adaptive_delay_fast option
* update symmetric70_proto/matrix_debug/readme.md
* update symmetric70_proto/matrix_fast/readme.md
* update symmetric70_proto/matrix_debug/readme.md
* Erase garbage
* fix symmetric70_proto/proton_c/proton_c.c
* improve adaptive_delay_fast in symmetric70_proto/matrix_debug/matrix.c
* update symmetric70_proto/matrix_debug/readme.md
* fix symmetric70_proto/matrix_debug/readme.md
* Update keyboards/handwired/symmetric70_proto/proton_c/rules.mk
Co-authored-by: Ryan <fauxpark@gmail.com>
* Update keyboards/handwired/symmetric70_proto/proton_c/rules.mk
Co-authored-by: Ryan <fauxpark@gmail.com>
* Update keyboards/handwired/symmetric70_proto/local_features.mk
Co-authored-by: Nick Brassel <nick@tzarc.org>
* Update keyboards/handwired/symmetric70_proto/local_features.mk
Co-authored-by: Nick Brassel <nick@tzarc.org>
* Update keyboards/handwired/symmetric70_proto/matrix_debug/matrix.c
Co-authored-by: Nick Brassel <nick@tzarc.org>
* Update keyboards/handwired/symmetric70_proto/matrix_debug/matrix.c
Co-authored-by: Nick Brassel <nick@tzarc.org>
* Update keyboards/handwired/symmetric70_proto/local_features.mk
Co-authored-by: Nick Brassel <nick@tzarc.org>
* Update keyboards/handwired/symmetric70_proto/matrix_debug/matrix.c
Co-authored-by: Nick Brassel <nick@tzarc.org>
* Update keyboards/handwired/symmetric70_proto/matrix_debug/readme.md
Co-authored-by: Nick Brassel <nick@tzarc.org>
* Update keyboards/handwired/symmetric70_proto/matrix_debug/readme.md
Co-authored-by: Nick Brassel <nick@tzarc.org>
* Update keyboards/handwired/symmetric70_proto/matrix_debug/readme.md
Co-authored-by: Nick Brassel <nick@tzarc.org>
* Update keyboards/handwired/symmetric70_proto/matrix_fast/matrix_config_expand.c
Co-authored-by: Nick Brassel <nick@tzarc.org>
Co-authored-by: Ryan <fauxpark@gmail.com>
Co-authored-by: Nick Brassel <nick@tzarc.org>
Diffstat (limited to 'keyboards/handwired/symmetric70_proto/matrix_fast/matrix.c')
-rw-r--r-- | keyboards/handwired/symmetric70_proto/matrix_fast/matrix.c | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/keyboards/handwired/symmetric70_proto/matrix_fast/matrix.c b/keyboards/handwired/symmetric70_proto/matrix_fast/matrix.c new file mode 100644 index 0000000000..cb21bfcf8d --- /dev/null +++ b/keyboards/handwired/symmetric70_proto/matrix_fast/matrix.c @@ -0,0 +1,234 @@ +/* +Copyright 2021 mtei + +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/>. +*/ +// clang-format off +#include <stdint.h> +#include <stdbool.h> +#include <gpio.h> +#ifndef readPort +# include "gpio_extr.h" +#endif +#include "util.h" +#include "matrix.h" +#include "matrix_extr.h" +#include "debounce.h" +#include "quantum.h" + +#define ALWAYS_INLINE inline __attribute__((always_inline)) +#define NO_INLINE __attribute__((noinline)) +#define LOCAL_FUNC static +#define LOCAL_DATA static + +#ifndef _BV +# define _BV(bit) (1 << (bit)) +#endif + +#ifndef MATRIX_DEBUG_PIN +# define MATRIX_DEBUG_PIN_INIT() +# define MATRIX_DEBUG_SCAN_START() +# define MATRIX_DEBUG_SCAN_END() +# define MATRIX_DEBUG_DELAY_START() +# define MATRIX_DEBUG_DELAY_END() +# define MATRIX_DEBUG_GAP() +#else +# define MATRIX_DEBUG_GAP() asm volatile("nop \n nop":::"memory") +#endif + +typedef uint16_t port_width_t; +#if MATRIX_TYPE == DIRECT_SWITCH || MATRIX_TYPE == DIODE_COL2ROW +# define MATRIX_LINES MATRIX_ROWS +typedef matrix_row_t matrix_line_t; +#endif +#if MATRIX_TYPE == DIODE_ROW2COL +# define MATRIX_LINES MATRIX_COLS +typedef matrix_col_t matrix_line_t; +#endif +typedef struct _port_descriptor { + int device; + pin_t port; +} port_descriptor; + +/* matrix state(1:on, 0:off) */ +extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values +extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values + +#define setPortBitOutput_writeLow(port, bit) \ + do { setPortBitOutput(port, bit); writePortBitLow(port, bit); } while(0) +#define setPortBitOutput_writeLow_atomic(port, bit) \ + do { ATOMIC_BLOCK_FORCEON { setPortBitOutput_writeLow(port, bit); } } while(0) +#define setPortBitInputHigh_atomic(port, bit) \ + do { ATOMIC_BLOCK_FORCEON { setPortBitInputHigh(port, bit); } } while(0) + +#if defined(MATRIX_IN_PORTS) && defined(MATRIX_IN_PINS) +# include "matrix_config_expand.c" +#else +# error matrix.c need defined MATRIX_IN_PORTS and MATRIX_IN_PINS +#endif + +LOCAL_FUNC +void unselect_output(uint8_t out_index) { + unselect_output_inline(out_index); +} + +LOCAL_FUNC +void init_output_ports(void) { + for (int i = 0; i < END_outpin_index; i++) { + unselect_output(i); + } +} + +LOCAL_FUNC +void init_all_ports(void) { + init_input_ports(); + init_output_ports(); + init_inport_mask(); + init_extension(); +} + +LOCAL_FUNC ALWAYS_INLINE void select_line_and_read_input_ports(uint8_t current_line, port_width_t port_buffer[NUM_OF_INPUT_PORTS]); +LOCAL_FUNC void select_line_and_read_input_ports(uint8_t current_line, port_width_t port_buffer[NUM_OF_INPUT_PORTS]) { + // Select row (or col) + select_output(current_line); + matrix_output_select_delay(); + + // Read ports + read_all_input_ports(port_buffer, false); + + // Unselect row (or col) + unselect_output_inline(current_line); +} + +LOCAL_FUNC ALWAYS_INLINE void read_matrix_line(matrix_line_t phy_matrix[], uint8_t current_line); + +#if MATRIX_TYPE == DIODE_ROW2COL || MATRIX_TYPE == DIODE_COL2ROW +LOCAL_FUNC void read_matrix_line(matrix_line_t phy_matrix[], uint8_t current_line) { + // Start with a clear matrix row + matrix_line_t current_line_value = 0; + port_width_t port_buffer[NUM_OF_INPUT_PORTS]; + +#ifdef MATRIX_GPIO_NEED_SEPARATE_ATOMIC + select_line_and_read_input_ports(current_line, port_buffer); +#else + ATOMIC_BLOCK_FORCEON { + select_line_and_read_input_ports(current_line, port_buffer); + } +#endif + + // Build row (or col) + current_line_value = build_matrix_line(port_buffer); + + // Wait signal raise up + if (current_line_value) { + MATRIX_DEBUG_DELAY_START(); + wait_unselect_done(); + MATRIX_DEBUG_DELAY_END(); + } + phy_matrix[current_line] = current_line_value; +} +#endif // MATRIX_TYPE == DIODE_ROW2COL || MATRIX_TYPE == DIODE_COL2ROW + +#if MATRIX_TYPE == DIRECT_SWITCH +LOCAL_FUNC void read_matrix_line(matrix_line_t phy_matrix[], uint8_t current_line) { + port_width_t port_buffer[NUM_OF_INPUT_PORTS]; + + if (current_line != 0) { + return; + } + + for (uint8_t i = 0; i < MATRIX_LINES; i++) { + phy_matrix[i] = 0; + } + + read_all_input_ports(port_buffer, false); + + // Build matrix + build_matrix_direct(port_buffer, phy_matrix); +} +#endif // MATRIX_TYPE == DIRECT_SWITCH + +void matrix_init(void) { + // initialize key pins + init_all_ports(); + + // 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) { + matrix_line_t phy_matrix[MATRIX_LINES]; + + MATRIX_DEBUG_PIN_INIT(); + + MATRIX_DEBUG_SCAN_START(); + + // read I/O port to phy_matrix[] (physical matrix) + //select line, read inputs + for (uint8_t current_line = 0; current_line < MATRIX_LINES; current_line++) { + read_matrix_line(phy_matrix, current_line); + } + MATRIX_DEBUG_SCAN_END(); MATRIX_DEBUG_GAP(); MATRIX_DEBUG_SCAN_START(); + + bool changed = false; +#if MATRIX_TYPE == DIRECT_SWITCH || MATRIX_TYPE == DIODE_COL2ROW + // copy phy_matrix[] to raw_matrix[] + for (uint8_t current_line = 0; current_line < MATRIX_ROWS; current_line++) { + if (raw_matrix[current_line] != phy_matrix[current_line]) { + changed = true; + raw_matrix[current_line] = phy_matrix[current_line]; + } + } +#endif +#if MATRIX_TYPE == DIODE_ROW2COL + // transpose phy_matrix[] to raw_matrix[] + matrix_row_t trans_matrix[MATRIX_ROWS]; + for (uint8_t i = 0; i < MATRIX_ROWS; i++ ) { + trans_matrix[i] = 0; + } + for (uint8_t src_line = 0; src_line < MATRIX_LINES; src_line++) { + matrix_line_t src_line_data = phy_matrix[src_line]; + matrix_row_t dist_bit = MATRIX_ROW_SHIFTER << src_line; + for (uint8_t dist_rows = 0; dist_rows < MATRIX_ROWS; dist_rows++) { + if ((src_line_data & 1) == 1) { + trans_matrix[dist_rows] |= dist_bit; + } + src_line_data >>= 1; + } + } + for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) { + if (raw_matrix[current_row] != trans_matrix[current_row]) { + changed = true; + raw_matrix[current_row] = trans_matrix[current_row]; + } + } +#endif + MATRIX_DEBUG_SCAN_END(); MATRIX_DEBUG_GAP(); MATRIX_DEBUG_SCAN_START(); + + // debounce raw_matrix[] to matrix[] + debounce(raw_matrix, matrix, MATRIX_ROWS, changed); + MATRIX_DEBUG_SCAN_END(); MATRIX_DEBUG_GAP(); + + MATRIX_DEBUG_SCAN_START(); + matrix_scan_quantum(); + MATRIX_DEBUG_SCAN_END(); + return (uint8_t)changed; +} |