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>
36 #ifndef DEBOUNCING_DELAY
37 # define DEBOUNCING_DELAY 5
40 #define print_matrix_header() print("\nr/c 01234567\n")
41 #define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
42 #define matrix_bitpop(i) bitpop(matrix[i])
43 #define ROW_SHIFTER ((uint8_t)1)
44 #define check_bit(var,pos) ((var) & (1<<(pos)))
46 #define NUM_ROW_PINS 5
47 #define NUM_COL_PINS 2
49 static const uint8_t row_pins [NUM_ROW_PINS] = MATRIX_ROW_PINS ;
50 static const uint8_t col_pins [NUM_ROW_PINS] = MATRIX_COL_PINS ;
52 #if ( DEBOUNCING_DELAY > 0 )
53 static uint16_t debouncing_time ;
54 static bool debouncing = false ;
57 static uint8_t matrix [MATRIX_ROWS] = {0};
59 #if ( DEBOUNCING_DELAY > 0 )
60 static uint8_t matrix_debounce [MATRIX_ROWS] = {0};
65 void toggle_led(void) {
66 uint8_t pin = LED_PIN ;
67 _SFR_IO8((pin >> 4) + 2) ^= _BV(pin & 0xF);
73 uint8_t pin = LED_PIN ;
74 _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT
75 _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
80 void init_data(void) {
81 uint8_t pin = MATRIX_DATA_PIN ;
82 _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
83 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // LO
88 void init_strobe(void) {
89 uint8_t pin = MATRIX_STROBE_PIN ;
90 _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT
91 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
96 void init_rows(void) {
97 for ( uint8_t i = 0 ; i < NUM_ROW_PINS; ++i ) {
98 uint8_t pin = row_pins[i];
99 _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT
100 _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
106 void init_cols(void) {
107 for ( uint8_t i = 0 ; i < NUM_COL_PINS; ++i ) {
108 uint8_t pin = col_pins[i];
109 _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT
110 _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
116 void select_row(uint8_t current_row) {
117 for ( uint8_t i = 0 ; i < NUM_ROW_PINS; ++i ) {
118 uint8_t pin = row_pins[i] ;
119 if ( check_bit( current_row, i ) ) {
120 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
122 _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
130 void select_col(uint8_t current_col) {
131 for ( uint8_t i = 0 ; i < NUM_COL_PINS; ++i ) {
132 uint8_t pin = col_pins[i] ;
133 if ( check_bit( current_col, i ) ) {
134 _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
136 _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
144 uint8_t matrix_strobe(uint8_t col_index) {
145 uint8_t strobe_pin = MATRIX_STROBE_PIN ;
146 uint8_t data_pin = MATRIX_DATA_PIN ;
148 // set strobe pin low
149 _SFR_IO8((strobe_pin >> 4) + 2) &= ~_BV(strobe_pin & 0xF);
154 uint8_t data = (_SFR_IO8(data_pin >> 4) & _BV(data_pin & 0xF)) ;
157 _SFR_IO8((strobe_pin >> 4) + 2) |= _BV(strobe_pin & 0xF);
159 uint8_t out = data ? (1 << col_index) : 0 ;
164 bool matrix_read(uint8_t current_matrix[], uint8_t current_row) {
165 // Store last value of row prior to reading
166 uint8_t last_row_value = current_matrix[current_row];
168 // Clear data in matrix row
169 current_matrix[current_row] = 0;
171 select_row(current_row);
174 for(uint8_t col_index = 0; col_index < MATRIX_COLS; ++col_index) {
176 select_col(col_index) ;
179 // Populate the matrix row with the state of the data pin
180 current_matrix[current_row] |= matrix_strobe(col_index) ;
183 bool test = last_row_value != current_matrix[current_row] ;
187 __attribute__ ((weak))
188 void matrix_init_quantum(void) {
192 __attribute__ ((weak))
193 void matrix_scan_quantum(void) {
197 __attribute__ ((weak))
198 void matrix_init_kb(void) {
202 __attribute__ ((weak))
203 void matrix_scan_kb(void) {
207 __attribute__ ((weak))
208 void matrix_init_user(void) {
211 __attribute__ ((weak))
212 void matrix_scan_user(void) {
216 uint8_t matrix_rows(void) {
221 uint8_t matrix_cols(void) {
226 uint8_t matrix_get_row(uint8_t row) {
230 void matrix_init(void) {
237 // initialize matrix state: all keys off
238 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
240 # if (DEBOUNCING_DELAY > 0)
241 matrix_debounce [i] = 0;
245 matrix_init_quantum() ;
248 uint8_t matrix_scan(void) {
249 for ( uint8_t current_row = 0; current_row < MATRIX_ROWS; ++current_row ) {
250 # if (DEBOUNCING_DELAY > 0)
251 bool matrix_changed = matrix_read(matrix_debounce, current_row);
253 if (matrix_changed) {
255 debouncing_time = timer_read();
259 matrix_read(matrix, current_row);
263 # if (DEBOUNCING_DELAY > 0)
264 if (debouncing && (timer_elapsed(debouncing_time) > DEBOUNCING_DELAY)) {
265 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
266 matrix[i] = matrix_debounce[i];
272 matrix_scan_quantum();
276 void matrix_print(void) {
277 print_matrix_header();
279 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
280 phex(row); print(": ");
281 print_matrix_row(row);