Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FATFileSystem mbed-rtos
Fork of USBHost by
USBHostHID/USBHostGamepad.cpp
- Committer:
- sayzyas
- Date:
- 2016-11-04
- Revision:
- 42:366a9be2060e
File content as of revision 42:366a9be2060e:
/* mbed USBHost Gamepad driver sample
* Copyright (c) 2014 Yuuichi Akagawa
*
* modified from mbed USBHostMouse
*
* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Refer to following URL:
* https://developer.mbed.org/users/YuuichiAkagawa/code/USBHostGamepad/file/7345e2afa41e/USBHostGamepad.cpp
*/
#include "USBHostGamepad.h"
//#if USBHOST_GAMEPAD
USBHostGamepad::USBHostGamepad() {
host = USBHost::getHostInst();
init();
}
void USBHostGamepad::init() {
dev = NULL;
int_in = NULL;
onUpdate = NULL;
report_id = 0;
dev_connected = false;
gamepad_device_found = false;
gamepad_intf = -1;
btnX = 0;
btnY = 0;
btnABCD = 0;
btnSpecial = 0;
btn00 = 0;
btn01 = 1;
btn02 = 2;
btn03 = 3;
btn04 = 4;
btn05 = 5;
btn06 = 6;
btn07 = 7;
btn08 = 8;
btn09 = 9;
btn01 = 10;
btn11 = 11;
btn12 = 12;
btn13 = 13;
btn14 = 14;
btn15 = 15;
}
bool USBHostGamepad::connected() {
return dev_connected;
}
bool USBHostGamepad::connect() {
int len_listen;
if (dev_connected) {
return true;
}
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if ((dev = host->getDevice(i)) != NULL) {
if(host->enumerate(dev, this))
break;
if (gamepad_device_found) {
int_in = dev->getEndpoint(gamepad_intf, INTERRUPT_ENDPOINT, IN);
if (!int_in)
break;
gamePad_VID = dev->getVid();
gamePad_PID = dev->getPid();
// USB_INFO("New Gamepad/Joystick device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, gamepad_intf);
USB_INFO("New Gamepad/Joystick device: VID:%04x PID:%04x [dev: %p - intf: %d]", gamePad_VID, gamePad_PID, dev, gamepad_intf);
#if DEBUG > 3
//Parse HID Report Descriptor
parseHidDescr();
#endif
dev->setName("Gamepad", gamepad_intf);
host->registerDriver(dev, gamepad_intf, this, &USBHostGamepad::init);
int_in->attach(this, &USBHostGamepad::rxHandler);
len_listen = int_in->getSize();
if (len_listen > sizeof(report)) {
len_listen = sizeof(report);
}
host->interruptRead(dev, int_in, report, len_listen, false);
dev_connected = true;
return true;
}
}
}
init();
return false;
}
void USBHostGamepad::rxHandler() {
int len_listen = int_in->getSize();
// printf("GamePad Length=%dyryn", len_listen);
#if DEBUG > 3
USB_DBG("USBHostGamepad::rxHandler() len_listen=%d\r\n", len_listen);
for (int i = 0; i < len_listen; i++){
printf("%02X ", report[i]);
}
printf("\r\n\r\n");
#endif
if (onUpdate) {
// (*onUpdate)(report[0], report[1], report[5], report[6]);
(*onUpdate)(
report[0],
report[1],
report[2],
report[3],
report[4],
report[5],
report[6],
report[7],
report[8],
report[9],
report[10],
report[11],
report[12],
report[13],
report[14],
report[15],
dev->getVid(),
dev->getPid()
);
}
// update gamepad state
// btnX = report[0];
// btnY = report[1];
// btnABCD = report[5];
// btnSpecial = report[6];
btn00 = report[0];
btn01 = report[1];
btn02 = report[2];
btn03 = report[3];
btn04 = report[4];
btn05 = report[5];
btn06 = report[6];
btn07 = report[7];
btn08 = report[8];
btn09 = report[9];
btn10 = report[10];
btn11 = report[11];
btn12 = report[12];
btn13 = report[13];
btn14 = report[14];
btn15 = report[15];
// gamePad_VID = dev->getVid();
// gamePad_PID = dev->getPid();
if (len_listen > sizeof(report)) {
len_listen = sizeof(report);
}
if (dev)
host->interruptRead(dev, int_in, report, len_listen, false);
}
/*virtual*/ void USBHostGamepad::setVidPid(uint16_t vid, uint16_t pid)
{
// we don't check VID/PID for gamepad driver
}
/*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
{
if ((gamepad_intf == -1) &&
(intf_class == HID_CLASS) &&
(intf_subclass == 0x00) &&
(intf_protocol == 0x00)) {
gamepad_intf = intf_nb;
return true;
}
return false;
}
/*virtual*/ bool USBHostGamepad::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
{
if (intf_nb == gamepad_intf) {
if (type == INTERRUPT_ENDPOINT && dir == IN) {
gamepad_device_found = true;
return true;
}
}
return false;
}
USB_TYPE USBHostGamepad::getReportDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_rep_descr)
{
USB_TYPE t = host->controlRead( dev,
USB_DEVICE_TO_HOST | USB_RECIPIENT_INTERFACE | USB_REQUEST_TYPE_STANDARD,
HID_GET_DESCRIPTOR,
0x2200,
0, buf, max_len_buf);
if (len_rep_descr)
*len_rep_descr = max_len_buf;
return t;
}
/*
* HID Report Descriptor parser
*/
bool USBHostGamepad::parseHidDescr()
{
bool ret = true;
uint8_t *buf;
uint16_t desclen = host->getLengthReportDescr();
//allocate report descriptor's buffer
buf = (uint8_t *)malloc(desclen);
if(buf == NULL){
return false;
}
getReportDescriptor(dev, buf, desclen);
#if (DEBUG > 3)
USB_DBG("HID REPORT DESCRIPTOR:\r\n");
for (int i = 0; i < desclen; i++)
printf("%02X ", buf[i]);
printf("\r\n\r\n");
#endif
if( buf[0] == 0x05 //Usage page
&& buf[1] == 0x01 //Generic Desktop
&& buf[2] == 0x09 //Usage
){
if( buf[3] == 0x04 ){
USB_DBG("This is GamePad:");
}else if( buf[3] == 0x05){
USB_DBG("This is JoyStick:");
}else{
ret = false;
}
}
free(buf);
return ret;
}
//#endif
