SDG+USBHost(Mouse) Sample

Dependencies:   Sound_Generator USBHost_custom

Fork of SDG_Mouse_Sample by GR-PEACH_producer_meeting

Information

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

What is this?

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

Settings

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

Operation

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

Others

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


概要

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

設定

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

操作方法

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

Others

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

Committer:
mbed_official
Date:
Wed Mar 06 16:27:14 2013 +0000
Revision:
0:a554658735bf
Child:
4:b320d68e98e7
first commit

Who changed what in which revision?

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