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:
Mon Jun 23 20:30:04 2014 +0900
Revision:
16:981c3104f6c0
Parent:
12:b91fdea8c0a7
Child:
18:61554f238584
add FRDM-K64F.(not tested)

Who changed what in which revision?

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