matrix.c (4715B)
1 /* 2 Copyright 2017 Gabriel Young <gabeplaysdrums@live.com> 3 Copyright 2018 Alexander Fougner <fougner89 at gmail.com> 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #include <stdint.h> 20 #include <stdbool.h> 21 #include <avr/io.h> 22 #include <util/delay.h> 23 #include "print.h" 24 #include "debug.h" 25 #include "util.h" 26 #include "matrix.h" 27 28 __attribute__ ((weak)) 29 void matrix_init_kb(void) { 30 matrix_init_user(); 31 } 32 33 __attribute__ ((weak)) 34 void matrix_scan_kb(void) { 35 matrix_scan_user(); 36 } 37 38 __attribute__ ((weak)) 39 void matrix_init_user(void) { 40 } 41 42 __attribute__ ((weak)) 43 void matrix_scan_user(void) { 44 } 45 46 #ifndef DEBOUNCE 47 # define DEBOUNCE 5 48 #endif 49 static uint8_t debouncing = DEBOUNCE; 50 51 static matrix_row_t matrix[MATRIX_ROWS]; 52 static matrix_row_t matrix_debouncing[MATRIX_ROWS]; 53 54 static matrix_row_t scan_col(void) { 55 return ( 56 (PINC&(1<<7) ? 0 : ((matrix_row_t)1<<0)) | 57 (PINB&(1<<6) ? 0 : ((matrix_row_t)1<<1)) | 58 (PINB&(1<<1) ? 0 : ((matrix_row_t)1<<2)) | 59 (PINB&(1<<0) ? 0 : ((matrix_row_t)1<<3)) | 60 (PINB&(1<<5) ? 0 : ((matrix_row_t)1<<4)) | 61 (PINB&(1<<3) ? 0 : ((matrix_row_t)1<<5)) | 62 (PINB&(1<<4) ? 0 : ((matrix_row_t)1<<6)) | 63 (PINB&(1<<2) ? 0 : ((matrix_row_t)1<<7)) 64 ); 65 } 66 67 static void select_col(uint8_t col) { 68 switch (col) { 69 case 0: PORTD = (PORTD & ~0b00111111) | 0b00110011; break; 70 case 1: PORTD = (PORTD & ~0b00111111) | 0b00100011; break; 71 case 2: PORTD = (PORTD & ~0b00111111) | 0b00010111; break; 72 case 3: PORTD = (PORTD & ~0b00111111) | 0b00110011; break; 73 case 4: PORTD = (PORTD & ~0b00111111) | 0b00010011; break; 74 case 5: PORTD = (PORTD & ~0b00111111) | 0b00011011; break; 75 case 6: PORTD = (PORTD & ~0b00111111) | 0b00110100; break; 76 case 7: PORTD = (PORTD & ~0b00111111) | 0b00111010; break; 77 case 8: PORTD = (PORTD & ~0b00111111) | 0b00111000; break; 78 case 9: PORTD = (PORTD & ~0b00111111) | 0b00111100; break; 79 case 10: PORTD = (PORTD & ~0b00111111) | 0b00110010; break; 80 case 11: PORTD = (PORTD & ~0b00111111) | 0b00011111; break; 81 case 12: PORTD = (PORTD & ~0b00111111) | 0b00001111; break; 82 case 13: PORTD = (PORTD & ~0b00111111) | 0b00100111; break; 83 case 14: PORTD = (PORTD & ~0b00111111) | 0b00000111; break; 84 case 15: PORTD = (PORTD & ~0b00111111) | 0b00110110; break; 85 case 16: PORTD = (PORTD & ~0b00111111) | 0b00001011; break; 86 case 17: PORTD = (PORTD & ~0b00111111) | 0b00000011; break; 87 } 88 } 89 90 void matrix_init(void) { 91 /* Row output pins */ 92 DDRD |= 0b00111111; 93 /* Column input pins */ 94 DDRC &= ~0b10000000; 95 DDRB &= ~0b01111111; 96 PORTC |= 0b10000000; 97 PORTB |= 0b01111111; 98 99 for (uint8_t i=0; i < MATRIX_ROWS; i++) 100 matrix[i] = matrix_debouncing[i] = 0; 101 102 matrix_init_kb(); 103 } 104 105 uint8_t matrix_scan(void) { 106 for (uint8_t col = 0; col < MATRIX_COLS; col++) { 107 select_col(col); 108 _delay_us(3); 109 matrix_row_t col_scan = scan_col(); 110 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { 111 bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col); 112 bool curr_bit = col_scan & (1<<row); 113 if (prev_bit != curr_bit) { 114 matrix_debouncing[row] ^= ((matrix_row_t)1<<col); 115 debouncing = DEBOUNCE; 116 } 117 } 118 } 119 120 if (debouncing) { 121 if (--debouncing) 122 _delay_ms(1); 123 else 124 for (uint8_t i = 0; i < MATRIX_ROWS; i++) 125 matrix[i] = matrix_debouncing[i]; 126 } 127 128 matrix_scan_kb(); 129 return 1; 130 } 131 132 inline matrix_row_t matrix_get_row(uint8_t row) { 133 return matrix[row]; 134 } 135 136 void matrix_print(void) { 137 #ifndef NO_PRINT 138 print("\nr\\c ABCDEFGHIJKLMNOPQR\n"); 139 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { 140 matrix_row_t matrix_row = matrix_get_row(row); 141 xprintf("%02X: ", row); 142 for (uint8_t col = 0; col < MATRIX_COLS; col++) { 143 bool curr_bit = matrix_row & (1<<col); 144 xprintf("%c", curr_bit ? '*' : '.'); 145 } 146 print("\n"); 147 } 148 #endif 149 }