2018.07.26

Dependencies:   FATFileSystem2 mbed-rtos

Fork of USBHost by mbed official

Committer:
sayzyas
Date:
Thu Jun 18 08:05:23 2015 +0000
Revision:
33:86c22c0c8aae
Parent:
32:e6717a485577
Child:
34:cac1e8336448
2015.06.18; ;

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 32:e6717a485577 89 USB_INFO("New Gamepad/Joystick device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, gamepad_intf);
sayzyas 32:e6717a485577 90 #if DEBUG > 3
sayzyas 32:e6717a485577 91 //Parse HID Report Descriptor
sayzyas 32:e6717a485577 92 parseHidDescr();
sayzyas 32:e6717a485577 93 #endif
sayzyas 32:e6717a485577 94 dev->setName("Gamepad", gamepad_intf);
sayzyas 32:e6717a485577 95 host->registerDriver(dev, gamepad_intf, this, &USBHostGamepad::init);
sayzyas 32:e6717a485577 96
sayzyas 32:e6717a485577 97 int_in->attach(this, &USBHostGamepad::rxHandler);
sayzyas 32:e6717a485577 98 len_listen = int_in->getSize();
sayzyas 32:e6717a485577 99 if (len_listen > sizeof(report)) {
sayzyas 32:e6717a485577 100 len_listen = sizeof(report);
sayzyas 32:e6717a485577 101 }
sayzyas 32:e6717a485577 102 host->interruptRead(dev, int_in, report, len_listen, false);
sayzyas 32:e6717a485577 103
sayzyas 32:e6717a485577 104 dev_connected = true;
sayzyas 32:e6717a485577 105 return true;
sayzyas 32:e6717a485577 106 }
sayzyas 32:e6717a485577 107 }
sayzyas 32:e6717a485577 108 }
sayzyas 32:e6717a485577 109 init();
sayzyas 32:e6717a485577 110 return false;
sayzyas 32:e6717a485577 111 }
sayzyas 32:e6717a485577 112
sayzyas 32:e6717a485577 113 void USBHostGamepad::rxHandler() {
sayzyas 32:e6717a485577 114 int len_listen = int_in->getSize();
sayzyas 33:86c22c0c8aae 115 // printf("GamePad Length=%dyryn", len_listen);
sayzyas 32:e6717a485577 116 #if DEBUG > 3
sayzyas 32:e6717a485577 117 USB_DBG("USBHostGamepad::rxHandler() len_listen=%d\r\n", len_listen);
sayzyas 32:e6717a485577 118 for (int i = 0; i < len_listen; i++)
sayzyas 32:e6717a485577 119 printf("%02X ", report[i]);
sayzyas 32:e6717a485577 120 printf("\r\n\r\n");
sayzyas 32:e6717a485577 121 #endif
sayzyas 32:e6717a485577 122 if (onUpdate) {
sayzyas 33:86c22c0c8aae 123 // (*onUpdate)(report[0], report[1], report[5], report[6]);
sayzyas 33:86c22c0c8aae 124 (*onUpdate)(
sayzyas 33:86c22c0c8aae 125 report[0],
sayzyas 33:86c22c0c8aae 126 report[1],
sayzyas 33:86c22c0c8aae 127 report[2],
sayzyas 33:86c22c0c8aae 128 report[3],
sayzyas 33:86c22c0c8aae 129 report[4],
sayzyas 33:86c22c0c8aae 130 report[5],
sayzyas 33:86c22c0c8aae 131 report[6],
sayzyas 33:86c22c0c8aae 132 report[7],
sayzyas 33:86c22c0c8aae 133 report[8],
sayzyas 33:86c22c0c8aae 134 report[9],
sayzyas 33:86c22c0c8aae 135 report[10],
sayzyas 33:86c22c0c8aae 136 report[11],
sayzyas 33:86c22c0c8aae 137 report[12],
sayzyas 33:86c22c0c8aae 138 report[13],
sayzyas 33:86c22c0c8aae 139 report[14],
sayzyas 33:86c22c0c8aae 140 report[15]
sayzyas 33:86c22c0c8aae 141 );
sayzyas 32:e6717a485577 142 }
sayzyas 32:e6717a485577 143
sayzyas 32:e6717a485577 144 // update gamepad state
sayzyas 33:86c22c0c8aae 145 // btnX = report[0];
sayzyas 33:86c22c0c8aae 146 // btnY = report[1];
sayzyas 33:86c22c0c8aae 147 // btnABCD = report[5];
sayzyas 33:86c22c0c8aae 148 // btnSpecial = report[6];
sayzyas 33:86c22c0c8aae 149 btn00 = report[0];
sayzyas 33:86c22c0c8aae 150 btn01 = report[1];
sayzyas 33:86c22c0c8aae 151 btn02 = report[2];
sayzyas 33:86c22c0c8aae 152 btn03 = report[3];
sayzyas 33:86c22c0c8aae 153 btn04 = report[4];
sayzyas 33:86c22c0c8aae 154 btn05 = report[5];
sayzyas 33:86c22c0c8aae 155 btn06 = report[6];
sayzyas 33:86c22c0c8aae 156 btn07 = report[7];
sayzyas 33:86c22c0c8aae 157 btn08 = report[8];
sayzyas 33:86c22c0c8aae 158 btn09 = report[9];
sayzyas 33:86c22c0c8aae 159 btn10 = report[10];
sayzyas 33:86c22c0c8aae 160 btn11 = report[11];
sayzyas 33:86c22c0c8aae 161 btn12 = report[12];
sayzyas 33:86c22c0c8aae 162 btn13 = report[13];
sayzyas 33:86c22c0c8aae 163 btn14 = report[14];
sayzyas 33:86c22c0c8aae 164 btn15 = report[15];
sayzyas 32:e6717a485577 165
sayzyas 32:e6717a485577 166 if (len_listen > sizeof(report)) {
sayzyas 32:e6717a485577 167 len_listen = sizeof(report);
sayzyas 32:e6717a485577 168 }
sayzyas 32:e6717a485577 169
sayzyas 32:e6717a485577 170 if (dev)
sayzyas 32:e6717a485577 171 host->interruptRead(dev, int_in, report, len_listen, false);
sayzyas 32:e6717a485577 172 }
sayzyas 32:e6717a485577 173
sayzyas 32:e6717a485577 174 /*virtual*/ void USBHostGamepad::setVidPid(uint16_t vid, uint16_t pid)
sayzyas 32:e6717a485577 175 {
sayzyas 32:e6717a485577 176 // we don't check VID/PID for gamepad driver
sayzyas 32:e6717a485577 177 }
sayzyas 32:e6717a485577 178
sayzyas 32:e6717a485577 179 /*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 180 {
sayzyas 32:e6717a485577 181 if ((gamepad_intf == -1) &&
sayzyas 32:e6717a485577 182 (intf_class == HID_CLASS) &&
sayzyas 32:e6717a485577 183 (intf_subclass == 0x00) &&
sayzyas 32:e6717a485577 184 (intf_protocol == 0x00)) {
sayzyas 32:e6717a485577 185 gamepad_intf = intf_nb;
sayzyas 32:e6717a485577 186 return true;
sayzyas 32:e6717a485577 187 }
sayzyas 32:e6717a485577 188 return false;
sayzyas 32:e6717a485577 189 }
sayzyas 32:e6717a485577 190
sayzyas 32:e6717a485577 191 /*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 192 {
sayzyas 32:e6717a485577 193 if (intf_nb == gamepad_intf) {
sayzyas 32:e6717a485577 194 if (type == INTERRUPT_ENDPOINT && dir == IN) {
sayzyas 32:e6717a485577 195 gamepad_device_found = true;
sayzyas 32:e6717a485577 196 return true;
sayzyas 32:e6717a485577 197 }
sayzyas 32:e6717a485577 198 }
sayzyas 32:e6717a485577 199 return false;
sayzyas 32:e6717a485577 200 }
sayzyas 32:e6717a485577 201
sayzyas 32:e6717a485577 202 USB_TYPE USBHostGamepad::getReportDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_rep_descr)
sayzyas 32:e6717a485577 203 {
sayzyas 32:e6717a485577 204 USB_TYPE t = host->controlRead( dev,
sayzyas 32:e6717a485577 205 USB_DEVICE_TO_HOST | USB_RECIPIENT_INTERFACE | USB_REQUEST_TYPE_STANDARD,
sayzyas 32:e6717a485577 206 HID_GET_DESCRIPTOR,
sayzyas 32:e6717a485577 207 0x2200,
sayzyas 32:e6717a485577 208 0, buf, max_len_buf);
sayzyas 32:e6717a485577 209 if (len_rep_descr)
sayzyas 32:e6717a485577 210 *len_rep_descr = max_len_buf;
sayzyas 32:e6717a485577 211
sayzyas 32:e6717a485577 212 return t;
sayzyas 32:e6717a485577 213 }
sayzyas 32:e6717a485577 214
sayzyas 32:e6717a485577 215 /*
sayzyas 32:e6717a485577 216 * HID Report Descriptor parser
sayzyas 32:e6717a485577 217 */
sayzyas 32:e6717a485577 218 bool USBHostGamepad::parseHidDescr()
sayzyas 32:e6717a485577 219 {
sayzyas 32:e6717a485577 220 bool ret = true;
sayzyas 32:e6717a485577 221 uint8_t *buf;
sayzyas 32:e6717a485577 222 uint16_t desclen = host->getLengthReportDescr();
sayzyas 32:e6717a485577 223
sayzyas 32:e6717a485577 224 //allocate report descriptor's buffer
sayzyas 32:e6717a485577 225 buf = (uint8_t *)malloc(desclen);
sayzyas 32:e6717a485577 226 if(buf == NULL){
sayzyas 32:e6717a485577 227 return false;
sayzyas 32:e6717a485577 228 }
sayzyas 32:e6717a485577 229 getReportDescriptor(dev, buf, desclen);
sayzyas 32:e6717a485577 230 #if (DEBUG > 3)
sayzyas 32:e6717a485577 231 USB_DBG("HID REPORT DESCRIPTOR:\r\n");
sayzyas 32:e6717a485577 232 for (int i = 0; i < desclen; i++)
sayzyas 32:e6717a485577 233 printf("%02X ", buf[i]);
sayzyas 32:e6717a485577 234 printf("\r\n\r\n");
sayzyas 32:e6717a485577 235 #endif
sayzyas 32:e6717a485577 236 if( buf[0] == 0x05 //Usage page
sayzyas 32:e6717a485577 237 && buf[1] == 0x01 //Generic Desktop
sayzyas 32:e6717a485577 238 && buf[2] == 0x09 //Usage
sayzyas 32:e6717a485577 239 ){
sayzyas 32:e6717a485577 240 if( buf[3] == 0x04 ){
sayzyas 33:86c22c0c8aae 241 USB_DBG("ゲームパッドです:");
sayzyas 32:e6717a485577 242 }else if( buf[3] == 0x05){
sayzyas 33:86c22c0c8aae 243 USB_DBG("ジョイスティックです:");
sayzyas 32:e6717a485577 244 }else{
sayzyas 32:e6717a485577 245 ret = false;
sayzyas 32:e6717a485577 246 }
sayzyas 32:e6717a485577 247 }
sayzyas 32:e6717a485577 248 free(buf);
sayzyas 32:e6717a485577 249 return ret;
sayzyas 32:e6717a485577 250 }
sayzyas 32:e6717a485577 251 //#endif