f68c5bf0 |
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 | |
28 | |
29 | /* |
30 | * Matrix Array usage: |
31 | * |
32 | * ROW: 16(4bits) |
33 | * COL: 8(3bits) |
34 | * |
35 | * 8bit wide |
36 | * +---------+ |
37 | * 0|00 ... 07| |
38 | * 1|08 ... 0F| |
39 | * :| ... | |
40 | * :| ... | |
41 | * E|70 ... 77| |
42 | * F|78 ... 7F| |
43 | * +---------+ |
44 | */ |
45 | static uint8_t matrix[MATRIX_ROWS]; |
46 | #define ROW(code) ((code>>3)&0xF) |
47 | #define COL(code) (code&0x07) |
48 | |
f68c5bf0 |
49 | |
504a9f42 |
50 | static void pc98_inhibit_repeat(void) |
51 | { |
52 | uint8_t code; |
53 | |
54 | while (serial_recv()) ; |
55 | RETRY: |
56 | PC98_RDY_PORT |= (1<<PC98_RDY_BIT); |
57 | _delay_ms(500); |
58 | serial_send(0x9C); |
59 | |
60 | PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT); |
61 | _delay_ms(100); |
62 | while (!(code = serial_recv())) ; |
63 | print("PC98: send 9C: "); print_hex8(code); print("\n"); |
64 | if (code != 0xFA) goto RETRY; |
65 | |
66 | |
67 | |
68 | PC98_RDY_PORT |= (1<<PC98_RDY_BIT); |
69 | _delay_ms(100); |
70 | serial_send(0x70); |
71 | |
72 | PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT); |
73 | _delay_ms(100); |
74 | //code = serial_recv(); |
75 | while (!(code = serial_recv())) ; |
76 | print("PC98: send 70: "); print_hex8(code); print("\n"); |
77 | if (code != 0xFA) goto RETRY; |
504a9f42 |
78 | } |
79 | |
f68c5bf0 |
80 | void matrix_init(void) |
81 | { |
f68c5bf0 |
82 | PC98_RST_DDR |= (1<<PC98_RST_BIT); |
83 | PC98_RDY_DDR |= (1<<PC98_RDY_BIT); |
84 | PC98_RTY_DDR |= (1<<PC98_RTY_BIT); |
85 | PC98_RST_PORT |= (1<<PC98_RST_BIT); |
86 | PC98_RDY_PORT |= (1<<PC98_RDY_BIT); |
87 | PC98_RTY_PORT |= (1<<PC98_RTY_BIT); |
88 | |
89 | |
90 | serial_init(); |
91 | |
92 | // PC98 reset |
504a9f42 |
93 | /* |
f68c5bf0 |
94 | PC98_RST_PORT &= ~(1<<PC98_RST_BIT); |
95 | _delay_us(15); |
96 | PC98_RST_PORT |= (1<<PC98_RST_BIT); |
97 | _delay_us(13); |
504a9f42 |
98 | PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT); |
99 | */ |
100 | |
101 | _delay_ms(500); |
102 | pc98_inhibit_repeat(); |
103 | |
f68c5bf0 |
104 | |
eb776c1b |
105 | // PC98 ready |
106 | PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT); |
107 | |
f68c5bf0 |
108 | // initialize matrix state: all keys off |
109 | for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00; |
110 | |
111 | debug("init\n"); |
112 | return; |
113 | } |
114 | |
115 | uint8_t matrix_scan(void) |
116 | { |
4a91d182 |
117 | uint16_t code; |
f68c5bf0 |
118 | PC98_RDY_PORT |= (1<<PC98_RDY_BIT); |
eb776c1b |
119 | _delay_us(30); |
4a91d182 |
120 | code = serial_recv2(); |
f68c5bf0 |
121 | PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT); |
4a91d182 |
122 | if (code == -1) return 0; |
f68c5bf0 |
123 | |
504a9f42 |
124 | if (code == 0x60) { |
125 | pc98_inhibit_repeat(); |
126 | |
127 | /* |
128 | PC98_RDY_PORT |= (1<<PC98_RDY_BIT); |
129 | _delay_ms(100); |
130 | serial_send(0x96); |
131 | PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT); |
132 | */ |
133 | |
134 | return 0; |
135 | } |
136 | |
137 | print_hex8(code); print(" "); |
f68c5bf0 |
138 | |
f68c5bf0 |
139 | if (code&0x80) { |
140 | // break code |
141 | if (matrix_is_on(ROW(code), COL(code))) { |
142 | matrix[ROW(code)] &= ~(1<<COL(code)); |
f68c5bf0 |
143 | } |
144 | } else { |
145 | // make code |
146 | if (!matrix_is_on(ROW(code), COL(code))) { |
147 | matrix[ROW(code)] |= (1<<COL(code)); |
f68c5bf0 |
148 | } |
149 | } |
f68c5bf0 |
150 | return code; |
151 | } |
152 | |
f68c5bf0 |
153 | inline |
154 | uint8_t matrix_get_row(uint8_t row) |
155 | { |
156 | return matrix[row]; |
157 | } |