2018.07.26

Dependencies:   FATFileSystem2 mbed-rtos

Fork of USBHost by mbed official

Committer:
sayzyas
Date:
Tue Aug 09 01:28:30 2016 +0000
Revision:
40:626c4810255c
Parent:
39:8fbe33e98b2b
1

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 32:e6717a485577 40 btnX = 0;
sayzyas 32:e6717a485577 41 btnY = 0;
sayzyas 32:e6717a485577 42 btnABCD = 0;
sayzyas 32:e6717a485577 43 btnSpecial = 0;
sayzyas 33:86c22c0c8aae 44
sayzyas 33:86c22c0c8aae 45 btn00 = 0;
sayzyas 33:86c22c0c8aae 46 btn01 = 1;
sayzyas 33:86c22c0c8aae 47 btn02 = 2;
sayzyas 33:86c22c0c8aae 48 btn03 = 3;
sayzyas 33:86c22c0c8aae 49 btn04 = 4;
sayzyas 33:86c22c0c8aae 50 btn05 = 5;
sayzyas 33:86c22c0c8aae 51 btn06 = 6;
sayzyas 33:86c22c0c8aae 52 btn07 = 7;
sayzyas 33:86c22c0c8aae 53 btn08 = 8;
sayzyas 33:86c22c0c8aae 54 btn09 = 9;
sayzyas 33:86c22c0c8aae 55 btn01 = 10;
sayzyas 33:86c22c0c8aae 56 btn11 = 11;
sayzyas 33:86c22c0c8aae 57 btn12 = 12;
sayzyas 33:86c22c0c8aae 58 btn13 = 13;
sayzyas 33:86c22c0c8aae 59 btn14 = 14;
sayzyas 33:86c22c0c8aae 60 btn15 = 15;
sayzyas 32:e6717a485577 61 }
sayzyas 32:e6717a485577 62
sayzyas 32:e6717a485577 63 bool USBHostGamepad::connected() {
sayzyas 32:e6717a485577 64 return dev_connected;
sayzyas 32:e6717a485577 65 }
sayzyas 32:e6717a485577 66
sayzyas 32:e6717a485577 67 bool USBHostGamepad::connect() {
sayzyas 32:e6717a485577 68 int len_listen;
sayzyas 32:e6717a485577 69
sayzyas 32:e6717a485577 70 if (dev_connected) {
sayzyas 32:e6717a485577 71 return true;
sayzyas 32:e6717a485577 72 }
sayzyas 32:e6717a485577 73
sayzyas 32:e6717a485577 74 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
sayzyas 32:e6717a485577 75 if ((dev = host->getDevice(i)) != NULL) {
sayzyas 32:e6717a485577 76
sayzyas 32:e6717a485577 77 if(host->enumerate(dev, this))
sayzyas 32:e6717a485577 78 break;
sayzyas 32:e6717a485577 79
sayzyas 32:e6717a485577 80 if (gamepad_device_found) {
sayzyas 32:e6717a485577 81
sayzyas 32:e6717a485577 82 int_in = dev->getEndpoint(gamepad_intf, INTERRUPT_ENDPOINT, IN);
sayzyas 32:e6717a485577 83 if (!int_in)
sayzyas 32:e6717a485577 84 break;
sayzyas 32:e6717a485577 85
sayzyas 34:cac1e8336448 86 gamePad_VID = dev->getVid();
sayzyas 34:cac1e8336448 87 gamePad_PID = dev->getPid();
sayzyas 34:cac1e8336448 88
sayzyas 34:cac1e8336448 89 // USB_INFO("New Gamepad/Joystick device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, gamepad_intf);
sayzyas 34:cac1e8336448 90 USB_INFO("New Gamepad/Joystick device: VID:%04x PID:%04x [dev: %p - intf: %d]", gamePad_VID, gamePad_PID, dev, gamepad_intf);
sayzyas 32:e6717a485577 91 #if DEBUG > 3
sayzyas 32:e6717a485577 92 //Parse HID Report Descriptor
sayzyas 32:e6717a485577 93 parseHidDescr();
sayzyas 32:e6717a485577 94 #endif
sayzyas 32:e6717a485577 95 dev->setName("Gamepad", gamepad_intf);
sayzyas 32:e6717a485577 96 host->registerDriver(dev, gamepad_intf, this, &USBHostGamepad::init);
sayzyas 32:e6717a485577 97
sayzyas 32:e6717a485577 98 int_in->attach(this, &USBHostGamepad::rxHandler);
sayzyas 32:e6717a485577 99 len_listen = int_in->getSize();
sayzyas 32:e6717a485577 100 if (len_listen > sizeof(report)) {
sayzyas 32:e6717a485577 101 len_listen = sizeof(report);
sayzyas 32:e6717a485577 102 }
sayzyas 32:e6717a485577 103 host->interruptRead(dev, int_in, report, len_listen, false);
sayzyas 32:e6717a485577 104
sayzyas 32:e6717a485577 105 dev_connected = true;
sayzyas 32:e6717a485577 106 return true;
sayzyas 32:e6717a485577 107 }
sayzyas 32:e6717a485577 108 }
sayzyas 32:e6717a485577 109 }
sayzyas 32:e6717a485577 110 init();
sayzyas 32:e6717a485577 111 return false;
sayzyas 32:e6717a485577 112 }
sayzyas 32:e6717a485577 113
sayzyas 32:e6717a485577 114 void USBHostGamepad::rxHandler() {
sayzyas 32:e6717a485577 115 int len_listen = int_in->getSize();
sayzyas 33:86c22c0c8aae 116 // printf("GamePad Length=%dyryn", len_listen);
sayzyas 32:e6717a485577 117 #if DEBUG > 3
sayzyas 32:e6717a485577 118 USB_DBG("USBHostGamepad::rxHandler() len_listen=%d\r\n", len_listen);
sayzyas 34:cac1e8336448 119 for (int i = 0; i < len_listen; i++){
sayzyas 32:e6717a485577 120 printf("%02X ", report[i]);
sayzyas 34:cac1e8336448 121 }
sayzyas 32:e6717a485577 122 printf("\r\n\r\n");
sayzyas 32:e6717a485577 123 #endif
sayzyas 32:e6717a485577 124 if (onUpdate) {
sayzyas 33:86c22c0c8aae 125 // (*onUpdate)(report[0], report[1], report[5], report[6]);
sayzyas 33:86c22c0c8aae 126 (*onUpdate)(
sayzyas 33:86c22c0c8aae 127 report[0],
sayzyas 33:86c22c0c8aae 128 report[1],
sayzyas 33:86c22c0c8aae 129 report[2],
sayzyas 33:86c22c0c8aae 130 report[3],
sayzyas 33:86c22c0c8aae 131 report[4],
sayzyas 33:86c22c0c8aae 132 report[5],
sayzyas 33:86c22c0c8aae 133 report[6],
sayzyas 33:86c22c0c8aae 134 report[7],
sayzyas 33:86c22c0c8aae 135 report[8],
sayzyas 33:86c22c0c8aae 136 report[9],
sayzyas 33:86c22c0c8aae 137 report[10],
sayzyas 33:86c22c0c8aae 138 report[11],
sayzyas 33:86c22c0c8aae 139 report[12],
sayzyas 33:86c22c0c8aae 140 report[13],
sayzyas 33:86c22c0c8aae 141 report[14],
sayzyas 34:cac1e8336448 142 report[15],
sayzyas 34:cac1e8336448 143 dev->getVid(),
sayzyas 34:cac1e8336448 144 dev->getPid()
sayzyas 34:cac1e8336448 145
sayzyas 33:86c22c0c8aae 146 );
sayzyas 32:e6717a485577 147 }
sayzyas 32:e6717a485577 148
sayzyas 32:e6717a485577 149 // update gamepad state
sayzyas 33:86c22c0c8aae 150 // btnX = report[0];
sayzyas 33:86c22c0c8aae 151 // btnY = report[1];
sayzyas 33:86c22c0c8aae 152 // btnABCD = report[5];
sayzyas 33:86c22c0c8aae 153 // btnSpecial = report[6];
sayzyas 33:86c22c0c8aae 154 btn00 = report[0];
sayzyas 33:86c22c0c8aae 155 btn01 = report[1];
sayzyas 33:86c22c0c8aae 156 btn02 = report[2];
sayzyas 33:86c22c0c8aae 157 btn03 = report[3];
sayzyas 33:86c22c0c8aae 158 btn04 = report[4];
sayzyas 33:86c22c0c8aae 159 btn05 = report[5];
sayzyas 33:86c22c0c8aae 160 btn06 = report[6];
sayzyas 33:86c22c0c8aae 161 btn07 = report[7];
sayzyas 33:86c22c0c8aae 162 btn08 = report[8];
sayzyas 33:86c22c0c8aae 163 btn09 = report[9];
sayzyas 33:86c22c0c8aae 164 btn10 = report[10];
sayzyas 33:86c22c0c8aae 165 btn11 = report[11];
sayzyas 33:86c22c0c8aae 166 btn12 = report[12];
sayzyas 33:86c22c0c8aae 167 btn13 = report[13];
sayzyas 33:86c22c0c8aae 168 btn14 = report[14];
sayzyas 33:86c22c0c8aae 169 btn15 = report[15];
sayzyas 34:cac1e8336448 170
sayzyas 34:cac1e8336448 171 // gamePad_VID = dev->getVid();
sayzyas 34:cac1e8336448 172 // gamePad_PID = dev->getPid();
sayzyas 32:e6717a485577 173
sayzyas 32:e6717a485577 174 if (len_listen > sizeof(report)) {
sayzyas 32:e6717a485577 175 len_listen = sizeof(report);
sayzyas 32:e6717a485577 176 }
sayzyas 32:e6717a485577 177
sayzyas 32:e6717a485577 178 if (dev)
sayzyas 32:e6717a485577 179 host->interruptRead(dev, int_in, report, len_listen, false);
sayzyas 32:e6717a485577 180 }
sayzyas 32:e6717a485577 181
sayzyas 32:e6717a485577 182 /*virtual*/ void USBHostGamepad::setVidPid(uint16_t vid, uint16_t pid)
sayzyas 32:e6717a485577 183 {
sayzyas 32:e6717a485577 184 // we don't check VID/PID for gamepad driver
sayzyas 32:e6717a485577 185 }
sayzyas 32:e6717a485577 186
sayzyas 32:e6717a485577 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 32:e6717a485577 188 {
sayzyas 32:e6717a485577 189 if ((gamepad_intf == -1) &&
sayzyas 32:e6717a485577 190 (intf_class == HID_CLASS) &&
sayzyas 32:e6717a485577 191 (intf_subclass == 0x00) &&
sayzyas 32:e6717a485577 192 (intf_protocol == 0x00)) {
sayzyas 32:e6717a485577 193 gamepad_intf = intf_nb;
sayzyas 32:e6717a485577 194 return true;
sayzyas 32:e6717a485577 195 }
sayzyas 32:e6717a485577 196 return false;
sayzyas 32:e6717a485577 197 }
sayzyas 32:e6717a485577 198
sayzyas 32:e6717a485577 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 32:e6717a485577 200 {
sayzyas 32:e6717a485577 201 if (intf_nb == gamepad_intf) {
sayzyas 32:e6717a485577 202 if (type == INTERRUPT_ENDPOINT && dir == IN) {
sayzyas 32:e6717a485577 203 gamepad_device_found = true;
sayzyas 32:e6717a485577 204 return true;
sayzyas 32:e6717a485577 205 }
sayzyas 32:e6717a485577 206 }
sayzyas 32:e6717a485577 207 return false;
sayzyas 32:e6717a485577 208 }
sayzyas 32:e6717a485577 209
sayzyas 32:e6717a485577 210 USB_TYPE USBHostGamepad::getReportDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_rep_descr)
sayzyas 32:e6717a485577 211 {
sayzyas 32:e6717a485577 212 USB_TYPE t = host->controlRead( dev,
sayzyas 32:e6717a485577 213 USB_DEVICE_TO_HOST | USB_RECIPIENT_INTERFACE | USB_REQUEST_TYPE_STANDARD,
sayzyas 32:e6717a485577 214 HID_GET_DESCRIPTOR,
sayzyas 32:e6717a485577 215 0x2200,
sayzyas 32:e6717a485577 216 0, buf, max_len_buf);
sayzyas 32:e6717a485577 217 if (len_rep_descr)
sayzyas 32:e6717a485577 218 *len_rep_descr = max_len_buf;
sayzyas 32:e6717a485577 219
sayzyas 32:e6717a485577 220 return t;
sayzyas 32:e6717a485577 221 }
sayzyas 32:e6717a485577 222
sayzyas 32:e6717a485577 223 /*
sayzyas 32:e6717a485577 224 * HID Report Descriptor parser
sayzyas 32:e6717a485577 225 */
sayzyas 32:e6717a485577 226 bool USBHostGamepad::parseHidDescr()
sayzyas 32:e6717a485577 227 {
sayzyas 32:e6717a485577 228 bool ret = true;
sayzyas 32:e6717a485577 229 uint8_t *buf;
sayzyas 32:e6717a485577 230 uint16_t desclen = host->getLengthReportDescr();
sayzyas 32:e6717a485577 231
sayzyas 32:e6717a485577 232 //allocate report descriptor's buffer
sayzyas 32:e6717a485577 233 buf = (uint8_t *)malloc(desclen);
sayzyas 32:e6717a485577 234 if(buf == NULL){
sayzyas 32:e6717a485577 235 return false;
sayzyas 32:e6717a485577 236 }
sayzyas 32:e6717a485577 237 getReportDescriptor(dev, buf, desclen);
sayzyas 32:e6717a485577 238 #if (DEBUG > 3)
sayzyas 32:e6717a485577 239 USB_DBG("HID REPORT DESCRIPTOR:\r\n");
sayzyas 32:e6717a485577 240 for (int i = 0; i < desclen; i++)
sayzyas 32:e6717a485577 241 printf("%02X ", buf[i]);
sayzyas 32:e6717a485577 242 printf("\r\n\r\n");
sayzyas 32:e6717a485577 243 #endif
sayzyas 32:e6717a485577 244 if( buf[0] == 0x05 //Usage page
sayzyas 32:e6717a485577 245 && buf[1] == 0x01 //Generic Desktop
sayzyas 32:e6717a485577 246 && buf[2] == 0x09 //Usage
sayzyas 32:e6717a485577 247 ){
sayzyas 32:e6717a485577 248 if( buf[3] == 0x04 ){
sayzyas 39:8fbe33e98b2b 249 USB_DBG("This is GamePad:");
sayzyas 32:e6717a485577 250 }else if( buf[3] == 0x05){
sayzyas 39:8fbe33e98b2b 251 USB_DBG("This is JoyStick:");
sayzyas 32:e6717a485577 252 }else{
sayzyas 32:e6717a485577 253 ret = false;
sayzyas 32:e6717a485577 254 }
sayzyas 32:e6717a485577 255 }
sayzyas 32:e6717a485577 256 free(buf);
sayzyas 32:e6717a485577 257 return ret;
sayzyas 32:e6717a485577 258 }
sayzyas 32:e6717a485577 259 //#endif