Renesas / Mbed OS SDG_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 09 13:15:21 2013 +0100
Revision:
16:ab8c9118524e
Parent:
15:6da3f071ee35
Child:
17:c7b1b8451598
Synchronized with git revision 330e59fb850b83aefe641d40f9cf02873ab00d08

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