b6677f10 |
1 | /* |
2 | Copyright 2012 Jun Wako <wakojun@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 | |
30 | |
31 | #ifndef DEBOUNCE |
32 | # define DEBOUNCE 5 |
33 | #endif |
34 | static uint8_t debouncing = DEBOUNCE; |
35 | |
36 | /* matrix state(1:on, 0:off) */ |
37 | static matrix_row_t matrix[MATRIX_ROWS]; |
38 | static matrix_row_t matrix_debouncing[MATRIX_ROWS]; |
39 | |
40 | static matrix_row_t read_cols(void); |
41 | static void init_cols(void); |
42 | static void unselect_rows(void); |
43 | static void select_row(uint8_t row); |
44 | |
45 | |
b6677f10 |
46 | void matrix_init(void) |
47 | { |
48 | debug_enable = true; |
49 | debug_matrix = true; |
755e4d8b |
50 | debug_mouse = true; |
b6677f10 |
51 | // initialize row and col |
52 | unselect_rows(); |
53 | init_cols(); |
54 | |
55 | // initialize matrix state: all keys off |
56 | for (uint8_t i=0; i < MATRIX_ROWS; i++) { |
57 | matrix[i] = 0; |
58 | matrix_debouncing[i] = 0; |
59 | } |
60 | } |
61 | |
62 | uint8_t matrix_scan(void) |
63 | { |
64 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { |
65 | select_row(i); |
66 | _delay_us(30); // without this wait read unstable value. |
67 | matrix_row_t cols = read_cols(); |
68 | if (matrix_debouncing[i] != cols) { |
69 | matrix_debouncing[i] = cols; |
70 | if (debouncing) { |
71 | debug("bounce!: "); debug_hex(debouncing); debug("\n"); |
72 | } |
73 | debouncing = DEBOUNCE; |
74 | } |
75 | unselect_rows(); |
76 | } |
77 | |
78 | if (debouncing) { |
79 | if (--debouncing) { |
80 | _delay_ms(1); |
81 | } else { |
82 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { |
83 | matrix[i] = matrix_debouncing[i]; |
84 | } |
85 | } |
86 | } |
87 | |
88 | return 1; |
89 | } |
90 | |
b6677f10 |
91 | inline |
92 | matrix_row_t matrix_get_row(uint8_t row) |
93 | { |
94 | return matrix[row]; |
95 | } |
96 | |
b6677f10 |
97 | /* Column pin configuration |
98 | * col: 0 |
05be3d85 |
99 | * pin: B0 |
b6677f10 |
100 | */ |
101 | static void init_cols(void) |
102 | { |
103 | // Input with pull-up(DDR:0, PORT:1) |
05be3d85 |
104 | DDRB &= ~(1<<0); |
105 | PORTB |= (1<<0); |
b6677f10 |
106 | } |
107 | |
108 | static matrix_row_t read_cols(void) |
109 | { |
05be3d85 |
110 | return (PINB&(1<<0) ? 0 : (1<<0)); |
b6677f10 |
111 | } |
112 | |
113 | /* Row pin configuration |
114 | * row: 0 |
05be3d85 |
115 | * pin: B1 |
b6677f10 |
116 | */ |
117 | static void unselect_rows(void) |
118 | { |
119 | // Hi-Z(DDR:0, PORT:0) to unselect |
05be3d85 |
120 | DDRB &= ~0b00000010; |
121 | PORTB &= ~0b00000010; |
b6677f10 |
122 | } |
123 | |
124 | static void select_row(uint8_t row) |
125 | { |
126 | // Output low(DDR:1, PORT:0) to select |
127 | switch (row) { |
128 | case 0: |
05be3d85 |
129 | DDRB |= (1<<1); |
130 | PORTB &= ~(1<<1); |
b6677f10 |
131 | break; |
132 | } |
133 | } |