z ysaito / USBHost2

Dependencies:   FATFileSystem2 mbed-rtos

Fork of USBHost by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBHostGamepad.cpp Source File

USBHostGamepad.cpp

00001 /* mbed USBHost Gamepad driver sample
00002  * Copyright (c) 2014 Yuuichi Akagawa
00003  *
00004  * modified from mbed USBHostMouse
00005  *
00006  * mbed USBHost Library
00007  * Copyright (c) 2006-2013 ARM Limited
00008  *
00009  * Licensed under the Apache License, Version 2.0 (the "License");
00010  * you may not use this file except in compliance with the License.
00011  * You may obtain a copy of the License at
00012  *
00013  *     http://www.apache.org/licenses/LICENSE-2.0
00014  *
00015  * Unless required by applicable law or agreed to in writing, software
00016  * distributed under the License is distributed on an "AS IS" BASIS,
00017  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00018  * See the License for the specific language governing permissions and
00019  * limitations under the License.
00020  * Refer to following URL: 
00021  * https://developer.mbed.org/users/YuuichiAkagawa/code/USBHostGamepad/file/7345e2afa41e/USBHostGamepad.cpp
00022  */
00023 #include "USBHostGamepad.h"
00024 //#if USBHOST_GAMEPAD
00025 
00026 USBHostGamepad::USBHostGamepad() {
00027     host = USBHost::getHostInst();
00028     init();
00029 }
00030 
00031 void USBHostGamepad::init() {
00032     dev = NULL;
00033     int_in = NULL;
00034     onUpdate = NULL;
00035     report_id = 0;
00036     dev_connected = false;
00037     gamepad_device_found = false;
00038     gamepad_intf = -1;
00039 
00040     btnX = 0;
00041     btnY = 0;
00042     btnABCD = 0;
00043     btnSpecial = 0;
00044 
00045     btn00 = 0;
00046     btn01 = 1;
00047     btn02 = 2;
00048     btn03 = 3;
00049     btn04 = 4;
00050     btn05 = 5;
00051     btn06 = 6;
00052     btn07 = 7;
00053     btn08 = 8;
00054     btn09 = 9;
00055     btn01 = 10;
00056     btn11 = 11;
00057     btn12 = 12;
00058     btn13 = 13;
00059     btn14 = 14;
00060     btn15 = 15;
00061 }
00062 
00063 bool USBHostGamepad::connected() {
00064     return dev_connected;
00065 }
00066 
00067 bool USBHostGamepad::connect() {
00068     int len_listen;
00069 
00070     if (dev_connected) {
00071         return true;
00072     }
00073 
00074     for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
00075         if ((dev = host->getDevice(i)) != NULL) {
00076 
00077             if(host->enumerate(dev, this))
00078                 break;
00079 
00080             if (gamepad_device_found) {
00081 
00082                 int_in = dev->getEndpoint(gamepad_intf, INTERRUPT_ENDPOINT, IN);
00083                 if (!int_in)
00084                     break;
00085 
00086                 gamePad_VID = dev->getVid();
00087                 gamePad_PID = dev->getPid();
00088                 
00089              //   USB_INFO("New Gamepad/Joystick device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, gamepad_intf);
00090                 USB_INFO("New Gamepad/Joystick device: VID:%04x PID:%04x [dev: %p - intf: %d]", gamePad_VID, gamePad_PID, dev, gamepad_intf);
00091 #if DEBUG > 3
00092                 //Parse HID Report Descriptor
00093                 parseHidDescr();
00094 #endif
00095                 dev->setName("Gamepad", gamepad_intf);
00096                 host->registerDriver(dev, gamepad_intf, this, &USBHostGamepad::init);
00097 
00098                 int_in->attach(this, &USBHostGamepad::rxHandler);
00099                 len_listen = int_in->getSize();
00100                 if (len_listen > sizeof(report)) {
00101                     len_listen = sizeof(report);
00102                 }
00103                 host->interruptRead(dev, int_in, report, len_listen, false);
00104 
00105                 dev_connected = true;
00106                 return true;
00107             }
00108         }
00109     }
00110     init();
00111     return false;
00112 }
00113 
00114 void USBHostGamepad::rxHandler() {
00115     int len_listen = int_in->getSize();
00116 //    printf("GamePad Length=%dyryn", len_listen);
00117 #if DEBUG > 3
00118     USB_DBG("USBHostGamepad::rxHandler() len_listen=%d\r\n", len_listen);
00119       for (int i = 0; i < len_listen; i++){
00120           printf("%02X ", report[i]);
00121       }
00122       printf("\r\n\r\n");
00123 #endif
00124     if (onUpdate) {
00125 //        (*onUpdate)(report[0], report[1], report[5], report[6]);
00126         (*onUpdate)(
00127             report[0], 
00128             report[1], 
00129             report[2], 
00130             report[3], 
00131             report[4], 
00132             report[5], 
00133             report[6], 
00134             report[7], 
00135             report[8], 
00136             report[9], 
00137             report[10], 
00138             report[11], 
00139             report[12],
00140             report[13],
00141             report[14],
00142             report[15],
00143             dev->getVid(),
00144             dev->getPid()
00145             
00146         );
00147     }
00148 
00149     // update gamepad state
00150 //   btnX       = report[0];
00151 //    btnY       = report[1];
00152 //    btnABCD    = report[5];
00153 //    btnSpecial = report[6];
00154       btn00 = report[0];
00155       btn01 = report[1];
00156       btn02 = report[2];
00157       btn03 = report[3];
00158       btn04 = report[4];
00159       btn05 = report[5];
00160       btn06 = report[6];
00161       btn07 = report[7];
00162       btn08 = report[8];
00163       btn09 = report[9];
00164       btn10 = report[10];
00165       btn11 = report[11];
00166       btn12 = report[12];
00167       btn13 = report[13];
00168       btn14 = report[14];
00169       btn15 = report[15];
00170       
00171  //     gamePad_VID = dev->getVid();
00172  //     gamePad_PID = dev->getPid();      
00173 
00174     if (len_listen > sizeof(report)) {
00175         len_listen = sizeof(report);
00176     }
00177 
00178     if (dev)
00179         host->interruptRead(dev, int_in, report, len_listen, false);
00180 }
00181 
00182 /*virtual*/ void USBHostGamepad::setVidPid(uint16_t vid, uint16_t pid)
00183 {
00184     // we don't check VID/PID for gamepad driver
00185 }
00186 
00187 /*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
00188 {
00189     if ((gamepad_intf == -1) &&
00190         (intf_class == HID_CLASS) &&
00191         (intf_subclass == 0x00) &&
00192         (intf_protocol == 0x00)) {
00193         gamepad_intf = intf_nb;
00194         return true;
00195     }
00196     return false;
00197 }
00198 
00199 /*virtual*/ bool USBHostGamepad::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
00200 {
00201     if (intf_nb == gamepad_intf) {
00202         if (type == INTERRUPT_ENDPOINT && dir == IN) {
00203             gamepad_device_found = true;
00204             return true;
00205         }
00206     }
00207     return false;
00208 }
00209 
00210 USB_TYPE USBHostGamepad::getReportDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_rep_descr)
00211 {
00212     USB_TYPE t = host->controlRead(  dev,
00213                          USB_DEVICE_TO_HOST | USB_RECIPIENT_INTERFACE | USB_REQUEST_TYPE_STANDARD,
00214                          HID_GET_DESCRIPTOR,
00215                          0x2200,
00216                          0, buf, max_len_buf);
00217     if (len_rep_descr)
00218         *len_rep_descr = max_len_buf;
00219 
00220     return t;
00221 }
00222 
00223 /*
00224  * HID Report Descriptor parser
00225  */ 
00226 bool USBHostGamepad::parseHidDescr()
00227 {
00228     bool ret = true;
00229     uint8_t *buf;
00230     uint16_t desclen = host->getLengthReportDescr();
00231 
00232     //allocate report descriptor's buffer
00233     buf = (uint8_t *)malloc(desclen);
00234     if(buf == NULL){
00235         return false;
00236     }
00237     getReportDescriptor(dev, buf, desclen);
00238   #if (DEBUG > 3)
00239       USB_DBG("HID REPORT DESCRIPTOR:\r\n");
00240       for (int i = 0; i < desclen; i++)
00241           printf("%02X ", buf[i]);
00242       printf("\r\n\r\n");
00243   #endif
00244   if(  buf[0] == 0x05 //Usage page
00245     && buf[1] == 0x01 //Generic Desktop
00246     && buf[2] == 0x09 //Usage
00247     ){
00248         if( buf[3] == 0x04 ){
00249             USB_DBG("This is GamePad:");
00250         }else if( buf[3] == 0x05){
00251             USB_DBG("This is JoyStick:");
00252         }else{
00253             ret = false;
00254         }
00255     }
00256     free(buf);
00257     return ret;
00258 }
00259 //#endif