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
Diff: USBHostXpad.cpp
- Revision:
- 1:5bb153989f33
- Parent:
- 0:bd0f6bf72a8b
- Child:
- 2:2749f4e649db
diff -r bd0f6bf72a8b -r 5bb153989f33 USBHostXpad.cpp --- a/USBHostXpad.cpp Tue Dec 10 06:50:37 2013 +0000 +++ b/USBHostXpad.cpp Wed Dec 11 04:11:04 2013 +0000 @@ -5,10 +5,8 @@ * * VID=0x045e PID=0x0719 * - * Note: 2012-12-10 - * The library has some problems. - * - X-logo lamp remains flickering. - * - probe() function is irresponsible. + * Reference: + * https://github.com/Grumbel/xboxdrv/blob/master/PROTOCOL */ #include "USBHostXpad.h" @@ -57,7 +55,6 @@ break; if (xpad_device_found) { - xpad_device_found = false; int_in = dev->getEndpoint(xpad_intf, INTERRUPT_ENDPOINT, IN); int_out = dev->getEndpoint(xpad_intf, INTERRUPT_ENDPOINT, OUT); @@ -68,30 +65,17 @@ 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); - int_in->attach(this, &USBHostXpad::rxHandler); - probe(0x00, 0x00, 0x08, 0x40); - probe(0x01, 0x03, 0x09, 0x01); - probe(0x01, 0x03, 0x08, 0x01); - probe(0x01, 0x03, 0x09, 0x00); - probe(0x01, 0x03, 0x09, 0x01); - probe(0x01, 0x03, 0x08, 0x01); - probe(0x01, 0x03, 0x09, 0x00); - probe(0x01, 0x03, 0x09, 0x01); - probe(0x01, 0x03, 0x08, 0x01); - probe(0x01, 0x03, 0x09, 0x00); - probe(0x01, 0x03, 0x09, 0x01); - probe(0x01, 0x03, 0x08, 0x01); - probe(0x01, 0x03, 0x09, 0x00); - host->interruptRead(dev, int_in, report, int_in->getSize(), false); + Thread::wait(100); + led(XPAD_LED_OFF); dev_connected = true; -// USB_INFO("RETURN TRUE"); return true; } - } //if() - } //for() -// USB_INFO("RETURN FALSE"); + } + } init(); return false; } @@ -100,28 +84,37 @@ int len_listen = int_in->getSize(); int len = int_in->getLengthTransferred(); - USB_INFO("rxHandler len:%d data:%02x %02x", len, report[0], report[1]); +/* for (int i = 0; i < len_listen; i ++) { std::printf(" %02x", report[i]); } std::printf("\r\n"); - +*/ if (report[0] == 0x08 && report[1] == 0x80) { - probe(0x00, 0x00, 0x00, 0x40); + // Connection Status Messages + send(0x00, 0x00, 0x00, 0x40); goto exit; } else if (report[0] == 0x00 && report[1] == 0x0f) { - probe(0x00, 0x00, 0x08, 0x46); - probe(0x00, 0x00, 0x00, 0x40); + // 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] == 0x0f) { - // + if (report[0] == 0x00 && report[1] == 0x00 && report[2] == 0x00 && report[3] == 0xf0) { + // Battery Full ? goto exit; } else - if (report[0] != 0x00 || !(report[1] & 1)) { // Check if it's the correct report - the controller also sends different status reports + 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]; @@ -172,44 +165,55 @@ return false; } -void USBHostXpad::poll () +void USBHostXpad::restart () { - probe(0x08, 0x00, 0x0f, 0xc0); - probe(0x08, 0x00, 0x0f, 0xc0); - probe(0x08, 0x00, 0x0f, 0xc0); - probe(0x08, 0x00, 0x0f, 0xc0); + send(0x08, 0x00, 0x0f, 0xc0); + send(0x08, 0x00, 0x0f, 0xc0); + send(0x08, 0x00, 0x0f, 0xc0); + send(0x08, 0x00, 0x0f, 0xc0); } -bool USBHostXpad::probe(int val1, int val2, int val3, int val4) +bool USBHostXpad::send(int val1, int val2, int val3, int val4) { - unsigned char bdata[32]; - memset(bdata, 0, sizeof(bdata)); - bdata[0] = val1; - bdata[1] = val2; - bdata[2] = val3; - bdata[3] = val4; + unsigned char odata[32]; + memset(odata, 0, sizeof(odata)); + odata[0] = val1; + odata[1] = val2; + odata[2] = val3; + odata[3] = val4; + if (dev) - host->interruptWrite(dev, int_out, bdata, 12, false); + if (host->interruptWrite(dev, int_out, odata, 12) == USB_TYPE_ERROR) { + init(); + return false; + } return true; } -bool USBHostXpad::effect(uint8_t strong, uint8_t weak) +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; +} - odata[0] = 0x00; +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[4] = 0x00; - odata[5] = strong; - odata[6] = weak; - odata[7] = 0x00; - odata[8] = 0x00; - odata[9] = 0x00; - odata[10] = 0x00; - odata[11] = 0x00; - host->interruptWrite(dev, int_in, odata, 12, false); + 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; }