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:
samux
Date:
Mon Mar 18 14:46:56 2013 +0000
Revision:
10:0c11cf1cc218
Parent:
9:7671b6a8c363
Child:
13:b58a2204422f
fixed skip bit - fixed max size conf descriptor

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