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:
samux
Date:
Thu Mar 14 11:49:53 2013 +0000
Revision:
8:93da8ea2708b
Parent:
6:1571e517a91b
Child:
9:7671b6a8c363
update doc + license

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) {
mbed_official 0:a554658735bf 71 osEvent evt = queue_usb_event.get();
mbed_official 0:a554658735bf 72
mbed_official 0:a554658735bf 73 if (evt.status == osEventMessage) {
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
mbed_official 0:a554658735bf 245 mpool_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 0:a554658735bf 289 if(addr == NULL)
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)
mbed_official 0:a554658735bf 320 message_t * usb_msg = mpool_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;
mbed_official 0:a554658735bf 324 queue_usb_event.put(usb_msg);
mbed_official 0:a554658735bf 325 }
samux 4:b320d68e98e7 326 ep->setState(state);
mbed_official 0:a554658735bf 327 }
mbed_official 0:a554658735bf 328 }
mbed_official 0:a554658735bf 329 }
mbed_official 0:a554658735bf 330
mbed_official 0:a554658735bf 331 USBHost * USBHost::getHostInst()
mbed_official 0:a554658735bf 332 {
mbed_official 0:a554658735bf 333 if (instHost == NULL) {
mbed_official 0:a554658735bf 334 instHost = new USBHost();
mbed_official 0:a554658735bf 335 instHost->init();
mbed_official 0:a554658735bf 336 }
mbed_official 0:a554658735bf 337 return instHost;
mbed_official 0:a554658735bf 338 }
mbed_official 0:a554658735bf 339
mbed_official 0:a554658735bf 340
mbed_official 0:a554658735bf 341 /*
mbed_official 0:a554658735bf 342 * Called when a device has been connected
mbed_official 0:a554658735bf 343 * Called in ISR!!!! (no printf)
mbed_official 0:a554658735bf 344 */
mbed_official 0:a554658735bf 345 /* virtual */ void USBHost::deviceConnected(int hub, int port, bool lowSpeed, USBHostHub * hub_parent)
mbed_official 0:a554658735bf 346 {
mbed_official 0:a554658735bf 347 // be sure that the new device connected is not already connected...
mbed_official 0:a554658735bf 348 int idx = findDevice(hub, port, hub_parent);
mbed_official 0:a554658735bf 349 if (idx != -1) {
samux 4:b320d68e98e7 350 if (deviceInited[idx])
mbed_official 0:a554658735bf 351 return;
mbed_official 0:a554658735bf 352 }
mbed_official 0:a554658735bf 353
mbed_official 0:a554658735bf 354 message_t * usb_msg = mpool_usb_event.alloc();
mbed_official 0:a554658735bf 355 usb_msg->event_id = DEVICE_CONNECTED_EVENT;
mbed_official 0:a554658735bf 356 usb_msg->hub = hub;
mbed_official 0:a554658735bf 357 usb_msg->port = port;
mbed_official 0:a554658735bf 358 usb_msg->lowSpeed = lowSpeed;
mbed_official 0:a554658735bf 359 usb_msg->hub_parent = hub_parent;
mbed_official 0:a554658735bf 360 queue_usb_event.put(usb_msg);
mbed_official 0:a554658735bf 361 }
mbed_official 0:a554658735bf 362
mbed_official 0:a554658735bf 363 /*
mbed_official 0:a554658735bf 364 * Called when a device has been disconnected
mbed_official 0:a554658735bf 365 * Called in ISR!!!! (no printf)
mbed_official 0:a554658735bf 366 */
mbed_official 0:a554658735bf 367 /* virtual */ void USBHost::deviceDisconnected(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr)
mbed_official 0:a554658735bf 368 {
mbed_official 0:a554658735bf 369 // be sure that the device disconnected is connected...
mbed_official 0:a554658735bf 370 int idx = findDevice(hub, port, hub_parent);
mbed_official 0:a554658735bf 371 if (idx != -1) {
mbed_official 0:a554658735bf 372 if (!deviceInUse[idx])
mbed_official 0:a554658735bf 373 return;
mbed_official 0:a554658735bf 374 } else {
mbed_official 0:a554658735bf 375 return;
mbed_official 0:a554658735bf 376 }
mbed_official 0:a554658735bf 377
mbed_official 0:a554658735bf 378 message_t * usb_msg = mpool_usb_event.alloc();
mbed_official 0:a554658735bf 379 usb_msg->event_id = DEVICE_DISCONNECTED_EVENT;
mbed_official 0:a554658735bf 380 usb_msg->hub = hub;
mbed_official 0:a554658735bf 381 usb_msg->port = port;
mbed_official 0:a554658735bf 382 usb_msg->hub_parent = hub_parent;
mbed_official 0:a554658735bf 383 queue_usb_event.put(usb_msg);
mbed_official 0:a554658735bf 384 }
mbed_official 0:a554658735bf 385
mbed_official 0:a554658735bf 386 void USBHost::freeDevice(USBDeviceConnected * dev)
mbed_official 0:a554658735bf 387 {
mbed_official 0:a554658735bf 388 USBEndpoint * ep = NULL;
mbed_official 0:a554658735bf 389 HCED * ed = NULL;
mbed_official 0:a554658735bf 390
mbed_official 0:a554658735bf 391 #if MAX_HUB_NB
mbed_official 0:a554658735bf 392 if (dev->getClass() == HUB_CLASS) {
mbed_official 0:a554658735bf 393 if (dev->hub == NULL) {
mbed_official 0:a554658735bf 394 USB_ERR("HUB NULL!!!!!\r\n");
mbed_official 0:a554658735bf 395 } else {
mbed_official 0:a554658735bf 396 dev->hub->hubDisconnected();
mbed_official 0:a554658735bf 397 for (uint8_t i = 0; i < MAX_HUB_NB; i++) {
mbed_official 0:a554658735bf 398 if (dev->hub == &hubs[i]) {
mbed_official 0:a554658735bf 399 hub_in_use[i] = false;
mbed_official 0:a554658735bf 400 break;
mbed_official 0:a554658735bf 401 }
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 // notify hub parent that this device has been disconnected
mbed_official 0:a554658735bf 407 if (dev->getHubParent())
mbed_official 0:a554658735bf 408 dev->getHubParent()->deviceDisconnected(dev);
mbed_official 0:a554658735bf 409
mbed_official 0:a554658735bf 410 #endif
mbed_official 0:a554658735bf 411
mbed_official 0:a554658735bf 412 int idx = findDevice(dev);
mbed_official 0:a554658735bf 413 if (idx != -1) {
mbed_official 0:a554658735bf 414 deviceInUse[idx] = false;
mbed_official 0:a554658735bf 415 deviceReset[idx] = false;
mbed_official 0:a554658735bf 416
samux 4:b320d68e98e7 417 for (uint8_t j = 0; j < MAX_INTF; j++) {
samux 4:b320d68e98e7 418 deviceAttachedDriver[idx][j] = false;
samux 4:b320d68e98e7 419 if (dev->getInterface(j) != NULL) {
samux 4:b320d68e98e7 420 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 421 for (int i = 0; i < dev->getInterface(j)->nb_endpoint; i++) {
samux 4:b320d68e98e7 422 if ((ep = dev->getEndpoint(j, i)) != NULL) {
samux 4:b320d68e98e7 423 ed = (HCED *)ep->getHCED();
samux 4:b320d68e98e7 424 ed->control |= (1 << 13); //sKip bit
samux 4:b320d68e98e7 425 unqueueEndpoint(ep);
mbed_official 0:a554658735bf 426
samux 4:b320d68e98e7 427 freeTD((volatile uint8_t*)ep->getTDList()[0]);
samux 4:b320d68e98e7 428 freeTD((volatile uint8_t*)ep->getTDList()[1]);
mbed_official 0:a554658735bf 429
samux 4:b320d68e98e7 430 freeED((uint8_t *)ep->getHCED());
samux 4:b320d68e98e7 431 }
samux 4:b320d68e98e7 432 printList(BULK_ENDPOINT);
samux 4:b320d68e98e7 433 printList(INTERRUPT_ENDPOINT);
mbed_official 0:a554658735bf 434 }
samux 4:b320d68e98e7 435 USB_INFO("Device disconnected [%p - %s - hub: %d - port: %d]", dev, dev->getName(j), dev->getHub(), dev->getPort());
mbed_official 0:a554658735bf 436 }
mbed_official 0:a554658735bf 437 }
mbed_official 0:a554658735bf 438 dev->disconnect();
mbed_official 0:a554658735bf 439 }
mbed_official 0:a554658735bf 440 }
mbed_official 0:a554658735bf 441
mbed_official 0:a554658735bf 442
mbed_official 0:a554658735bf 443 void USBHost::unqueueEndpoint(USBEndpoint * ep)
mbed_official 0:a554658735bf 444 {
mbed_official 0:a554658735bf 445 USBEndpoint * prec = NULL;
mbed_official 0:a554658735bf 446 USBEndpoint * current = NULL;
mbed_official 0:a554658735bf 447
mbed_official 0:a554658735bf 448 for (int i = 0; i < 2; i++) {
mbed_official 0:a554658735bf 449 current = (i == 0) ? (USBEndpoint*)headBulkEndpoint : (USBEndpoint*)headInterruptEndpoint;
mbed_official 0:a554658735bf 450 prec = current;
mbed_official 0:a554658735bf 451 while (current != NULL) {
mbed_official 0:a554658735bf 452 if (current == ep) {
mbed_official 0:a554658735bf 453 if (current->nextEndpoint() != NULL) {
mbed_official 0:a554658735bf 454 prec->queueEndpoint(current->nextEndpoint());
mbed_official 0:a554658735bf 455 if (current == headBulkEndpoint) {
mbed_official 0:a554658735bf 456 updateBulkHeadED((uint32_t)current->nextEndpoint()->getHCED());
mbed_official 0:a554658735bf 457 headBulkEndpoint = current->nextEndpoint();
mbed_official 0:a554658735bf 458 } else if (current == headInterruptEndpoint) {
mbed_official 0:a554658735bf 459 updateInterruptHeadED((uint32_t)current->nextEndpoint()->getHCED());
mbed_official 0:a554658735bf 460 headInterruptEndpoint = current->nextEndpoint();
mbed_official 0:a554658735bf 461 }
mbed_official 0:a554658735bf 462 }
mbed_official 0:a554658735bf 463 // here we are dequeuing the queue of ed
mbed_official 0:a554658735bf 464 // we need to update the tail pointer
mbed_official 0:a554658735bf 465 else {
mbed_official 0:a554658735bf 466 prec->queueEndpoint(NULL);
mbed_official 0:a554658735bf 467 if (current == headBulkEndpoint) {
mbed_official 0:a554658735bf 468 updateBulkHeadED(0);
mbed_official 0:a554658735bf 469 headBulkEndpoint = current->nextEndpoint();
mbed_official 0:a554658735bf 470 } else if (current == headInterruptEndpoint) {
mbed_official 0:a554658735bf 471 updateInterruptHeadED(0);
mbed_official 0:a554658735bf 472 headInterruptEndpoint = current->nextEndpoint();
mbed_official 0:a554658735bf 473 }
mbed_official 0:a554658735bf 474
mbed_official 0:a554658735bf 475 // modify tail
mbed_official 0:a554658735bf 476 switch (current->getType()) {
mbed_official 0:a554658735bf 477 case BULK_ENDPOINT:
mbed_official 0:a554658735bf 478 tailBulkEndpoint = prec;
mbed_official 0:a554658735bf 479 break;
mbed_official 0:a554658735bf 480 case INTERRUPT_ENDPOINT:
mbed_official 0:a554658735bf 481 tailInterruptEndpoint = prec;
mbed_official 0:a554658735bf 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 4:b320d68e98e7 531 wait_ms(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
mbed_official 0:a554658735bf 540 wait_ms(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 {
mbed_official 0:a554658735bf 692
mbed_official 0:a554658735bf 693 // allocate a TD which will be freed in TDcompletion
mbed_official 0:a554658735bf 694 volatile HCTD * td = ed->getNextTD();
mbed_official 0:a554658735bf 695 if (td == NULL) {
mbed_official 0:a554658735bf 696 return USB_TYPE_ERROR;
mbed_official 0:a554658735bf 697 }
mbed_official 0:a554658735bf 698
mbed_official 0:a554658735bf 699 uint32_t token = (ed->isSetup() ? TD_SETUP : ( (ed->getDir() == IN) ? TD_IN : TD_OUT ));
mbed_official 0:a554658735bf 700
mbed_official 0:a554658735bf 701 uint32_t td_toggle;
mbed_official 0:a554658735bf 702
mbed_official 0:a554658735bf 703 if (ed->getType() == CONTROL_ENDPOINT) {
mbed_official 0:a554658735bf 704 if (ed->isSetup()) {
mbed_official 0:a554658735bf 705 td_toggle = TD_TOGGLE_0;
mbed_official 0:a554658735bf 706 } else {
mbed_official 0:a554658735bf 707 td_toggle = TD_TOGGLE_1;
mbed_official 0:a554658735bf 708 }
mbed_official 0:a554658735bf 709 } else {
mbed_official 0:a554658735bf 710 td_toggle = 0;
mbed_official 0:a554658735bf 711 }
mbed_official 0:a554658735bf 712
mbed_official 0:a554658735bf 713 td->control = (TD_ROUNDING | token | TD_DELAY_INT(0) | td_toggle | TD_CC);
mbed_official 0:a554658735bf 714 td->currBufPtr = buf;
mbed_official 0:a554658735bf 715 td->bufEnd = (buf + (len - 1));
mbed_official 0:a554658735bf 716
mbed_official 0:a554658735bf 717 ENDPOINT_TYPE type = ed->getType();
mbed_official 0:a554658735bf 718
mbed_official 0:a554658735bf 719 disableList(type);
mbed_official 0:a554658735bf 720 ed->queueTransfer();
mbed_official 0:a554658735bf 721 printList(type);
mbed_official 0:a554658735bf 722 enableList(type);
mbed_official 0:a554658735bf 723
mbed_official 0:a554658735bf 724 return USB_TYPE_PROCESSING;
mbed_official 0:a554658735bf 725 }
mbed_official 0:a554658735bf 726
mbed_official 0:a554658735bf 727
mbed_official 0:a554658735bf 728
mbed_official 0:a554658735bf 729 USB_TYPE USBHost::getDeviceDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_dev_descr)
mbed_official 0:a554658735bf 730 {
mbed_official 0:a554658735bf 731 USB_TYPE t = controlRead( dev,
mbed_official 0:a554658735bf 732 USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE,
mbed_official 0:a554658735bf 733 GET_DESCRIPTOR,
mbed_official 0:a554658735bf 734 (DEVICE_DESCRIPTOR << 8) | (0),
mbed_official 0:a554658735bf 735 0, buf, MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf));
mbed_official 0:a554658735bf 736 if (len_dev_descr)
mbed_official 0:a554658735bf 737 *len_dev_descr = MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf);
mbed_official 0:a554658735bf 738
mbed_official 0:a554658735bf 739 return t;
mbed_official 0:a554658735bf 740 }
mbed_official 0:a554658735bf 741
mbed_official 0:a554658735bf 742 USB_TYPE USBHost::getConfigurationDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_conf_descr)
mbed_official 0:a554658735bf 743 {
mbed_official 0:a554658735bf 744 USB_TYPE res;
mbed_official 0:a554658735bf 745 uint16_t total_conf_descr_length = 0;
mbed_official 0:a554658735bf 746
mbed_official 0:a554658735bf 747 // fourth step: get the beginning of the configuration descriptor to have the total length of the conf descr
mbed_official 0:a554658735bf 748 res = controlRead( dev,
mbed_official 0:a554658735bf 749 USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE,
mbed_official 0:a554658735bf 750 GET_DESCRIPTOR,
mbed_official 0:a554658735bf 751 (CONFIGURATION_DESCRIPTOR << 8) | (0),
mbed_official 0:a554658735bf 752 0, buf, CONFIGURATION_DESCRIPTOR_LENGTH);
mbed_official 0:a554658735bf 753
mbed_official 0:a554658735bf 754 if (res != USB_TYPE_OK) {
mbed_official 0:a554658735bf 755 USB_ERR("GET CONF 1 DESCR FAILED");
mbed_official 0:a554658735bf 756 return res;
mbed_official 0:a554658735bf 757 }
mbed_official 0:a554658735bf 758 total_conf_descr_length = buf[2] | (buf[3] << 8);
mbed_official 0:a554658735bf 759 total_conf_descr_length = MIN(max_len_buf, total_conf_descr_length);
mbed_official 0:a554658735bf 760
mbed_official 0:a554658735bf 761 if (len_conf_descr)
mbed_official 0:a554658735bf 762 *len_conf_descr = total_conf_descr_length;
mbed_official 0:a554658735bf 763
mbed_official 0:a554658735bf 764 USB_DBG("TOTAL_LENGTH: %d \t NUM_INTERF: %d", total_conf_descr_length, buf[4]);
mbed_official 0:a554658735bf 765
mbed_official 0:a554658735bf 766 return controlRead( dev,
mbed_official 0:a554658735bf 767 USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE,
mbed_official 0:a554658735bf 768 GET_DESCRIPTOR,
mbed_official 0:a554658735bf 769 (CONFIGURATION_DESCRIPTOR << 8) | (0),
mbed_official 0:a554658735bf 770 0, buf, total_conf_descr_length);
mbed_official 0:a554658735bf 771 }
mbed_official 0:a554658735bf 772
mbed_official 0:a554658735bf 773
mbed_official 0:a554658735bf 774 USB_TYPE USBHost::setAddress(USBDeviceConnected * dev, uint8_t address) {
mbed_official 0:a554658735bf 775 return controlWrite( dev,
mbed_official 0:a554658735bf 776 USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE,
mbed_official 0:a554658735bf 777 SET_ADDRESS,
mbed_official 0:a554658735bf 778 address,
mbed_official 0:a554658735bf 779 0, NULL, 0);
mbed_official 0:a554658735bf 780
mbed_official 0:a554658735bf 781 }
mbed_official 0:a554658735bf 782
mbed_official 0:a554658735bf 783 USB_TYPE USBHost::setConfiguration(USBDeviceConnected * dev, uint8_t conf)
mbed_official 0:a554658735bf 784 {
mbed_official 0:a554658735bf 785 return controlWrite( dev,
mbed_official 0:a554658735bf 786 USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE,
mbed_official 0:a554658735bf 787 SET_CONFIGURATION,
mbed_official 0:a554658735bf 788 conf,
mbed_official 0:a554658735bf 789 0, NULL, 0);
mbed_official 0:a554658735bf 790 }
mbed_official 0:a554658735bf 791
samux 4:b320d68e98e7 792 uint8_t USBHost::numberDriverAttached(USBDeviceConnected * dev) {
samux 4:b320d68e98e7 793 int index = findDevice(dev);
samux 4:b320d68e98e7 794 uint8_t cnt = 0;
samux 4:b320d68e98e7 795 if (index == -1)
samux 4:b320d68e98e7 796 return 0;
samux 4:b320d68e98e7 797 for (uint8_t i = 0; i < MAX_INTF; i++) {
samux 4:b320d68e98e7 798 if (deviceAttachedDriver[index][i])
samux 4:b320d68e98e7 799 cnt++;
samux 4:b320d68e98e7 800 }
samux 4:b320d68e98e7 801 return cnt;
samux 4:b320d68e98e7 802 }
mbed_official 0:a554658735bf 803
mbed_official 0:a554658735bf 804 // enumerate a device with the control USBEndpoint
mbed_official 0:a554658735bf 805 USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerator)
mbed_official 0:a554658735bf 806 {
mbed_official 0:a554658735bf 807 uint16_t total_conf_descr_length = 0;
mbed_official 0:a554658735bf 808 USB_TYPE res;
mbed_official 0:a554658735bf 809
samux 4:b320d68e98e7 810 usb_mutex.lock();
samux 4:b320d68e98e7 811
samux 4:b320d68e98e7 812 // don't enumerate a device which all interfaces are registered to a specific driver
samux 4:b320d68e98e7 813 int index = findDevice(dev);
samux 4:b320d68e98e7 814
samux 4:b320d68e98e7 815 if (index == -1) {
samux 4:b320d68e98e7 816 usb_mutex.unlock();
samux 4:b320d68e98e7 817 return USB_TYPE_ERROR;
samux 4:b320d68e98e7 818 }
samux 4:b320d68e98e7 819
samux 4:b320d68e98e7 820 uint8_t nb_intf_attached = numberDriverAttached(dev);
samux 4:b320d68e98e7 821 USB_DBG("dev: %p nb_intf: %d", dev, dev->getNbIntf());
samux 4:b320d68e98e7 822 USB_DBG("dev: %p nb_intf_attached: %d", dev, nb_intf_attached);
samux 4:b320d68e98e7 823 if ((nb_intf_attached != 0) && (dev->getNbIntf() == nb_intf_attached)) {
samux 4:b320d68e98e7 824 USB_DBG("Don't enumerate dev: %p because all intf are registered with a driver", dev);
samux 4:b320d68e98e7 825 usb_mutex.unlock();
mbed_official 0:a554658735bf 826 return USB_TYPE_OK;
mbed_official 0:a554658735bf 827 }
mbed_official 0:a554658735bf 828
samux 4:b320d68e98e7 829 USB_DBG("Enumerate dev: %p", dev);
samux 4:b320d68e98e7 830
mbed_official 0:a554658735bf 831 // third step: get the whole device descriptor to see vid, pid
mbed_official 0:a554658735bf 832 res = getDeviceDescriptor(dev, data, DEVICE_DESCRIPTOR_LENGTH);
mbed_official 0:a554658735bf 833
samux 4:b320d68e98e7 834 if (res != USB_TYPE_OK) {
mbed_official 0:a554658735bf 835 USB_DBG("GET DEV DESCR FAILED");
samux 4:b320d68e98e7 836 usb_mutex.unlock();
mbed_official 0:a554658735bf 837 return res;
mbed_official 0:a554658735bf 838 }
mbed_official 0:a554658735bf 839
mbed_official 0:a554658735bf 840 dev->setClass(data[4]);
mbed_official 0:a554658735bf 841 dev->setSubClass(data[5]);
mbed_official 0:a554658735bf 842 dev->setProtocol(data[6]);
mbed_official 0:a554658735bf 843 dev->setVid(data[8] | (data[9] << 8));
mbed_official 0:a554658735bf 844 dev->setPid(data[10] | (data[11] << 8));
mbed_official 0:a554658735bf 845 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 846
mbed_official 0:a554658735bf 847 pEnumerator->setVidPid( data[8] | (data[9] << 8), data[10] | (data[11] << 8) );
mbed_official 0:a554658735bf 848
mbed_official 0:a554658735bf 849 res = getConfigurationDescriptor(dev, data, 400, &total_conf_descr_length);
mbed_official 0:a554658735bf 850 if (res != USB_TYPE_OK) {
samux 4:b320d68e98e7 851 usb_mutex.unlock();
mbed_official 0:a554658735bf 852 return res;
mbed_official 0:a554658735bf 853 }
mbed_official 0:a554658735bf 854
mbed_official 0:a554658735bf 855 #if DEBUG
mbed_official 0:a554658735bf 856 USB_DBG("CONFIGURATION DESCRIPTOR:\r\n");
mbed_official 0:a554658735bf 857 for (int i = 0; i < total_conf_descr_length; i++)
mbed_official 0:a554658735bf 858 printf("%02X ", data[i]);
mbed_official 0:a554658735bf 859 printf("\r\n\r\n");
mbed_official 0:a554658735bf 860 #endif
mbed_official 0:a554658735bf 861
mbed_official 0:a554658735bf 862 // Parse the configuration descriptor
mbed_official 0:a554658735bf 863 parseConfDescr(dev, data, total_conf_descr_length, pEnumerator);
mbed_official 0:a554658735bf 864
samux 4:b320d68e98e7 865 // only set configuration if not enumerated before
samux 4:b320d68e98e7 866 if (!dev->isEnumerated()) {
samux 4:b320d68e98e7 867
samux 4:b320d68e98e7 868 USB_DBG("Set configuration 1 on dev: %p", dev);
samux 4:b320d68e98e7 869 // sixth step: set configuration (only 1 supported)
samux 4:b320d68e98e7 870 res = setConfiguration(dev, 1);
mbed_official 0:a554658735bf 871
samux 4:b320d68e98e7 872 if (res != USB_TYPE_OK) {
samux 4:b320d68e98e7 873 USB_DBG("SET CONF FAILED");
samux 4:b320d68e98e7 874 usb_mutex.unlock();
samux 4:b320d68e98e7 875 return res;
samux 4:b320d68e98e7 876 }
mbed_official 0:a554658735bf 877 }
samux 4:b320d68e98e7 878
samux 4:b320d68e98e7 879 dev->setEnumerated();
mbed_official 0:a554658735bf 880
mbed_official 0:a554658735bf 881 // Now the device is enumerated!
samux 4:b320d68e98e7 882 USB_DBG("dev %p is enumerated\r\n", dev);
samux 4:b320d68e98e7 883 usb_mutex.unlock();
mbed_official 0:a554658735bf 884
mbed_official 0:a554658735bf 885 // Some devices may require this delay
samux 4:b320d68e98e7 886 wait_ms(100);
mbed_official 0:a554658735bf 887
mbed_official 0:a554658735bf 888 return USB_TYPE_OK;
mbed_official 0:a554658735bf 889 }
mbed_official 0:a554658735bf 890
mbed_official 0:a554658735bf 891 // this method fills the USBDeviceConnected object: class,.... . It also add endpoints found in the descriptor.
mbed_official 0:a554658735bf 892 void USBHost::parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len, IUSBEnumerator* pEnumerator)
mbed_official 0:a554658735bf 893 {
mbed_official 0:a554658735bf 894 uint32_t index = 0;
mbed_official 0:a554658735bf 895 uint32_t len_desc = 0;
mbed_official 0:a554658735bf 896 uint8_t id = 0;
mbed_official 0:a554658735bf 897 int nb_endpoints_used = 0;
mbed_official 0:a554658735bf 898 USBEndpoint * ep = NULL;
mbed_official 0:a554658735bf 899 uint8_t intf_nb = 0;
mbed_official 0:a554658735bf 900 bool parsing_intf = false;
samux 4:b320d68e98e7 901 uint8_t current_intf = 0;
mbed_official 0:a554658735bf 902
mbed_official 0:a554658735bf 903 while (index < len) {
mbed_official 0:a554658735bf 904 len_desc = conf_descr[index];
mbed_official 0:a554658735bf 905 id = conf_descr[index+1];
mbed_official 0:a554658735bf 906 switch (id) {
mbed_official 0:a554658735bf 907 case CONFIGURATION_DESCRIPTOR:
samux 4:b320d68e98e7 908 USB_DBG("dev: %p has %d intf", dev, conf_descr[4]);
samux 4:b320d68e98e7 909 dev->setNbIntf(conf_descr[4]);
mbed_official 0:a554658735bf 910 break;
mbed_official 0:a554658735bf 911 case INTERFACE_DESCRIPTOR:
samux 4:b320d68e98e7 912 if(pEnumerator->parseInterface(conf_descr[index + 2], conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7])) {
mbed_official 0:a554658735bf 913 if (intf_nb++ <= MAX_INTF) {
samux 4:b320d68e98e7 914 current_intf = conf_descr[index + 2];
samux 4:b320d68e98e7 915 dev->addInterface(current_intf, conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7]);
mbed_official 0:a554658735bf 916 nb_endpoints_used = 0;
samux 4:b320d68e98e7 917 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 918 } else {
mbed_official 0:a554658735bf 919 USB_DBG("Drop intf...");
mbed_official 0:a554658735bf 920 }
mbed_official 0:a554658735bf 921 parsing_intf = true;
mbed_official 0:a554658735bf 922 } else {
mbed_official 0:a554658735bf 923 parsing_intf = false;
mbed_official 0:a554658735bf 924 }
mbed_official 0:a554658735bf 925 break;
mbed_official 0:a554658735bf 926 case ENDPOINT_DESCRIPTOR:
mbed_official 0:a554658735bf 927 if (parsing_intf && (intf_nb <= MAX_INTF) ) {
mbed_official 0:a554658735bf 928 if (nb_endpoints_used < MAX_ENDPOINT_PER_INTERFACE) {
samux 4:b320d68e98e7 929 if( pEnumerator->useEndpoint(current_intf, (ENDPOINT_TYPE)(conf_descr[index + 3] & 0x03), (ENDPOINT_DIRECTION)((conf_descr[index + 2] >> 7) + 1)) ) {
mbed_official 0:a554658735bf 930 // if the USBEndpoint is isochronous -> skip it (TODO: fix this)
mbed_official 0:a554658735bf 931 if ((conf_descr[index + 3] & 0x03) != ISOCHRONOUS_ENDPOINT) {
mbed_official 0:a554658735bf 932 ep = newEndpoint((ENDPOINT_TYPE)(conf_descr[index+3] & 0x03),
mbed_official 0:a554658735bf 933 (ENDPOINT_DIRECTION)((conf_descr[index + 2] >> 7) + 1),
mbed_official 0:a554658735bf 934 conf_descr[index + 4] | (conf_descr[index + 5] << 8),
mbed_official 0:a554658735bf 935 conf_descr[index + 2] & 0x0f);
samux 4:b320d68e98e7 936 USB_DBG("ADD USBEndpoint %p, on interf %d on device %p", ep, current_intf, dev);
mbed_official 0:a554658735bf 937 if (ep != NULL && dev != NULL) {
samux 4:b320d68e98e7 938 addEndpoint(dev, current_intf, ep);
mbed_official 0:a554658735bf 939 } else {
mbed_official 0:a554658735bf 940 USB_DBG("EP NULL");
mbed_official 0:a554658735bf 941 }
mbed_official 0:a554658735bf 942 nb_endpoints_used++;
mbed_official 0:a554658735bf 943 } else {
mbed_official 0:a554658735bf 944 USB_DBG("ISO USBEndpoint NOT SUPPORTED");
mbed_official 0:a554658735bf 945 }
mbed_official 0:a554658735bf 946 }
mbed_official 0:a554658735bf 947 }
mbed_official 0:a554658735bf 948 }
mbed_official 0:a554658735bf 949 break;
mbed_official 0:a554658735bf 950 case HID_DESCRIPTOR:
mbed_official 0:a554658735bf 951 lenReportDescr = conf_descr[index + 7] | (conf_descr[index + 8] << 8);
mbed_official 0:a554658735bf 952 break;
mbed_official 0:a554658735bf 953 default:
mbed_official 0:a554658735bf 954 break;
mbed_official 0:a554658735bf 955 }
mbed_official 0:a554658735bf 956 index += len_desc;
mbed_official 0:a554658735bf 957 }
mbed_official 0:a554658735bf 958 }
mbed_official 0:a554658735bf 959
mbed_official 0:a554658735bf 960
mbed_official 0:a554658735bf 961 USB_TYPE USBHost::bulkWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking)
mbed_official 0:a554658735bf 962 {
mbed_official 0:a554658735bf 963 return generalTransfer(dev, ep, buf, len, blocking, BULK_ENDPOINT, true);
mbed_official 0:a554658735bf 964 }
mbed_official 0:a554658735bf 965
mbed_official 0:a554658735bf 966 USB_TYPE USBHost::bulkRead(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, false);
mbed_official 0:a554658735bf 969 }
mbed_official 0:a554658735bf 970
mbed_official 0:a554658735bf 971 USB_TYPE USBHost::interruptWrite(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, INTERRUPT_ENDPOINT, true);
mbed_official 0:a554658735bf 974 }
mbed_official 0:a554658735bf 975
mbed_official 0:a554658735bf 976 USB_TYPE USBHost::interruptRead(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, false);
mbed_official 0:a554658735bf 979 }
mbed_official 0:a554658735bf 980
mbed_official 0:a554658735bf 981 USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking, ENDPOINT_TYPE type, bool write) {
samux 4:b320d68e98e7 982
mbed_official 0:a554658735bf 983 #if DEBUG_TRANSFER
mbed_official 0:a554658735bf 984 const char * type_str = (type == BULK_ENDPOINT) ? "BULK" : ((type == INTERRUPT_ENDPOINT) ? "INTERRUPT" : "ISOCHRONOUS");
samux 4:b320d68e98e7 985 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 986 #endif
samux 4:b320d68e98e7 987
mbed_official 0:a554658735bf 988 USB_TYPE res;
mbed_official 0:a554658735bf 989 ENDPOINT_DIRECTION dir = (write) ? OUT : IN;
samux 4:b320d68e98e7 990
samux 4:b320d68e98e7 991 usb_mutex.lock();
samux 4:b320d68e98e7 992
mbed_official 0:a554658735bf 993 if (dev == NULL) {
mbed_official 0:a554658735bf 994 USB_ERR("dev NULL");
samux 4:b320d68e98e7 995 usb_mutex.unlock();
mbed_official 0:a554658735bf 996 return USB_TYPE_ERROR;
mbed_official 0:a554658735bf 997 }
mbed_official 0:a554658735bf 998
mbed_official 0:a554658735bf 999 if (ep == NULL) {
mbed_official 0:a554658735bf 1000 USB_ERR("ep NULL");
samux 4:b320d68e98e7 1001 usb_mutex.unlock();
mbed_official 0:a554658735bf 1002 return USB_TYPE_ERROR;
mbed_official 0:a554658735bf 1003 }
mbed_official 0:a554658735bf 1004
mbed_official 0:a554658735bf 1005 if (ep->getState() != USB_TYPE_IDLE) {
samux 4:b320d68e98e7 1006 USB_WARN("[ep: %p - dev: %p - %s] NOT IDLE: %s", ep, ep->dev, ep->dev->getName(ep->getIntfNb()), ep->getStateString());
samux 4:b320d68e98e7 1007 usb_mutex.unlock();
mbed_official 0:a554658735bf 1008 return ep->getState();
mbed_official 0:a554658735bf 1009 }
mbed_official 0:a554658735bf 1010
mbed_official 0:a554658735bf 1011 if ((ep->getDir() != dir) || (ep->getType() != type)) {
mbed_official 0:a554658735bf 1012 USB_ERR("[ep: %p - dev: %p] wrong dir or bad USBEndpoint type", ep, ep->dev);
samux 4:b320d68e98e7 1013 usb_mutex.unlock();
mbed_official 0:a554658735bf 1014 return USB_TYPE_ERROR;
mbed_official 0:a554658735bf 1015 }
mbed_official 0:a554658735bf 1016
mbed_official 0:a554658735bf 1017 if (dev->getAddress() != ep->getDeviceAddress()) {
mbed_official 0:a554658735bf 1018 USB_ERR("[ep: %p - dev: %p] USBEndpoint addr and device addr don't match", ep, ep->dev);
samux 4:b320d68e98e7 1019 usb_mutex.unlock();
mbed_official 0:a554658735bf 1020 return USB_TYPE_ERROR;
mbed_official 0:a554658735bf 1021 }
mbed_official 0:a554658735bf 1022
mbed_official 0:a554658735bf 1023 #if DEBUG_TRANSFER
mbed_official 0:a554658735bf 1024 if (write) {
mbed_official 0:a554658735bf 1025 USB_DBG_TRANSFER("%s WRITE buffer", type_str);
mbed_official 0:a554658735bf 1026 for (int i = 0; i < ep->getLengthTransferred(); i++)
mbed_official 0:a554658735bf 1027 printf("%02X ", buf[i]);
mbed_official 0:a554658735bf 1028 printf("\r\n\r\n");
mbed_official 0:a554658735bf 1029 }
mbed_official 0:a554658735bf 1030 #endif
mbed_official 0:a554658735bf 1031 addTransfer(ep, buf, len);
mbed_official 0:a554658735bf 1032
mbed_official 0:a554658735bf 1033 if (blocking) {
samux 4:b320d68e98e7 1034
samux 4:b320d68e98e7 1035 while((res = ep->getState()) == USB_TYPE_PROCESSING);
samux 4:b320d68e98e7 1036
samux 4:b320d68e98e7 1037 USB_DBG_TRANSFER("%s TRANSFER res: %s on ep: %p\r\n", type_str, ep->getStateString(), ep);
samux 4:b320d68e98e7 1038
mbed_official 0:a554658735bf 1039 if (res != USB_TYPE_IDLE) {
samux 4:b320d68e98e7 1040 usb_mutex.unlock();
mbed_official 0:a554658735bf 1041 return res;
mbed_official 0:a554658735bf 1042 }
mbed_official 0:a554658735bf 1043
samux 4:b320d68e98e7 1044 usb_mutex.unlock();
mbed_official 0:a554658735bf 1045 return USB_TYPE_OK;
mbed_official 0:a554658735bf 1046 }
samux 4:b320d68e98e7 1047
samux 4:b320d68e98e7 1048 usb_mutex.unlock();
mbed_official 0:a554658735bf 1049 return USB_TYPE_PROCESSING;
mbed_official 0:a554658735bf 1050
mbed_official 0:a554658735bf 1051 }
mbed_official 0:a554658735bf 1052
mbed_official 0:a554658735bf 1053
mbed_official 0:a554658735bf 1054 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 1055 return controlTransfer(dev, requestType, request, value, index, buf, len, false);
mbed_official 0:a554658735bf 1056 }
mbed_official 0:a554658735bf 1057
mbed_official 0:a554658735bf 1058 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 1059 return controlTransfer(dev, requestType, request, value, index, buf, len, true);
mbed_official 0:a554658735bf 1060 }
mbed_official 0:a554658735bf 1061
mbed_official 0:a554658735bf 1062 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 1063 {
samux 4:b320d68e98e7 1064 usb_mutex.lock();
samux 4:b320d68e98e7 1065 USB_DBG_TRANSFER("----- CONTROL %s [dev: %p - hub: %d - port: %d] ------", (write) ? "WRITE" : "READ", dev, dev->getHub(), dev->getPort());
mbed_official 0:a554658735bf 1066
mbed_official 0:a554658735bf 1067 int length_transfer = len;
mbed_official 0:a554658735bf 1068 USB_TYPE res;
mbed_official 0:a554658735bf 1069 uint32_t token;
mbed_official 0:a554658735bf 1070
mbed_official 0:a554658735bf 1071 control->setSpeed(dev->getSpeed());
mbed_official 0:a554658735bf 1072 control->setSize(dev->getSizeControlEndpoint());
mbed_official 0:a554658735bf 1073 if (dev->isActiveAddress()) {
mbed_official 0:a554658735bf 1074 control->setDeviceAddress(dev->getAddress());
mbed_official 0:a554658735bf 1075 } else {
mbed_official 0:a554658735bf 1076 control->setDeviceAddress(0);
mbed_official 0:a554658735bf 1077 }
samux 4:b320d68e98e7 1078
mbed_official 0:a554658735bf 1079 USB_DBG_TRANSFER("Control transfer on device: %d\r\n", control->getDeviceAddress());
mbed_official 0:a554658735bf 1080 fillControlBuf(requestType, request, value, index, len);
mbed_official 0:a554658735bf 1081
mbed_official 0:a554658735bf 1082 #if DEBUG_TRANSFER
mbed_official 0:a554658735bf 1083 USB_DBG_TRANSFER("SETUP PACKET: ");
mbed_official 0:a554658735bf 1084 for (int i = 0; i < 8; i++)
mbed_official 0:a554658735bf 1085 printf("%01X ", setupPacket[i]);
mbed_official 0:a554658735bf 1086 printf("\r\n");
mbed_official 0:a554658735bf 1087 #endif
mbed_official 0:a554658735bf 1088
mbed_official 0:a554658735bf 1089 control->setNextToken(TD_SETUP);
mbed_official 0:a554658735bf 1090 addTransfer(control, (uint8_t*)setupPacket, 8);
mbed_official 0:a554658735bf 1091
samux 4:b320d68e98e7 1092 while((res = control->getState()) == USB_TYPE_PROCESSING);
mbed_official 0:a554658735bf 1093
mbed_official 0:a554658735bf 1094 USB_DBG_TRANSFER("CONTROL setup stage %s", control->getStateString());
mbed_official 0:a554658735bf 1095
mbed_official 0:a554658735bf 1096 if (res != USB_TYPE_IDLE) {
mbed_official 0:a554658735bf 1097 usb_mutex.unlock();
mbed_official 0:a554658735bf 1098 return res;
mbed_official 0:a554658735bf 1099 }
mbed_official 0:a554658735bf 1100
mbed_official 0:a554658735bf 1101 if (length_transfer) {
mbed_official 0:a554658735bf 1102 token = (write) ? TD_OUT : TD_IN;
mbed_official 0:a554658735bf 1103 control->setNextToken(token);
mbed_official 0:a554658735bf 1104 addTransfer(control, (uint8_t *)buf, length_transfer);
mbed_official 0:a554658735bf 1105
samux 4:b320d68e98e7 1106 while((res = control->getState()) == USB_TYPE_PROCESSING);
mbed_official 0:a554658735bf 1107
mbed_official 0:a554658735bf 1108 #if DEBUG_TRANSFER
mbed_official 0:a554658735bf 1109 USB_DBG_TRANSFER("CONTROL %s stage %s", (write) ? "WRITE" : "READ", control->getStateString());
mbed_official 0:a554658735bf 1110 if (write) {
mbed_official 0:a554658735bf 1111 USB_DBG_TRANSFER("CONTROL WRITE buffer");
mbed_official 0:a554658735bf 1112 for (int i = 0; i < control->getLengthTransferred(); i++)
mbed_official 0:a554658735bf 1113 printf("%02X ", buf[i]);
mbed_official 0:a554658735bf 1114 printf("\r\n\r\n");
mbed_official 0:a554658735bf 1115 } else {
mbed_official 0:a554658735bf 1116 USB_DBG_TRANSFER("CONTROL READ SUCCESS [%d bytes transferred]", control->getLengthTransferred());
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 }
mbed_official 0:a554658735bf 1121 #endif
mbed_official 0:a554658735bf 1122
mbed_official 0:a554658735bf 1123 if (res != USB_TYPE_IDLE) {
mbed_official 0:a554658735bf 1124 usb_mutex.unlock();
mbed_official 0:a554658735bf 1125 return res;
mbed_official 0:a554658735bf 1126 }
mbed_official 0:a554658735bf 1127 }
mbed_official 0:a554658735bf 1128
mbed_official 0:a554658735bf 1129 token = (write) ? TD_IN : TD_OUT;
mbed_official 0:a554658735bf 1130 control->setNextToken(token);
mbed_official 0:a554658735bf 1131 addTransfer(control, NULL, 0);
mbed_official 0:a554658735bf 1132
samux 4:b320d68e98e7 1133 while((res = control->getState()) == USB_TYPE_PROCESSING);
mbed_official 0:a554658735bf 1134
mbed_official 0:a554658735bf 1135 USB_DBG_TRANSFER("CONTROL ack stage %s", control->getStateString());
mbed_official 0:a554658735bf 1136 usb_mutex.unlock();
mbed_official 0:a554658735bf 1137
mbed_official 0:a554658735bf 1138 if (res != USB_TYPE_IDLE)
mbed_official 0:a554658735bf 1139 return res;
mbed_official 0:a554658735bf 1140
mbed_official 0:a554658735bf 1141 return USB_TYPE_OK;
mbed_official 0:a554658735bf 1142 }
mbed_official 0:a554658735bf 1143
mbed_official 0:a554658735bf 1144
mbed_official 0:a554658735bf 1145 void USBHost::fillControlBuf(uint8_t requestType, uint8_t request, uint16_t value, uint16_t index, int len)
mbed_official 0:a554658735bf 1146 {
mbed_official 0:a554658735bf 1147 #ifdef __BIG_ENDIAN
mbed_official 0:a554658735bf 1148 #error "Must implement BE to LE conv here"
mbed_official 0:a554658735bf 1149 #endif
mbed_official 0:a554658735bf 1150 setupPacket[0] = requestType;
mbed_official 0:a554658735bf 1151 setupPacket[1] = request;
mbed_official 0:a554658735bf 1152 //We are in LE so it's fine
mbed_official 0:a554658735bf 1153 *((uint16_t*)&setupPacket[2]) = value;
mbed_official 0:a554658735bf 1154 *((uint16_t*)&setupPacket[4]) = index;
mbed_official 0:a554658735bf 1155 *((uint16_t*)&setupPacket[6]) = (uint32_t) len;
mbed_official 0:a554658735bf 1156 }