2018.07.26

Dependencies:   FATFileSystem2 mbed-rtos

Fork of USBHost by mbed official

Committer:
sayzyas
Date:
Mon Mar 28 00:06:57 2016 +0000
Revision:
39:8fbe33e98b2b
Parent:
34:cac1e8336448
Child:
40:626c4810255c
Rev20160325

Who changed what in which revision?

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