]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - converter/terminal_usb/matrix.c
ibmpc_usb: Update prebuilt firmware hex files
[max/tmk_keyboard.git] / converter / terminal_usb / matrix.c
1 /*
2 Copyright 2011 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 "debug.h"
25 #include "ps2.h"
26 #include "matrix.h"
27
28
29 static void matrix_make(uint8_t code);
30 static void matrix_break(uint8_t code);
31
32
33 /*
34  * Matrix Array usage:
35  * 'Scan Code Set 3' is assigned into 17x8 cell matrix.
36  *
37  *    8bit wide
38  *   +---------+
39  *  0|         |
40  *  :|         | 0x00-0x87
41  *  ;|         |
42  * 17|         |
43  *   +---------+
44  */
45 static uint8_t matrix[MATRIX_ROWS];
46 #define ROW(code)      (code>>3)
47 #define COL(code)      (code&0x07)
48
49
50 void matrix_init(void)
51 {
52     debug_enable = true;
53     //debug_matrix = true;
54     //debug_keyboard = true;
55     //debug_mouse = false;
56
57     ps2_host_init();
58
59     // initialize matrix state: all keys off
60     for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
61
62     return;
63 }
64
65 uint8_t matrix_scan(void)
66 {
67
68     // scan code reading states
69     static enum {
70         RESET,
71         RESET_RESPONSE,
72         KBD_ID0,
73         KBD_ID1,
74         CONFIG,
75         READY,
76         F0,
77     } state = RESET;
78
79     uint8_t code;
80     if ((code = ps2_host_recv())) {
81         debug("r"); debug_hex(code); debug(" ");
82     }
83
84     switch (state) {
85         case RESET:
86             debug("wFF ");
87             if (ps2_host_send(0xFF) == 0xFA) {
88                 debug("[ack]\nRESET_RESPONSE: ");
89                 state = RESET_RESPONSE;
90             }
91             break;
92         case RESET_RESPONSE:
93             if (code == 0xAA) {
94                 debug("[ok]\nKBD_ID: ");
95                 state = KBD_ID0;
96             } else if (code) {
97                 debug("err\nRESET: ");
98                 state = RESET;
99             }
100             break;
101         // after reset receive keyboad ID(2 bytes)
102         case KBD_ID0:
103             if (code) {
104                 state = KBD_ID1;
105             }
106             break;
107         case KBD_ID1:
108             if (code) {
109                 debug("\nCONFIG: ");
110                 state = CONFIG;
111             }
112             break;
113         case CONFIG:
114             debug("wF8 ");
115             if (ps2_host_send(0xF8) == 0xFA) {
116                 debug("[ack]\nREADY\n");
117                 state = READY;
118             }
119             break;
120         case READY:
121             switch (code) {
122                 case 0x00:
123                     break;
124                 case 0xF0:
125                     state = F0;
126                     debug(" ");
127                     break;
128                 default:    // normal key make
129                     if (code < 0x88) {
130                         matrix_make(code);
131                     } else {
132                         debug("unexpected scan code at READY: "); debug_hex(code); debug("\n");
133                     }
134                     state = READY;
135                     debug("\n");
136             }
137             break;
138         case F0:    // Break code
139             switch (code) {
140                 case 0x00:
141                     break;
142                 default:
143                     if (code < 0x88) {
144                         matrix_break(code);
145                     } else {
146                         debug("unexpected scan code at F0: "); debug_hex(code); debug("\n");
147                     }
148                     state = READY;
149                     debug("\n");
150             }
151             break;
152     }
153     return 1;
154 }
155
156 inline
157 uint8_t matrix_get_row(uint8_t row)
158 {
159     return matrix[row];
160 }
161
162 inline
163 static void matrix_make(uint8_t code)
164 {
165     if (!matrix_is_on(ROW(code), COL(code))) {
166         matrix[ROW(code)] |= 1<<COL(code);
167     }
168 }
169
170 inline
171 static void matrix_break(uint8_t code)
172 {
173     if (matrix_is_on(ROW(code), COL(code))) {
174         matrix[ROW(code)] &= ~(1<<COL(code));
175     }
176 }