Simple USBHost library for Nucleo F446RE/F411RE/F401RE FRDM-KL46Z/KL25Z/F64F LPC4088/LPC1768

Dependencies:   FATFileSystem

Dependents:   F401RE-BTstack_example F401RE-USBHostMSD_HelloWorld

Fork of KL46Z-USBHost by Norimasa Okamoto

簡易USBホストライブラリです。
official-USBHostの下位互換で対応プログラムを僅かな修正で動かすことが出来ます。

Platforms

  • Nucleo F446RE
  • Nucleo F411RE
  • Nucleo F401RE
  • FRDM-K64F
  • FRDM-KL46Z
  • FRDM-KL25Z
  • LPC4088
  • LPC1768

Nucleo F446RE/F411RE/F401REのUSB接続方法

ST morphoUSB
U5V (CN10-8)VBUS (1 RED)
PA11 (CN10-14)DM  (2 WHITE)
PA12 (CN10-12)DP  (3 GREEN)
GND (CN10-20)GND (4 BLACK)

Examples

Import programF446RE-USBHostMouse_HelloWorld

USBHostMouse Hello World for ST-Nucleo-F446RE

Import programF401RE-USBHostMSD_HelloWorld

Simple USBHost MSD(USB flash drive) for Nucleo F401RE/FRDM-KL46Z test program

Import programF401RE-USBHostC270_example

Simple USBHost WebCam test program

Import programK64F_USBHostC270_example

Simple USBHost C270 example

Import programF401RE-BTstack_example

BTstack for Nucleo F401RE/FRDM-KL46Z example program

Import programUSBHostRSSI_example

Bluetooth device discovery example program.

Import programKL46Z-USBHostGPS_HelloWorld

Simple USBHost GPS Dongle Receiver for FRDM-KL46Z test program

Committer:
va009039
Date:
Sun May 01 03:18:11 2016 +0000
Revision:
23:4ab8bc835303
Parent:
18:61554f238584
add ST-Nucleo-F446RE

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 18:61554f238584 1 /* mbed USBHost Library
va009039 18:61554f238584 2 * Copyright (c) 2006-2013 ARM Limited
va009039 18:61554f238584 3 *
va009039 18:61554f238584 4 * Licensed under the Apache License, Version 2.0 (the "License");
va009039 18:61554f238584 5 * you may not use this file except in compliance with the License.
va009039 18:61554f238584 6 * You may obtain a copy of the License at
va009039 18:61554f238584 7 *
va009039 18:61554f238584 8 * http://www.apache.org/licenses/LICENSE-2.0
va009039 18:61554f238584 9 *
va009039 18:61554f238584 10 * Unless required by applicable law or agreed to in writing, software
va009039 18:61554f238584 11 * distributed under the License is distributed on an "AS IS" BASIS,
va009039 18:61554f238584 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
va009039 18:61554f238584 13 * See the License for the specific language governing permissions and
va009039 18:61554f238584 14 * limitations under the License.
va009039 18:61554f238584 15 */
va009039 18:61554f238584 16
va009039 12:b91fdea8c0a7 17 #include "USBHost.h"
va009039 12:b91fdea8c0a7 18
va009039 18:61554f238584 19 #define USB_TRACE1(A) while(0)
va009039 18:61554f238584 20 #undef USB_TEST_ASSERT
va009039 18:61554f238584 21 void usb_test_assert_internal(const char *expr, const char *file, int line);
va009039 18:61554f238584 22 #define USB_TEST_ASSERT(EXPR) while(!(EXPR)){usb_test_assert_internal(#EXPR,__FILE__,__LINE__);}
va009039 18:61554f238584 23
va009039 12:b91fdea8c0a7 24 USBHost* USBHost::inst = NULL;
va009039 12:b91fdea8c0a7 25
va009039 18:61554f238584 26 USBHost* USBHost::getHostInst() {
va009039 12:b91fdea8c0a7 27 if (inst == NULL) {
va009039 12:b91fdea8c0a7 28 inst = new USBHost();
va009039 12:b91fdea8c0a7 29 inst->init();
va009039 12:b91fdea8c0a7 30 }
va009039 12:b91fdea8c0a7 31 return inst;
va009039 12:b91fdea8c0a7 32 }
va009039 12:b91fdea8c0a7 33
va009039 12:b91fdea8c0a7 34 void USBHost::poll()
va009039 12:b91fdea8c0a7 35 {
va009039 12:b91fdea8c0a7 36 if (inst) {
va009039 12:b91fdea8c0a7 37 inst->task();
va009039 12:b91fdea8c0a7 38 }
va009039 12:b91fdea8c0a7 39 }
va009039 12:b91fdea8c0a7 40
va009039 12:b91fdea8c0a7 41 USBHost::USBHost() {
va009039 12:b91fdea8c0a7 42 }
va009039 12:b91fdea8c0a7 43
va009039 12:b91fdea8c0a7 44 /* virtual */ bool USBHost::addDevice(USBDeviceConnected* parent, int port, bool lowSpeed) {
va009039 12:b91fdea8c0a7 45 USBDeviceConnected* dev = new USBDeviceConnected;
va009039 12:b91fdea8c0a7 46 USBEndpoint* ep = new USBEndpoint(dev);
va009039 12:b91fdea8c0a7 47 dev->init(0, port, lowSpeed);
va009039 12:b91fdea8c0a7 48 dev->setAddress(0);
va009039 12:b91fdea8c0a7 49 dev->setEpCtl(ep);
va009039 12:b91fdea8c0a7 50 uint8_t desc[18];
va009039 12:b91fdea8c0a7 51 wait_ms(100);
va009039 12:b91fdea8c0a7 52
va009039 12:b91fdea8c0a7 53 int rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 1<<8, 0, desc, 8);
va009039 12:b91fdea8c0a7 54 USB_TEST_ASSERT(rc == USB_TYPE_OK);
va009039 12:b91fdea8c0a7 55 if (rc != USB_TYPE_OK) {
va009039 12:b91fdea8c0a7 56 USB_ERR("ADD DEVICE FAILD");
va009039 12:b91fdea8c0a7 57 }
va009039 12:b91fdea8c0a7 58 USB_DBG_HEX(desc, 8);
va009039 12:b91fdea8c0a7 59 DeviceDescriptor* dev_desc = reinterpret_cast<DeviceDescriptor*>(desc);
va009039 12:b91fdea8c0a7 60 ep->setSize(dev_desc->bMaxPacketSize);
va009039 12:b91fdea8c0a7 61
va009039 12:b91fdea8c0a7 62 int new_addr = USBDeviceConnected::getNewAddress();
va009039 12:b91fdea8c0a7 63 rc = controlWrite(dev, 0x00, SET_ADDRESS, new_addr, 0, NULL, 0);
va009039 12:b91fdea8c0a7 64 USB_TEST_ASSERT(rc == USB_TYPE_OK);
va009039 12:b91fdea8c0a7 65 dev->setAddress(new_addr);
va009039 12:b91fdea8c0a7 66 wait_ms(100);
va009039 12:b91fdea8c0a7 67
va009039 12:b91fdea8c0a7 68 rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 1<<8, 0, desc, sizeof(desc));
va009039 12:b91fdea8c0a7 69 USB_TEST_ASSERT(rc == USB_TYPE_OK);
va009039 12:b91fdea8c0a7 70 USB_DBG_HEX(desc, sizeof(desc));
va009039 12:b91fdea8c0a7 71
va009039 12:b91fdea8c0a7 72 dev->setVid(dev_desc->idVendor);
va009039 12:b91fdea8c0a7 73 dev->setPid(dev_desc->idProduct);
va009039 12:b91fdea8c0a7 74 dev->setClass(dev_desc->bDeviceClass);
va009039 12:b91fdea8c0a7 75 USB_INFO("parent:%p port:%d speed:%s VID:%04x PID:%04x class:%02x addr:%d",
va009039 12:b91fdea8c0a7 76 parent, port, (lowSpeed ? "low " : "full"), dev->getVid(), dev->getPid(), dev->getClass(),
va009039 12:b91fdea8c0a7 77 dev->getAddress());
va009039 12:b91fdea8c0a7 78
va009039 12:b91fdea8c0a7 79 DeviceLists.push_back(dev);
va009039 12:b91fdea8c0a7 80
va009039 12:b91fdea8c0a7 81 if (dev->getClass() == HUB_CLASS) {
va009039 12:b91fdea8c0a7 82 const int config = 1;
va009039 12:b91fdea8c0a7 83 int rc = controlWrite(dev, 0x00, SET_CONFIGURATION, config, 0, NULL, 0);
va009039 12:b91fdea8c0a7 84 USB_TEST_ASSERT(rc == USB_TYPE_OK);
va009039 12:b91fdea8c0a7 85 wait_ms(100);
va009039 12:b91fdea8c0a7 86 Hub(dev);
va009039 12:b91fdea8c0a7 87 }
va009039 12:b91fdea8c0a7 88 return true;
va009039 12:b91fdea8c0a7 89 }
va009039 12:b91fdea8c0a7 90
va009039 12:b91fdea8c0a7 91 // enumerate a device with the control USBEndpoint
va009039 12:b91fdea8c0a7 92 USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerator)
va009039 12:b91fdea8c0a7 93 {
va009039 12:b91fdea8c0a7 94 if (dev->getClass() == HUB_CLASS) { // skip hub class
va009039 12:b91fdea8c0a7 95 return USB_TYPE_OK;
va009039 12:b91fdea8c0a7 96 }
va009039 12:b91fdea8c0a7 97 uint8_t desc[18];
va009039 12:b91fdea8c0a7 98 USB_TYPE rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 1<<8, 0, desc, sizeof(desc));
va009039 12:b91fdea8c0a7 99 USB_TEST_ASSERT(rc == USB_TYPE_OK);
va009039 12:b91fdea8c0a7 100 USB_DBG_HEX(desc, sizeof(desc));
va009039 12:b91fdea8c0a7 101 if (rc != USB_TYPE_OK) {
va009039 12:b91fdea8c0a7 102 return rc;
va009039 12:b91fdea8c0a7 103 }
va009039 12:b91fdea8c0a7 104 DeviceDescriptor* dev_desc = reinterpret_cast<DeviceDescriptor*>(desc);
va009039 12:b91fdea8c0a7 105 dev->setClass(dev_desc->bDeviceClass);
va009039 12:b91fdea8c0a7 106 pEnumerator->setVidPid(dev->getVid(), dev->getPid());
va009039 12:b91fdea8c0a7 107
va009039 12:b91fdea8c0a7 108 rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 2<<8, 0, desc, 4);
va009039 12:b91fdea8c0a7 109 USB_TEST_ASSERT(rc == USB_TYPE_OK);
va009039 12:b91fdea8c0a7 110 USB_DBG_HEX(desc, 4);
va009039 12:b91fdea8c0a7 111
va009039 12:b91fdea8c0a7 112 int TotalLength = desc[2]|desc[3]<<8;
va009039 12:b91fdea8c0a7 113 uint8_t* buf = new uint8_t[TotalLength];
va009039 12:b91fdea8c0a7 114 rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 2<<8, 0, buf, TotalLength);
va009039 12:b91fdea8c0a7 115 USB_TEST_ASSERT(rc == USB_TYPE_OK);
va009039 12:b91fdea8c0a7 116 //USB_DBG_HEX(buf, TotalLength);
va009039 12:b91fdea8c0a7 117
va009039 12:b91fdea8c0a7 118 // Parse the configuration descriptor
va009039 12:b91fdea8c0a7 119 parseConfDescr(dev, buf, TotalLength, pEnumerator);
va009039 12:b91fdea8c0a7 120 delete[] buf;
va009039 12:b91fdea8c0a7 121 // only set configuration if not enumerated before
va009039 12:b91fdea8c0a7 122 if (!dev->isEnumerated()) {
va009039 12:b91fdea8c0a7 123 USB_DBG("Set configuration 1 on dev: %p", dev);
va009039 12:b91fdea8c0a7 124 // sixth step: set configuration (only 1 supported)
va009039 12:b91fdea8c0a7 125 int config = 1;
va009039 12:b91fdea8c0a7 126 USB_TYPE res = controlWrite(dev, 0x00, SET_CONFIGURATION, config, 0, NULL, 0);
va009039 12:b91fdea8c0a7 127 if (res != USB_TYPE_OK) {
va009039 12:b91fdea8c0a7 128 USB_ERR("SET CONF FAILED");
va009039 12:b91fdea8c0a7 129 return res;
va009039 12:b91fdea8c0a7 130 }
va009039 12:b91fdea8c0a7 131 // Some devices may require this delay
va009039 12:b91fdea8c0a7 132 wait_ms(100);
va009039 12:b91fdea8c0a7 133 dev->setEnumerated();
va009039 12:b91fdea8c0a7 134 // Now the device is enumerated!
va009039 12:b91fdea8c0a7 135 USB_DBG("dev %p is enumerated", dev);
va009039 12:b91fdea8c0a7 136 }
va009039 12:b91fdea8c0a7 137 return USB_TYPE_OK;
va009039 12:b91fdea8c0a7 138 }
va009039 12:b91fdea8c0a7 139
va009039 12:b91fdea8c0a7 140 // this method fills the USBDeviceConnected object: class,.... . It also add endpoints found in the descriptor.
va009039 12:b91fdea8c0a7 141 void USBHost::parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len, IUSBEnumerator* pEnumerator)
va009039 12:b91fdea8c0a7 142 {
va009039 12:b91fdea8c0a7 143 uint32_t index = 0;
va009039 12:b91fdea8c0a7 144 uint32_t len_desc = 0;
va009039 12:b91fdea8c0a7 145 uint8_t id = 0;
va009039 12:b91fdea8c0a7 146 USBEndpoint * ep = NULL;
va009039 12:b91fdea8c0a7 147 uint8_t intf_nb = 0;
va009039 12:b91fdea8c0a7 148 bool parsing_intf = false;
va009039 12:b91fdea8c0a7 149 uint8_t current_intf = 0;
va009039 12:b91fdea8c0a7 150 EndpointDescriptor* ep_desc;
va009039 12:b91fdea8c0a7 151
va009039 12:b91fdea8c0a7 152 while (index < len) {
va009039 12:b91fdea8c0a7 153 len_desc = conf_descr[index];
va009039 12:b91fdea8c0a7 154 id = conf_descr[index+1];
va009039 12:b91fdea8c0a7 155 USB_DBG_HEX(conf_descr+index, len_desc);
va009039 12:b91fdea8c0a7 156 switch (id) {
va009039 12:b91fdea8c0a7 157 case CONFIGURATION_DESCRIPTOR:
va009039 12:b91fdea8c0a7 158 USB_DBG("dev: %p has %d intf", dev, conf_descr[4]);
va009039 12:b91fdea8c0a7 159 dev->setNbIntf(conf_descr[4]);
va009039 12:b91fdea8c0a7 160 break;
va009039 12:b91fdea8c0a7 161 case INTERFACE_DESCRIPTOR:
va009039 12:b91fdea8c0a7 162 if(pEnumerator->parseInterface(conf_descr[index + 2], conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7])) {
va009039 12:b91fdea8c0a7 163 intf_nb++;
va009039 12:b91fdea8c0a7 164 current_intf = conf_descr[index + 2];
va009039 12:b91fdea8c0a7 165 dev->addInterface(current_intf, conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7]);
va009039 12:b91fdea8c0a7 166 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]);
va009039 12:b91fdea8c0a7 167 parsing_intf = true;
va009039 12:b91fdea8c0a7 168 } else {
va009039 12:b91fdea8c0a7 169 parsing_intf = false;
va009039 12:b91fdea8c0a7 170 }
va009039 12:b91fdea8c0a7 171 break;
va009039 12:b91fdea8c0a7 172 case ENDPOINT_DESCRIPTOR:
va009039 12:b91fdea8c0a7 173 ep_desc = reinterpret_cast<EndpointDescriptor*>(conf_descr+index);
va009039 12:b91fdea8c0a7 174 if (parsing_intf && (intf_nb <= MAX_INTF) ) {
va009039 12:b91fdea8c0a7 175 ENDPOINT_TYPE type = (ENDPOINT_TYPE)(ep_desc->bmAttributes & 0x03);
va009039 12:b91fdea8c0a7 176 ENDPOINT_DIRECTION dir = (ep_desc->bEndpointAddress & 0x80) ? IN : OUT;
va009039 12:b91fdea8c0a7 177 if(pEnumerator->useEndpoint(current_intf, type, dir)) {
va009039 12:b91fdea8c0a7 178 ep = new USBEndpoint(dev);
va009039 12:b91fdea8c0a7 179 ep->init(type, dir, ep_desc->wMaxPacketSize, ep_desc->bEndpointAddress);
va009039 12:b91fdea8c0a7 180 USB_DBG("ADD USBEndpoint %p, on interf %d on device %p", ep, current_intf, dev);
va009039 12:b91fdea8c0a7 181 dev->addEndpoint(current_intf, ep);
va009039 12:b91fdea8c0a7 182 }
va009039 12:b91fdea8c0a7 183 }
va009039 12:b91fdea8c0a7 184 break;
va009039 12:b91fdea8c0a7 185 case HID_DESCRIPTOR:
va009039 12:b91fdea8c0a7 186 //lenReportDescr = conf_descr[index + 7] | (conf_descr[index + 8] << 8);
va009039 12:b91fdea8c0a7 187 break;
va009039 12:b91fdea8c0a7 188 default:
va009039 12:b91fdea8c0a7 189 break;
va009039 12:b91fdea8c0a7 190 }
va009039 12:b91fdea8c0a7 191 index += len_desc;
va009039 12:b91fdea8c0a7 192 }
va009039 12:b91fdea8c0a7 193 }
va009039 12:b91fdea8c0a7 194
va009039 12:b91fdea8c0a7 195 USB_TYPE USBHost::controlRead(USBDeviceConnected* dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) {
va009039 18:61554f238584 196 USBEndpoint* ep = dev->getEpCtl();
va009039 18:61554f238584 197 SETUP_PACKET setup(requestType, request, value, index, len);
va009039 18:61554f238584 198
va009039 18:61554f238584 199 int result = token_setup(ep, &setup, len); // setup stage
va009039 18:61554f238584 200 USB_TRACE1(result);
va009039 18:61554f238584 201 if (result < 0) {
va009039 18:61554f238584 202 return USB_TYPE_ERROR;
va009039 18:61554f238584 203 }
va009039 18:61554f238584 204
va009039 18:61554f238584 205 int read_len = multi_token_in(ep, buf, len); // data stage
va009039 18:61554f238584 206 USB_TRACE1(read_len);
va009039 18:61554f238584 207 if (read_len < 0) {
va009039 18:61554f238584 208 return USB_TYPE_ERROR;
va009039 18:61554f238584 209 }
va009039 18:61554f238584 210
va009039 18:61554f238584 211 setToggle(ep, 1); // DATA1
va009039 18:61554f238584 212 result = multi_token_out(ep); // status stage
va009039 18:61554f238584 213 USB_TRACE1(result);
va009039 18:61554f238584 214 if (result < 0) {
va009039 18:61554f238584 215 return USB_TYPE_ERROR;
va009039 18:61554f238584 216 }
va009039 18:61554f238584 217 ep->setLengthTransferred(read_len);
va009039 18:61554f238584 218 return USB_TYPE_OK;
va009039 12:b91fdea8c0a7 219 }
va009039 12:b91fdea8c0a7 220
va009039 12:b91fdea8c0a7 221 USB_TYPE USBHost::controlWrite(USBDeviceConnected* dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) {
va009039 18:61554f238584 222 USBEndpoint* ep = dev->getEpCtl();
va009039 18:61554f238584 223 SETUP_PACKET setup(requestType, request, value, index, len);
va009039 18:61554f238584 224
va009039 18:61554f238584 225 int result = token_setup(ep, &setup, len); // setup stage
va009039 18:61554f238584 226 USB_TRACE1(result);
va009039 18:61554f238584 227 if (result < 0) {
va009039 18:61554f238584 228 return USB_TYPE_ERROR;
va009039 12:b91fdea8c0a7 229 }
va009039 18:61554f238584 230 int write_len = 0;
va009039 18:61554f238584 231 if (buf != NULL) {
va009039 18:61554f238584 232 write_len = multi_token_out(ep, buf, len); // data stage
va009039 18:61554f238584 233 USB_TRACE1(write_len);
va009039 18:61554f238584 234 if (write_len < 0) {
va009039 18:61554f238584 235 return USB_TYPE_ERROR;
va009039 18:61554f238584 236 }
va009039 18:61554f238584 237 }
va009039 18:61554f238584 238
va009039 18:61554f238584 239 setToggle(ep, 1); // DATA1
va009039 18:61554f238584 240 result = multi_token_in(ep); // status stage
va009039 18:61554f238584 241 USB_TRACE1(result);
va009039 18:61554f238584 242 if (result < 0) {
va009039 18:61554f238584 243 return USB_TYPE_ERROR;
va009039 18:61554f238584 244 }
va009039 18:61554f238584 245 ep->setLengthTransferred(write_len);
va009039 18:61554f238584 246 return USB_TYPE_OK;
va009039 12:b91fdea8c0a7 247 }
va009039 12:b91fdea8c0a7 248
va009039 12:b91fdea8c0a7 249 USB_TYPE USBHost::bulkRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) {
va009039 12:b91fdea8c0a7 250 if (blocking == false) {
va009039 12:b91fdea8c0a7 251 ep->setBuffer(buf, len);
va009039 12:b91fdea8c0a7 252 ep_queue.push(ep);
va009039 18:61554f238584 253 multi_token_inNB(ep, buf, len);
va009039 12:b91fdea8c0a7 254 return USB_TYPE_PROCESSING;
va009039 12:b91fdea8c0a7 255 }
va009039 18:61554f238584 256 int result = multi_token_in(ep, buf, len);
va009039 18:61554f238584 257 USB_TRACE1(result);
va009039 18:61554f238584 258 if (result < 0) {
va009039 18:61554f238584 259 return USB_TYPE_ERROR;
va009039 12:b91fdea8c0a7 260 }
va009039 18:61554f238584 261 ep->setLengthTransferred(result);
va009039 18:61554f238584 262 return USB_TYPE_OK;
va009039 12:b91fdea8c0a7 263 }
va009039 12:b91fdea8c0a7 264
va009039 12:b91fdea8c0a7 265 USB_TYPE USBHost::bulkWrite(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) {
va009039 12:b91fdea8c0a7 266 USB_TEST_ASSERT(blocking);
va009039 18:61554f238584 267 int result = multi_token_out(ep, buf, len);
va009039 18:61554f238584 268 USB_TRACE1(result);
va009039 18:61554f238584 269 if (result < 0) {
va009039 18:61554f238584 270 return USB_TYPE_ERROR;
va009039 12:b91fdea8c0a7 271 }
va009039 18:61554f238584 272 ep->setLengthTransferred(result);
va009039 18:61554f238584 273 return USB_TYPE_OK;
va009039 12:b91fdea8c0a7 274 }
va009039 12:b91fdea8c0a7 275
va009039 12:b91fdea8c0a7 276 USB_TYPE USBHost::interruptRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) {
va009039 12:b91fdea8c0a7 277 if (blocking == false) {
va009039 12:b91fdea8c0a7 278 ep->setBuffer(buf, len);
va009039 12:b91fdea8c0a7 279 ep_queue.push(ep);
va009039 18:61554f238584 280 multi_token_inNB(ep, buf, len);
va009039 12:b91fdea8c0a7 281 return USB_TYPE_PROCESSING;
va009039 12:b91fdea8c0a7 282 }
va009039 18:61554f238584 283 int result = multi_token_in(ep, buf, len);
va009039 18:61554f238584 284 USB_TRACE1(result);
va009039 18:61554f238584 285 if (result < 0) {
va009039 18:61554f238584 286 return USB_TYPE_ERROR;
va009039 18:61554f238584 287 }
va009039 18:61554f238584 288 ep->setLengthTransferred(result);
va009039 12:b91fdea8c0a7 289 return USB_TYPE_OK;
va009039 12:b91fdea8c0a7 290 }
va009039 12:b91fdea8c0a7 291
va009039 12:b91fdea8c0a7 292 USB_TYPE USBHost::interruptWrite(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) {
va009039 12:b91fdea8c0a7 293 USB_TEST_ASSERT(blocking);
va009039 18:61554f238584 294 int result = multi_token_out(ep, buf, len);
va009039 18:61554f238584 295 USB_TRACE1(result);
va009039 18:61554f238584 296 if (result < 0) {
va009039 18:61554f238584 297 return USB_TYPE_ERROR;
va009039 18:61554f238584 298 }
va009039 18:61554f238584 299 ep->setLengthTransferred(result);
va009039 12:b91fdea8c0a7 300 return USB_TYPE_OK;
va009039 12:b91fdea8c0a7 301 }
va009039 12:b91fdea8c0a7 302
va009039 12:b91fdea8c0a7 303 USB_TYPE USBHost::isochronousRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) {
va009039 18:61554f238584 304 USB_TEST_ASSERT(blocking);
va009039 12:b91fdea8c0a7 305 isochronousReadNB(ep, buf, len);
va009039 12:b91fdea8c0a7 306 return USB_TYPE_OK;
va009039 12:b91fdea8c0a7 307 }
va009039 12:b91fdea8c0a7 308
va009039 18:61554f238584 309 int USBHost::interruptReadNB(USBEndpoint* ep, uint8_t* data, int size) {
va009039 18:61554f238584 310 USB_TRACE1(size);
va009039 18:61554f238584 311 if (ep->getState() != USB_TYPE_PROCESSING) {
va009039 18:61554f238584 312 ep->setState(USB_TYPE_PROCESSING);
va009039 18:61554f238584 313 ep->setBuffer(data, size);
va009039 18:61554f238584 314 multi_token_inNB(ep, data, size);
va009039 12:b91fdea8c0a7 315 }
va009039 18:61554f238584 316 if (multi_token_inNB_result(ep) != USB_TYPE_PROCESSING) {
va009039 18:61554f238584 317 return ep->getLengthTransferred();
va009039 12:b91fdea8c0a7 318 }
va009039 18:61554f238584 319 return -1;
va009039 12:b91fdea8c0a7 320 }
va009039 12:b91fdea8c0a7 321
va009039 18:61554f238584 322 int USBHost::bulkReadNB(USBEndpoint* ep, uint8_t* data, int size) {
va009039 18:61554f238584 323 USB_TRACE1(size);
va009039 18:61554f238584 324 return interruptReadNB(ep, data, size);
va009039 12:b91fdea8c0a7 325 }
va009039 12:b91fdea8c0a7 326
va009039 12:b91fdea8c0a7 327 int USBHost::isochronousReadNB(USBEndpoint* ep, uint8_t* data, int size) {
va009039 18:61554f238584 328 USB_TRACE1(size);
va009039 12:b91fdea8c0a7 329 int result = token_iso_in(ep, data, size);
va009039 12:b91fdea8c0a7 330 if (result >= 0) {
va009039 12:b91fdea8c0a7 331 ep->setLengthTransferred(result);
va009039 12:b91fdea8c0a7 332 }
va009039 12:b91fdea8c0a7 333 return result;
va009039 12:b91fdea8c0a7 334 }
va009039 12:b91fdea8c0a7 335
va009039 18:61554f238584 336 void USBHost::task() {
va009039 12:b91fdea8c0a7 337 USBEndpoint* ep = ep_queue.pop();
va009039 18:61554f238584 338 if (ep) {
va009039 18:61554f238584 339 USB_TEST_ASSERT(ep->getDir() == IN);
va009039 18:61554f238584 340 if (multi_token_inNB_result(ep) != USB_TYPE_PROCESSING) {
va009039 18:61554f238584 341 ep->call();
va009039 18:61554f238584 342 } else {
va009039 18:61554f238584 343 ep_queue.push(ep);
va009039 18:61554f238584 344 }
va009039 12:b91fdea8c0a7 345 }
va009039 12:b91fdea8c0a7 346 }
va009039 18:61554f238584 347
va009039 18:61554f238584 348 void usb_test_assert_internal(const char *expr, const char *file, int line){
va009039 18:61554f238584 349 error("\n\n%s@%d %s ASSERT!\n\n", file, line, expr);
va009039 18:61554f238584 350 }
va009039 18:61554f238584 351