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.
Fork of USBHostXpad by
USBHostXpad.cpp
- Committer:
- okini3939
- Date:
- 2013-12-11
- Revision:
- 1:5bb153989f33
- Parent:
- 0:bd0f6bf72a8b
- Child:
- 2:2749f4e649db
File content as of revision 1:5bb153989f33:
/* * Xbox 360 Wireless Controller for Windows library * for mbed USBHost library * Copyright (c) 2013 Hiroshi Suga * * VID=0x045e PID=0x0719 * * Reference: * https://github.com/Grumbel/xboxdrv/blob/master/PROTOCOL */ #include "USBHostXpad.h" #if 1 or USBHOST_XPAD #include "dbg.h" #define DEVICE_TO_HOST 0x80 #define HOST_TO_DEVICE 0x00 USBHostXpad::USBHostXpad() { host = USBHost::getHostInst(); init(); } void USBHostXpad::init() { dev_connected = false; dev = NULL; int_in = NULL; int_out = NULL; xpad_intf = -1; xpad_device_found = false; nb_ep = 0; } bool USBHostXpad::connected() { return dev_connected; } bool USBHostXpad::connect() { if (dev_connected) { return true; } for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { if ((dev = host->getDevice(i)) != NULL) { USB_DBG("Trying to connect MSD device\r\n"); if(host->enumerate(dev, this)) break; if (xpad_device_found) { int_in = dev->getEndpoint(xpad_intf, INTERRUPT_ENDPOINT, IN); int_out = dev->getEndpoint(xpad_intf, INTERRUPT_ENDPOINT, OUT); if (!int_in || !int_out) continue; USB_INFO("New MSD device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, xpad_intf); USB_INFO("endpoint in:%08x out:%08x", int_in, int_out); dev->setName("XPAD", xpad_intf); host->registerDriver(dev, xpad_intf, this, &USBHostXpad::init); int_in->attach(this, &USBHostXpad::rxHandler); host->interruptRead(dev, int_in, report, int_in->getSize(), false); Thread::wait(100); led(XPAD_LED_OFF); dev_connected = true; return true; } } } init(); return false; } void USBHostXpad::rxHandler() { int len_listen = int_in->getSize(); int len = int_in->getLengthTransferred(); /* for (int i = 0; i < len_listen; i ++) { std::printf(" %02x", report[i]); } std::printf("\r\n"); */ if (report[0] == 0x08 && report[1] == 0x80) { // Connection Status Messages send(0x00, 0x00, 0x00, 0x40); goto exit; } else if (report[0] == 0x00 && report[1] == 0x0f) { // On connection led(XPAD_LED1_ON); send(0x00, 0x00, 0x00, 0x40); goto exit; } else if (report[0] == 0x00 && report[1] == 0xf8) { // Battery Status Msg (maybe) goto exit; } else if (report[0] == 0x00 && report[1] == 0x00 && report[2] == 0x00 && report[3] == 0xf0) { // Battery Full ? goto exit; } else if (report[0] != 0x00 || report[1] != 0x01 || report[2] != 0x00 || report[3] != 0xf0) { // Unknown USB_INFO("rxHandler len:%d data:%02x %02x %02x %02x", len, report[0], report[1], report[2], report[3]); goto exit; } // Event data buttons = ((uint32_t)report[7] << 8) | report[6]; trigger_l = report[8]; trigger_r = report[9]; stick_lx = ((int16_t)report[11] << 8) | report[10]; stick_ly = ((int16_t)report[13] << 8) | report[12]; stick_rx = ((int16_t)report[15] << 8) | report[14]; stick_ry = ((int16_t)report[17] << 8) | report[16]; if (onUpdate) { (*onUpdate)(buttons, stick_lx, stick_ly, stick_rx, stick_ry, trigger_l, trigger_r); } exit: if (dev) host->interruptRead(dev, int_in, report, len_listen, false); } /*virtual*/ void USBHostXpad::setVidPid(uint16_t vid, uint16_t pid) { // we don't check VID/PID for MSD driver } /*virtual*/ bool USBHostXpad::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 { USB_INFO("parseInterface class:%02x subclass:%02x protocol:%02x [nb: %d - intf: %d]", intf_class, intf_subclass, intf_protocol, intf_nb, xpad_intf); if ((xpad_intf == -1) && (intf_class == 0xff) && (intf_subclass == 0x5d) && (intf_protocol == 0x81)) { xpad_intf = intf_nb; return true; } return false; } /*virtual*/ bool USBHostXpad::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used { USB_INFO("useEndpoint nb:%d type:%d dir:%d", intf_nb, type, dir); if (intf_nb == xpad_intf) { if (type == INTERRUPT_ENDPOINT) { nb_ep ++; if (nb_ep == 2) xpad_device_found = true; return true; } } return false; } void USBHostXpad::restart () { send(0x08, 0x00, 0x0f, 0xc0); send(0x08, 0x00, 0x0f, 0xc0); send(0x08, 0x00, 0x0f, 0xc0); send(0x08, 0x00, 0x0f, 0xc0); } bool USBHostXpad::send(int val1, int val2, int val3, int val4) { unsigned char odata[32]; memset(odata, 0, sizeof(odata)); odata[0] = val1; odata[1] = val2; odata[2] = val3; odata[3] = val4; if (dev) if (host->interruptWrite(dev, int_out, odata, 12) == USB_TYPE_ERROR) { init(); return false; } return true; } bool USBHostXpad::led(int cmd) { unsigned char odata[32]; memset(odata, 0, sizeof(odata)); odata[2] = 0x08; odata[3] = 0x40 + (cmd % 0x0e); if (dev) if (host->interruptWrite(dev, int_out, odata, 12) == USB_TYPE_ERROR) return false; return true; } bool USBHostXpad::rumble(uint8_t large, uint8_t small) { unsigned char odata[32]; memset(odata, 0, sizeof(odata)); odata[1] = 0x01; odata[2] = 0x0f; odata[3] = 0xc0; odata[5] = large; odata[6] = small; if (dev) if (host->interruptWrite(dev, int_out, odata, 12) == USB_TYPE_ERROR) return false; return true; } #endif