Fork to support Mouse boot protocol and steam controllers.

Fork of USBHOST by ST

Committer:
geekylou
Date:
Sat Aug 19 19:47:53 2017 +0000
Revision:
8:e57ccb876952
Child:
9:6bbea1ccc9f8
Add steam controller support.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
geekylou 8:e57ccb876952 1 /* mbed USBHost Library
geekylou 8:e57ccb876952 2 * Copyright (c) 2006-2013 ARM Limited
geekylou 8:e57ccb876952 3 *
geekylou 8:e57ccb876952 4 * Licensed under the Apache License, Version 2.0 (the "License");
geekylou 8:e57ccb876952 5 * you may not use this file except in compliance with the License.
geekylou 8:e57ccb876952 6 * You may obtain a copy of the License at
geekylou 8:e57ccb876952 7 *
geekylou 8:e57ccb876952 8 * http://www.apache.org/licenses/LICENSE-2.0
geekylou 8:e57ccb876952 9 *
geekylou 8:e57ccb876952 10 * Unless required by applicable law or agreed to in writing, software
geekylou 8:e57ccb876952 11 * distributed under the License is distributed on an "AS IS" BASIS,
geekylou 8:e57ccb876952 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
geekylou 8:e57ccb876952 13 * See the License for the specific language governing permissions and
geekylou 8:e57ccb876952 14 * limitations under the License.
geekylou 8:e57ccb876952 15 */
geekylou 8:e57ccb876952 16
geekylou 8:e57ccb876952 17 #include "USBHostSteamController.h"
geekylou 8:e57ccb876952 18
geekylou 8:e57ccb876952 19 #if USBHOST_STEAM
geekylou 8:e57ccb876952 20
geekylou 8:e57ccb876952 21 USBHostSteamController::USBHostSteamController() {
geekylou 8:e57ccb876952 22 host = USBHost::getHostInst();
geekylou 8:e57ccb876952 23 init();
geekylou 8:e57ccb876952 24 }
geekylou 8:e57ccb876952 25
geekylou 8:e57ccb876952 26 void USBHostSteamController::init() {
geekylou 8:e57ccb876952 27 dev = NULL;
geekylou 8:e57ccb876952 28 int_in = NULL;
geekylou 8:e57ccb876952 29 onUpdate = NULL;
geekylou 8:e57ccb876952 30 onButtonUpdate = NULL;
geekylou 8:e57ccb876952 31 onXUpdate = NULL;
geekylou 8:e57ccb876952 32 onYUpdate = NULL;
geekylou 8:e57ccb876952 33 onZUpdate = NULL;
geekylou 8:e57ccb876952 34 report_id = 0;
geekylou 8:e57ccb876952 35 dev_connected = false;
geekylou 8:e57ccb876952 36 mouse_device_found = false;
geekylou 8:e57ccb876952 37 mouse_intf = -1;
geekylou 8:e57ccb876952 38
geekylou 8:e57ccb876952 39 buttons = 0;
geekylou 8:e57ccb876952 40 x = 0;
geekylou 8:e57ccb876952 41 y = 0;
geekylou 8:e57ccb876952 42 z = 0;
geekylou 8:e57ccb876952 43
geekylou 8:e57ccb876952 44 right_pad_x = 0;
geekylou 8:e57ccb876952 45 right_pad_y = 0;
geekylou 8:e57ccb876952 46 }
geekylou 8:e57ccb876952 47
geekylou 8:e57ccb876952 48 bool USBHostSteamController::connected() {
geekylou 8:e57ccb876952 49 return dev_connected;
geekylou 8:e57ccb876952 50 }
geekylou 8:e57ccb876952 51
geekylou 8:e57ccb876952 52 bool USBHostSteamController::connect()
geekylou 8:e57ccb876952 53 {
geekylou 8:e57ccb876952 54 int len_listen;
geekylou 8:e57ccb876952 55
geekylou 8:e57ccb876952 56 if (dev_connected) {
geekylou 8:e57ccb876952 57 return true;
geekylou 8:e57ccb876952 58 }
geekylou 8:e57ccb876952 59
geekylou 8:e57ccb876952 60 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
geekylou 8:e57ccb876952 61 if ((dev = host->getDevice(i)) != NULL) {
geekylou 8:e57ccb876952 62
geekylou 8:e57ccb876952 63 if(host->enumerate(dev, this))
geekylou 8:e57ccb876952 64 break;
geekylou 8:e57ccb876952 65 if (mouse_device_found) {
geekylou 8:e57ccb876952 66 {
geekylou 8:e57ccb876952 67 /* As this is done in a specific thread
geekylou 8:e57ccb876952 68 * this lock is taken to avoid to process the device
geekylou 8:e57ccb876952 69 * disconnect in usb process during the device registering */
geekylou 8:e57ccb876952 70 USBHost::Lock Lock(host);
geekylou 8:e57ccb876952 71 int_in = dev->getEndpoint(mouse_intf, INTERRUPT_ENDPOINT, IN);
geekylou 8:e57ccb876952 72 if (!int_in)
geekylou 8:e57ccb876952 73 break;
geekylou 8:e57ccb876952 74
geekylou 8:e57ccb876952 75 USB_INFO("New Mouse device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, mouse_intf);
geekylou 8:e57ccb876952 76 dev->setName("Mouse", mouse_intf);
geekylou 8:e57ccb876952 77 host->registerDriver(dev, mouse_intf, this, &USBHostSteamController::init);
geekylou 8:e57ccb876952 78
geekylou 8:e57ccb876952 79 int_in->attach(this, &USBHostSteamController::rxHandler);
geekylou 8:e57ccb876952 80 len_listen = int_in->getSize();
geekylou 8:e57ccb876952 81 if (len_listen > sizeof(report)) {
geekylou 8:e57ccb876952 82 len_listen = sizeof(report);
geekylou 8:e57ccb876952 83 }
geekylou 8:e57ccb876952 84 }
geekylou 8:e57ccb876952 85 int ret=host->interruptRead(dev, int_in, report, len_listen, false);
geekylou 8:e57ccb876952 86 MBED_ASSERT((ret==USB_TYPE_OK) || (ret ==USB_TYPE_PROCESSING) || (ret == USB_TYPE_FREE));
geekylou 8:e57ccb876952 87 if ((ret==USB_TYPE_OK) || (ret ==USB_TYPE_PROCESSING))
geekylou 8:e57ccb876952 88 dev_connected = true;
geekylou 8:e57ccb876952 89 if (ret == USB_TYPE_FREE)
geekylou 8:e57ccb876952 90 dev_connected = false;
geekylou 8:e57ccb876952 91 return true;
geekylou 8:e57ccb876952 92 }
geekylou 8:e57ccb876952 93 }
geekylou 8:e57ccb876952 94 }
geekylou 8:e57ccb876952 95 init();
geekylou 8:e57ccb876952 96 return false;
geekylou 8:e57ccb876952 97 }
geekylou 8:e57ccb876952 98
geekylou 8:e57ccb876952 99 void USBHostSteamController::rxHandler() {
geekylou 8:e57ccb876952 100 int len_listen = int_in->getLengthTransferred();
geekylou 8:e57ccb876952 101 int buttons_t, x_t, y_t, z_t;
geekylou 8:e57ccb876952 102 {
geekylou 8:e57ccb876952 103 int index;
geekylou 8:e57ccb876952 104 for (index=0;index < len_listen; index++)
geekylou 8:e57ccb876952 105 {
geekylou 8:e57ccb876952 106 printf("%2x ",report[index]);
geekylou 8:e57ccb876952 107 }
geekylou 8:e57ccb876952 108
geekylou 8:e57ccb876952 109 if (index>0) printf(" %x:%x \r\n",dev->getVid(), dev->getPid());
geekylou 8:e57ccb876952 110 }
geekylou 8:e57ccb876952 111
geekylou 8:e57ccb876952 112 if (report[2] != 1)
geekylou 8:e57ccb876952 113 {
geekylou 8:e57ccb876952 114 return;
geekylou 8:e57ccb876952 115 }
geekylou 8:e57ccb876952 116
geekylou 8:e57ccb876952 117 // We really should be parsing the pid report but this is a good workaround
geekylou 8:e57ccb876952 118 // for my wireless mouse for now!
geekylou 8:e57ccb876952 119
geekylou 8:e57ccb876952 120 buttons_t = report[8] + (report[9] << 8) + (report[10] << 16); // << 4;
geekylou 8:e57ccb876952 121 x_t = report[17]; // report[16] lsb
geekylou 8:e57ccb876952 122 y_t = report[19]; // report[18] lsb
geekylou 8:e57ccb876952 123
geekylou 8:e57ccb876952 124 z_t = 0; //report[4];
geekylou 8:e57ccb876952 125
geekylou 8:e57ccb876952 126 right_pad_x = (report[21] << 8) + report[20];
geekylou 8:e57ccb876952 127 right_pad_y = (report[23] << 8) + report[22];
geekylou 8:e57ccb876952 128
geekylou 8:e57ccb876952 129 if (len_listen !=0) {
geekylou 8:e57ccb876952 130
geekylou 8:e57ccb876952 131 if (onUpdate) {
geekylou 8:e57ccb876952 132 (*onUpdate)(buttons_t, x_t, y_t, right_pad_x, right_pad_y);
geekylou 8:e57ccb876952 133 }
geekylou 8:e57ccb876952 134
geekylou 8:e57ccb876952 135 if (onButtonUpdate && (buttons != (report[0]))) {
geekylou 8:e57ccb876952 136 (*onButtonUpdate)(report[0]);
geekylou 8:e57ccb876952 137 }
geekylou 8:e57ccb876952 138
geekylou 8:e57ccb876952 139 if (onXUpdate && (x != report[1])) {
geekylou 8:e57ccb876952 140 (*onXUpdate)(x_t);
geekylou 8:e57ccb876952 141 }
geekylou 8:e57ccb876952 142
geekylou 8:e57ccb876952 143 if (onYUpdate && (y != report[2])) {
geekylou 8:e57ccb876952 144 (*onYUpdate)(y_t);
geekylou 8:e57ccb876952 145 }
geekylou 8:e57ccb876952 146
geekylou 8:e57ccb876952 147 if (onZUpdate && (z != report[3])) {
geekylou 8:e57ccb876952 148 (*onZUpdate)(z_t);
geekylou 8:e57ccb876952 149 }
geekylou 8:e57ccb876952 150
geekylou 8:e57ccb876952 151 // update mouse state
geekylou 8:e57ccb876952 152 buttons = buttons_t;
geekylou 8:e57ccb876952 153 x = x_t;
geekylou 8:e57ccb876952 154 y = y_t;
geekylou 8:e57ccb876952 155 z = z_t;
geekylou 8:e57ccb876952 156 }
geekylou 8:e57ccb876952 157 /* set again the maximum value */
geekylou 8:e57ccb876952 158 len_listen = int_in->getSize();
geekylou 8:e57ccb876952 159
geekylou 8:e57ccb876952 160 if (len_listen > sizeof(report)) {
geekylou 8:e57ccb876952 161 len_listen = sizeof(report);
geekylou 8:e57ccb876952 162 }
geekylou 8:e57ccb876952 163
geekylou 8:e57ccb876952 164 if (dev)
geekylou 8:e57ccb876952 165 host->interruptRead(dev, int_in, report, len_listen, false);
geekylou 8:e57ccb876952 166 }
geekylou 8:e57ccb876952 167
geekylou 8:e57ccb876952 168 /*virtual*/ void USBHostSteamController::setVidPid(uint16_t vid, uint16_t pid)
geekylou 8:e57ccb876952 169 {
geekylou 8:e57ccb876952 170 // we don't check VID/PID for mouse driver
geekylou 8:e57ccb876952 171 }
geekylou 8:e57ccb876952 172
geekylou 8:e57ccb876952 173 /*virtual*/ bool USBHostSteamController::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
geekylou 8:e57ccb876952 174 {
geekylou 8:e57ccb876952 175 //printf("intf_class %x intf_subclass %x intf_protocol %x\r\n", intf_class,intf_subclass, intf_protocol);
geekylou 8:e57ccb876952 176
geekylou 8:e57ccb876952 177 if ((mouse_intf == -1) &&
geekylou 8:e57ccb876952 178 (intf_class == HID_CLASS) &&
geekylou 8:e57ccb876952 179 (intf_subclass == 0x00) &&
geekylou 8:e57ccb876952 180 (intf_protocol == 0x00)) {
geekylou 8:e57ccb876952 181 mouse_intf = intf_nb;
geekylou 8:e57ccb876952 182 return true;
geekylou 8:e57ccb876952 183 }
geekylou 8:e57ccb876952 184 return false;
geekylou 8:e57ccb876952 185 }
geekylou 8:e57ccb876952 186
geekylou 8:e57ccb876952 187 /*virtual*/ bool USBHostSteamController::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
geekylou 8:e57ccb876952 188 {
geekylou 8:e57ccb876952 189 if (intf_nb == mouse_intf) {
geekylou 8:e57ccb876952 190 if (type == INTERRUPT_ENDPOINT && dir == IN) {
geekylou 8:e57ccb876952 191 mouse_device_found = true;
geekylou 8:e57ccb876952 192 return true;
geekylou 8:e57ccb876952 193 }
geekylou 8:e57ccb876952 194 }
geekylou 8:e57ccb876952 195 return false;
geekylou 8:e57ccb876952 196 }
geekylou 8:e57ccb876952 197
geekylou 8:e57ccb876952 198 #endif