matrix.c (4871B)
1 /* 2 Copyright 2014 Kai Ryu <kai1103@gmail.com> 3 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. 8 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. 13 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/>. 16 */ 17 18 /* 19 * scan matrix 20 */ 21 #include <stdint.h> 22 #include <stdbool.h> 23 #include <avr/io.h> 24 #include <util/delay.h> 25 #include "print.h" 26 #include "debug.h" 27 #include "util.h" 28 #include "matrix.h" 29 #ifdef UART_RGB_ENABLE 30 #include "uart_rgb.h" 31 #endif 32 33 #ifndef DEBOUNCE 34 # define DEBOUNCE 5 35 #endif 36 static uint8_t debouncing = DEBOUNCE; 37 38 /* matrix state(1:on, 0:off) */ 39 static matrix_row_t matrix[MATRIX_ROWS]; 40 static matrix_row_t matrix_debouncing[MATRIX_ROWS]; 41 42 static matrix_row_t read_cols(void); 43 static void init_cols(void); 44 static void init_rows(void); 45 static void unselect_rows(void); 46 static void select_row(uint8_t row); 47 48 inline 49 uint8_t matrix_rows(void) 50 { 51 return MATRIX_ROWS; 52 } 53 54 inline 55 uint8_t matrix_cols(void) 56 { 57 return MATRIX_COLS; 58 } 59 60 void matrix_init(void) 61 { 62 63 #ifdef UART_RGB_ENABLE 64 uart_rgb_init(); 65 #endif 66 67 // 85 REST 68 gpio_set_pin_output(D7); 69 gpio_write_pin_high(D7); 70 71 // initialize row and col 72 init_rows(); 73 init_cols(); 74 75 // initialize matrix state: all keys off 76 for (uint8_t i=0; i < MATRIX_ROWS; i++) { 77 matrix[i] = 0; 78 matrix_debouncing[i] = 0; 79 } 80 } 81 82 uint8_t matrix_scan(void) 83 { 84 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 85 select_row(i); 86 _delay_us(30); // without this wait read unstable value. 87 matrix_row_t cols = read_cols(); 88 if (matrix_debouncing[i] != cols) { 89 matrix_debouncing[i] = cols; 90 if (debouncing) { 91 dprintf("bounce!: %02X\n", debouncing); 92 } 93 debouncing = DEBOUNCE; 94 } 95 unselect_rows(); 96 } 97 98 if (debouncing) { 99 if (--debouncing) { 100 _delay_ms(1); 101 } else { 102 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 103 matrix[i] = matrix_debouncing[i]; 104 } 105 } 106 } 107 108 return 1; 109 } 110 111 inline 112 bool matrix_is_on(uint8_t row, uint8_t col) 113 { 114 return (matrix[row] & ((matrix_row_t)1<<col)); 115 } 116 117 inline 118 matrix_row_t matrix_get_row(uint8_t row) 119 { 120 return matrix[row]; 121 } 122 123 void matrix_print(void) 124 { 125 print("\nr/c 0123456789ABCDEF\n"); 126 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { 127 print_hex8(row); print(": "); 128 print_bin_reverse16(matrix_get_row(row)); 129 print("\n"); 130 } 131 } 132 133 /* Column pin configuration 134 * col: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 135 * pin: F7 F6 F5 F4 F1 F0 E6 D7 D6 D5 D1 D0 B7 B6 B0 C7 136 * */ 137 static void init_cols(void) 138 { 139 // Input with pull-up(DDR:0, PORT:1) 140 DDRF &= 0b00001100; 141 PORTF |= 0b11110011; 142 143 DDRD &= 0b00011100; 144 PORTD |= 0b11100011; 145 146 gpio_set_pin_input_high(B0); 147 gpio_set_pin_input_high(B6); 148 gpio_set_pin_input_high(B7); 149 150 gpio_set_pin_input_high(E6); 151 152 gpio_set_pin_input_high(C7); 153 154 } 155 156 static matrix_row_t read_cols(void) 157 { 158 159 return (gpio_read_pin(F7) ? 0 : (1<<0)) | 160 (gpio_read_pin(F6) ? 0 : (1<<1)) | 161 (gpio_read_pin(F5) ? 0 : (1<<2)) | 162 (gpio_read_pin(F4) ? 0 : (1<<3)) | 163 (gpio_read_pin(F1) ? 0 : (1<<4)) | 164 (gpio_read_pin(F0) ? 0 : (1<<5)) | 165 (gpio_read_pin(E6) ? 0 : (1<<6)) | 166 (gpio_read_pin(D7) ? 0 : (1<<7)) | 167 (gpio_read_pin(D6) ? 0 : (1<<8)) | 168 (gpio_read_pin(D5) ? 0 : (1<<9)) | 169 (gpio_read_pin(D1) ? 0 : (1<<10)) | 170 (gpio_read_pin(D0) ? 0 : (1<<11)) | 171 (gpio_read_pin(B7) ? 0 : (1<<12)) | 172 (gpio_read_pin(B6) ? 0 : (1<<13)) | 173 (gpio_read_pin(B0) ? 0 : (1<<14)) | 174 (gpio_read_pin(C7) ? 0 : (1<<15)); 175 } 176 177 /* Row pin configuration 178 * row: 0 1 2 3 4 5 x 179 * pin: B3 0 1 0 1 0 1 1 180 * B2 0 0 1 1 0 0 1 181 * B1 0 0 0 0 1 1 1 182 */ 183 184 static void init_rows(void) 185 { 186 gpio_set_pin_input(B1); 187 gpio_set_pin_input(B2); 188 gpio_set_pin_input(B3); 189 } 190 191 static void unselect_rows(void) 192 { 193 // Hi-Z(DDR:0, PORT:0) to unselect 194 gpio_write_pin_high(B1); 195 gpio_write_pin_high(B2); 196 gpio_write_pin_high(B3); 197 } 198 199 static void select_row(uint8_t row) 200 { 201 // Output low(DDR:1, PORT:0) to select 202 gpio_write_pin(B3, row & (1<<0)); 203 gpio_write_pin(B2, row & (1<<1)); 204 gpio_write_pin(B1, row & (1<<2)); 205 }