2 Copyright 2018 listofoptions <listofoptions@gmail.com>
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include <util/delay.h>
32 #include "LUFA/Drivers/Peripheral/SPI.h"
37 #ifndef DEBOUNCING_DELAY
38 # define DEBOUNCING_DELAY 5
41 #if ( DEBOUNCING_DELAY > 0 )
42 static uint16_t debouncing_time ;
43 static bool debouncing = false ;
46 static uint8_t matrix [MATRIX_ROWS] = {0};
48 #if ( DEBOUNCING_DELAY > 0 )
49 static uint8_t matrix_debounce_old [MATRIX_ROWS] = {0};
50 static uint8_t matrix_debounce_new [MATRIX_ROWS] = {0};
53 __attribute__ ((weak))
54 void matrix_init_quantum(void) {
58 __attribute__ ((weak))
59 void matrix_scan_quantum(void) {
63 __attribute__ ((weak))
64 void matrix_init_kb(void) {
68 __attribute__ ((weak))
69 void matrix_scan_kb(void) {
73 __attribute__ ((weak))
74 void matrix_init_user(void) {
77 __attribute__ ((weak))
78 void matrix_scan_user(void) {
81 // the keyboard's internal wiring is such that the inputs to the logic are
82 // a clock signal, and a reset line.
83 // the output is a single output pin. im bitbanging here, but the SPI controller
84 // would work normally
86 // the device functions, by using the clock signal to count 128 bits, the lower
87 // 3 bits of this 7 bit counter are tied to a 1-of-8 multiplexer, this forms
89 // the upper 4 bits form the rows, and are decoded using bcd to decimal
90 // decoders, so that 14 out of 16 of the outputs are wired to the rows of the
91 // matrix. each switch has a diode, such that the row signal feeds into the
92 // switch, and then into the diode, then into one of the columns into the
93 // matrix. the reset pin can be used to reset the entire counter.
95 #define RESET _BV(PB0)
97 #define SDATA _BV(PB3)
102 void SCLK_increment(void) {
104 _delay_us( 4 ) ; // make sure the line is stable
113 void Matrix_Reset(void) {
115 _delay_us( 4 ) ; // make sure the line is stable
123 uint8_t Matrix_ReceiveByte (void) {
124 uint8_t received = 0 ;
126 for ( uint8_t bit = 0; bit < MATRIX_COLS; ++bit ) {
129 temp = (PINB & SDATA) << 4 ;
130 received |= temp >> bit ;
138 void Matrix_ThrowByte(void) {
139 // we use MATRIX_COLS - 1 here because that would put us at 7 clocks
140 for ( uint8_t bit = 0; bit < MATRIX_COLS - 1; ++bit ) {
148 void matrix_init () {
150 // PB0 (SS) and PB1 (SCLK) set to outputs
151 DDRB |= RESET | SCLK ;
152 // PB2, is unused, and PB3 is our serial input
155 // SS is reset for this board, and is active High
156 // SCLK is the serial clock and is active High
164 matrix_init_quantum();
166 //toggle reset, to put the keyboard logic into a known state
170 uint8_t matrix_scan(void) {
172 // the first byte of the keyboard's output data can be ignored
175 #if ( DEBOUNCING_DELAY > 0 )
177 for ( uint8_t row = 0 ; row < MATRIX_ROWS ; ++row ) {
178 //transfer old debouncing values
179 matrix_debounce_old[row] = matrix_debounce_new[row] ;
180 // read new key-states in
181 matrix_debounce_new[row] = Matrix_ReceiveByte() ;
183 if ( matrix_debounce_new[row] != matrix_debounce_old[row] ) {
185 debouncing_time = timer_read() ;
190 // without debouncing we simply just read in the raw matrix
191 for ( uint8_t row = 0 ; row < MATRIX_ROWS ; ++row ) {
192 matrix[row] = Matrix_ReceiveByte ;
197 #if ( DEBOUNCING_DELAY > 0 )
198 if ( debouncing && ( timer_elapsed( debouncing_time ) > DEBOUNCING_DELAY ) ) {
200 for ( uint8_t row = 0 ; row < MATRIX_ROWS ; ++row ) {
201 matrix[row] = matrix_debounce_new[row] ;
209 matrix_scan_quantum() ;
214 uint8_t matrix_get_row( uint8_t row ) {
218 void matrix_print(void)
220 print("\nr/c 01234567\n");
222 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
223 phex(row); print(": ");
224 print_bin_reverse8(matrix_get_row(row));
230 uint8_t matrix_rows(void) {
235 uint8_t matrix_cols(void) {
239 // as an aside, I used the M0110 converter:
240 // tmk_core/common/keyboard.c, quantum/matrix.c, and the project layout of the planck
241 // the online ducmentation starting from :
242 // https://docs.qmk.fm/#/config_options
243 // https://docs.qmk.fm/#/understanding_qmk
244 // and probably a few i forgot....