97ee1be5 |
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 | #include <stdint.h> |
19 | #include <stdbool.h> |
20 | #include <avr/io.h> |
21 | #include <util/delay.h> |
22 | #include "print.h" |
23 | #include "util.h" |
97ee1be5 |
24 | #include "matrix.h" |
25 | #include "debug.h" |
b56717b8 |
26 | #include "protocol/serial.h" |
1ad31539 |
27 | #include "led.h" |
28 | #include "host.h" |
97ee1be5 |
29 | |
30 | |
31 | /* |
32 | * Matrix Array usage: |
33 | * |
34 | * ROW: 16(4bits) |
35 | * COL: 8(3bits) |
36 | * |
37 | * 8bit wide |
38 | * +---------+ |
39 | * 0|00 ... 07| |
40 | * 1|08 ... 0F| |
41 | * :| ... | |
42 | * :| ... | |
43 | * E|70 ... 77| |
44 | * F|78 ... 7F| |
45 | * +---------+ |
97ee1be5 |
46 | */ |
47 | static uint8_t matrix[MATRIX_ROWS]; |
48 | #define ROW(code) ((code>>3)&0xF) |
49 | #define COL(code) (code&0x07) |
50 | |
97ee1be5 |
51 | |
52 | void matrix_init(void) |
53 | { |
62117e7e |
54 | DDRD |= (1<<6); |
55 | PORTD |= (1<<6); |
523cc6aa |
56 | //debug_enable = true; |
97ee1be5 |
57 | |
58 | serial_init(); |
59 | |
60 | // initialize matrix state: all keys off |
61 | for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00; |
62 | |
49b0c7e5 |
63 | // wait for keyboard coming up |
64 | // otherwise LED status update fails |
65 | print("Reseting "); |
66 | while (1) { |
67 | print("."); |
68 | while (serial_recv()); |
69 | serial_send(0x01); |
70 | _delay_ms(500); |
71 | if (serial_recv() == 0xFF) { |
72 | _delay_ms(500); |
73 | if (serial_recv() == 0x04) |
74 | break; |
75 | } |
76 | } |
77 | print(" Done\n"); |
62e92645 |
78 | |
79 | PORTD &= ~(1<<6); |
97ee1be5 |
80 | return; |
81 | } |
82 | |
83 | uint8_t matrix_scan(void) |
84 | { |
97ee1be5 |
85 | uint8_t code; |
86 | code = serial_recv(); |
b56717b8 |
87 | if (!code) return 0; |
88 | |
89 | debug_hex(code); debug(" "); |
90 | |
91 | switch (code) { |
a5516088 |
92 | case 0xFF: // reset success: FF 04 |
93 | print("reset: "); |
b56717b8 |
94 | _delay_ms(500); |
a5516088 |
95 | code = serial_recv(); |
96 | xprintf("%02X\n", code); |
97 | if (code == 0x04) { |
98 | // LED status |
99 | led_set(host_keyboard_leds()); |
100 | } |
101 | return 0; |
102 | case 0xFE: // layout: FE <layout> |
103 | print("layout: "); |
104 | _delay_ms(500); |
105 | xprintf("%02X\n", serial_recv()); |
106 | return 0; |
107 | case 0x7E: // reset fail: 7E 01 |
108 | print("reset fail: "); |
109 | _delay_ms(500); |
110 | xprintf("%02X\n", serial_recv()); |
111 | return 0; |
b56717b8 |
112 | case 0x7F: |
113 | // all keys up |
114 | for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00; |
115 | return 0; |
97ee1be5 |
116 | } |
117 | |
97ee1be5 |
118 | if (code&0x80) { |
119 | // break code |
120 | if (matrix_is_on(ROW(code), COL(code))) { |
121 | matrix[ROW(code)] &= ~(1<<COL(code)); |
97ee1be5 |
122 | } |
123 | } else { |
124 | // make code |
125 | if (!matrix_is_on(ROW(code), COL(code))) { |
126 | matrix[ROW(code)] |= (1<<COL(code)); |
97ee1be5 |
127 | } |
128 | } |
129 | return code; |
130 | } |
131 | |
97ee1be5 |
132 | inline |
133 | uint8_t matrix_get_row(uint8_t row) |
134 | { |
135 | return matrix[row]; |
136 | } |