USBHost modified for vmRideR2016b

Dependencies:   FATFileSystem mbed-rtos

Dependents:  

Fork of USBHost by mbed official

Committer:
JuanManuelAmador
Date:
Thu May 19 13:37:30 2016 +0000
Revision:
33:556baf244dc4
Previo cambios en autocalibracion.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JuanManuelAmador 33:556baf244dc4 1 /* mbed USBHost Library
JuanManuelAmador 33:556baf244dc4 2 * Copyright (c) 2006-2013 ARM Limited
JuanManuelAmador 33:556baf244dc4 3 *
JuanManuelAmador 33:556baf244dc4 4 * Licensed under the Apache License, Version 2.0 (the "License");
JuanManuelAmador 33:556baf244dc4 5 * you may not use this file except in compliance with the License.
JuanManuelAmador 33:556baf244dc4 6 * You may obtain a copy of the License at
JuanManuelAmador 33:556baf244dc4 7 *
JuanManuelAmador 33:556baf244dc4 8 * http://www.apache.org/licenses/LICENSE-2.0
JuanManuelAmador 33:556baf244dc4 9 *
JuanManuelAmador 33:556baf244dc4 10 * Unless required by applicable law or agreed to in writing, software
JuanManuelAmador 33:556baf244dc4 11 * distributed under the License is distributed on an "AS IS" BASIS,
JuanManuelAmador 33:556baf244dc4 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
JuanManuelAmador 33:556baf244dc4 13 * See the License for the specific language governing permissions and
JuanManuelAmador 33:556baf244dc4 14 * limitations under the License.
JuanManuelAmador 33:556baf244dc4 15 */
JuanManuelAmador 33:556baf244dc4 16
JuanManuelAmador 33:556baf244dc4 17 #include "USBHostHub.h"
JuanManuelAmador 33:556baf244dc4 18
JuanManuelAmador 33:556baf244dc4 19 #if MAX_HUB_NB
JuanManuelAmador 33:556baf244dc4 20
JuanManuelAmador 33:556baf244dc4 21 #include "USBHost.h"
JuanManuelAmador 33:556baf244dc4 22 #include "dbg.h"
JuanManuelAmador 33:556baf244dc4 23
JuanManuelAmador 33:556baf244dc4 24 #define GET_STATUS 0x00
JuanManuelAmador 33:556baf244dc4 25 #define CLEAR_FEATURE 0x01
JuanManuelAmador 33:556baf244dc4 26 #define GET_STATE 0x02
JuanManuelAmador 33:556baf244dc4 27 #define SET_FEATURE 0x03
JuanManuelAmador 33:556baf244dc4 28 #define GET_DESCRIPTOR 0x06
JuanManuelAmador 33:556baf244dc4 29
JuanManuelAmador 33:556baf244dc4 30 #define PORT_CONNECTION_FEATURE (0x00)
JuanManuelAmador 33:556baf244dc4 31 #define PORT_ENABLE_FEATURE (0x01)
JuanManuelAmador 33:556baf244dc4 32 #define PORT_RESET_FEATURE (0x04)
JuanManuelAmador 33:556baf244dc4 33 #define PORT_POWER_FEATURE (0x08)
JuanManuelAmador 33:556baf244dc4 34
JuanManuelAmador 33:556baf244dc4 35 #define C_PORT_CONNECTION_FEATURE (16)
JuanManuelAmador 33:556baf244dc4 36 #define C_PORT_ENABLE_FEATURE (17)
JuanManuelAmador 33:556baf244dc4 37 #define C_PORT_RESET_FEATURE (20)
JuanManuelAmador 33:556baf244dc4 38
JuanManuelAmador 33:556baf244dc4 39 #define PORT_CONNECTION (1 << 0)
JuanManuelAmador 33:556baf244dc4 40 #define PORT_ENABLE (1 << 1)
JuanManuelAmador 33:556baf244dc4 41 #define PORT_SUSPEND (1 << 2)
JuanManuelAmador 33:556baf244dc4 42 #define PORT_OVER_CURRENT (1 << 3)
JuanManuelAmador 33:556baf244dc4 43 #define PORT_RESET (1 << 4)
JuanManuelAmador 33:556baf244dc4 44 #define PORT_POWER (1 << 8)
JuanManuelAmador 33:556baf244dc4 45 #define PORT_LOW_SPEED (1 << 9)
JuanManuelAmador 33:556baf244dc4 46
JuanManuelAmador 33:556baf244dc4 47 #define C_PORT_CONNECTION (1 << 16)
JuanManuelAmador 33:556baf244dc4 48 #define C_PORT_ENABLE (1 << 17)
JuanManuelAmador 33:556baf244dc4 49 #define C_PORT_SUSPEND (1 << 18)
JuanManuelAmador 33:556baf244dc4 50 #define C_PORT_OVER_CURRENT (1 << 19)
JuanManuelAmador 33:556baf244dc4 51 #define C_PORT_RESET (1 << 20)
JuanManuelAmador 33:556baf244dc4 52
JuanManuelAmador 33:556baf244dc4 53 USBHostHub::USBHostHub() {
JuanManuelAmador 33:556baf244dc4 54 host = NULL;
JuanManuelAmador 33:556baf244dc4 55 init();
JuanManuelAmador 33:556baf244dc4 56 }
JuanManuelAmador 33:556baf244dc4 57
JuanManuelAmador 33:556baf244dc4 58 void USBHostHub::init() {
JuanManuelAmador 33:556baf244dc4 59 dev_connected = false;
JuanManuelAmador 33:556baf244dc4 60 dev = NULL;
JuanManuelAmador 33:556baf244dc4 61 int_in = NULL;
JuanManuelAmador 33:556baf244dc4 62 dev_connected = false;
JuanManuelAmador 33:556baf244dc4 63 hub_intf = -1;
JuanManuelAmador 33:556baf244dc4 64 hub_device_found = false;
JuanManuelAmador 33:556baf244dc4 65 nb_port = 0;
JuanManuelAmador 33:556baf244dc4 66 hub_characteristics = 0;
JuanManuelAmador 33:556baf244dc4 67
JuanManuelAmador 33:556baf244dc4 68 for (int i = 0; i < MAX_HUB_PORT; i++) {
JuanManuelAmador 33:556baf244dc4 69 device_children[i] = NULL;
JuanManuelAmador 33:556baf244dc4 70 }
JuanManuelAmador 33:556baf244dc4 71 }
JuanManuelAmador 33:556baf244dc4 72
JuanManuelAmador 33:556baf244dc4 73 void USBHostHub::setHost(USBHost * host_) {
JuanManuelAmador 33:556baf244dc4 74 host = host_;
JuanManuelAmador 33:556baf244dc4 75 }
JuanManuelAmador 33:556baf244dc4 76
JuanManuelAmador 33:556baf244dc4 77 bool USBHostHub::connected()
JuanManuelAmador 33:556baf244dc4 78 {
JuanManuelAmador 33:556baf244dc4 79 return dev_connected;
JuanManuelAmador 33:556baf244dc4 80 }
JuanManuelAmador 33:556baf244dc4 81
JuanManuelAmador 33:556baf244dc4 82 bool USBHostHub::connect(USBDeviceConnected * dev)
JuanManuelAmador 33:556baf244dc4 83 {
JuanManuelAmador 33:556baf244dc4 84 if (dev_connected) {
JuanManuelAmador 33:556baf244dc4 85 return true;
JuanManuelAmador 33:556baf244dc4 86 }
JuanManuelAmador 33:556baf244dc4 87
JuanManuelAmador 33:556baf244dc4 88 if(host->enumerate(dev, this)) {
JuanManuelAmador 33:556baf244dc4 89 init();
JuanManuelAmador 33:556baf244dc4 90 return false;
JuanManuelAmador 33:556baf244dc4 91 }
JuanManuelAmador 33:556baf244dc4 92
JuanManuelAmador 33:556baf244dc4 93 if (hub_device_found) {
JuanManuelAmador 33:556baf244dc4 94 this->dev = dev;
JuanManuelAmador 33:556baf244dc4 95
JuanManuelAmador 33:556baf244dc4 96 int_in = dev->getEndpoint(hub_intf, INTERRUPT_ENDPOINT, IN);
JuanManuelAmador 33:556baf244dc4 97
JuanManuelAmador 33:556baf244dc4 98 if (!int_in) {
JuanManuelAmador 33:556baf244dc4 99 init();
JuanManuelAmador 33:556baf244dc4 100 return false;
JuanManuelAmador 33:556baf244dc4 101 }
JuanManuelAmador 33:556baf244dc4 102
JuanManuelAmador 33:556baf244dc4 103 USB_INFO("New HUB: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, hub_intf);
JuanManuelAmador 33:556baf244dc4 104 dev->setName("Hub", hub_intf);
JuanManuelAmador 33:556baf244dc4 105 host->registerDriver(dev, hub_intf, this, &USBHostHub::disconnect);
JuanManuelAmador 33:556baf244dc4 106
JuanManuelAmador 33:556baf244dc4 107 int_in->attach(this, &USBHostHub::rxHandler);
JuanManuelAmador 33:556baf244dc4 108
JuanManuelAmador 33:556baf244dc4 109 // get HUB descriptor
JuanManuelAmador 33:556baf244dc4 110 host->controlRead( dev,
JuanManuelAmador 33:556baf244dc4 111 USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS,
JuanManuelAmador 33:556baf244dc4 112 GET_DESCRIPTOR,
JuanManuelAmador 33:556baf244dc4 113 0x29 << 8, 0, buf, sizeof(HubDescriptor));
JuanManuelAmador 33:556baf244dc4 114 nb_port = buf[2];
JuanManuelAmador 33:556baf244dc4 115 hub_characteristics = buf[3];
JuanManuelAmador 33:556baf244dc4 116
JuanManuelAmador 33:556baf244dc4 117 USB_DBG("Hub has %d port", nb_port);
JuanManuelAmador 33:556baf244dc4 118
JuanManuelAmador 33:556baf244dc4 119 for (uint8_t j = 1; j <= nb_port; j++) {
JuanManuelAmador 33:556baf244dc4 120 setPortFeature(PORT_POWER_FEATURE, j);
JuanManuelAmador 33:556baf244dc4 121 }
JuanManuelAmador 33:556baf244dc4 122 wait_ms(buf[5]*2);
JuanManuelAmador 33:556baf244dc4 123
JuanManuelAmador 33:556baf244dc4 124 host->interruptRead(dev, int_in, buf, 1, false);
JuanManuelAmador 33:556baf244dc4 125 dev_connected = true;
JuanManuelAmador 33:556baf244dc4 126 return true;
JuanManuelAmador 33:556baf244dc4 127 }
JuanManuelAmador 33:556baf244dc4 128
JuanManuelAmador 33:556baf244dc4 129 return false;
JuanManuelAmador 33:556baf244dc4 130 }
JuanManuelAmador 33:556baf244dc4 131
JuanManuelAmador 33:556baf244dc4 132 void USBHostHub::disconnect() {
JuanManuelAmador 33:556baf244dc4 133 init();
JuanManuelAmador 33:556baf244dc4 134 }
JuanManuelAmador 33:556baf244dc4 135
JuanManuelAmador 33:556baf244dc4 136 /*virtual*/ void USBHostHub::setVidPid(uint16_t vid, uint16_t pid)
JuanManuelAmador 33:556baf244dc4 137 {
JuanManuelAmador 33:556baf244dc4 138 // we don't check VID/PID for MSD driver
JuanManuelAmador 33:556baf244dc4 139 }
JuanManuelAmador 33:556baf244dc4 140
JuanManuelAmador 33:556baf244dc4 141 /*virtual*/ bool USBHostHub::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
JuanManuelAmador 33:556baf244dc4 142 {
JuanManuelAmador 33:556baf244dc4 143 if ((hub_intf == -1) &&
JuanManuelAmador 33:556baf244dc4 144 (intf_class == HUB_CLASS) &&
JuanManuelAmador 33:556baf244dc4 145 (intf_subclass == 0) &&
JuanManuelAmador 33:556baf244dc4 146 (intf_protocol == 0)) {
JuanManuelAmador 33:556baf244dc4 147 hub_intf = intf_nb;
JuanManuelAmador 33:556baf244dc4 148 return true;
JuanManuelAmador 33:556baf244dc4 149 }
JuanManuelAmador 33:556baf244dc4 150 return false;
JuanManuelAmador 33:556baf244dc4 151 }
JuanManuelAmador 33:556baf244dc4 152
JuanManuelAmador 33:556baf244dc4 153 /*virtual*/ bool USBHostHub::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
JuanManuelAmador 33:556baf244dc4 154 {
JuanManuelAmador 33:556baf244dc4 155 if (intf_nb == hub_intf) {
JuanManuelAmador 33:556baf244dc4 156 if ((type == INTERRUPT_ENDPOINT) && (dir == IN)) {
JuanManuelAmador 33:556baf244dc4 157 hub_device_found = true;
JuanManuelAmador 33:556baf244dc4 158 return true;
JuanManuelAmador 33:556baf244dc4 159 }
JuanManuelAmador 33:556baf244dc4 160 }
JuanManuelAmador 33:556baf244dc4 161 return false;
JuanManuelAmador 33:556baf244dc4 162 }
JuanManuelAmador 33:556baf244dc4 163
JuanManuelAmador 33:556baf244dc4 164 void USBHostHub::deviceConnected(USBDeviceConnected * dev) {
JuanManuelAmador 33:556baf244dc4 165 device_children[dev->getPort() - 1] = dev;
JuanManuelAmador 33:556baf244dc4 166 }
JuanManuelAmador 33:556baf244dc4 167
JuanManuelAmador 33:556baf244dc4 168 void USBHostHub::deviceDisconnected(USBDeviceConnected * dev) {
JuanManuelAmador 33:556baf244dc4 169 device_children[dev->getPort() - 1] = NULL;
JuanManuelAmador 33:556baf244dc4 170 }
JuanManuelAmador 33:556baf244dc4 171
JuanManuelAmador 33:556baf244dc4 172 void USBHostHub::hubDisconnected() {
JuanManuelAmador 33:556baf244dc4 173 for (uint8_t i = 0; i < MAX_HUB_PORT; i++) {
JuanManuelAmador 33:556baf244dc4 174 if (device_children[i] != NULL) {
JuanManuelAmador 33:556baf244dc4 175 host->freeDevice(device_children[i]);
JuanManuelAmador 33:556baf244dc4 176 }
JuanManuelAmador 33:556baf244dc4 177 }
JuanManuelAmador 33:556baf244dc4 178 }
JuanManuelAmador 33:556baf244dc4 179
JuanManuelAmador 33:556baf244dc4 180 void USBHostHub::rxHandler() {
JuanManuelAmador 33:556baf244dc4 181 uint32_t status;
JuanManuelAmador 33:556baf244dc4 182 if (int_in) {
JuanManuelAmador 33:556baf244dc4 183 if (int_in->getState() == USB_TYPE_IDLE) {
JuanManuelAmador 33:556baf244dc4 184 for (int port = 1; port <= nb_port; port++) {
JuanManuelAmador 33:556baf244dc4 185 status = getPortStatus(port);
JuanManuelAmador 33:556baf244dc4 186 USB_DBG("[hub handler hub: %d] status port %d [hub: %p]: 0x%X", dev->getHub(), port, dev, status);
JuanManuelAmador 33:556baf244dc4 187
JuanManuelAmador 33:556baf244dc4 188 // if connection status has changed
JuanManuelAmador 33:556baf244dc4 189 if (status & C_PORT_CONNECTION) {
JuanManuelAmador 33:556baf244dc4 190 if (status & PORT_CONNECTION) {
JuanManuelAmador 33:556baf244dc4 191 USB_DBG("[hub handler hub: %d - port: %d] new device connected", dev->getHub(), port);
JuanManuelAmador 33:556baf244dc4 192 host->deviceConnected(dev->getHub() + 1, port, status & PORT_LOW_SPEED, this);
JuanManuelAmador 33:556baf244dc4 193 } else {
JuanManuelAmador 33:556baf244dc4 194 USB_DBG("[hub handler hub: %d - port: %d] device disconnected", dev->getHub(), port);
JuanManuelAmador 33:556baf244dc4 195 host->deviceDisconnected(dev->getHub() + 1, port, this, 0);
JuanManuelAmador 33:556baf244dc4 196 }
JuanManuelAmador 33:556baf244dc4 197
JuanManuelAmador 33:556baf244dc4 198 clearPortFeature(C_PORT_CONNECTION_FEATURE, port);
JuanManuelAmador 33:556baf244dc4 199 }
JuanManuelAmador 33:556baf244dc4 200
JuanManuelAmador 33:556baf244dc4 201 if (status & C_PORT_RESET) {
JuanManuelAmador 33:556baf244dc4 202 clearPortFeature(C_PORT_RESET_FEATURE, port);
JuanManuelAmador 33:556baf244dc4 203 }
JuanManuelAmador 33:556baf244dc4 204
JuanManuelAmador 33:556baf244dc4 205 if (status & C_PORT_ENABLE) {
JuanManuelAmador 33:556baf244dc4 206 clearPortFeature(C_PORT_ENABLE_FEATURE, port);
JuanManuelAmador 33:556baf244dc4 207 }
JuanManuelAmador 33:556baf244dc4 208
JuanManuelAmador 33:556baf244dc4 209 if ((status & PORT_OVER_CURRENT)) {
JuanManuelAmador 33:556baf244dc4 210 USB_ERR("OVER CURRENT DETECTED\r\n");
JuanManuelAmador 33:556baf244dc4 211 clearPortFeature(PORT_OVER_CURRENT, port);
JuanManuelAmador 33:556baf244dc4 212 host->deviceDisconnected(dev->getHub() + 1, port, this, 0);
JuanManuelAmador 33:556baf244dc4 213 }
JuanManuelAmador 33:556baf244dc4 214 }
JuanManuelAmador 33:556baf244dc4 215 }
JuanManuelAmador 33:556baf244dc4 216 host->interruptRead(dev, int_in, buf, 1, false);
JuanManuelAmador 33:556baf244dc4 217 }
JuanManuelAmador 33:556baf244dc4 218 }
JuanManuelAmador 33:556baf244dc4 219
JuanManuelAmador 33:556baf244dc4 220 void USBHostHub::portReset(uint8_t port) {
JuanManuelAmador 33:556baf244dc4 221 // reset port
JuanManuelAmador 33:556baf244dc4 222 uint32_t status;
JuanManuelAmador 33:556baf244dc4 223 USB_DBG("reset port %d on hub: %p [this: %p]", port, dev, this)
JuanManuelAmador 33:556baf244dc4 224 setPortFeature(PORT_RESET_FEATURE, port);
JuanManuelAmador 33:556baf244dc4 225 #if defined(TARGET_RZ_A1H)
JuanManuelAmador 33:556baf244dc4 226 Thread::wait(50); // Reset release waiting for Hi-Speed check.
JuanManuelAmador 33:556baf244dc4 227 #endif
JuanManuelAmador 33:556baf244dc4 228 while(1) {
JuanManuelAmador 33:556baf244dc4 229 status = getPortStatus(port);
JuanManuelAmador 33:556baf244dc4 230 if (status & (PORT_ENABLE | PORT_RESET))
JuanManuelAmador 33:556baf244dc4 231 break;
JuanManuelAmador 33:556baf244dc4 232 if (status & PORT_OVER_CURRENT) {
JuanManuelAmador 33:556baf244dc4 233 USB_ERR("OVER CURRENT DETECTED\r\n");
JuanManuelAmador 33:556baf244dc4 234 clearPortFeature(PORT_OVER_CURRENT, port);
JuanManuelAmador 33:556baf244dc4 235 host->deviceDisconnected(dev->getHub() + 1, port, this, 0);
JuanManuelAmador 33:556baf244dc4 236 break;
JuanManuelAmador 33:556baf244dc4 237 }
JuanManuelAmador 33:556baf244dc4 238 Thread::wait(10);
JuanManuelAmador 33:556baf244dc4 239 }
JuanManuelAmador 33:556baf244dc4 240 }
JuanManuelAmador 33:556baf244dc4 241
JuanManuelAmador 33:556baf244dc4 242 void USBHostHub::setPortFeature(uint32_t feature, uint8_t port) {
JuanManuelAmador 33:556baf244dc4 243 host->controlWrite( dev,
JuanManuelAmador 33:556baf244dc4 244 USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT,
JuanManuelAmador 33:556baf244dc4 245 SET_FEATURE,
JuanManuelAmador 33:556baf244dc4 246 feature,
JuanManuelAmador 33:556baf244dc4 247 port,
JuanManuelAmador 33:556baf244dc4 248 NULL,
JuanManuelAmador 33:556baf244dc4 249 0);
JuanManuelAmador 33:556baf244dc4 250 }
JuanManuelAmador 33:556baf244dc4 251
JuanManuelAmador 33:556baf244dc4 252 void USBHostHub::clearPortFeature(uint32_t feature, uint8_t port) {
JuanManuelAmador 33:556baf244dc4 253 host->controlWrite( dev,
JuanManuelAmador 33:556baf244dc4 254 USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT,
JuanManuelAmador 33:556baf244dc4 255 CLEAR_FEATURE,
JuanManuelAmador 33:556baf244dc4 256 feature,
JuanManuelAmador 33:556baf244dc4 257 port,
JuanManuelAmador 33:556baf244dc4 258 NULL,
JuanManuelAmador 33:556baf244dc4 259 0);
JuanManuelAmador 33:556baf244dc4 260 }
JuanManuelAmador 33:556baf244dc4 261
JuanManuelAmador 33:556baf244dc4 262 uint32_t USBHostHub::getPortStatus(uint8_t port) {
JuanManuelAmador 33:556baf244dc4 263 uint32_t st;
JuanManuelAmador 33:556baf244dc4 264 host->controlRead( dev,
JuanManuelAmador 33:556baf244dc4 265 USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT,
JuanManuelAmador 33:556baf244dc4 266 GET_STATUS,
JuanManuelAmador 33:556baf244dc4 267 0,
JuanManuelAmador 33:556baf244dc4 268 port,
JuanManuelAmador 33:556baf244dc4 269 (uint8_t *)&st,
JuanManuelAmador 33:556baf244dc4 270 4);
JuanManuelAmador 33:556baf244dc4 271 return st;
JuanManuelAmador 33:556baf244dc4 272 }
JuanManuelAmador 33:556baf244dc4 273
JuanManuelAmador 33:556baf244dc4 274 #endif