SDG+USBHost(Mouse) Sample

Dependencies:   Sound_Generator USBHost_custom

Fork of SDG_Mouse_Sample by GR-PEACH_producer_meeting

Information

Japanese version is available in lower part of this page.
このページの後半に日本語版が用意されています.

What is this?

This program is a demonstration that sounds the sound by mouse operation by using USBHost(Mouse) and Sound Generator.

Settings

Close JP3 of GR-PEACH.
/media/uploads/RyoheiHagimoto/sdg-mouse.jpg

Operation

operationeffect
Right clickSounds
Left clickReset to base tone (C)
Moves the mouse to the rightLower the sound
Moves the mouse to the leftHigher the sound
Center cursorAdjust the sensitivity.
Reset the reference value in the click.

Others

The default setting of serial communication (baud rate etc.) in mbed is shown the following link.
Please refer to the link and change the settings of your PC terminal software.
The default value of baud rate in mbed is 9600, and this application uses baud rate 9600.
https://developer.mbed.org/teams/Renesas/wiki/GR-PEACH-Getting-Started#install-the-usb-serial-communication


概要

このプログラムは、USBHost(Mouse) + Sound Generatorで、マウス操作による擬似笛デモです。

設定

GR-PEACHのJP3をショートする必要があります。
/media/uploads/RyoheiHagimoto/sdg-mouse.jpg

操作方法

操作内容
右クリック音出力開始
左クリック基準音(ド)にリセット
マウス右移動高音になります
マウス左移動低音になります
センターカーソル音高低の変化量調整(クリックで基準値にリセット)

Others

mbedのシリアル通信(ボーレート等)のデフォルト設定は以下のリンクに示しています。
リンクを参考に、お使いのPCターミナルソフトの設定を変更して下さい。
mbedでのボーレートのデフォルト値は9600で、このサンプルではボーレート9600を使います。
https://developer.mbed.org/teams/Renesas/wiki/GR-PEACH-Getting-Started#install-the-usb-serial-communication

Committer:
mbed_official
Date:
Tue Jun 03 11:30:38 2014 +0100
Revision:
24:868cbfe611a7
Parent:
23:759ec18ee1a7
Synchronized with git revision bcacbb9fbf3432829227430830cca4315b57c1b9

Full URL: https://github.com/mbedmicro/mbed/commit/bcacbb9fbf3432829227430830cca4315b57c1b9/

Who changed what in which revision?

UserRevisionLine numberNew contents of line
samux 8:93da8ea2708b 1 /* mbed USBHost Library
samux 8:93da8ea2708b 2 * Copyright (c) 2006-2013 ARM Limited
samux 8:93da8ea2708b 3 *
samux 8:93da8ea2708b 4 * Licensed under the Apache License, Version 2.0 (the "License");
samux 8:93da8ea2708b 5 * you may not use this file except in compliance with the License.
samux 8:93da8ea2708b 6 * You may obtain a copy of the License at
samux 8:93da8ea2708b 7 *
samux 8:93da8ea2708b 8 * http://www.apache.org/licenses/LICENSE-2.0
samux 8:93da8ea2708b 9 *
samux 8:93da8ea2708b 10 * Unless required by applicable law or agreed to in writing, software
samux 8:93da8ea2708b 11 * distributed under the License is distributed on an "AS IS" BASIS,
samux 8:93da8ea2708b 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
samux 8:93da8ea2708b 13 * See the License for the specific language governing permissions and
samux 8:93da8ea2708b 14 * limitations under the License.
samux 8:93da8ea2708b 15 */
mbed_official 0:a554658735bf 16
mbed_official 0:a554658735bf 17
mbed_official 0:a554658735bf 18 #include "USBHost.h"
mbed_official 0:a554658735bf 19 #include "USBHostHub.h"
mbed_official 0:a554658735bf 20
mbed_official 0:a554658735bf 21 USBHost * USBHost::instHost = NULL;
mbed_official 0:a554658735bf 22
mbed_official 0:a554658735bf 23 #define DEVICE_CONNECTED_EVENT (1 << 0)
mbed_official 0:a554658735bf 24 #define DEVICE_DISCONNECTED_EVENT (1 << 1)
mbed_official 0:a554658735bf 25 #define TD_PROCESSED_EVENT (1 << 2)
mbed_official 0:a554658735bf 26
mbed_official 0:a554658735bf 27 #define MAX_TRY_ENUMERATE_HUB 3
mbed_official 0:a554658735bf 28
mbed_official 0:a554658735bf 29 #define MIN(a, b) ((a > b) ? b : a)
mbed_official 0:a554658735bf 30
mbed_official 0:a554658735bf 31 /**
mbed_official 0:a554658735bf 32 * How interrupts are processed:
mbed_official 0:a554658735bf 33 * - new device connected:
samux 8:93da8ea2708b 34 * - a message is queued in queue_usb_event with the id DEVICE_CONNECTED_EVENT
samux 8:93da8ea2708b 35 * - when the usb_thread receives the event, it:
samux 8:93da8ea2708b 36 * - resets the device
samux 8:93da8ea2708b 37 * - reads the device descriptor
samux 8:93da8ea2708b 38 * - sets the address of the device
samux 8:93da8ea2708b 39 * - if it is a hub, enumerates it
samux 8:93da8ea2708b 40 * - device disconnected:
samux 8:93da8ea2708b 41 * - a message is queued in queue_usb_event with the id DEVICE_DISCONNECTED_EVENT
samux 8:93da8ea2708b 42 * - when the usb_thread receives the event, it:
samux 8:93da8ea2708b 43 * - free the device and all its children (hub)
samux 8:93da8ea2708b 44 * - td processed
samux 8:93da8ea2708b 45 * - a message is queued in queue_usb_event with the id TD_PROCESSED_EVENT
samux 8:93da8ea2708b 46 * - when the usb_thread receives the event, it:
samux 8:93da8ea2708b 47 * - call the callback attached to the endpoint where the td is attached
mbed_official 0:a554658735bf 48 */
mbed_official 0:a554658735bf 49 void USBHost::usb_process() {
mbed_official 24:868cbfe611a7 50
mbed_official 0:a554658735bf 51 bool controlListState;
mbed_official 0:a554658735bf 52 bool bulkListState;
mbed_official 0:a554658735bf 53 bool interruptListState;
mbed_official 0:a554658735bf 54 USBEndpoint * ep;
mbed_official 0:a554658735bf 55 uint8_t i, j, res, timeout_set_addr = 10;
mbed_official 0:a554658735bf 56 uint8_t buf[8];
mbed_official 0:a554658735bf 57 bool too_many_hub;
mbed_official 0:a554658735bf 58 int idx;
mbed_official 0:a554658735bf 59
mbed_official 0:a554658735bf 60 #if DEBUG_TRANSFER
mbed_official 0:a554658735bf 61 uint8_t * buf_transfer;
mbed_official 0:a554658735bf 62 #endif
mbed_official 24:868cbfe611a7 63
mbed_official 0:a554658735bf 64 #if MAX_HUB_NB
mbed_official 0:a554658735bf 65 uint8_t k;
mbed_official 0:a554658735bf 66 #endif
mbed_official 24:868cbfe611a7 67
mbed_official 0:a554658735bf 68 while(1) {
samux 9:7671b6a8c363 69 osEvent evt = mail_usb_event.get();
mbed_official 24:868cbfe611a7 70
samux 9:7671b6a8c363 71 if (evt.status == osEventMail) {
mbed_official 24:868cbfe611a7 72
mbed_official 0:a554658735bf 73 message_t * usb_msg = (message_t*)evt.value.p;
mbed_official 24:868cbfe611a7 74
mbed_official 0:a554658735bf 75 switch (usb_msg->event_id) {
mbed_official 24:868cbfe611a7 76
mbed_official 0:a554658735bf 77 // a new device has been connected
mbed_official 0:a554658735bf 78 case DEVICE_CONNECTED_EVENT:
mbed_official 0:a554658735bf 79 too_many_hub = false;
mbed_official 0:a554658735bf 80 buf[4] = 0;
mbed_official 24:868cbfe611a7 81
mbed_official 23:759ec18ee1a7 82 do
mbed_official 23:759ec18ee1a7 83 {
mbed_official 23:759ec18ee1a7 84 Lock lock(this);
mbed_official 24:868cbfe611a7 85
mbed_official 23:759ec18ee1a7 86 for (i = 0; i < MAX_DEVICE_CONNECTED; i++) {
mbed_official 23:759ec18ee1a7 87 if (!deviceInUse[i]) {
mbed_official 23:759ec18ee1a7 88 USB_DBG_EVENT("new device connected: %p\r\n", &devices[i]);
mbed_official 23:759ec18ee1a7 89 devices[i].init(usb_msg->hub, usb_msg->port, usb_msg->lowSpeed);
mbed_official 23:759ec18ee1a7 90 deviceReset[i] = false;
mbed_official 23:759ec18ee1a7 91 deviceInited[i] = true;
mbed_official 23:759ec18ee1a7 92 break;
mbed_official 23:759ec18ee1a7 93 }
mbed_official 23:759ec18ee1a7 94 }
mbed_official 24:868cbfe611a7 95
mbed_official 23:759ec18ee1a7 96 if (i == MAX_DEVICE_CONNECTED) {
mbed_official 23:759ec18ee1a7 97 USB_ERR("Too many device connected!!\r\n");
mbed_official 23:759ec18ee1a7 98 continue;
mbed_official 23:759ec18ee1a7 99 }
mbed_official 24:868cbfe611a7 100
mbed_official 23:759ec18ee1a7 101 if (!controlEndpointAllocated) {
mbed_official 23:759ec18ee1a7 102 control = newEndpoint(CONTROL_ENDPOINT, OUT, 0x08, 0x00);
mbed_official 23:759ec18ee1a7 103 addEndpoint(NULL, 0, (USBEndpoint*)control);
mbed_official 23:759ec18ee1a7 104 controlEndpointAllocated = true;
mbed_official 23:759ec18ee1a7 105 }
mbed_official 24:868cbfe611a7 106
mbed_official 23:759ec18ee1a7 107 #if MAX_HUB_NB
mbed_official 23:759ec18ee1a7 108 if (usb_msg->hub_parent)
mbed_official 23:759ec18ee1a7 109 devices[i].setHubParent((USBHostHub *)(usb_msg->hub_parent));
mbed_official 23:759ec18ee1a7 110 #endif
mbed_official 24:868cbfe611a7 111
mbed_official 23:759ec18ee1a7 112 for (j = 0; j < timeout_set_addr; j++) {
mbed_official 24:868cbfe611a7 113
mbed_official 23:759ec18ee1a7 114 resetDevice(&devices[i]);
mbed_official 24:868cbfe611a7 115
mbed_official 23:759ec18ee1a7 116 // set size of control endpoint
mbed_official 23:759ec18ee1a7 117 devices[i].setSizeControlEndpoint(8);
mbed_official 24:868cbfe611a7 118
mbed_official 23:759ec18ee1a7 119 devices[i].activeAddress(false);
mbed_official 24:868cbfe611a7 120
mbed_official 23:759ec18ee1a7 121 // get first 8 bit of device descriptor
mbed_official 23:759ec18ee1a7 122 // and check if we deal with a hub
mbed_official 23:759ec18ee1a7 123 USB_DBG("usb_thread read device descriptor on dev: %p\r\n", &devices[i]);
mbed_official 23:759ec18ee1a7 124 res = getDeviceDescriptor(&devices[i], buf, 8);
mbed_official 24:868cbfe611a7 125
mbed_official 23:759ec18ee1a7 126 if (res != USB_TYPE_OK) {
mbed_official 23:759ec18ee1a7 127 USB_ERR("usb_thread could not read dev descr");
mbed_official 23:759ec18ee1a7 128 continue;
mbed_official 23:759ec18ee1a7 129 }
mbed_official 24:868cbfe611a7 130
mbed_official 23:759ec18ee1a7 131 // set size of control endpoint
mbed_official 23:759ec18ee1a7 132 devices[i].setSizeControlEndpoint(buf[7]);
mbed_official 24:868cbfe611a7 133
mbed_official 23:759ec18ee1a7 134 // second step: set an address to the device
mbed_official 23:759ec18ee1a7 135 res = setAddress(&devices[i], devices[i].getAddress());
mbed_official 24:868cbfe611a7 136
mbed_official 23:759ec18ee1a7 137 if (res != USB_TYPE_OK) {
mbed_official 23:759ec18ee1a7 138 USB_ERR("SET ADDR FAILED");
mbed_official 23:759ec18ee1a7 139 continue;
mbed_official 23:759ec18ee1a7 140 }
mbed_official 23:759ec18ee1a7 141 devices[i].activeAddress(true);
mbed_official 23:759ec18ee1a7 142 USB_DBG("Address of %p: %d", &devices[i], devices[i].getAddress());
mbed_official 24:868cbfe611a7 143
mbed_official 23:759ec18ee1a7 144 // try to read again the device descriptor to check if the device
mbed_official 23:759ec18ee1a7 145 // answers to its new address
mbed_official 23:759ec18ee1a7 146 res = getDeviceDescriptor(&devices[i], buf, 8);
mbed_official 24:868cbfe611a7 147
mbed_official 23:759ec18ee1a7 148 if (res == USB_TYPE_OK) {
mbed_official 23:759ec18ee1a7 149 break;
mbed_official 23:759ec18ee1a7 150 }
mbed_official 24:868cbfe611a7 151
mbed_official 23:759ec18ee1a7 152 Thread::wait(100);
mbed_official 23:759ec18ee1a7 153 }
mbed_official 24:868cbfe611a7 154
mbed_official 23:759ec18ee1a7 155 USB_INFO("New device connected: %p [hub: %d - port: %d]", &devices[i], usb_msg->hub, usb_msg->port);
mbed_official 24:868cbfe611a7 156
mbed_official 23:759ec18ee1a7 157 #if MAX_HUB_NB
mbed_official 23:759ec18ee1a7 158 if (buf[4] == HUB_CLASS) {
mbed_official 23:759ec18ee1a7 159 for (k = 0; k < MAX_HUB_NB; k++) {
mbed_official 23:759ec18ee1a7 160 if (hub_in_use[k] == false) {
mbed_official 23:759ec18ee1a7 161 for (uint8_t j = 0; j < MAX_TRY_ENUMERATE_HUB; j++) {
mbed_official 23:759ec18ee1a7 162 if (hubs[k].connect(&devices[i])) {
mbed_official 23:759ec18ee1a7 163 devices[i].hub = &hubs[k];
mbed_official 23:759ec18ee1a7 164 hub_in_use[k] = true;
mbed_official 23:759ec18ee1a7 165 break;
mbed_official 23:759ec18ee1a7 166 }
mbed_official 23:759ec18ee1a7 167 }
mbed_official 23:759ec18ee1a7 168 if (hub_in_use[k] == true)
mbed_official 23:759ec18ee1a7 169 break;
mbed_official 23:759ec18ee1a7 170 }
mbed_official 23:759ec18ee1a7 171 }
mbed_official 24:868cbfe611a7 172
mbed_official 23:759ec18ee1a7 173 if (k == MAX_HUB_NB) {
mbed_official 23:759ec18ee1a7 174 USB_ERR("Too many hubs connected!!\r\n");
mbed_official 23:759ec18ee1a7 175 too_many_hub = true;
mbed_official 23:759ec18ee1a7 176 }
mbed_official 23:759ec18ee1a7 177 }
mbed_official 24:868cbfe611a7 178
mbed_official 23:759ec18ee1a7 179 if (usb_msg->hub_parent)
mbed_official 23:759ec18ee1a7 180 ((USBHostHub *)(usb_msg->hub_parent))->deviceConnected(&devices[i]);
mbed_official 23:759ec18ee1a7 181 #endif
mbed_official 24:868cbfe611a7 182
mbed_official 23:759ec18ee1a7 183 if ((i < MAX_DEVICE_CONNECTED) && !too_many_hub) {
mbed_official 23:759ec18ee1a7 184 deviceInUse[i] = true;
mbed_official 23:759ec18ee1a7 185 }
mbed_official 24:868cbfe611a7 186
mbed_official 23:759ec18ee1a7 187 } while(0);
mbed_official 24:868cbfe611a7 188
mbed_official 0:a554658735bf 189 break;
mbed_official 24:868cbfe611a7 190
mbed_official 0:a554658735bf 191 // a device has been disconnected
mbed_official 0:a554658735bf 192 case DEVICE_DISCONNECTED_EVENT:
mbed_official 24:868cbfe611a7 193
mbed_official 23:759ec18ee1a7 194 do
mbed_official 23:759ec18ee1a7 195 {
mbed_official 23:759ec18ee1a7 196 Lock lock(this);
mbed_official 24:868cbfe611a7 197
mbed_official 23:759ec18ee1a7 198 controlListState = disableList(CONTROL_ENDPOINT);
mbed_official 23:759ec18ee1a7 199 bulkListState = disableList(BULK_ENDPOINT);
mbed_official 23:759ec18ee1a7 200 interruptListState = disableList(INTERRUPT_ENDPOINT);
mbed_official 24:868cbfe611a7 201
mbed_official 23:759ec18ee1a7 202 idx = findDevice(usb_msg->hub, usb_msg->port, (USBHostHub *)(usb_msg->hub_parent));
mbed_official 23:759ec18ee1a7 203 if (idx != -1) {
mbed_official 23:759ec18ee1a7 204 freeDevice((USBDeviceConnected*)&devices[idx]);
mbed_official 23:759ec18ee1a7 205 }
mbed_official 24:868cbfe611a7 206
mbed_official 23:759ec18ee1a7 207 if (controlListState) enableList(CONTROL_ENDPOINT);
mbed_official 23:759ec18ee1a7 208 if (bulkListState) enableList(BULK_ENDPOINT);
mbed_official 23:759ec18ee1a7 209 if (interruptListState) enableList(INTERRUPT_ENDPOINT);
mbed_official 24:868cbfe611a7 210
mbed_official 23:759ec18ee1a7 211 } while(0);
mbed_official 24:868cbfe611a7 212
mbed_official 0:a554658735bf 213 break;
mbed_official 24:868cbfe611a7 214
mbed_official 0:a554658735bf 215 // a td has been processed
mbed_official 0:a554658735bf 216 // call callback on the ed associated to the td
mbed_official 0:a554658735bf 217 // we are not in ISR -> users can use printf in their callback method
mbed_official 0:a554658735bf 218 case TD_PROCESSED_EVENT:
mbed_official 0:a554658735bf 219 ep = (USBEndpoint *) ((HCTD *)usb_msg->td_addr)->ep;
samux 4:b320d68e98e7 220 if (usb_msg->td_state == USB_TYPE_IDLE) {
samux 4:b320d68e98e7 221 USB_DBG_EVENT("call callback on td %p [ep: %p state: %s - dev: %p - %s]", usb_msg->td_addr, ep, ep->getStateString(), ep->dev, ep->dev->getName(ep->getIntfNb()));
samux 4:b320d68e98e7 222
mbed_official 0:a554658735bf 223 #if DEBUG_TRANSFER
mbed_official 0:a554658735bf 224 if (ep->getDir() == IN) {
mbed_official 0:a554658735bf 225 buf_transfer = ep->getBufStart();
samux 4:b320d68e98e7 226 printf("READ SUCCESS [%d bytes transferred - td: 0x%08X] on ep: [%p - addr: %02X]: ", ep->getLengthTransferred(), usb_msg->td_addr, ep, ep->getAddress());
mbed_official 0:a554658735bf 227 for (int i = 0; i < ep->getLengthTransferred(); i++)
mbed_official 0:a554658735bf 228 printf("%02X ", buf_transfer[i]);
mbed_official 0:a554658735bf 229 printf("\r\n\r\n");
mbed_official 0:a554658735bf 230 }
mbed_official 0:a554658735bf 231 #endif
mbed_official 0:a554658735bf 232 ep->call();
mbed_official 0:a554658735bf 233 } else {
mbed_official 0:a554658735bf 234 idx = findDevice(ep->dev);
mbed_official 0:a554658735bf 235 if (idx != -1) {
samux 4:b320d68e98e7 236 if (deviceInUse[idx]) {
samux 4:b320d68e98e7 237 USB_WARN("td %p processed but not in idle state: %s [ep: %p - dev: %p - %s]", usb_msg->td_addr, ep->getStateString(), ep, ep->dev, ep->dev->getName(ep->getIntfNb()));
samux 4:b320d68e98e7 238 ep->setState(USB_TYPE_IDLE);
samux 4:b320d68e98e7 239 }
mbed_official 0:a554658735bf 240 }
mbed_official 0:a554658735bf 241 }
mbed_official 0:a554658735bf 242 break;
mbed_official 0:a554658735bf 243 }
mbed_official 24:868cbfe611a7 244
samux 9:7671b6a8c363 245 mail_usb_event.free(usb_msg);
mbed_official 0:a554658735bf 246 }
mbed_official 0:a554658735bf 247 }
mbed_official 0:a554658735bf 248 }
mbed_official 0:a554658735bf 249
mbed_official 0:a554658735bf 250 /* static */void USBHost::usb_process_static(void const * arg) {
mbed_official 0:a554658735bf 251 ((USBHost *)arg)->usb_process();
mbed_official 0:a554658735bf 252 }
mbed_official 0:a554658735bf 253
mbed_official 0:a554658735bf 254 USBHost::USBHost() : usbThread(USBHost::usb_process_static, (void *)this, osPriorityNormal, USB_THREAD_STACK)
mbed_official 0:a554658735bf 255 {
mbed_official 0:a554658735bf 256 headControlEndpoint = NULL;
mbed_official 0:a554658735bf 257 headBulkEndpoint = NULL;
mbed_official 0:a554658735bf 258 headInterruptEndpoint = NULL;
mbed_official 0:a554658735bf 259 tailControlEndpoint = NULL;
mbed_official 0:a554658735bf 260 tailBulkEndpoint = NULL;
mbed_official 0:a554658735bf 261 tailInterruptEndpoint = NULL;
mbed_official 0:a554658735bf 262
mbed_official 0:a554658735bf 263 lenReportDescr = 0;
mbed_official 0:a554658735bf 264
mbed_official 0:a554658735bf 265 controlEndpointAllocated = false;
mbed_official 0:a554658735bf 266
mbed_official 0:a554658735bf 267 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
mbed_official 0:a554658735bf 268 deviceInUse[i] = false;
mbed_official 0:a554658735bf 269 devices[i].setAddress(i + 1);
mbed_official 0:a554658735bf 270 deviceReset[i] = false;
samux 4:b320d68e98e7 271 deviceInited[i] = false;
samux 4:b320d68e98e7 272 for (uint8_t j = 0; j < MAX_INTF; j++)
samux 4:b320d68e98e7 273 deviceAttachedDriver[i][j] = false;
mbed_official 0:a554658735bf 274 }
mbed_official 24:868cbfe611a7 275
mbed_official 0:a554658735bf 276 #if MAX_HUB_NB
mbed_official 0:a554658735bf 277 for (uint8_t i = 0; i < MAX_HUB_NB; i++) {
mbed_official 0:a554658735bf 278 hubs[i].setHost(this);
mbed_official 0:a554658735bf 279 hub_in_use[i] = false;
mbed_official 0:a554658735bf 280 }
mbed_official 0:a554658735bf 281 #endif
mbed_official 0:a554658735bf 282 }
mbed_official 0:a554658735bf 283
mbed_official 23:759ec18ee1a7 284 USBHost::Lock::Lock(USBHost* pHost) : m_pHost(pHost)
mbed_official 23:759ec18ee1a7 285 {
mbed_official 23:759ec18ee1a7 286 m_pHost->usb_mutex.lock();
mbed_official 23:759ec18ee1a7 287 }
mbed_official 23:759ec18ee1a7 288
mbed_official 23:759ec18ee1a7 289 USBHost::Lock::~Lock()
mbed_official 23:759ec18ee1a7 290 {
mbed_official 23:759ec18ee1a7 291 m_pHost->usb_mutex.unlock();
mbed_official 23:759ec18ee1a7 292 }
mbed_official 0:a554658735bf 293
mbed_official 0:a554658735bf 294 void USBHost::transferCompleted(volatile uint32_t addr)
mbed_official 0:a554658735bf 295 {
mbed_official 0:a554658735bf 296 uint8_t state;
mbed_official 0:a554658735bf 297
mbed_official 13:b58a2204422f 298 if(addr == 0)
mbed_official 0:a554658735bf 299 return;
mbed_official 0:a554658735bf 300
mbed_official 0:a554658735bf 301 volatile HCTD* tdList = NULL;
mbed_official 0:a554658735bf 302
mbed_official 0:a554658735bf 303 //First we must reverse the list order and dequeue each TD
mbed_official 0:a554658735bf 304 do {
mbed_official 0:a554658735bf 305 volatile HCTD* td = (volatile HCTD*)addr;
samux 4:b320d68e98e7 306 addr = (uint32_t)td->nextTD; //Dequeue from physical list
samux 4:b320d68e98e7 307 td->nextTD = tdList; //Enqueue into reversed list
mbed_official 0:a554658735bf 308 tdList = td;
mbed_official 0:a554658735bf 309 } while(addr);
mbed_official 0:a554658735bf 310
mbed_official 0:a554658735bf 311 while(tdList != NULL) {
mbed_official 0:a554658735bf 312 volatile HCTD* td = tdList;
mbed_official 0:a554658735bf 313 tdList = (volatile HCTD*)td->nextTD; //Dequeue element now as it could be modified below
mbed_official 0:a554658735bf 314 if (td->ep != NULL) {
mbed_official 0:a554658735bf 315 USBEndpoint * ep = (USBEndpoint *)(td->ep);
mbed_official 24:868cbfe611a7 316
mbed_official 0:a554658735bf 317 if (((HCTD *)td)->control >> 28) {
mbed_official 0:a554658735bf 318 state = ((HCTD *)td)->control >> 28;
mbed_official 0:a554658735bf 319 } else {
mbed_official 0:a554658735bf 320 if (td->currBufPtr)
mbed_official 0:a554658735bf 321 ep->setLengthTransferred((uint32_t)td->currBufPtr - (uint32_t)ep->getBufStart());
mbed_official 0:a554658735bf 322 state = 16 /*USB_TYPE_IDLE*/;
mbed_official 0:a554658735bf 323 }
mbed_official 24:868cbfe611a7 324
mbed_official 0:a554658735bf 325 ep->unqueueTransfer(td);
mbed_official 24:868cbfe611a7 326
mbed_official 0:a554658735bf 327 if (ep->getType() != CONTROL_ENDPOINT) {
mbed_official 0:a554658735bf 328 // callback on the processed td will be called from the usb_thread (not in ISR)
samux 9:7671b6a8c363 329 message_t * usb_msg = mail_usb_event.alloc();
mbed_official 0:a554658735bf 330 usb_msg->event_id = TD_PROCESSED_EVENT;
mbed_official 0:a554658735bf 331 usb_msg->td_addr = (void *)td;
mbed_official 0:a554658735bf 332 usb_msg->td_state = state;
samux 9:7671b6a8c363 333 mail_usb_event.put(usb_msg);
mbed_official 0:a554658735bf 334 }
samux 4:b320d68e98e7 335 ep->setState(state);
samux 9:7671b6a8c363 336 ep->ep_queue.put((uint8_t*)1);
mbed_official 0:a554658735bf 337 }
mbed_official 0:a554658735bf 338 }
mbed_official 0:a554658735bf 339 }
mbed_official 0:a554658735bf 340
mbed_official 0:a554658735bf 341 USBHost * USBHost::getHostInst()
mbed_official 0:a554658735bf 342 {
mbed_official 0:a554658735bf 343 if (instHost == NULL) {
mbed_official 0:a554658735bf 344 instHost = new USBHost();
mbed_official 0:a554658735bf 345 instHost->init();
mbed_official 0:a554658735bf 346 }
mbed_official 0:a554658735bf 347 return instHost;
mbed_official 0:a554658735bf 348 }
mbed_official 0:a554658735bf 349
mbed_official 0:a554658735bf 350
mbed_official 0:a554658735bf 351 /*
mbed_official 0:a554658735bf 352 * Called when a device has been connected
mbed_official 0:a554658735bf 353 * Called in ISR!!!! (no printf)
mbed_official 0:a554658735bf 354 */
mbed_official 0:a554658735bf 355 /* virtual */ void USBHost::deviceConnected(int hub, int port, bool lowSpeed, USBHostHub * hub_parent)
mbed_official 0:a554658735bf 356 {
mbed_official 0:a554658735bf 357 // be sure that the new device connected is not already connected...
mbed_official 0:a554658735bf 358 int idx = findDevice(hub, port, hub_parent);
mbed_official 0:a554658735bf 359 if (idx != -1) {
samux 4:b320d68e98e7 360 if (deviceInited[idx])
mbed_official 0:a554658735bf 361 return;
mbed_official 0:a554658735bf 362 }
mbed_official 24:868cbfe611a7 363
samux 9:7671b6a8c363 364 message_t * usb_msg = mail_usb_event.alloc();
mbed_official 0:a554658735bf 365 usb_msg->event_id = DEVICE_CONNECTED_EVENT;
mbed_official 0:a554658735bf 366 usb_msg->hub = hub;
mbed_official 0:a554658735bf 367 usb_msg->port = port;
mbed_official 0:a554658735bf 368 usb_msg->lowSpeed = lowSpeed;
mbed_official 0:a554658735bf 369 usb_msg->hub_parent = hub_parent;
samux 9:7671b6a8c363 370 mail_usb_event.put(usb_msg);
mbed_official 0:a554658735bf 371 }
mbed_official 0:a554658735bf 372
mbed_official 0:a554658735bf 373 /*
mbed_official 0:a554658735bf 374 * Called when a device has been disconnected
mbed_official 0:a554658735bf 375 * Called in ISR!!!! (no printf)
mbed_official 0:a554658735bf 376 */
mbed_official 0:a554658735bf 377 /* virtual */ void USBHost::deviceDisconnected(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr)
mbed_official 0:a554658735bf 378 {
mbed_official 0:a554658735bf 379 // be sure that the device disconnected is connected...
mbed_official 0:a554658735bf 380 int idx = findDevice(hub, port, hub_parent);
mbed_official 0:a554658735bf 381 if (idx != -1) {
mbed_official 0:a554658735bf 382 if (!deviceInUse[idx])
mbed_official 0:a554658735bf 383 return;
mbed_official 0:a554658735bf 384 } else {
mbed_official 0:a554658735bf 385 return;
mbed_official 0:a554658735bf 386 }
mbed_official 24:868cbfe611a7 387
samux 9:7671b6a8c363 388 message_t * usb_msg = mail_usb_event.alloc();
mbed_official 0:a554658735bf 389 usb_msg->event_id = DEVICE_DISCONNECTED_EVENT;
mbed_official 0:a554658735bf 390 usb_msg->hub = hub;
mbed_official 0:a554658735bf 391 usb_msg->port = port;
mbed_official 0:a554658735bf 392 usb_msg->hub_parent = hub_parent;
samux 9:7671b6a8c363 393 mail_usb_event.put(usb_msg);
mbed_official 0:a554658735bf 394 }
mbed_official 0:a554658735bf 395
mbed_official 0:a554658735bf 396 void USBHost::freeDevice(USBDeviceConnected * dev)
mbed_official 0:a554658735bf 397 {
mbed_official 0:a554658735bf 398 USBEndpoint * ep = NULL;
mbed_official 0:a554658735bf 399 HCED * ed = NULL;
mbed_official 24:868cbfe611a7 400
mbed_official 0:a554658735bf 401 #if MAX_HUB_NB
mbed_official 0:a554658735bf 402 if (dev->getClass() == HUB_CLASS) {
mbed_official 0:a554658735bf 403 if (dev->hub == NULL) {
mbed_official 0:a554658735bf 404 USB_ERR("HUB NULL!!!!!\r\n");
mbed_official 0:a554658735bf 405 } else {
mbed_official 0:a554658735bf 406 dev->hub->hubDisconnected();
mbed_official 0:a554658735bf 407 for (uint8_t i = 0; i < MAX_HUB_NB; i++) {
mbed_official 0:a554658735bf 408 if (dev->hub == &hubs[i]) {
mbed_official 0:a554658735bf 409 hub_in_use[i] = false;
mbed_official 0:a554658735bf 410 break;
mbed_official 0:a554658735bf 411 }
mbed_official 0:a554658735bf 412 }
mbed_official 0:a554658735bf 413 }
mbed_official 0:a554658735bf 414 }
mbed_official 24:868cbfe611a7 415
mbed_official 0:a554658735bf 416 // notify hub parent that this device has been disconnected
mbed_official 0:a554658735bf 417 if (dev->getHubParent())
mbed_official 0:a554658735bf 418 dev->getHubParent()->deviceDisconnected(dev);
mbed_official 24:868cbfe611a7 419
mbed_official 0:a554658735bf 420 #endif
mbed_official 24:868cbfe611a7 421
mbed_official 0:a554658735bf 422 int idx = findDevice(dev);
mbed_official 0:a554658735bf 423 if (idx != -1) {
mbed_official 0:a554658735bf 424 deviceInUse[idx] = false;
mbed_official 0:a554658735bf 425 deviceReset[idx] = false;
mbed_official 0:a554658735bf 426
samux 4:b320d68e98e7 427 for (uint8_t j = 0; j < MAX_INTF; j++) {
samux 4:b320d68e98e7 428 deviceAttachedDriver[idx][j] = false;
samux 4:b320d68e98e7 429 if (dev->getInterface(j) != NULL) {
samux 4:b320d68e98e7 430 USB_DBG("FREE INTF %d on dev: %p, %p, nb_endpot: %d, %s", j, (void *)dev->getInterface(j), dev, dev->getInterface(j)->nb_endpoint, dev->getName(j));
samux 4:b320d68e98e7 431 for (int i = 0; i < dev->getInterface(j)->nb_endpoint; i++) {
samux 4:b320d68e98e7 432 if ((ep = dev->getEndpoint(j, i)) != NULL) {
samux 4:b320d68e98e7 433 ed = (HCED *)ep->getHCED();
samux 10:0c11cf1cc218 434 ed->control |= (1 << 14); //sKip bit
samux 4:b320d68e98e7 435 unqueueEndpoint(ep);
mbed_official 0:a554658735bf 436
samux 4:b320d68e98e7 437 freeTD((volatile uint8_t*)ep->getTDList()[0]);
samux 4:b320d68e98e7 438 freeTD((volatile uint8_t*)ep->getTDList()[1]);
mbed_official 0:a554658735bf 439
samux 4:b320d68e98e7 440 freeED((uint8_t *)ep->getHCED());
samux 4:b320d68e98e7 441 }
samux 4:b320d68e98e7 442 printList(BULK_ENDPOINT);
samux 4:b320d68e98e7 443 printList(INTERRUPT_ENDPOINT);
mbed_official 0:a554658735bf 444 }
samux 4:b320d68e98e7 445 USB_INFO("Device disconnected [%p - %s - hub: %d - port: %d]", dev, dev->getName(j), dev->getHub(), dev->getPort());
mbed_official 0:a554658735bf 446 }
mbed_official 0:a554658735bf 447 }
mbed_official 0:a554658735bf 448 dev->disconnect();
mbed_official 0:a554658735bf 449 }
mbed_official 0:a554658735bf 450 }
mbed_official 0:a554658735bf 451
mbed_official 0:a554658735bf 452
mbed_official 0:a554658735bf 453 void USBHost::unqueueEndpoint(USBEndpoint * ep)
mbed_official 0:a554658735bf 454 {
mbed_official 0:a554658735bf 455 USBEndpoint * prec = NULL;
mbed_official 0:a554658735bf 456 USBEndpoint * current = NULL;
mbed_official 0:a554658735bf 457
mbed_official 0:a554658735bf 458 for (int i = 0; i < 2; i++) {
mbed_official 0:a554658735bf 459 current = (i == 0) ? (USBEndpoint*)headBulkEndpoint : (USBEndpoint*)headInterruptEndpoint;
mbed_official 0:a554658735bf 460 prec = current;
mbed_official 0:a554658735bf 461 while (current != NULL) {
mbed_official 0:a554658735bf 462 if (current == ep) {
mbed_official 0:a554658735bf 463 if (current->nextEndpoint() != NULL) {
mbed_official 0:a554658735bf 464 prec->queueEndpoint(current->nextEndpoint());
mbed_official 0:a554658735bf 465 if (current == headBulkEndpoint) {
mbed_official 0:a554658735bf 466 updateBulkHeadED((uint32_t)current->nextEndpoint()->getHCED());
mbed_official 0:a554658735bf 467 headBulkEndpoint = current->nextEndpoint();
mbed_official 0:a554658735bf 468 } else if (current == headInterruptEndpoint) {
mbed_official 0:a554658735bf 469 updateInterruptHeadED((uint32_t)current->nextEndpoint()->getHCED());
mbed_official 0:a554658735bf 470 headInterruptEndpoint = current->nextEndpoint();
mbed_official 0:a554658735bf 471 }
mbed_official 0:a554658735bf 472 }
mbed_official 0:a554658735bf 473 // here we are dequeuing the queue of ed
mbed_official 0:a554658735bf 474 // we need to update the tail pointer
mbed_official 0:a554658735bf 475 else {
mbed_official 0:a554658735bf 476 prec->queueEndpoint(NULL);
mbed_official 0:a554658735bf 477 if (current == headBulkEndpoint) {
mbed_official 0:a554658735bf 478 updateBulkHeadED(0);
mbed_official 0:a554658735bf 479 headBulkEndpoint = current->nextEndpoint();
mbed_official 0:a554658735bf 480 } else if (current == headInterruptEndpoint) {
mbed_official 0:a554658735bf 481 updateInterruptHeadED(0);
mbed_official 0:a554658735bf 482 headInterruptEndpoint = current->nextEndpoint();
mbed_official 0:a554658735bf 483 }
mbed_official 24:868cbfe611a7 484
mbed_official 0:a554658735bf 485 // modify tail
mbed_official 0:a554658735bf 486 switch (current->getType()) {
mbed_official 0:a554658735bf 487 case BULK_ENDPOINT:
mbed_official 0:a554658735bf 488 tailBulkEndpoint = prec;
mbed_official 0:a554658735bf 489 break;
mbed_official 0:a554658735bf 490 case INTERRUPT_ENDPOINT:
mbed_official 0:a554658735bf 491 tailInterruptEndpoint = prec;
mbed_official 0:a554658735bf 492 break;
mbed_official 13:b58a2204422f 493 default:
mbed_official 13:b58a2204422f 494 break;
mbed_official 0:a554658735bf 495 }
mbed_official 0:a554658735bf 496 }
mbed_official 0:a554658735bf 497 current->setState(USB_TYPE_FREE);
mbed_official 0:a554658735bf 498 return;
mbed_official 0:a554658735bf 499 }
mbed_official 0:a554658735bf 500 prec = current;
mbed_official 0:a554658735bf 501 current = current->nextEndpoint();
mbed_official 0:a554658735bf 502 }
mbed_official 0:a554658735bf 503 }
mbed_official 0:a554658735bf 504 }
mbed_official 0:a554658735bf 505
mbed_official 0:a554658735bf 506
mbed_official 0:a554658735bf 507 USBDeviceConnected * USBHost::getDevice(uint8_t index)
mbed_official 0:a554658735bf 508 {
samux 4:b320d68e98e7 509 if ((index >= MAX_DEVICE_CONNECTED) || (!deviceInUse[index])) {
mbed_official 0:a554658735bf 510 return NULL;
mbed_official 0:a554658735bf 511 }
mbed_official 0:a554658735bf 512 return (USBDeviceConnected*)&devices[index];
mbed_official 0:a554658735bf 513 }
mbed_official 0:a554658735bf 514
mbed_official 0:a554658735bf 515 // create an USBEndpoint descriptor. the USBEndpoint is not linked
mbed_official 0:a554658735bf 516 USBEndpoint * USBHost::newEndpoint(ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint32_t size, uint8_t addr)
mbed_official 0:a554658735bf 517 {
mbed_official 0:a554658735bf 518 int i = 0;
mbed_official 0:a554658735bf 519 HCED * ed = (HCED *)getED();
mbed_official 0:a554658735bf 520 HCTD* td_list[2] = { (HCTD*)getTD(), (HCTD*)getTD() };
mbed_official 0:a554658735bf 521
mbed_official 0:a554658735bf 522 memset((void *)td_list[0], 0x00, sizeof(HCTD));
mbed_official 0:a554658735bf 523 memset((void *)td_list[1], 0x00, sizeof(HCTD));
mbed_official 0:a554658735bf 524
mbed_official 0:a554658735bf 525 // search a free USBEndpoint
mbed_official 0:a554658735bf 526 for (i = 0; i < MAX_ENDPOINT; i++) {
mbed_official 0:a554658735bf 527 if (endpoints[i].getState() == USB_TYPE_FREE) {
mbed_official 0:a554658735bf 528 endpoints[i].init(ed, type, dir, size, addr, td_list);
samux 4:b320d68e98e7 529 USB_DBG("USBEndpoint created (%p): type: %d, dir: %d, size: %d, addr: %d, state: %s", &endpoints[i], type, dir, size, addr, endpoints[i].getStateString());
mbed_official 0:a554658735bf 530 return &endpoints[i];
mbed_official 0:a554658735bf 531 }
mbed_official 0:a554658735bf 532 }
mbed_official 0:a554658735bf 533 USB_ERR("could not allocate more endpoints!!!!");
mbed_official 0:a554658735bf 534 return NULL;
mbed_official 0:a554658735bf 535 }
mbed_official 0:a554658735bf 536
mbed_official 0:a554658735bf 537
mbed_official 0:a554658735bf 538 USB_TYPE USBHost::resetDevice(USBDeviceConnected * dev)
mbed_official 0:a554658735bf 539 {
mbed_official 0:a554658735bf 540 int index = findDevice(dev);
mbed_official 0:a554658735bf 541 if (index != -1) {
mbed_official 0:a554658735bf 542 USB_DBG("Resetting hub %d, port %d\n", dev->getHub(), dev->getPort());
samux 9:7671b6a8c363 543 Thread::wait(100);
mbed_official 0:a554658735bf 544 if (dev->getHub() == 0) {
mbed_official 0:a554658735bf 545 resetRootHub();
mbed_official 0:a554658735bf 546 }
mbed_official 0:a554658735bf 547 #if MAX_HUB_NB
mbed_official 0:a554658735bf 548 else {
mbed_official 0:a554658735bf 549 dev->getHubParent()->portReset(dev->getPort());
mbed_official 0:a554658735bf 550 }
mbed_official 0:a554658735bf 551 #endif
samux 9:7671b6a8c363 552 Thread::wait(100);
mbed_official 0:a554658735bf 553 deviceReset[index] = true;
mbed_official 0:a554658735bf 554 return USB_TYPE_OK;
mbed_official 0:a554658735bf 555 }
mbed_official 24:868cbfe611a7 556
mbed_official 0:a554658735bf 557 return USB_TYPE_ERROR;
mbed_official 0:a554658735bf 558 }
mbed_official 0:a554658735bf 559
mbed_official 0:a554658735bf 560 // link the USBEndpoint to the linked list and attach an USBEndpoint to a device
mbed_official 0:a554658735bf 561 bool USBHost::addEndpoint(USBDeviceConnected * dev, uint8_t intf_nb, USBEndpoint * ep)
mbed_official 0:a554658735bf 562 {
mbed_official 0:a554658735bf 563
mbed_official 0:a554658735bf 564 if (ep == NULL) {
mbed_official 0:a554658735bf 565 return false;
mbed_official 0:a554658735bf 566 }
mbed_official 0:a554658735bf 567
mbed_official 0:a554658735bf 568 HCED * prevEd;
mbed_official 0:a554658735bf 569
mbed_official 0:a554658735bf 570 // set device address in the USBEndpoint descriptor
mbed_official 0:a554658735bf 571 if (dev == NULL) {
mbed_official 0:a554658735bf 572 ep->setDeviceAddress(0);
mbed_official 0:a554658735bf 573 } else {
mbed_official 0:a554658735bf 574 ep->setDeviceAddress(dev->getAddress());
mbed_official 0:a554658735bf 575 }
mbed_official 0:a554658735bf 576
mbed_official 0:a554658735bf 577 if ((dev != NULL) && dev->getSpeed()) {
mbed_official 0:a554658735bf 578 ep->setSpeed(dev->getSpeed());
mbed_official 0:a554658735bf 579 }
mbed_official 24:868cbfe611a7 580
samux 4:b320d68e98e7 581 ep->setIntfNb(intf_nb);
mbed_official 0:a554658735bf 582
mbed_official 0:a554658735bf 583 // queue the new USBEndpoint on the ED list
mbed_official 0:a554658735bf 584 switch (ep->getType()) {
mbed_official 0:a554658735bf 585
mbed_official 0:a554658735bf 586 case CONTROL_ENDPOINT:
mbed_official 0:a554658735bf 587 prevEd = ( HCED*) controlHeadED();
mbed_official 0:a554658735bf 588 if (!prevEd) {
mbed_official 0:a554658735bf 589 updateControlHeadED((uint32_t) ep->getHCED());
samux 4:b320d68e98e7 590 USB_DBG_TRANSFER("First control USBEndpoint: %08X", (uint32_t) ep->getHCED());
mbed_official 0:a554658735bf 591 headControlEndpoint = ep;
mbed_official 0:a554658735bf 592 tailControlEndpoint = ep;
mbed_official 0:a554658735bf 593 return true;
mbed_official 0:a554658735bf 594 }
mbed_official 0:a554658735bf 595 tailControlEndpoint->queueEndpoint(ep);
mbed_official 0:a554658735bf 596 tailControlEndpoint = ep;
mbed_official 0:a554658735bf 597 return true;
mbed_official 0:a554658735bf 598
mbed_official 0:a554658735bf 599 case BULK_ENDPOINT:
mbed_official 0:a554658735bf 600 prevEd = ( HCED*) bulkHeadED();
mbed_official 0:a554658735bf 601 if (!prevEd) {
mbed_official 0:a554658735bf 602 updateBulkHeadED((uint32_t) ep->getHCED());
samux 4:b320d68e98e7 603 USB_DBG_TRANSFER("First bulk USBEndpoint: %08X\r\n", (uint32_t) ep->getHCED());
mbed_official 0:a554658735bf 604 headBulkEndpoint = ep;
mbed_official 0:a554658735bf 605 tailBulkEndpoint = ep;
mbed_official 0:a554658735bf 606 break;
mbed_official 0:a554658735bf 607 }
samux 4:b320d68e98e7 608 USB_DBG_TRANSFER("Queue BULK Ed %p after %p\r\n",ep->getHCED(), prevEd);
mbed_official 0:a554658735bf 609 tailBulkEndpoint->queueEndpoint(ep);
mbed_official 0:a554658735bf 610 tailBulkEndpoint = ep;
mbed_official 0:a554658735bf 611 break;
mbed_official 0:a554658735bf 612
mbed_official 0:a554658735bf 613 case INTERRUPT_ENDPOINT:
mbed_official 0:a554658735bf 614 prevEd = ( HCED*) interruptHeadED();
mbed_official 0:a554658735bf 615 if (!prevEd) {
mbed_official 0:a554658735bf 616 updateInterruptHeadED((uint32_t) ep->getHCED());
samux 4:b320d68e98e7 617 USB_DBG_TRANSFER("First interrupt USBEndpoint: %08X\r\n", (uint32_t) ep->getHCED());
mbed_official 0:a554658735bf 618 headInterruptEndpoint = ep;
mbed_official 0:a554658735bf 619 tailInterruptEndpoint = ep;
mbed_official 0:a554658735bf 620 break;
mbed_official 0:a554658735bf 621 }
samux 4:b320d68e98e7 622 USB_DBG_TRANSFER("Queue INTERRUPT Ed %p after %p\r\n",ep->getHCED(), prevEd);
mbed_official 0:a554658735bf 623 tailInterruptEndpoint->queueEndpoint(ep);
mbed_official 0:a554658735bf 624 tailInterruptEndpoint = ep;
mbed_official 0:a554658735bf 625 break;
mbed_official 0:a554658735bf 626 default:
mbed_official 0:a554658735bf 627 return false;
mbed_official 0:a554658735bf 628 }
mbed_official 24:868cbfe611a7 629
mbed_official 0:a554658735bf 630 ep->dev = dev;
mbed_official 0:a554658735bf 631 dev->addEndpoint(intf_nb, ep);
mbed_official 0:a554658735bf 632
mbed_official 0:a554658735bf 633 return true;
mbed_official 0:a554658735bf 634 }
mbed_official 0:a554658735bf 635
mbed_official 0:a554658735bf 636
mbed_official 0:a554658735bf 637 int USBHost::findDevice(USBDeviceConnected * dev)
mbed_official 0:a554658735bf 638 {
mbed_official 0:a554658735bf 639 for (int i = 0; i < MAX_DEVICE_CONNECTED; i++) {
mbed_official 0:a554658735bf 640 if (dev == &devices[i]) {
mbed_official 0:a554658735bf 641 return i;
mbed_official 0:a554658735bf 642 }
mbed_official 0:a554658735bf 643 }
mbed_official 0:a554658735bf 644 return -1;
mbed_official 0:a554658735bf 645 }
mbed_official 0:a554658735bf 646
mbed_official 0:a554658735bf 647 int USBHost::findDevice(uint8_t hub, uint8_t port, USBHostHub * hub_parent)
mbed_official 0:a554658735bf 648 {
mbed_official 0:a554658735bf 649 for (int i = 0; i < MAX_DEVICE_CONNECTED; i++) {
mbed_official 0:a554658735bf 650 if (devices[i].getHub() == hub && devices[i].getPort() == port) {
mbed_official 0:a554658735bf 651 if (hub_parent != NULL) {
mbed_official 0:a554658735bf 652 if (hub_parent == devices[i].getHubParent())
mbed_official 0:a554658735bf 653 return i;
mbed_official 0:a554658735bf 654 } else {
mbed_official 0:a554658735bf 655 return i;
mbed_official 0:a554658735bf 656 }
mbed_official 0:a554658735bf 657 }
mbed_official 0:a554658735bf 658 }
mbed_official 0:a554658735bf 659 return -1;
mbed_official 0:a554658735bf 660 }
mbed_official 0:a554658735bf 661
mbed_official 0:a554658735bf 662 void USBHost::printList(ENDPOINT_TYPE type)
mbed_official 0:a554658735bf 663 {
mbed_official 0:a554658735bf 664 #if DEBUG_EP_STATE
samux 4:b320d68e98e7 665 volatile HCED * hced;
mbed_official 0:a554658735bf 666 switch(type) {
mbed_official 0:a554658735bf 667 case CONTROL_ENDPOINT:
mbed_official 0:a554658735bf 668 hced = (HCED *)controlHeadED();
mbed_official 0:a554658735bf 669 break;
mbed_official 0:a554658735bf 670 case BULK_ENDPOINT:
mbed_official 0:a554658735bf 671 hced = (HCED *)bulkHeadED();
mbed_official 0:a554658735bf 672 break;
mbed_official 0:a554658735bf 673 case INTERRUPT_ENDPOINT:
mbed_official 0:a554658735bf 674 hced = (HCED *)interruptHeadED();
mbed_official 0:a554658735bf 675 break;
mbed_official 0:a554658735bf 676 }
samux 4:b320d68e98e7 677 volatile HCTD * hctd = NULL;
mbed_official 0:a554658735bf 678 const char * type_str = (type == BULK_ENDPOINT) ? "BULK" :
mbed_official 0:a554658735bf 679 ((type == INTERRUPT_ENDPOINT) ? "INTERRUPT" :
mbed_official 0:a554658735bf 680 ((type == CONTROL_ENDPOINT) ? "CONTROL" : "ISOCHRONOUS"));
mbed_official 0:a554658735bf 681 printf("State of %s:\r\n", type_str);
mbed_official 0:a554658735bf 682 while (hced != NULL) {
mbed_official 0:a554658735bf 683 uint8_t dir = ((hced->control & (3 << 11)) >> 11);
mbed_official 0:a554658735bf 684 printf("hced: %p [ADDR: %d, DIR: %s, EP_NB: 0x%X]\r\n", hced,
mbed_official 0:a554658735bf 685 hced->control & 0x7f,
mbed_official 0:a554658735bf 686 (dir == 1) ? "OUT" : ((dir == 0) ? "FROM_TD":"IN"),
mbed_official 0:a554658735bf 687 (hced->control & (0xf << 7)) >> 7);
mbed_official 0:a554658735bf 688 hctd = (HCTD *)((uint32_t)(hced->headTD) & ~(0xf));
samux 4:b320d68e98e7 689 while (hctd != hced->tailTD) {
mbed_official 0:a554658735bf 690 printf("\thctd: %p [DIR: %s]\r\n", hctd, ((hctd->control & (3 << 19)) >> 19) == 1 ? "OUT" : "IN");
samux 4:b320d68e98e7 691 hctd = hctd->nextTD;
mbed_official 0:a554658735bf 692 }
mbed_official 0:a554658735bf 693 printf("\thctd: %p\r\n", hctd);
samux 4:b320d68e98e7 694 hced = hced->nextED;
mbed_official 0:a554658735bf 695 }
mbed_official 0:a554658735bf 696 printf("\r\n\r\n");
mbed_official 0:a554658735bf 697 #endif
mbed_official 0:a554658735bf 698 }
mbed_official 0:a554658735bf 699
mbed_official 0:a554658735bf 700
mbed_official 0:a554658735bf 701 // add a transfer on the TD linked list
mbed_official 0:a554658735bf 702 USB_TYPE USBHost::addTransfer(USBEndpoint * ed, uint8_t * buf, uint32_t len)
mbed_official 0:a554658735bf 703 {
samux 9:7671b6a8c363 704 td_mutex.lock();
mbed_official 0:a554658735bf 705
mbed_official 0:a554658735bf 706 // allocate a TD which will be freed in TDcompletion
mbed_official 0:a554658735bf 707 volatile HCTD * td = ed->getNextTD();
mbed_official 0:a554658735bf 708 if (td == NULL) {
mbed_official 0:a554658735bf 709 return USB_TYPE_ERROR;
mbed_official 0:a554658735bf 710 }
mbed_official 0:a554658735bf 711
mbed_official 0:a554658735bf 712 uint32_t token = (ed->isSetup() ? TD_SETUP : ( (ed->getDir() == IN) ? TD_IN : TD_OUT ));
mbed_official 0:a554658735bf 713
mbed_official 0:a554658735bf 714 uint32_t td_toggle;
mbed_official 0:a554658735bf 715
mbed_official 0:a554658735bf 716 if (ed->getType() == CONTROL_ENDPOINT) {
mbed_official 0:a554658735bf 717 if (ed->isSetup()) {
mbed_official 0:a554658735bf 718 td_toggle = TD_TOGGLE_0;
mbed_official 0:a554658735bf 719 } else {
mbed_official 0:a554658735bf 720 td_toggle = TD_TOGGLE_1;
mbed_official 0:a554658735bf 721 }
mbed_official 0:a554658735bf 722 } else {
mbed_official 0:a554658735bf 723 td_toggle = 0;
mbed_official 0:a554658735bf 724 }
mbed_official 0:a554658735bf 725
mbed_official 0:a554658735bf 726 td->control = (TD_ROUNDING | token | TD_DELAY_INT(0) | td_toggle | TD_CC);
mbed_official 0:a554658735bf 727 td->currBufPtr = buf;
mbed_official 0:a554658735bf 728 td->bufEnd = (buf + (len - 1));
mbed_official 0:a554658735bf 729
mbed_official 0:a554658735bf 730 ENDPOINT_TYPE type = ed->getType();
mbed_official 0:a554658735bf 731
mbed_official 0:a554658735bf 732 disableList(type);
mbed_official 0:a554658735bf 733 ed->queueTransfer();
mbed_official 0:a554658735bf 734 printList(type);
mbed_official 0:a554658735bf 735 enableList(type);
mbed_official 24:868cbfe611a7 736
samux 9:7671b6a8c363 737 td_mutex.unlock();
mbed_official 0:a554658735bf 738
mbed_official 0:a554658735bf 739 return USB_TYPE_PROCESSING;
mbed_official 0:a554658735bf 740 }
mbed_official 0:a554658735bf 741
mbed_official 0:a554658735bf 742
mbed_official 0:a554658735bf 743
mbed_official 0:a554658735bf 744 USB_TYPE USBHost::getDeviceDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_dev_descr)
mbed_official 0:a554658735bf 745 {
mbed_official 0:a554658735bf 746 USB_TYPE t = controlRead( dev,
mbed_official 0:a554658735bf 747 USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE,
mbed_official 0:a554658735bf 748 GET_DESCRIPTOR,
mbed_official 0:a554658735bf 749 (DEVICE_DESCRIPTOR << 8) | (0),
mbed_official 0:a554658735bf 750 0, buf, MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf));
mbed_official 0:a554658735bf 751 if (len_dev_descr)
mbed_official 0:a554658735bf 752 *len_dev_descr = MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf);
mbed_official 24:868cbfe611a7 753
mbed_official 0:a554658735bf 754 return t;
mbed_official 0:a554658735bf 755 }
mbed_official 0:a554658735bf 756
mbed_official 0:a554658735bf 757 USB_TYPE USBHost::getConfigurationDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_conf_descr)
mbed_official 0:a554658735bf 758 {
mbed_official 0:a554658735bf 759 USB_TYPE res;
mbed_official 0:a554658735bf 760 uint16_t total_conf_descr_length = 0;
mbed_official 0:a554658735bf 761
mbed_official 0:a554658735bf 762 // fourth step: get the beginning of the configuration descriptor to have the total length of the conf descr
mbed_official 0:a554658735bf 763 res = controlRead( dev,
mbed_official 0:a554658735bf 764 USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE,
mbed_official 0:a554658735bf 765 GET_DESCRIPTOR,
mbed_official 0:a554658735bf 766 (CONFIGURATION_DESCRIPTOR << 8) | (0),
mbed_official 0:a554658735bf 767 0, buf, CONFIGURATION_DESCRIPTOR_LENGTH);
mbed_official 0:a554658735bf 768
mbed_official 0:a554658735bf 769 if (res != USB_TYPE_OK) {
mbed_official 0:a554658735bf 770 USB_ERR("GET CONF 1 DESCR FAILED");
mbed_official 0:a554658735bf 771 return res;
mbed_official 0:a554658735bf 772 }
mbed_official 0:a554658735bf 773 total_conf_descr_length = buf[2] | (buf[3] << 8);
mbed_official 0:a554658735bf 774 total_conf_descr_length = MIN(max_len_buf, total_conf_descr_length);
mbed_official 24:868cbfe611a7 775
mbed_official 0:a554658735bf 776 if (len_conf_descr)
mbed_official 0:a554658735bf 777 *len_conf_descr = total_conf_descr_length;
mbed_official 24:868cbfe611a7 778
mbed_official 0:a554658735bf 779 USB_DBG("TOTAL_LENGTH: %d \t NUM_INTERF: %d", total_conf_descr_length, buf[4]);
mbed_official 0:a554658735bf 780
mbed_official 0:a554658735bf 781 return controlRead( dev,
mbed_official 0:a554658735bf 782 USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE,
mbed_official 0:a554658735bf 783 GET_DESCRIPTOR,
mbed_official 0:a554658735bf 784 (CONFIGURATION_DESCRIPTOR << 8) | (0),
mbed_official 0:a554658735bf 785 0, buf, total_conf_descr_length);
mbed_official 0:a554658735bf 786 }
mbed_official 0:a554658735bf 787
mbed_official 0:a554658735bf 788
mbed_official 0:a554658735bf 789 USB_TYPE USBHost::setAddress(USBDeviceConnected * dev, uint8_t address) {
mbed_official 0:a554658735bf 790 return controlWrite( dev,
mbed_official 0:a554658735bf 791 USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE,
mbed_official 0:a554658735bf 792 SET_ADDRESS,
mbed_official 0:a554658735bf 793 address,
mbed_official 0:a554658735bf 794 0, NULL, 0);
mbed_official 24:868cbfe611a7 795
mbed_official 0:a554658735bf 796 }
mbed_official 0:a554658735bf 797
mbed_official 0:a554658735bf 798 USB_TYPE USBHost::setConfiguration(USBDeviceConnected * dev, uint8_t conf)
mbed_official 0:a554658735bf 799 {
mbed_official 0:a554658735bf 800 return controlWrite( dev,
mbed_official 0:a554658735bf 801 USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE,
mbed_official 0:a554658735bf 802 SET_CONFIGURATION,
mbed_official 0:a554658735bf 803 conf,
mbed_official 0:a554658735bf 804 0, NULL, 0);
mbed_official 0:a554658735bf 805 }
mbed_official 0:a554658735bf 806
samux 4:b320d68e98e7 807 uint8_t USBHost::numberDriverAttached(USBDeviceConnected * dev) {
samux 4:b320d68e98e7 808 int index = findDevice(dev);
samux 4:b320d68e98e7 809 uint8_t cnt = 0;
samux 4:b320d68e98e7 810 if (index == -1)
samux 4:b320d68e98e7 811 return 0;
samux 4:b320d68e98e7 812 for (uint8_t i = 0; i < MAX_INTF; i++) {
samux 4:b320d68e98e7 813 if (deviceAttachedDriver[index][i])
samux 4:b320d68e98e7 814 cnt++;
samux 4:b320d68e98e7 815 }
samux 4:b320d68e98e7 816 return cnt;
samux 4:b320d68e98e7 817 }
mbed_official 0:a554658735bf 818
mbed_official 0:a554658735bf 819 // enumerate a device with the control USBEndpoint
mbed_official 0:a554658735bf 820 USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerator)
mbed_official 0:a554658735bf 821 {
mbed_official 0:a554658735bf 822 uint16_t total_conf_descr_length = 0;
mbed_official 0:a554658735bf 823 USB_TYPE res;
mbed_official 24:868cbfe611a7 824
mbed_official 23:759ec18ee1a7 825 do
mbed_official 23:759ec18ee1a7 826 {
mbed_official 23:759ec18ee1a7 827 Lock lock(this);
mbed_official 24:868cbfe611a7 828
mbed_official 23:759ec18ee1a7 829 // don't enumerate a device which all interfaces are registered to a specific driver
mbed_official 23:759ec18ee1a7 830 int index = findDevice(dev);
mbed_official 24:868cbfe611a7 831
mbed_official 23:759ec18ee1a7 832 if (index == -1) {
mbed_official 23:759ec18ee1a7 833 return USB_TYPE_ERROR;
mbed_official 23:759ec18ee1a7 834 }
mbed_official 24:868cbfe611a7 835
mbed_official 23:759ec18ee1a7 836 uint8_t nb_intf_attached = numberDriverAttached(dev);
mbed_official 23:759ec18ee1a7 837 USB_DBG("dev: %p nb_intf: %d", dev, dev->getNbIntf());
mbed_official 23:759ec18ee1a7 838 USB_DBG("dev: %p nb_intf_attached: %d", dev, nb_intf_attached);
mbed_official 23:759ec18ee1a7 839 if ((nb_intf_attached != 0) && (dev->getNbIntf() == nb_intf_attached)) {
mbed_official 23:759ec18ee1a7 840 USB_DBG("Don't enumerate dev: %p because all intf are registered with a driver", dev);
mbed_official 23:759ec18ee1a7 841 return USB_TYPE_OK;
mbed_official 23:759ec18ee1a7 842 }
mbed_official 24:868cbfe611a7 843
mbed_official 23:759ec18ee1a7 844 USB_DBG("Enumerate dev: %p", dev);
mbed_official 24:868cbfe611a7 845
mbed_official 23:759ec18ee1a7 846 // third step: get the whole device descriptor to see vid, pid
mbed_official 23:759ec18ee1a7 847 res = getDeviceDescriptor(dev, data, DEVICE_DESCRIPTOR_LENGTH);
mbed_official 0:a554658735bf 848
mbed_official 23:759ec18ee1a7 849 if (res != USB_TYPE_OK) {
mbed_official 23:759ec18ee1a7 850 USB_DBG("GET DEV DESCR FAILED");
mbed_official 23:759ec18ee1a7 851 return res;
mbed_official 23:759ec18ee1a7 852 }
mbed_official 24:868cbfe611a7 853
mbed_official 23:759ec18ee1a7 854 dev->setClass(data[4]);
mbed_official 23:759ec18ee1a7 855 dev->setSubClass(data[5]);
mbed_official 23:759ec18ee1a7 856 dev->setProtocol(data[6]);
mbed_official 23:759ec18ee1a7 857 dev->setVid(data[8] | (data[9] << 8));
mbed_official 23:759ec18ee1a7 858 dev->setPid(data[10] | (data[11] << 8));
mbed_official 23:759ec18ee1a7 859 USB_DBG("CLASS: %02X \t VID: %04X \t PID: %04X", data[4], data[8] | (data[9] << 8), data[10] | (data[11] << 8));
mbed_official 0:a554658735bf 860
mbed_official 23:759ec18ee1a7 861 pEnumerator->setVidPid( data[8] | (data[9] << 8), data[10] | (data[11] << 8) );
mbed_official 0:a554658735bf 862
mbed_official 23:759ec18ee1a7 863 res = getConfigurationDescriptor(dev, data, sizeof(data), &total_conf_descr_length);
mbed_official 23:759ec18ee1a7 864 if (res != USB_TYPE_OK) {
mbed_official 23:759ec18ee1a7 865 return res;
mbed_official 23:759ec18ee1a7 866 }
mbed_official 0:a554658735bf 867
mbed_official 23:759ec18ee1a7 868 #if (DEBUG > 3)
mbed_official 23:759ec18ee1a7 869 USB_DBG("CONFIGURATION DESCRIPTOR:\r\n");
mbed_official 23:759ec18ee1a7 870 for (int i = 0; i < total_conf_descr_length; i++)
mbed_official 23:759ec18ee1a7 871 printf("%02X ", data[i]);
mbed_official 23:759ec18ee1a7 872 printf("\r\n\r\n");
mbed_official 23:759ec18ee1a7 873 #endif
mbed_official 0:a554658735bf 874
mbed_official 23:759ec18ee1a7 875 // Parse the configuration descriptor
mbed_official 23:759ec18ee1a7 876 parseConfDescr(dev, data, total_conf_descr_length, pEnumerator);
mbed_official 0:a554658735bf 877
mbed_official 23:759ec18ee1a7 878 // only set configuration if not enumerated before
mbed_official 23:759ec18ee1a7 879 if (!dev->isEnumerated()) {
mbed_official 24:868cbfe611a7 880
mbed_official 23:759ec18ee1a7 881 USB_DBG("Set configuration 1 on dev: %p", dev);
mbed_official 23:759ec18ee1a7 882 // sixth step: set configuration (only 1 supported)
mbed_official 23:759ec18ee1a7 883 res = setConfiguration(dev, 1);
mbed_official 0:a554658735bf 884
mbed_official 23:759ec18ee1a7 885 if (res != USB_TYPE_OK) {
mbed_official 23:759ec18ee1a7 886 USB_DBG("SET CONF FAILED");
mbed_official 23:759ec18ee1a7 887 return res;
mbed_official 23:759ec18ee1a7 888 }
mbed_official 23:759ec18ee1a7 889 }
mbed_official 24:868cbfe611a7 890
mbed_official 23:759ec18ee1a7 891 dev->setEnumerated();
mbed_official 0:a554658735bf 892
mbed_official 23:759ec18ee1a7 893 // Now the device is enumerated!
mbed_official 23:759ec18ee1a7 894 USB_DBG("dev %p is enumerated\r\n", dev);
mbed_official 24:868cbfe611a7 895
mbed_official 23:759ec18ee1a7 896 } while(0);
mbed_official 0:a554658735bf 897
mbed_official 0:a554658735bf 898 // Some devices may require this delay
mbed_official 23:759ec18ee1a7 899 Thread::wait(100);
mbed_official 0:a554658735bf 900
mbed_official 0:a554658735bf 901 return USB_TYPE_OK;
mbed_official 0:a554658735bf 902 }
mbed_official 0:a554658735bf 903 // this method fills the USBDeviceConnected object: class,.... . It also add endpoints found in the descriptor.
mbed_official 0:a554658735bf 904 void USBHost::parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len, IUSBEnumerator* pEnumerator)
mbed_official 0:a554658735bf 905 {
mbed_official 0:a554658735bf 906 uint32_t index = 0;
mbed_official 0:a554658735bf 907 uint32_t len_desc = 0;
mbed_official 0:a554658735bf 908 uint8_t id = 0;
mbed_official 0:a554658735bf 909 int nb_endpoints_used = 0;
mbed_official 0:a554658735bf 910 USBEndpoint * ep = NULL;
mbed_official 0:a554658735bf 911 uint8_t intf_nb = 0;
mbed_official 0:a554658735bf 912 bool parsing_intf = false;
samux 4:b320d68e98e7 913 uint8_t current_intf = 0;
mbed_official 0:a554658735bf 914
mbed_official 0:a554658735bf 915 while (index < len) {
mbed_official 0:a554658735bf 916 len_desc = conf_descr[index];
mbed_official 0:a554658735bf 917 id = conf_descr[index+1];
mbed_official 0:a554658735bf 918 switch (id) {
mbed_official 0:a554658735bf 919 case CONFIGURATION_DESCRIPTOR:
samux 4:b320d68e98e7 920 USB_DBG("dev: %p has %d intf", dev, conf_descr[4]);
samux 4:b320d68e98e7 921 dev->setNbIntf(conf_descr[4]);
mbed_official 0:a554658735bf 922 break;
mbed_official 0:a554658735bf 923 case INTERFACE_DESCRIPTOR:
samux 4:b320d68e98e7 924 if(pEnumerator->parseInterface(conf_descr[index + 2], conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7])) {
mbed_official 0:a554658735bf 925 if (intf_nb++ <= MAX_INTF) {
samux 4:b320d68e98e7 926 current_intf = conf_descr[index + 2];
samux 4:b320d68e98e7 927 dev->addInterface(current_intf, conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7]);
mbed_official 0:a554658735bf 928 nb_endpoints_used = 0;
samux 4:b320d68e98e7 929 USB_DBG("ADD INTF %d on device %p: class: %d, subclass: %d, proto: %d", current_intf, dev, conf_descr[index + 5],conf_descr[index + 6],conf_descr[index + 7]);
mbed_official 0:a554658735bf 930 } else {
mbed_official 0:a554658735bf 931 USB_DBG("Drop intf...");
mbed_official 0:a554658735bf 932 }
mbed_official 0:a554658735bf 933 parsing_intf = true;
mbed_official 0:a554658735bf 934 } else {
mbed_official 0:a554658735bf 935 parsing_intf = false;
mbed_official 0:a554658735bf 936 }
mbed_official 0:a554658735bf 937 break;
mbed_official 0:a554658735bf 938 case ENDPOINT_DESCRIPTOR:
mbed_official 0:a554658735bf 939 if (parsing_intf && (intf_nb <= MAX_INTF) ) {
mbed_official 0:a554658735bf 940 if (nb_endpoints_used < MAX_ENDPOINT_PER_INTERFACE) {
samux 4:b320d68e98e7 941 if( pEnumerator->useEndpoint(current_intf, (ENDPOINT_TYPE)(conf_descr[index + 3] & 0x03), (ENDPOINT_DIRECTION)((conf_descr[index + 2] >> 7) + 1)) ) {
mbed_official 0:a554658735bf 942 // if the USBEndpoint is isochronous -> skip it (TODO: fix this)
mbed_official 0:a554658735bf 943 if ((conf_descr[index + 3] & 0x03) != ISOCHRONOUS_ENDPOINT) {
mbed_official 0:a554658735bf 944 ep = newEndpoint((ENDPOINT_TYPE)(conf_descr[index+3] & 0x03),
mbed_official 0:a554658735bf 945 (ENDPOINT_DIRECTION)((conf_descr[index + 2] >> 7) + 1),
mbed_official 0:a554658735bf 946 conf_descr[index + 4] | (conf_descr[index + 5] << 8),
mbed_official 0:a554658735bf 947 conf_descr[index + 2] & 0x0f);
samux 4:b320d68e98e7 948 USB_DBG("ADD USBEndpoint %p, on interf %d on device %p", ep, current_intf, dev);
mbed_official 0:a554658735bf 949 if (ep != NULL && dev != NULL) {
samux 4:b320d68e98e7 950 addEndpoint(dev, current_intf, ep);
mbed_official 0:a554658735bf 951 } else {
mbed_official 0:a554658735bf 952 USB_DBG("EP NULL");
mbed_official 0:a554658735bf 953 }
mbed_official 0:a554658735bf 954 nb_endpoints_used++;
mbed_official 0:a554658735bf 955 } else {
mbed_official 0:a554658735bf 956 USB_DBG("ISO USBEndpoint NOT SUPPORTED");
mbed_official 0:a554658735bf 957 }
mbed_official 0:a554658735bf 958 }
mbed_official 0:a554658735bf 959 }
mbed_official 0:a554658735bf 960 }
mbed_official 0:a554658735bf 961 break;
mbed_official 0:a554658735bf 962 case HID_DESCRIPTOR:
mbed_official 0:a554658735bf 963 lenReportDescr = conf_descr[index + 7] | (conf_descr[index + 8] << 8);
mbed_official 0:a554658735bf 964 break;
mbed_official 0:a554658735bf 965 default:
mbed_official 0:a554658735bf 966 break;
mbed_official 0:a554658735bf 967 }
mbed_official 0:a554658735bf 968 index += len_desc;
mbed_official 0:a554658735bf 969 }
mbed_official 0:a554658735bf 970 }
mbed_official 0:a554658735bf 971
mbed_official 0:a554658735bf 972
mbed_official 0:a554658735bf 973 USB_TYPE USBHost::bulkWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking)
mbed_official 0:a554658735bf 974 {
mbed_official 0:a554658735bf 975 return generalTransfer(dev, ep, buf, len, blocking, BULK_ENDPOINT, true);
mbed_official 0:a554658735bf 976 }
mbed_official 0:a554658735bf 977
mbed_official 0:a554658735bf 978 USB_TYPE USBHost::bulkRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking)
mbed_official 0:a554658735bf 979 {
mbed_official 0:a554658735bf 980 return generalTransfer(dev, ep, buf, len, blocking, BULK_ENDPOINT, false);
mbed_official 0:a554658735bf 981 }
mbed_official 0:a554658735bf 982
mbed_official 0:a554658735bf 983 USB_TYPE USBHost::interruptWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking)
mbed_official 0:a554658735bf 984 {
mbed_official 0:a554658735bf 985 return generalTransfer(dev, ep, buf, len, blocking, INTERRUPT_ENDPOINT, true);
mbed_official 0:a554658735bf 986 }
mbed_official 0:a554658735bf 987
mbed_official 0:a554658735bf 988 USB_TYPE USBHost::interruptRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking)
mbed_official 0:a554658735bf 989 {
mbed_official 0:a554658735bf 990 return generalTransfer(dev, ep, buf, len, blocking, INTERRUPT_ENDPOINT, false);
mbed_official 0:a554658735bf 991 }
mbed_official 0:a554658735bf 992
mbed_official 0:a554658735bf 993 USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking, ENDPOINT_TYPE type, bool write) {
mbed_official 24:868cbfe611a7 994
mbed_official 0:a554658735bf 995 #if DEBUG_TRANSFER
mbed_official 0:a554658735bf 996 const char * type_str = (type == BULK_ENDPOINT) ? "BULK" : ((type == INTERRUPT_ENDPOINT) ? "INTERRUPT" : "ISOCHRONOUS");
samux 4:b320d68e98e7 997 USB_DBG_TRANSFER("----- %s %s [dev: %p - %s - hub: %d - port: %d - addr: %d - ep: %02X]------", type_str, (write) ? "WRITE" : "READ", dev, dev->getName(ep->getIntfNb()), dev->getHub(), dev->getPort(), dev->getAddress(), ep->getAddress());
mbed_official 0:a554658735bf 998 #endif
mbed_official 24:868cbfe611a7 999
mbed_official 23:759ec18ee1a7 1000 Lock lock(this);
mbed_official 24:868cbfe611a7 1001
mbed_official 0:a554658735bf 1002 USB_TYPE res;
mbed_official 0:a554658735bf 1003 ENDPOINT_DIRECTION dir = (write) ? OUT : IN;
mbed_official 24:868cbfe611a7 1004
mbed_official 0:a554658735bf 1005 if (dev == NULL) {
mbed_official 0:a554658735bf 1006 USB_ERR("dev NULL");
mbed_official 0:a554658735bf 1007 return USB_TYPE_ERROR;
mbed_official 0:a554658735bf 1008 }
mbed_official 0:a554658735bf 1009
mbed_official 0:a554658735bf 1010 if (ep == NULL) {
mbed_official 0:a554658735bf 1011 USB_ERR("ep NULL");
mbed_official 0:a554658735bf 1012 return USB_TYPE_ERROR;
mbed_official 0:a554658735bf 1013 }
mbed_official 0:a554658735bf 1014
mbed_official 0:a554658735bf 1015 if (ep->getState() != USB_TYPE_IDLE) {
samux 4:b320d68e98e7 1016 USB_WARN("[ep: %p - dev: %p - %s] NOT IDLE: %s", ep, ep->dev, ep->dev->getName(ep->getIntfNb()), ep->getStateString());
mbed_official 0:a554658735bf 1017 return ep->getState();
mbed_official 0:a554658735bf 1018 }
mbed_official 0:a554658735bf 1019
mbed_official 0:a554658735bf 1020 if ((ep->getDir() != dir) || (ep->getType() != type)) {
mbed_official 0:a554658735bf 1021 USB_ERR("[ep: %p - dev: %p] wrong dir or bad USBEndpoint type", ep, ep->dev);
mbed_official 0:a554658735bf 1022 return USB_TYPE_ERROR;
mbed_official 0:a554658735bf 1023 }
mbed_official 0:a554658735bf 1024
mbed_official 0:a554658735bf 1025 if (dev->getAddress() != ep->getDeviceAddress()) {
mbed_official 0:a554658735bf 1026 USB_ERR("[ep: %p - dev: %p] USBEndpoint addr and device addr don't match", ep, ep->dev);
mbed_official 0:a554658735bf 1027 return USB_TYPE_ERROR;
mbed_official 0:a554658735bf 1028 }
mbed_official 24:868cbfe611a7 1029
mbed_official 0:a554658735bf 1030 #if DEBUG_TRANSFER
mbed_official 0:a554658735bf 1031 if (write) {
mbed_official 0:a554658735bf 1032 USB_DBG_TRANSFER("%s WRITE buffer", type_str);
mbed_official 0:a554658735bf 1033 for (int i = 0; i < ep->getLengthTransferred(); i++)
mbed_official 0:a554658735bf 1034 printf("%02X ", buf[i]);
mbed_official 0:a554658735bf 1035 printf("\r\n\r\n");
mbed_official 0:a554658735bf 1036 }
mbed_official 0:a554658735bf 1037 #endif
mbed_official 0:a554658735bf 1038 addTransfer(ep, buf, len);
mbed_official 0:a554658735bf 1039
mbed_official 0:a554658735bf 1040 if (blocking) {
mbed_official 24:868cbfe611a7 1041
samux 9:7671b6a8c363 1042 ep->ep_queue.get();
samux 9:7671b6a8c363 1043 res = ep->getState();
mbed_official 24:868cbfe611a7 1044
samux 4:b320d68e98e7 1045 USB_DBG_TRANSFER("%s TRANSFER res: %s on ep: %p\r\n", type_str, ep->getStateString(), ep);
mbed_official 24:868cbfe611a7 1046
mbed_official 0:a554658735bf 1047 if (res != USB_TYPE_IDLE) {
mbed_official 0:a554658735bf 1048 return res;
mbed_official 0:a554658735bf 1049 }
mbed_official 24:868cbfe611a7 1050
mbed_official 0:a554658735bf 1051 return USB_TYPE_OK;
mbed_official 0:a554658735bf 1052 }
mbed_official 24:868cbfe611a7 1053
mbed_official 0:a554658735bf 1054 return USB_TYPE_PROCESSING;
mbed_official 0:a554658735bf 1055
mbed_official 0:a554658735bf 1056 }
mbed_official 0:a554658735bf 1057
mbed_official 0:a554658735bf 1058
mbed_official 0:a554658735bf 1059 USB_TYPE USBHost::controlRead(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) {
mbed_official 0:a554658735bf 1060 return controlTransfer(dev, requestType, request, value, index, buf, len, false);
mbed_official 0:a554658735bf 1061 }
mbed_official 0:a554658735bf 1062
mbed_official 0:a554658735bf 1063 USB_TYPE USBHost::controlWrite(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) {
mbed_official 0:a554658735bf 1064 return controlTransfer(dev, requestType, request, value, index, buf, len, true);
mbed_official 0:a554658735bf 1065 }
mbed_official 0:a554658735bf 1066
mbed_official 0:a554658735bf 1067 USB_TYPE USBHost::controlTransfer(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len, bool write)
mbed_official 0:a554658735bf 1068 {
mbed_official 23:759ec18ee1a7 1069 Lock lock(this);
samux 4:b320d68e98e7 1070 USB_DBG_TRANSFER("----- CONTROL %s [dev: %p - hub: %d - port: %d] ------", (write) ? "WRITE" : "READ", dev, dev->getHub(), dev->getPort());
mbed_official 0:a554658735bf 1071
mbed_official 0:a554658735bf 1072 int length_transfer = len;
mbed_official 0:a554658735bf 1073 USB_TYPE res;
mbed_official 0:a554658735bf 1074 uint32_t token;
mbed_official 0:a554658735bf 1075
mbed_official 0:a554658735bf 1076 control->setSpeed(dev->getSpeed());
mbed_official 0:a554658735bf 1077 control->setSize(dev->getSizeControlEndpoint());
mbed_official 0:a554658735bf 1078 if (dev->isActiveAddress()) {
mbed_official 0:a554658735bf 1079 control->setDeviceAddress(dev->getAddress());
mbed_official 0:a554658735bf 1080 } else {
mbed_official 0:a554658735bf 1081 control->setDeviceAddress(0);
mbed_official 0:a554658735bf 1082 }
samux 4:b320d68e98e7 1083
mbed_official 0:a554658735bf 1084 USB_DBG_TRANSFER("Control transfer on device: %d\r\n", control->getDeviceAddress());
mbed_official 0:a554658735bf 1085 fillControlBuf(requestType, request, value, index, len);
mbed_official 0:a554658735bf 1086
mbed_official 0:a554658735bf 1087 #if DEBUG_TRANSFER
mbed_official 0:a554658735bf 1088 USB_DBG_TRANSFER("SETUP PACKET: ");
mbed_official 0:a554658735bf 1089 for (int i = 0; i < 8; i++)
mbed_official 0:a554658735bf 1090 printf("%01X ", setupPacket[i]);
mbed_official 0:a554658735bf 1091 printf("\r\n");
mbed_official 0:a554658735bf 1092 #endif
mbed_official 0:a554658735bf 1093
mbed_official 0:a554658735bf 1094 control->setNextToken(TD_SETUP);
mbed_official 0:a554658735bf 1095 addTransfer(control, (uint8_t*)setupPacket, 8);
mbed_official 0:a554658735bf 1096
samux 9:7671b6a8c363 1097 control->ep_queue.get();
samux 9:7671b6a8c363 1098 res = control->getState();
mbed_official 0:a554658735bf 1099
mbed_official 0:a554658735bf 1100 USB_DBG_TRANSFER("CONTROL setup stage %s", control->getStateString());
mbed_official 0:a554658735bf 1101
mbed_official 0:a554658735bf 1102 if (res != USB_TYPE_IDLE) {
mbed_official 0:a554658735bf 1103 return res;
mbed_official 0:a554658735bf 1104 }
mbed_official 0:a554658735bf 1105
mbed_official 0:a554658735bf 1106 if (length_transfer) {
mbed_official 0:a554658735bf 1107 token = (write) ? TD_OUT : TD_IN;
mbed_official 0:a554658735bf 1108 control->setNextToken(token);
mbed_official 0:a554658735bf 1109 addTransfer(control, (uint8_t *)buf, length_transfer);
mbed_official 0:a554658735bf 1110
samux 9:7671b6a8c363 1111 control->ep_queue.get();
samux 9:7671b6a8c363 1112 res = control->getState();
mbed_official 0:a554658735bf 1113
mbed_official 0:a554658735bf 1114 #if DEBUG_TRANSFER
mbed_official 0:a554658735bf 1115 USB_DBG_TRANSFER("CONTROL %s stage %s", (write) ? "WRITE" : "READ", control->getStateString());
mbed_official 0:a554658735bf 1116 if (write) {
mbed_official 0:a554658735bf 1117 USB_DBG_TRANSFER("CONTROL WRITE buffer");
mbed_official 0:a554658735bf 1118 for (int i = 0; i < control->getLengthTransferred(); i++)
mbed_official 0:a554658735bf 1119 printf("%02X ", buf[i]);
mbed_official 0:a554658735bf 1120 printf("\r\n\r\n");
mbed_official 0:a554658735bf 1121 } else {
mbed_official 0:a554658735bf 1122 USB_DBG_TRANSFER("CONTROL READ SUCCESS [%d bytes transferred]", control->getLengthTransferred());
mbed_official 0:a554658735bf 1123 for (int i = 0; i < control->getLengthTransferred(); i++)
mbed_official 0:a554658735bf 1124 printf("%02X ", buf[i]);
mbed_official 0:a554658735bf 1125 printf("\r\n\r\n");
mbed_official 0:a554658735bf 1126 }
mbed_official 0:a554658735bf 1127 #endif
mbed_official 0:a554658735bf 1128
mbed_official 0:a554658735bf 1129 if (res != USB_TYPE_IDLE) {
mbed_official 0:a554658735bf 1130 return res;
mbed_official 0:a554658735bf 1131 }
mbed_official 0:a554658735bf 1132 }
mbed_official 0:a554658735bf 1133
mbed_official 0:a554658735bf 1134 token = (write) ? TD_IN : TD_OUT;
mbed_official 0:a554658735bf 1135 control->setNextToken(token);
mbed_official 0:a554658735bf 1136 addTransfer(control, NULL, 0);
mbed_official 0:a554658735bf 1137
samux 9:7671b6a8c363 1138 control->ep_queue.get();
samux 9:7671b6a8c363 1139 res = control->getState();
mbed_official 0:a554658735bf 1140
mbed_official 0:a554658735bf 1141 USB_DBG_TRANSFER("CONTROL ack stage %s", control->getStateString());
mbed_official 0:a554658735bf 1142
mbed_official 0:a554658735bf 1143 if (res != USB_TYPE_IDLE)
mbed_official 0:a554658735bf 1144 return res;
mbed_official 0:a554658735bf 1145
mbed_official 0:a554658735bf 1146 return USB_TYPE_OK;
mbed_official 0:a554658735bf 1147 }
mbed_official 0:a554658735bf 1148
mbed_official 0:a554658735bf 1149
mbed_official 0:a554658735bf 1150 void USBHost::fillControlBuf(uint8_t requestType, uint8_t request, uint16_t value, uint16_t index, int len)
mbed_official 0:a554658735bf 1151 {
mbed_official 0:a554658735bf 1152 setupPacket[0] = requestType;
mbed_official 0:a554658735bf 1153 setupPacket[1] = request;
mbed_official 13:b58a2204422f 1154 setupPacket[2] = (uint8_t) value;
mbed_official 13:b58a2204422f 1155 setupPacket[3] = (uint8_t) (value >> 8);
mbed_official 13:b58a2204422f 1156 setupPacket[4] = (uint8_t) index;
mbed_official 13:b58a2204422f 1157 setupPacket[5] = (uint8_t) (index >> 8);
mbed_official 13:b58a2204422f 1158 setupPacket[6] = (uint8_t) len;
mbed_official 13:b58a2204422f 1159 setupPacket[7] = (uint8_t) (len >> 8);
mbed_official 0:a554658735bf 1160 }