test public

Dependencies:   HttpServer_snapshot_mbed-os

Committer:
anhtran
Date:
Fri Oct 18 03:09:43 2019 +0000
Revision:
0:e9fd5575b10e
abc

Who changed what in which revision?

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