Zoltan Hudak / USBHost-STM32F4

Dependents:   STM32F407VET6_USBHostMSD STM32F407VET6_USBHostMouse STM32F407VET6_USBHostKeyboard STM32F407VET6_USBHostMSD_1

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBHostKeyboard.cpp Source File

USBHostKeyboard.cpp

00001 /* mbed USBHost Library
00002  * Copyright (c) 2006-2013 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "USBHostKeyboard.h"
00018 
00019 #if USBHOST_KEYBOARD
00020 
00021 /*$off*/
00022 static uint8_t keymap[4][0x39] = { 
00023     {   0,   0,   0,   0, 'a', 'b', 'c', 'd', 'e', 'f',
00024       'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 
00025       'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 
00026       '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 
00027       0x0A /*enter*/, 0x1B /*escape*/, 0x08 /*backspace*/, 0x09/*tab*/, 0x20/*space*/, '-', '=', '[', ']', '\\', 
00028       '#', ';', '\'',  0, ',', '.', '/'
00029     },
00030 
00031     /* CTRL MODIFIER */
00032     {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
00033         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
00034         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
00035         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
00036         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
00037         0,   0,   0,   0,   0,   0,   0
00038     },
00039   
00040     /* SHIFT MODIFIER */
00041     {  0,    0,   0,   0, 'A', 'B', 'C', 'D', 'E', 'F',
00042       'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
00043       'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
00044       '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
00045        0,    0,   0,   0,   0,   0, '+', '{', '}', '|',
00046       '~', ':', '"',   0, '<', '>', '?'
00047     },
00048 
00049     /* ALT MODIFIER */
00050     {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
00051         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
00052         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
00053         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
00054         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
00055         0,   0,   0,   0,   0,   0,   0
00056     },
00057 };
00058 /*$on*/
00059 
00060 USBHostKeyboard::USBHostKeyboard() {
00061     host = USBHost::getHostInst();
00062     init();
00063 }
00064 
00065 void USBHostKeyboard::init() {
00066     dev = NULL;
00067     int_in = NULL;
00068     report_id = 0;
00069     onKey = NULL;
00070     onKeyCode = NULL;
00071     dev_connected = false;
00072     keyboard_intf = -1;
00073     keyboard_device_found = false;
00074 }
00075 
00076 bool USBHostKeyboard::connected() {
00077     return dev_connected;
00078 }
00079 
00080 
00081 bool USBHostKeyboard::connect() {
00082     
00083     if (dev_connected) {
00084         return true;
00085     }
00086     
00087     for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
00088         if ((dev = host->getDevice(i)) != NULL) {
00089 
00090             if (host->enumerate(dev, this))
00091                 break;
00092             
00093             if (keyboard_device_found) {
00094                 int_in = dev->getEndpoint(keyboard_intf, INTERRUPT_ENDPOINT, IN);
00095                 
00096                 if (!int_in)
00097                     break;
00098                 
00099                 USB_INFO("New Keyboard device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, keyboard_intf);
00100                 dev->setName("Keyboard", keyboard_intf);
00101                 host->registerDriver(dev, keyboard_intf, this, &USBHostKeyboard::init);
00102                 
00103                 int_in->attach(this, &USBHostKeyboard::rxHandler);
00104                 host->interruptRead(dev, int_in, report, int_in->getSize(), false);
00105                 
00106                 dev_connected = true;
00107                 return true;
00108             }
00109         }
00110     }
00111     init();
00112     return false;
00113 }
00114 
00115 void USBHostKeyboard::rxHandler() {
00116     int len = int_in->getLengthTransferred();
00117     int index = (len == 9) ? 1 : 0;
00118     int len_listen = int_in->getSize();
00119     uint8_t key = 0;
00120     if (len == 8 || len == 9) {
00121         uint8_t modifier = (report[index] == 4) ? 3 : report[index];
00122         len_listen = len;
00123         key = keymap[modifier][report[index + 2]];
00124         if (key && onKey) {
00125             (*onKey)(key);
00126         }
00127         if ((report[index + 2] || modifier) && onKeyCode) {
00128             (*onKeyCode)(report[index + 2], modifier);
00129         }
00130     }
00131     if (dev && int_in)
00132         host->interruptRead(dev, int_in, report, len_listen, false);
00133 }
00134 
00135 /*virtual*/ void USBHostKeyboard::setVidPid(uint16_t vid, uint16_t pid)
00136 {
00137     // we don't check VID/PID for keyboard driver
00138 }
00139 
00140 /*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
00141 {
00142     if ((keyboard_intf == -1) &&
00143         (intf_class == HID_CLASS) &&
00144         (intf_subclass == 0x01) &&
00145         (intf_protocol == 0x01)) {
00146         keyboard_intf = intf_nb;
00147         return true;
00148     }
00149     return false;
00150 }
00151 
00152 /*virtual*/ bool USBHostKeyboard::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
00153 {
00154     if (intf_nb == keyboard_intf) {
00155         if (type == INTERRUPT_ENDPOINT && dir == IN) {
00156             keyboard_device_found = true;
00157             return true;
00158         }
00159     }
00160     return false;
00161 }
00162 
00163 #endif