2018.07.26

Dependencies:   FATFileSystem3 mbed-rtos

Fork of USBHost by mbed official

Committer:
sayzyas
Date:
Fri Nov 04 04:52:29 2016 +0000
Revision:
42:366a9be2060e
20161104;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sayzyas 42:366a9be2060e 1 /* mbed USBHost Gamepad driver sample
sayzyas 42:366a9be2060e 2 * Copyright (c) 2014 Yuuichi Akagawa
sayzyas 42:366a9be2060e 3 *
sayzyas 42:366a9be2060e 4 * modified from mbed USBHostMouse
sayzyas 42:366a9be2060e 5 *
sayzyas 42:366a9be2060e 6 * mbed USBHost Library
sayzyas 42:366a9be2060e 7 * Copyright (c) 2006-2013 ARM Limited
sayzyas 42:366a9be2060e 8 *
sayzyas 42:366a9be2060e 9 * Licensed under the Apache License, Version 2.0 (the "License");
sayzyas 42:366a9be2060e 10 * you may not use this file except in compliance with the License.
sayzyas 42:366a9be2060e 11 * You may obtain a copy of the License at
sayzyas 42:366a9be2060e 12 *
sayzyas 42:366a9be2060e 13 * http://www.apache.org/licenses/LICENSE-2.0
sayzyas 42:366a9be2060e 14 *
sayzyas 42:366a9be2060e 15 * Unless required by applicable law or agreed to in writing, software
sayzyas 42:366a9be2060e 16 * distributed under the License is distributed on an "AS IS" BASIS,
sayzyas 42:366a9be2060e 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
sayzyas 42:366a9be2060e 18 * See the License for the specific language governing permissions and
sayzyas 42:366a9be2060e 19 * limitations under the License.
sayzyas 42:366a9be2060e 20 * Refer to following URL:
sayzyas 42:366a9be2060e 21 * https://developer.mbed.org/users/YuuichiAkagawa/code/USBHostGamepad/file/7345e2afa41e/USBHostGamepad.cpp
sayzyas 42:366a9be2060e 22 */
sayzyas 42:366a9be2060e 23 #include "USBHostGamepad.h"
sayzyas 42:366a9be2060e 24 //#if USBHOST_GAMEPAD
sayzyas 42:366a9be2060e 25
sayzyas 42:366a9be2060e 26 USBHostGamepad::USBHostGamepad() {
sayzyas 42:366a9be2060e 27 host = USBHost::getHostInst();
sayzyas 42:366a9be2060e 28 init();
sayzyas 42:366a9be2060e 29 }
sayzyas 42:366a9be2060e 30
sayzyas 42:366a9be2060e 31 void USBHostGamepad::init() {
sayzyas 42:366a9be2060e 32 dev = NULL;
sayzyas 42:366a9be2060e 33 int_in = NULL;
sayzyas 42:366a9be2060e 34 onUpdate = NULL;
sayzyas 42:366a9be2060e 35 report_id = 0;
sayzyas 42:366a9be2060e 36 dev_connected = false;
sayzyas 42:366a9be2060e 37 gamepad_device_found = false;
sayzyas 42:366a9be2060e 38 gamepad_intf = -1;
sayzyas 42:366a9be2060e 39
sayzyas 42:366a9be2060e 40 btnX = 0;
sayzyas 42:366a9be2060e 41 btnY = 0;
sayzyas 42:366a9be2060e 42 btnABCD = 0;
sayzyas 42:366a9be2060e 43 btnSpecial = 0;
sayzyas 42:366a9be2060e 44
sayzyas 42:366a9be2060e 45 btn00 = 0;
sayzyas 42:366a9be2060e 46 btn01 = 1;
sayzyas 42:366a9be2060e 47 btn02 = 2;
sayzyas 42:366a9be2060e 48 btn03 = 3;
sayzyas 42:366a9be2060e 49 btn04 = 4;
sayzyas 42:366a9be2060e 50 btn05 = 5;
sayzyas 42:366a9be2060e 51 btn06 = 6;
sayzyas 42:366a9be2060e 52 btn07 = 7;
sayzyas 42:366a9be2060e 53 btn08 = 8;
sayzyas 42:366a9be2060e 54 btn09 = 9;
sayzyas 42:366a9be2060e 55 btn01 = 10;
sayzyas 42:366a9be2060e 56 btn11 = 11;
sayzyas 42:366a9be2060e 57 btn12 = 12;
sayzyas 42:366a9be2060e 58 btn13 = 13;
sayzyas 42:366a9be2060e 59 btn14 = 14;
sayzyas 42:366a9be2060e 60 btn15 = 15;
sayzyas 42:366a9be2060e 61 }
sayzyas 42:366a9be2060e 62
sayzyas 42:366a9be2060e 63 bool USBHostGamepad::connected() {
sayzyas 42:366a9be2060e 64 return dev_connected;
sayzyas 42:366a9be2060e 65 }
sayzyas 42:366a9be2060e 66
sayzyas 42:366a9be2060e 67 bool USBHostGamepad::connect() {
sayzyas 42:366a9be2060e 68 int len_listen;
sayzyas 42:366a9be2060e 69
sayzyas 42:366a9be2060e 70 if (dev_connected) {
sayzyas 42:366a9be2060e 71 return true;
sayzyas 42:366a9be2060e 72 }
sayzyas 42:366a9be2060e 73
sayzyas 42:366a9be2060e 74 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
sayzyas 42:366a9be2060e 75 if ((dev = host->getDevice(i)) != NULL) {
sayzyas 42:366a9be2060e 76
sayzyas 42:366a9be2060e 77 if(host->enumerate(dev, this))
sayzyas 42:366a9be2060e 78 break;
sayzyas 42:366a9be2060e 79
sayzyas 42:366a9be2060e 80 if (gamepad_device_found) {
sayzyas 42:366a9be2060e 81
sayzyas 42:366a9be2060e 82 int_in = dev->getEndpoint(gamepad_intf, INTERRUPT_ENDPOINT, IN);
sayzyas 42:366a9be2060e 83 if (!int_in)
sayzyas 42:366a9be2060e 84 break;
sayzyas 42:366a9be2060e 85
sayzyas 42:366a9be2060e 86 gamePad_VID = dev->getVid();
sayzyas 42:366a9be2060e 87 gamePad_PID = dev->getPid();
sayzyas 42:366a9be2060e 88
sayzyas 42:366a9be2060e 89 // USB_INFO("New Gamepad/Joystick device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, gamepad_intf);
sayzyas 42:366a9be2060e 90 USB_INFO("New Gamepad/Joystick device: VID:%04x PID:%04x [dev: %p - intf: %d]", gamePad_VID, gamePad_PID, dev, gamepad_intf);
sayzyas 42:366a9be2060e 91 #if DEBUG > 3
sayzyas 42:366a9be2060e 92 //Parse HID Report Descriptor
sayzyas 42:366a9be2060e 93 parseHidDescr();
sayzyas 42:366a9be2060e 94 #endif
sayzyas 42:366a9be2060e 95 dev->setName("Gamepad", gamepad_intf);
sayzyas 42:366a9be2060e 96 host->registerDriver(dev, gamepad_intf, this, &USBHostGamepad::init);
sayzyas 42:366a9be2060e 97
sayzyas 42:366a9be2060e 98 int_in->attach(this, &USBHostGamepad::rxHandler);
sayzyas 42:366a9be2060e 99 len_listen = int_in->getSize();
sayzyas 42:366a9be2060e 100 if (len_listen > sizeof(report)) {
sayzyas 42:366a9be2060e 101 len_listen = sizeof(report);
sayzyas 42:366a9be2060e 102 }
sayzyas 42:366a9be2060e 103 host->interruptRead(dev, int_in, report, len_listen, false);
sayzyas 42:366a9be2060e 104
sayzyas 42:366a9be2060e 105 dev_connected = true;
sayzyas 42:366a9be2060e 106 return true;
sayzyas 42:366a9be2060e 107 }
sayzyas 42:366a9be2060e 108 }
sayzyas 42:366a9be2060e 109 }
sayzyas 42:366a9be2060e 110 init();
sayzyas 42:366a9be2060e 111 return false;
sayzyas 42:366a9be2060e 112 }
sayzyas 42:366a9be2060e 113
sayzyas 42:366a9be2060e 114 void USBHostGamepad::rxHandler() {
sayzyas 42:366a9be2060e 115 int len_listen = int_in->getSize();
sayzyas 42:366a9be2060e 116 // printf("GamePad Length=%dyryn", len_listen);
sayzyas 42:366a9be2060e 117 #if DEBUG > 3
sayzyas 42:366a9be2060e 118 USB_DBG("USBHostGamepad::rxHandler() len_listen=%d\r\n", len_listen);
sayzyas 42:366a9be2060e 119 for (int i = 0; i < len_listen; i++){
sayzyas 42:366a9be2060e 120 printf("%02X ", report[i]);
sayzyas 42:366a9be2060e 121 }
sayzyas 42:366a9be2060e 122 printf("\r\n\r\n");
sayzyas 42:366a9be2060e 123 #endif
sayzyas 42:366a9be2060e 124 if (onUpdate) {
sayzyas 42:366a9be2060e 125 // (*onUpdate)(report[0], report[1], report[5], report[6]);
sayzyas 42:366a9be2060e 126 (*onUpdate)(
sayzyas 42:366a9be2060e 127 report[0],
sayzyas 42:366a9be2060e 128 report[1],
sayzyas 42:366a9be2060e 129 report[2],
sayzyas 42:366a9be2060e 130 report[3],
sayzyas 42:366a9be2060e 131 report[4],
sayzyas 42:366a9be2060e 132 report[5],
sayzyas 42:366a9be2060e 133 report[6],
sayzyas 42:366a9be2060e 134 report[7],
sayzyas 42:366a9be2060e 135 report[8],
sayzyas 42:366a9be2060e 136 report[9],
sayzyas 42:366a9be2060e 137 report[10],
sayzyas 42:366a9be2060e 138 report[11],
sayzyas 42:366a9be2060e 139 report[12],
sayzyas 42:366a9be2060e 140 report[13],
sayzyas 42:366a9be2060e 141 report[14],
sayzyas 42:366a9be2060e 142 report[15],
sayzyas 42:366a9be2060e 143 dev->getVid(),
sayzyas 42:366a9be2060e 144 dev->getPid()
sayzyas 42:366a9be2060e 145
sayzyas 42:366a9be2060e 146 );
sayzyas 42:366a9be2060e 147 }
sayzyas 42:366a9be2060e 148
sayzyas 42:366a9be2060e 149 // update gamepad state
sayzyas 42:366a9be2060e 150 // btnX = report[0];
sayzyas 42:366a9be2060e 151 // btnY = report[1];
sayzyas 42:366a9be2060e 152 // btnABCD = report[5];
sayzyas 42:366a9be2060e 153 // btnSpecial = report[6];
sayzyas 42:366a9be2060e 154 btn00 = report[0];
sayzyas 42:366a9be2060e 155 btn01 = report[1];
sayzyas 42:366a9be2060e 156 btn02 = report[2];
sayzyas 42:366a9be2060e 157 btn03 = report[3];
sayzyas 42:366a9be2060e 158 btn04 = report[4];
sayzyas 42:366a9be2060e 159 btn05 = report[5];
sayzyas 42:366a9be2060e 160 btn06 = report[6];
sayzyas 42:366a9be2060e 161 btn07 = report[7];
sayzyas 42:366a9be2060e 162 btn08 = report[8];
sayzyas 42:366a9be2060e 163 btn09 = report[9];
sayzyas 42:366a9be2060e 164 btn10 = report[10];
sayzyas 42:366a9be2060e 165 btn11 = report[11];
sayzyas 42:366a9be2060e 166 btn12 = report[12];
sayzyas 42:366a9be2060e 167 btn13 = report[13];
sayzyas 42:366a9be2060e 168 btn14 = report[14];
sayzyas 42:366a9be2060e 169 btn15 = report[15];
sayzyas 42:366a9be2060e 170
sayzyas 42:366a9be2060e 171 // gamePad_VID = dev->getVid();
sayzyas 42:366a9be2060e 172 // gamePad_PID = dev->getPid();
sayzyas 42:366a9be2060e 173
sayzyas 42:366a9be2060e 174 if (len_listen > sizeof(report)) {
sayzyas 42:366a9be2060e 175 len_listen = sizeof(report);
sayzyas 42:366a9be2060e 176 }
sayzyas 42:366a9be2060e 177
sayzyas 42:366a9be2060e 178 if (dev)
sayzyas 42:366a9be2060e 179 host->interruptRead(dev, int_in, report, len_listen, false);
sayzyas 42:366a9be2060e 180 }
sayzyas 42:366a9be2060e 181
sayzyas 42:366a9be2060e 182 /*virtual*/ void USBHostGamepad::setVidPid(uint16_t vid, uint16_t pid)
sayzyas 42:366a9be2060e 183 {
sayzyas 42:366a9be2060e 184 // we don't check VID/PID for gamepad driver
sayzyas 42:366a9be2060e 185 }
sayzyas 42:366a9be2060e 186
sayzyas 42:366a9be2060e 187 /*virtual*/ bool USBHostGamepad::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
sayzyas 42:366a9be2060e 188 {
sayzyas 42:366a9be2060e 189 if ((gamepad_intf == -1) &&
sayzyas 42:366a9be2060e 190 (intf_class == HID_CLASS) &&
sayzyas 42:366a9be2060e 191 (intf_subclass == 0x00) &&
sayzyas 42:366a9be2060e 192 (intf_protocol == 0x00)) {
sayzyas 42:366a9be2060e 193 gamepad_intf = intf_nb;
sayzyas 42:366a9be2060e 194 return true;
sayzyas 42:366a9be2060e 195 }
sayzyas 42:366a9be2060e 196 return false;
sayzyas 42:366a9be2060e 197 }
sayzyas 42:366a9be2060e 198
sayzyas 42:366a9be2060e 199 /*virtual*/ bool USBHostGamepad::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
sayzyas 42:366a9be2060e 200 {
sayzyas 42:366a9be2060e 201 if (intf_nb == gamepad_intf) {
sayzyas 42:366a9be2060e 202 if (type == INTERRUPT_ENDPOINT && dir == IN) {
sayzyas 42:366a9be2060e 203 gamepad_device_found = true;
sayzyas 42:366a9be2060e 204 return true;
sayzyas 42:366a9be2060e 205 }
sayzyas 42:366a9be2060e 206 }
sayzyas 42:366a9be2060e 207 return false;
sayzyas 42:366a9be2060e 208 }
sayzyas 42:366a9be2060e 209
sayzyas 42:366a9be2060e 210 USB_TYPE USBHostGamepad::getReportDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_rep_descr)
sayzyas 42:366a9be2060e 211 {
sayzyas 42:366a9be2060e 212 USB_TYPE t = host->controlRead( dev,
sayzyas 42:366a9be2060e 213 USB_DEVICE_TO_HOST | USB_RECIPIENT_INTERFACE | USB_REQUEST_TYPE_STANDARD,
sayzyas 42:366a9be2060e 214 HID_GET_DESCRIPTOR,
sayzyas 42:366a9be2060e 215 0x2200,
sayzyas 42:366a9be2060e 216 0, buf, max_len_buf);
sayzyas 42:366a9be2060e 217 if (len_rep_descr)
sayzyas 42:366a9be2060e 218 *len_rep_descr = max_len_buf;
sayzyas 42:366a9be2060e 219
sayzyas 42:366a9be2060e 220 return t;
sayzyas 42:366a9be2060e 221 }
sayzyas 42:366a9be2060e 222
sayzyas 42:366a9be2060e 223 /*
sayzyas 42:366a9be2060e 224 * HID Report Descriptor parser
sayzyas 42:366a9be2060e 225 */
sayzyas 42:366a9be2060e 226 bool USBHostGamepad::parseHidDescr()
sayzyas 42:366a9be2060e 227 {
sayzyas 42:366a9be2060e 228 bool ret = true;
sayzyas 42:366a9be2060e 229 uint8_t *buf;
sayzyas 42:366a9be2060e 230 uint16_t desclen = host->getLengthReportDescr();
sayzyas 42:366a9be2060e 231
sayzyas 42:366a9be2060e 232 //allocate report descriptor's buffer
sayzyas 42:366a9be2060e 233 buf = (uint8_t *)malloc(desclen);
sayzyas 42:366a9be2060e 234 if(buf == NULL){
sayzyas 42:366a9be2060e 235 return false;
sayzyas 42:366a9be2060e 236 }
sayzyas 42:366a9be2060e 237 getReportDescriptor(dev, buf, desclen);
sayzyas 42:366a9be2060e 238 #if (DEBUG > 3)
sayzyas 42:366a9be2060e 239 USB_DBG("HID REPORT DESCRIPTOR:\r\n");
sayzyas 42:366a9be2060e 240 for (int i = 0; i < desclen; i++)
sayzyas 42:366a9be2060e 241 printf("%02X ", buf[i]);
sayzyas 42:366a9be2060e 242 printf("\r\n\r\n");
sayzyas 42:366a9be2060e 243 #endif
sayzyas 42:366a9be2060e 244 if( buf[0] == 0x05 //Usage page
sayzyas 42:366a9be2060e 245 && buf[1] == 0x01 //Generic Desktop
sayzyas 42:366a9be2060e 246 && buf[2] == 0x09 //Usage
sayzyas 42:366a9be2060e 247 ){
sayzyas 42:366a9be2060e 248 if( buf[3] == 0x04 ){
sayzyas 42:366a9be2060e 249 USB_DBG("This is GamePad:");
sayzyas 42:366a9be2060e 250 }else if( buf[3] == 0x05){
sayzyas 42:366a9be2060e 251 USB_DBG("This is JoyStick:");
sayzyas 42:366a9be2060e 252 }else{
sayzyas 42:366a9be2060e 253 ret = false;
sayzyas 42:366a9be2060e 254 }
sayzyas 42:366a9be2060e 255 }
sayzyas 42:366a9be2060e 256 free(buf);
sayzyas 42:366a9be2060e 257 return ret;
sayzyas 42:366a9be2060e 258 }
sayzyas 42:366a9be2060e 259 //#endif