]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/USBHost/USBHostHID/USBHostKeyboard.cpp
Merge commit '20b787fc1284176834cbe7ca2134e4b36bec5828'
[max/tmk_keyboard.git] / tmk_core / tool / mbed / mbed-sdk / libraries / USBHost / USBHostHID / USBHostKeyboard.cpp
1 /* mbed USBHost Library
2  * Copyright (c) 2006-2013 ARM Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "USBHostKeyboard.h"
18
19 #if USBHOST_KEYBOARD
20
21 static uint8_t keymap[4][0x39] = {
22     { 0, 0, 0, 0, 'a', 'b' /*0x05*/,
23       'c', 'd', 'e', 'f', 'g' /*0x0a*/,
24       'h', 'i', 'j', 'k', 'l'/*0x0f*/,
25       'm', 'n', 'o', 'p', 'q'/*0x14*/,
26       'r', 's', 't', 'u', 'v'/*0x19*/,
27       'w', 'x', 'y', 'z', '1'/*0x1E*/,
28       '2', '3', '4', '5', '6'/*0x23*/,
29       '7', '8', '9', '0', 0x0A /*enter*/, /*0x28*/
30       0x1B /*escape*/, 0x08 /*backspace*/, 0x09/*tab*/, 0x20/*space*/, '-', /*0x2d*/
31       '=', '[', ']', '\\', '#', /*0x32*/
32       ';', '\'', 0, ',', '.', /*0x37*/
33       '/'},
34
35     /* CTRL MODIFIER */
36     { 0, 0, 0, 0, 0, 0 /*0x05*/,
37       0, 0, 0, 0, 0 /*0x0a*/,
38       0, 0, 0, 0, 0/*0x0f*/,
39       0, 0, 0, 0, 0/*0x14*/,
40       0, 0, 0, 0, 0/*0x19*/,
41       0, 0, 0, 0, 0/*0x1E*/,
42       0, 0, 0, 0, 0/*0x23*/,
43       0, 0, 0, 0, 0 /*enter*/, /*0x28*/
44       0, 0, 0, 0, 0, /*0x2d*/
45       0, 0, 0, 0, 0, /*0x32*/
46       0, 0, 0, 0, 0, /*0x37*/
47       0},
48
49     /* SHIFT MODIFIER */
50     { 0, 0, 0, 0, 'A', 'B' /*0x05*/,
51       'C', 'D', 'E', 'F', 'G' /*0x0a*/,
52       'H', 'I', 'J', 'K', 'L'/*0x0f*/,
53       'M', 'N', 'O', 'P', 'Q'/*0x14*/,
54       'R', 'S', 'T', 'U', 'V'/*0x19*/,
55       'W', 'X', 'Y', 'Z', '!'/*0x1E*/,
56       '@', '#', '$', '%', '^'/*0x23*/,
57       '&', '*', '(', ')', 0, /*0x28*/
58       0, 0, 0, 0, 0, /*0x2d*/
59       '+', '{', '}', '|', '~', /*0x32*/
60       ':', '"', 0, '<', '>', /*0x37*/
61       '?'},
62
63     /* ALT MODIFIER */
64     { 0, 0, 0, 0, 0, 0 /*0x05*/,
65       0, 0, 0, 0, 0 /*0x0a*/,
66       0, 0, 0, 0, 0/*0x0f*/,
67       0, 0, 0, 0, 0/*0x14*/,
68       0, 0, 0, 0, 0/*0x19*/,
69       0, 0, 0, 0, 0/*0x1E*/,
70       0, 0, 0, 0, 0/*0x23*/,
71       0, 0, 0, 0, 0 /*enter*/, /*0x28*/
72       0, 0, 0, 0, 0, /*0x2d*/
73       0, 0, 0, 0, 0, /*0x32*/
74       0, 0, 0, 0, 0, /*0x37*/
75       0}
76
77 };
78
79
80 USBHostKeyboard::USBHostKeyboard() {
81     host = USBHost::getHostInst();
82     init();
83 }
84
85
86 void USBHostKeyboard::init() {
87     dev = NULL;
88     int_in = NULL;
89     report_id = 0;
90     onKey = NULL;
91     onKeyCode = NULL;
92     dev_connected = false;
93     keyboard_intf = -1;
94     keyboard_device_found = false;
95 }
96
97 bool USBHostKeyboard::connected() {
98     return dev_connected;
99 }
100
101
102 bool USBHostKeyboard::connect() {
103
104     if (dev_connected) {
105         return true;
106     }
107
108     for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
109         if ((dev = host->getDevice(i)) != NULL) {
110
111             if (host->enumerate(dev, this))
112                 break;
113
114             if (keyboard_device_found) {
115                 int_in = dev->getEndpoint(keyboard_intf, INTERRUPT_ENDPOINT, IN);
116
117                 if (!int_in)
118                     break;
119
120                 USB_INFO("New Keyboard device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, keyboard_intf);
121                 dev->setName("Keyboard", keyboard_intf);
122                 host->registerDriver(dev, keyboard_intf, this, &USBHostKeyboard::init);
123
124                 int_in->attach(this, &USBHostKeyboard::rxHandler);
125                 host->interruptRead(dev, int_in, report, int_in->getSize(), false);
126
127                 dev_connected = true;
128                 return true;
129             }
130         }
131     }
132     init();
133     return false;
134 }
135
136 void USBHostKeyboard::rxHandler() {
137     int len = int_in->getLengthTransferred();
138     int index = (len == 9) ? 1 : 0;
139     int len_listen = int_in->getSize();
140     uint8_t key = 0;
141     if (len == 8 || len == 9) {
142         uint8_t modifier = (report[index] == 4) ? 3 : report[index];
143         len_listen = len;
144         key = keymap[modifier][report[index + 2]];
145         if (key && onKey) {
146             (*onKey)(key);
147         }
148         if ((report[index + 2] || modifier) && onKeyCode) {
149             (*onKeyCode)(report[index + 2], modifier);
150         }
151     }
152     if (dev && int_in)
153         host->interruptRead(dev, int_in, report, len_listen, false);
154 }
155
156 /*virtual*/ void USBHostKeyboard::setVidPid(uint16_t vid, uint16_t pid)
157 {
158     // we don't check VID/PID for keyboard driver
159 }
160
161 /*virtual*/ bool USBHostKeyboard::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
162 {
163     if ((keyboard_intf == -1) &&
164         (intf_class == HID_CLASS) &&
165         (intf_subclass == 0x01) &&
166         (intf_protocol == 0x01)) {
167         keyboard_intf = intf_nb;
168         return true;
169     }
170     return false;
171 }
172
173 /*virtual*/ bool USBHostKeyboard::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
174 {
175     if (intf_nb == keyboard_intf) {
176         if (type == INTERRUPT_ENDPOINT && dir == IN) {
177             keyboard_device_found = true;
178             return true;
179         }
180     }
181     return false;
182 }
183
184 #endif