Simple USBHost library for STM32F746NG Discovery board. Only either the Fastspeed or the Highspeed port can be used( not both together)

Dependents:   DISCO-F746NG_USB_Host

Fork of KL46Z-USBHost by Norimasa Okamoto

Committer:
DieterGraef
Date:
Mon Jun 13 17:21:07 2016 +0000
Revision:
24:5396b6a93262
Parent:
18:61554f238584
Child:
25:7d6d9fc471bf
USB Host for STM32F746 DISCO Board. At the moment you can only use either the High Speed Port or the Fast Speed Port.

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