Pierre Provent / USBHost

Dependents:   TEST_USB_Nucleo_F429ZI Essais_USB_Nucleo_F429ZI SID_V3_Nucleo_F429ZI SID_V4_Nucleo_F429ZI_copy

Committer:
pierreprovent
Date:
Fri Sep 25 10:17:49 2020 +0000
Revision:
0:77ca32e8e04e
Programme acquisition en enregistrement sur clef USB carte Nucleo F429ZI cours ELE118 Cnam

Who changed what in which revision?

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