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:
Wed Oct 16 14:15:18 2013 +0100
Revision:
17:c7b1b8451598
Parent:
16:ab8c9118524e
Child:
22:f4191d3837dc
Synchronized with git revision d8c3822c4c4e995cd7eaff0ce99f2d3284dde9cd

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