Fork to support Mouse boot protocol and steam controllers.

Fork of USBHOST by ST

Committer:
Louise Newberry
Date:
Thu Aug 31 21:36:56 2017 +0100
Revision:
11:ba29414a455e
Parent:
10:89cf0de5f793
Add control write to select boot mode as mice require this to
guarentee boot reports are selected.

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 10:89cf0de5f793 36 steam_device_found = false;
geekylou 10:89cf0de5f793 37 steam_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 10:89cf0de5f793 65 if (steam_device_found) {
geekylou 8:e57ccb876952 66 {
geekylou 9:6bbea1ccc9f8 67 printf("found!");
geekylou 8:e57ccb876952 68 /* As this is done in a specific thread
geekylou 8:e57ccb876952 69 * this lock is taken to avoid to process the device
geekylou 8:e57ccb876952 70 * disconnect in usb process during the device registering */
geekylou 8:e57ccb876952 71 USBHost::Lock Lock(host);
geekylou 10:89cf0de5f793 72 int_in = dev->getEndpoint(steam_intf, INTERRUPT_ENDPOINT, IN);
geekylou 8:e57ccb876952 73 if (!int_in)
geekylou 8:e57ccb876952 74 break;
geekylou 10:89cf0de5f793 75 USB_INFO("New SteamController device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, steam_intf);
geekylou 10:89cf0de5f793 76 dev->setName("Steam", steam_intf);
geekylou 10:89cf0de5f793 77 host->registerDriver(dev, steam_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 9:6bbea1ccc9f8 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 9:6bbea1ccc9f8 109 if (index>0) printf(" %x:%x %d\r\n",dev->getVid(), dev->getPid(),len_listen);
geekylou 9:6bbea1ccc9f8 110 }*/
geekylou 8:e57ccb876952 111
geekylou 8:e57ccb876952 112
geekylou 9:6bbea1ccc9f8 113 if ((len_listen !=0) && (report[2] == 1))
geekylou 9:6bbea1ccc9f8 114 {
geekylou 9:6bbea1ccc9f8 115 buttons_t = report[8] + (report[9] << 8) + (report[10] << 16); // << 4;
geekylou 9:6bbea1ccc9f8 116 x_t = report[17]; // report[16] lsb
geekylou 9:6bbea1ccc9f8 117 y_t = report[19]; // report[18] lsb
geekylou 9:6bbea1ccc9f8 118
geekylou 9:6bbea1ccc9f8 119 z_t = 0; //report[4];
geekylou 8:e57ccb876952 120
geekylou 9:6bbea1ccc9f8 121 right_pad_x = (report[21] << 8) + report[20];
geekylou 9:6bbea1ccc9f8 122 right_pad_y = (report[23] << 8) + report[22];
geekylou 8:e57ccb876952 123
geekylou 8:e57ccb876952 124 if (onUpdate) {
geekylou 8:e57ccb876952 125 (*onUpdate)(buttons_t, x_t, y_t, right_pad_x, right_pad_y);
geekylou 8:e57ccb876952 126 }
geekylou 8:e57ccb876952 127
geekylou 9:6bbea1ccc9f8 128 /* if (onButtonUpdate && (buttons != (report[0]))) {
geekylou 8:e57ccb876952 129 (*onButtonUpdate)(report[0]);
geekylou 8:e57ccb876952 130 }
geekylou 8:e57ccb876952 131
geekylou 8:e57ccb876952 132 if (onXUpdate && (x != report[1])) {
geekylou 8:e57ccb876952 133 (*onXUpdate)(x_t);
geekylou 8:e57ccb876952 134 }
geekylou 8:e57ccb876952 135
geekylou 8:e57ccb876952 136 if (onYUpdate && (y != report[2])) {
geekylou 8:e57ccb876952 137 (*onYUpdate)(y_t);
geekylou 8:e57ccb876952 138 }
geekylou 8:e57ccb876952 139
geekylou 8:e57ccb876952 140 if (onZUpdate && (z != report[3])) {
geekylou 8:e57ccb876952 141 (*onZUpdate)(z_t);
geekylou 9:6bbea1ccc9f8 142 }*/
geekylou 8:e57ccb876952 143
geekylou 8:e57ccb876952 144 // update mouse state
geekylou 8:e57ccb876952 145 buttons = buttons_t;
geekylou 8:e57ccb876952 146 x = x_t;
geekylou 8:e57ccb876952 147 y = y_t;
geekylou 8:e57ccb876952 148 z = z_t;
geekylou 8:e57ccb876952 149 }
geekylou 8:e57ccb876952 150 /* set again the maximum value */
geekylou 8:e57ccb876952 151 len_listen = int_in->getSize();
geekylou 8:e57ccb876952 152
geekylou 8:e57ccb876952 153 if (len_listen > sizeof(report)) {
geekylou 8:e57ccb876952 154 len_listen = sizeof(report);
geekylou 8:e57ccb876952 155 }
geekylou 8:e57ccb876952 156
geekylou 8:e57ccb876952 157 if (dev)
geekylou 8:e57ccb876952 158 host->interruptRead(dev, int_in, report, len_listen, false);
geekylou 8:e57ccb876952 159 }
geekylou 8:e57ccb876952 160
geekylou 8:e57ccb876952 161 /*virtual*/ void USBHostSteamController::setVidPid(uint16_t vid, uint16_t pid)
geekylou 8:e57ccb876952 162 {
geekylou 8:e57ccb876952 163 // we don't check VID/PID for mouse driver
geekylou 8:e57ccb876952 164 }
geekylou 8:e57ccb876952 165
geekylou 8:e57ccb876952 166 /*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 167 {
geekylou 10:89cf0de5f793 168 //printf("intf_nb %d (%d) intf_class %x intf_subclass %x intf_protocol %x\r\n", intf_nb, steam_intf, intf_class,intf_subclass, intf_protocol);
geekylou 8:e57ccb876952 169
geekylou 10:89cf0de5f793 170 if ((steam_intf == -1) &&
geekylou 8:e57ccb876952 171 (intf_class == HID_CLASS) &&
geekylou 8:e57ccb876952 172 (intf_subclass == 0x00) &&
geekylou 8:e57ccb876952 173 (intf_protocol == 0x00)) {
geekylou 10:89cf0de5f793 174 steam_intf = intf_nb;
geekylou 9:6bbea1ccc9f8 175
geekylou 9:6bbea1ccc9f8 176 printf("true!");
geekylou 8:e57ccb876952 177 return true;
geekylou 8:e57ccb876952 178 }
geekylou 8:e57ccb876952 179 return false;
geekylou 8:e57ccb876952 180 }
geekylou 8:e57ccb876952 181
geekylou 8:e57ccb876952 182 /*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 183 {
geekylou 10:89cf0de5f793 184 if (intf_nb == steam_intf) {
geekylou 8:e57ccb876952 185 if (type == INTERRUPT_ENDPOINT && dir == IN) {
geekylou 10:89cf0de5f793 186 steam_device_found = true;
geekylou 8:e57ccb876952 187 return true;
geekylou 8:e57ccb876952 188 }
geekylou 8:e57ccb876952 189 }
geekylou 8:e57ccb876952 190 return false;
geekylou 8:e57ccb876952 191 }
geekylou 8:e57ccb876952 192
geekylou 8:e57ccb876952 193 #endif