SDG+USBHost(Mouse) Sample

Dependencies:   Sound_Generator USBHost_custom

Fork of SDG_Mouse_Sample by GR-PEACH_producer_meeting

Information

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

What is this?

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

Settings

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

Operation

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

Others

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


概要

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

設定

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

操作方法

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

Others

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

Committer:
samux
Date:
Wed Mar 13 15:43:54 2013 +0000
Revision:
6:1571e517a91b
Parent:
4:b320d68e98e7
Child:
8:93da8ea2708b
remove useless mutex calls

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