HEBOCON machine

Dependencies:   mbed Motorfader Servo WT2003M03

Committer:
abanum
Date:
Mon Jul 29 05:51:31 2019 +0000
Revision:
1:312b63cf250e
Parent:
0:a30ec7d94c3a
first pubrish

Who changed what in which revision?

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