]>
Commit | Line | Data |
---|---|---|
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" | |
24 | #include "matrix.h" | |
25 | #include "debug.h" | |
26 | #include "protocol/serial.h" | |
27 | #include "led.h" | |
28 | #include "host.h" | |
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 | * +---------+ | |
46 | */ | |
47 | static uint8_t matrix[MATRIX_ROWS]; | |
48 | #define ROW(code) ((code>>3)&0xF) | |
49 | #define COL(code) (code&0x07) | |
50 | ||
51 | ||
52 | void matrix_init(void) | |
53 | { | |
54 | DDRD |= (1<<6); | |
55 | PORTD |= (1<<6); | |
56 | //debug_enable = true; | |
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 | ||
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"); | |
78 | ||
79 | PORTD &= ~(1<<6); | |
80 | return; | |
81 | } | |
82 | ||
83 | uint8_t matrix_scan(void) | |
84 | { | |
85 | uint8_t code; | |
86 | code = serial_recv(); | |
87 | if (!code) return 0; | |
88 | ||
89 | debug_hex(code); debug(" "); | |
90 | ||
91 | switch (code) { | |
92 | case 0xFF: // reset success: FF 04 | |
93 | print("reset: "); | |
94 | _delay_ms(500); | |
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; | |
112 | case 0x7F: | |
113 | // all keys up | |
114 | for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00; | |
115 | return 0; | |
116 | } | |
117 | ||
118 | if (code&0x80) { | |
119 | // break code | |
120 | if (matrix_is_on(ROW(code), COL(code))) { | |
121 | matrix[ROW(code)] &= ~(1<<COL(code)); | |
122 | } | |
123 | } else { | |
124 | // make code | |
125 | if (!matrix_is_on(ROW(code), COL(code))) { | |
126 | matrix[ROW(code)] |= (1<<COL(code)); | |
127 | } | |
128 | } | |
129 | return code; | |
130 | } | |
131 | ||
132 | inline | |
133 | uint8_t matrix_get_row(uint8_t row) | |
134 | { | |
135 | return matrix[row]; | |
136 | } |