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:
Tue Jan 28 06:50:12 2014 +0000
Revision:
7:9a20482c9a7a
Child:
8:6463cd1964c0
Control transfer status stage must set DATA1.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 7:9a20482c9a7a 1 // Simple USBHost for FRDM-KL46Z
va009039 7:9a20482c9a7a 2 #include "USBHost.h"
va009039 7:9a20482c9a7a 3 #include <algorithm>
va009039 7:9a20482c9a7a 4
va009039 7:9a20482c9a7a 5 template <bool>struct CtAssert;
va009039 7:9a20482c9a7a 6 template <>struct CtAssert<true> {};
va009039 7:9a20482c9a7a 7 #define CTASSERT(A) CtAssert<A>();
va009039 7:9a20482c9a7a 8
va009039 7:9a20482c9a7a 9
va009039 7:9a20482c9a7a 10 #ifdef _USB_DBG
va009039 7:9a20482c9a7a 11 #define USB_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");} while(0);
va009039 7:9a20482c9a7a 12 #define USB_DBG2(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");} while(0);
va009039 7:9a20482c9a7a 13 #define USB_DBG_HEX(A,B) debug_hex(A,B)
va009039 7:9a20482c9a7a 14 #define USB_DBG_ERRSTAT() report.print_errstat();
va009039 7:9a20482c9a7a 15 void debug_hex(uint8_t* buf, int size);
va009039 7:9a20482c9a7a 16 #else
va009039 7:9a20482c9a7a 17 #define USB_DBG(...) while(0)
va009039 7:9a20482c9a7a 18 #define USB_DBG2(...) while(0)
va009039 7:9a20482c9a7a 19 #define USB_DBG_HEX(A,B) while(0)
va009039 7:9a20482c9a7a 20 #define USB_DBG_ERRSTAT() while(0)
va009039 7:9a20482c9a7a 21 #endif
va009039 7:9a20482c9a7a 22
va009039 7:9a20482c9a7a 23 #define USB_TEST_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
va009039 7:9a20482c9a7a 24 #define USB_TEST_ASSERT_FALSE(A) USB_TEST_ASSERT(!(A))
va009039 7:9a20482c9a7a 25
va009039 7:9a20482c9a7a 26 #define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);}while(0);
va009039 7:9a20482c9a7a 27
va009039 7:9a20482c9a7a 28 USBHost* USBHost::inst = NULL;
va009039 7:9a20482c9a7a 29
va009039 7:9a20482c9a7a 30 USBHost* USBHost::getHostInst()
va009039 7:9a20482c9a7a 31 {
va009039 7:9a20482c9a7a 32 if (inst == NULL) {
va009039 7:9a20482c9a7a 33 inst = new USBHost();
va009039 7:9a20482c9a7a 34 inst->init();
va009039 7:9a20482c9a7a 35 }
va009039 7:9a20482c9a7a 36 return inst;
va009039 7:9a20482c9a7a 37 }
va009039 7:9a20482c9a7a 38
va009039 7:9a20482c9a7a 39 USBHost::USBHost() {
va009039 7:9a20482c9a7a 40 }
va009039 7:9a20482c9a7a 41
va009039 7:9a20482c9a7a 42 /* virtual */ bool USBHost::enumeration() {
va009039 7:9a20482c9a7a 43 USBEndpoint* ep = &ep_ctl_in_out;
va009039 7:9a20482c9a7a 44 uint8_t desc[64];
va009039 7:9a20482c9a7a 45 ep->setAddress(0);
va009039 7:9a20482c9a7a 46 ep->setSize(8); // max packet size
va009039 7:9a20482c9a7a 47 dev.addr = 0;
va009039 7:9a20482c9a7a 48 wait_ms(100);
va009039 7:9a20482c9a7a 49 SETUP_PACKET setup_get_descriptor = {0x80, GET_DESCRIPTOR, 1<<8, 0, 0};
va009039 7:9a20482c9a7a 50 int result = ControlRead(&setup_get_descriptor, desc, ep->getSize());
va009039 7:9a20482c9a7a 51 if (result < ep->getSize()) {
va009039 7:9a20482c9a7a 52 USB_DBG("result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 53 USB_DBG_ERRSTAT();
va009039 7:9a20482c9a7a 54 return false;
va009039 7:9a20482c9a7a 55 }
va009039 7:9a20482c9a7a 56 USB_DBG_HEX(desc, result);
va009039 7:9a20482c9a7a 57 USB_DBG_ERRSTAT();
va009039 7:9a20482c9a7a 58 DeviceDescriptor* dev_desc = reinterpret_cast<DeviceDescriptor*>(desc);
va009039 7:9a20482c9a7a 59 ep->setSize(dev_desc->bMaxPacketSize);
va009039 7:9a20482c9a7a 60
va009039 7:9a20482c9a7a 61 SETUP_PACKET setup_set_address = {0x00, SET_ADDRESS, 1, 0, 0};
va009039 7:9a20482c9a7a 62 result = ControlWrite(&setup_set_address);
va009039 7:9a20482c9a7a 63 if (result < 0) {
va009039 7:9a20482c9a7a 64 USB_DBG("result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 65 USB_DBG_ERRSTAT();
va009039 7:9a20482c9a7a 66 return false;
va009039 7:9a20482c9a7a 67 }
va009039 7:9a20482c9a7a 68 wait_ms(100);
va009039 7:9a20482c9a7a 69 dev.addr = 1;
va009039 7:9a20482c9a7a 70
va009039 7:9a20482c9a7a 71 result = ControlRead(&setup_get_descriptor, desc, sizeof(desc));
va009039 7:9a20482c9a7a 72 if (result < 8) {
va009039 7:9a20482c9a7a 73 USB_DBG("result=%d", result);
va009039 7:9a20482c9a7a 74 USB_DBG_ERRSTAT();
va009039 7:9a20482c9a7a 75 return false;
va009039 7:9a20482c9a7a 76 }
va009039 7:9a20482c9a7a 77 USB_DBG_HEX(desc, result);
va009039 7:9a20482c9a7a 78 USB_DBG_ERRSTAT();
va009039 7:9a20482c9a7a 79
va009039 7:9a20482c9a7a 80 dev.vid = dev_desc->idVendor;
va009039 7:9a20482c9a7a 81 dev.pid = dev_desc->idProduct;
va009039 7:9a20482c9a7a 82 USB_INFO("USB VID: %04x, PID: %04x\n", dev.vid, dev.pid);
va009039 7:9a20482c9a7a 83 if (dev_desc->bDeviceClass == HUB_CLASS) {
va009039 7:9a20482c9a7a 84 USB_INFO("USB hub not supported.\n\n");
va009039 7:9a20482c9a7a 85 exit(1);
va009039 7:9a20482c9a7a 86 }
va009039 7:9a20482c9a7a 87
va009039 7:9a20482c9a7a 88 setup_get_descriptor.wValue = 2<<8; // config descriptor
va009039 7:9a20482c9a7a 89 result = ControlRead(&setup_get_descriptor, desc, 4);
va009039 7:9a20482c9a7a 90 if (result != 4) {
va009039 7:9a20482c9a7a 91 USB_DBG("result=%d", result);
va009039 7:9a20482c9a7a 92 USB_DBG_ERRSTAT();
va009039 7:9a20482c9a7a 93 return false;
va009039 7:9a20482c9a7a 94 }
va009039 7:9a20482c9a7a 95 USB_DBG_HEX(desc, 4);
va009039 7:9a20482c9a7a 96 USB_DBG_ERRSTAT();
va009039 7:9a20482c9a7a 97
va009039 7:9a20482c9a7a 98 int TotalLength = desc[2]|desc[3]<<8;
va009039 7:9a20482c9a7a 99 uint8_t* buf = new uint8_t[TotalLength];
va009039 7:9a20482c9a7a 100 result = ControlRead(&setup_get_descriptor, buf, TotalLength);
va009039 7:9a20482c9a7a 101 if (result != TotalLength) {
va009039 7:9a20482c9a7a 102 USB_DBG("result=%d TotalLength=%d %02x", result, TotalLength, LastStatus);
va009039 7:9a20482c9a7a 103 USB_DBG_ERRSTAT();
va009039 7:9a20482c9a7a 104 return false;
va009039 7:9a20482c9a7a 105 }
va009039 7:9a20482c9a7a 106 USB_DBG_HEX(buf, TotalLength);
va009039 7:9a20482c9a7a 107 USB_DBG_ERRSTAT();
va009039 7:9a20482c9a7a 108
va009039 7:9a20482c9a7a 109 for(int i = 0; i < TotalLength; ) {
va009039 7:9a20482c9a7a 110 int Length = buf[i];
va009039 7:9a20482c9a7a 111 uint8_t DescriptorType = buf[i+1];
va009039 7:9a20482c9a7a 112 if (DescriptorType == 0x05) { // endpoint
va009039 7:9a20482c9a7a 113 EndpointDescriptor* desc = reinterpret_cast<EndpointDescriptor*>(buf+i);
va009039 7:9a20482c9a7a 114 USBEndpoint* ep = NULL;
va009039 7:9a20482c9a7a 115 if (desc->bmAttributes == 0x03) { // interrupt
va009039 7:9a20482c9a7a 116 if (desc->bEndpointAddress & 0x80) {
va009039 7:9a20482c9a7a 117 ep = &ep_int_in;
va009039 7:9a20482c9a7a 118 }
va009039 7:9a20482c9a7a 119 } else if (desc->bmAttributes == 0x02) { // bulk
va009039 7:9a20482c9a7a 120 ep = (desc->bEndpointAddress & 0x80) ? &ep_bulk_in : &ep_bulk_out;
va009039 7:9a20482c9a7a 121 }
va009039 7:9a20482c9a7a 122 if (ep) {
va009039 7:9a20482c9a7a 123 ep->setAddress(desc->bEndpointAddress);
va009039 7:9a20482c9a7a 124 ep->setSize(desc->wMaxPacketSize);
va009039 7:9a20482c9a7a 125 }
va009039 7:9a20482c9a7a 126 }
va009039 7:9a20482c9a7a 127 USB_DBG_HEX(buf+i, Length);
va009039 7:9a20482c9a7a 128 i += Length;
va009039 7:9a20482c9a7a 129 }
va009039 7:9a20482c9a7a 130 delete[] buf;
va009039 7:9a20482c9a7a 131
va009039 7:9a20482c9a7a 132 // config = 1
va009039 7:9a20482c9a7a 133 SETUP_PACKET setup_set_config = {0x00, SET_CONFIGURATION, 1, 0, 0};
va009039 7:9a20482c9a7a 134 result = ControlWrite(&setup_set_config);
va009039 7:9a20482c9a7a 135 if (result < 0) {
va009039 7:9a20482c9a7a 136 USB_DBG("set config: %02x", LastStatus);
va009039 7:9a20482c9a7a 137 USB_DBG_ERRSTAT();
va009039 7:9a20482c9a7a 138 if (lowSpeed && LastStatus == STALL) { // TODO:
va009039 7:9a20482c9a7a 139 wait_ms(100);
va009039 7:9a20482c9a7a 140 return true;
va009039 7:9a20482c9a7a 141 }
va009039 7:9a20482c9a7a 142 return false;
va009039 7:9a20482c9a7a 143 }
va009039 7:9a20482c9a7a 144 wait_ms(100);
va009039 7:9a20482c9a7a 145 return true;
va009039 7:9a20482c9a7a 146 }
va009039 7:9a20482c9a7a 147
va009039 7:9a20482c9a7a 148 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 7:9a20482c9a7a 149 SETUP_PACKET setup = {requestType, request, value, index};
va009039 7:9a20482c9a7a 150 int result = ControlRead(&setup, buf, len);
va009039 7:9a20482c9a7a 151 USB_DBG2("result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 152 return (result >= 0) ? USB_TYPE_OK : USB_TYPE_ERROR;
va009039 7:9a20482c9a7a 153 }
va009039 7:9a20482c9a7a 154
va009039 7:9a20482c9a7a 155 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 7:9a20482c9a7a 156 SETUP_PACKET setup = {requestType, request, value, index};
va009039 7:9a20482c9a7a 157 int result = ControlWrite(&setup, buf, len);
va009039 7:9a20482c9a7a 158 if (result >= 0) {
va009039 7:9a20482c9a7a 159 return USB_TYPE_OK;
va009039 7:9a20482c9a7a 160 }
va009039 7:9a20482c9a7a 161 USB_DBG("result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 162 USB_DBG_ERRSTAT();
va009039 7:9a20482c9a7a 163 USB_DBG_HEX(buf, len);
va009039 7:9a20482c9a7a 164 return USB_TYPE_ERROR;
va009039 7:9a20482c9a7a 165 }
va009039 7:9a20482c9a7a 166
va009039 7:9a20482c9a7a 167 USB_TYPE USBHost::bulkRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking) {
va009039 7:9a20482c9a7a 168 USB_TEST_ASSERT(blocking);
va009039 7:9a20482c9a7a 169 int result = BulkRead(buf, len);
va009039 7:9a20482c9a7a 170 if (result >= 0) {
va009039 7:9a20482c9a7a 171 return USB_TYPE_OK;
va009039 7:9a20482c9a7a 172 }
va009039 7:9a20482c9a7a 173 //USB_DBG2("result=%d %02x", result, host->LastStatus);
va009039 7:9a20482c9a7a 174 return USB_TYPE_ERROR;
va009039 7:9a20482c9a7a 175 }
va009039 7:9a20482c9a7a 176
va009039 7:9a20482c9a7a 177 USB_TYPE USBHost::bulkWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking) {
va009039 7:9a20482c9a7a 178 USB_TEST_ASSERT(blocking);
va009039 7:9a20482c9a7a 179 int result = BulkWrite(buf, len);
va009039 7:9a20482c9a7a 180 if (result >= 0) {
va009039 7:9a20482c9a7a 181 return USB_TYPE_OK;
va009039 7:9a20482c9a7a 182 }
va009039 7:9a20482c9a7a 183 USB_DBG2("result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 184 return USB_TYPE_ERROR;
va009039 7:9a20482c9a7a 185 }
va009039 7:9a20482c9a7a 186
va009039 7:9a20482c9a7a 187 USB_TYPE USBHost::interruptWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking) {
va009039 7:9a20482c9a7a 188 USB_TEST_ASSERT(blocking);
va009039 7:9a20482c9a7a 189 int result = InterruptRead(buf, len);
va009039 7:9a20482c9a7a 190 if (result >= 0) {
va009039 7:9a20482c9a7a 191 return USB_TYPE_OK;
va009039 7:9a20482c9a7a 192 }
va009039 7:9a20482c9a7a 193 return USB_TYPE_ERROR;
va009039 7:9a20482c9a7a 194 }
va009039 7:9a20482c9a7a 195
va009039 7:9a20482c9a7a 196 int USBHost::ControlRead(SETUP_PACKET* setup, uint8_t* data, int size) {
va009039 7:9a20482c9a7a 197 USBEndpoint* ep = &ep_ctl_in_out;
va009039 7:9a20482c9a7a 198 setAddr(dev.addr);
va009039 7:9a20482c9a7a 199 token_setup(ep, setup, size); // setup stage
va009039 7:9a20482c9a7a 200 if (LastStatus != ACK) {
va009039 7:9a20482c9a7a 201 USB_DBG("setup %02x", LastStatus);
va009039 7:9a20482c9a7a 202 return -1;
va009039 7:9a20482c9a7a 203 }
va009039 7:9a20482c9a7a 204 int read_len = 0;
va009039 7:9a20482c9a7a 205 while(read_len < size) {
va009039 7:9a20482c9a7a 206 int size2 = std::min(size-read_len, ep->getSize());
va009039 7:9a20482c9a7a 207 int result = token_in(ep, data+read_len, size2);
va009039 7:9a20482c9a7a 208 //USB_DBG("token_in result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 209 if (result < 0) {
va009039 7:9a20482c9a7a 210 USB_DBG("token_in %d/%d %02x", read_len, size, LastStatus);
va009039 7:9a20482c9a7a 211 return result;
va009039 7:9a20482c9a7a 212 }
va009039 7:9a20482c9a7a 213 read_len += result;
va009039 7:9a20482c9a7a 214 if (result < ep->getSize()) {
va009039 7:9a20482c9a7a 215 break;
va009039 7:9a20482c9a7a 216 }
va009039 7:9a20482c9a7a 217 }
va009039 7:9a20482c9a7a 218 ep->setData01(DATA1);
va009039 7:9a20482c9a7a 219 int result = token_out(ep); // status stage
va009039 7:9a20482c9a7a 220 if (result < 0) {
va009039 7:9a20482c9a7a 221 USB_DBG("status token_out %02x", LastStatus);
va009039 7:9a20482c9a7a 222 if (LastStatus == STALL) {
va009039 7:9a20482c9a7a 223 return read_len;
va009039 7:9a20482c9a7a 224 }
va009039 7:9a20482c9a7a 225 return result;
va009039 7:9a20482c9a7a 226 }
va009039 7:9a20482c9a7a 227 return read_len;
va009039 7:9a20482c9a7a 228 }
va009039 7:9a20482c9a7a 229
va009039 7:9a20482c9a7a 230 int USBHost::ControlWrite(SETUP_PACKET* setup, uint8_t* data, int size) {
va009039 7:9a20482c9a7a 231 USBEndpoint* ep = &ep_ctl_in_out;
va009039 7:9a20482c9a7a 232 setAddr(dev.addr);
va009039 7:9a20482c9a7a 233 token_setup(ep, setup, size); // setup stage
va009039 7:9a20482c9a7a 234 if (LastStatus != ACK) {
va009039 7:9a20482c9a7a 235 USB_DBG("setup %02x", LastStatus);
va009039 7:9a20482c9a7a 236 return -1;
va009039 7:9a20482c9a7a 237 }
va009039 7:9a20482c9a7a 238 int write_len = 0;
va009039 7:9a20482c9a7a 239 if (data != NULL) {
va009039 7:9a20482c9a7a 240 write_len = token_out(ep, data, size);
va009039 7:9a20482c9a7a 241 if (write_len < 0) {
va009039 7:9a20482c9a7a 242 return -1;
va009039 7:9a20482c9a7a 243 }
va009039 7:9a20482c9a7a 244 }
va009039 7:9a20482c9a7a 245 ep->setData01(DATA1);
va009039 7:9a20482c9a7a 246 int result = token_in(ep); // status stage
va009039 7:9a20482c9a7a 247 if (result < 0) {
va009039 7:9a20482c9a7a 248 USB_DBG("result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 249 //return result;
va009039 7:9a20482c9a7a 250 }
va009039 7:9a20482c9a7a 251 return write_len;
va009039 7:9a20482c9a7a 252 }
va009039 7:9a20482c9a7a 253
va009039 7:9a20482c9a7a 254 int USBHost::InterruptRead(uint8_t* data, int size) {
va009039 7:9a20482c9a7a 255 USBEndpoint* ep = &ep_int_in;
va009039 7:9a20482c9a7a 256 setAddr(dev.addr);
va009039 7:9a20482c9a7a 257 setEndpoint();
va009039 7:9a20482c9a7a 258 const int retryLimit = 0;
va009039 7:9a20482c9a7a 259 int read_len = 0;
va009039 7:9a20482c9a7a 260 for(int n = 0; read_len < size; n++) {
va009039 7:9a20482c9a7a 261 int size2 = std::min(size-read_len, ep->getSize());
va009039 7:9a20482c9a7a 262 int result = token_in(ep, data+read_len, size2, retryLimit);
va009039 7:9a20482c9a7a 263 if (result < 0) {
va009039 7:9a20482c9a7a 264 if (LastStatus == NAK) {
va009039 7:9a20482c9a7a 265 if (n == 0) {
va009039 7:9a20482c9a7a 266 return -1;
va009039 7:9a20482c9a7a 267 }
va009039 7:9a20482c9a7a 268 break;
va009039 7:9a20482c9a7a 269 }
va009039 7:9a20482c9a7a 270 USB_DBG("token_in result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 271 return result;
va009039 7:9a20482c9a7a 272 }
va009039 7:9a20482c9a7a 273 read_len += result;
va009039 7:9a20482c9a7a 274 if (result < ep->getSize()) {
va009039 7:9a20482c9a7a 275 break;
va009039 7:9a20482c9a7a 276 }
va009039 7:9a20482c9a7a 277 }
va009039 7:9a20482c9a7a 278 return read_len;
va009039 7:9a20482c9a7a 279 }
va009039 7:9a20482c9a7a 280
va009039 7:9a20482c9a7a 281 int USBHost::BulkRead(uint8_t* data, int size, int timeout_ms) {
va009039 7:9a20482c9a7a 282 USBEndpoint* ep = &ep_bulk_in;
va009039 7:9a20482c9a7a 283 setAddr(dev.addr);
va009039 7:9a20482c9a7a 284 setEndpoint();
va009039 7:9a20482c9a7a 285 int retryLimit = (timeout_ms == 0) ? 0 : 10;
va009039 7:9a20482c9a7a 286 int read_len = 0;
va009039 7:9a20482c9a7a 287 Timer t;
va009039 7:9a20482c9a7a 288 for(int n = 0; read_len < size; n++) {
va009039 7:9a20482c9a7a 289 int size2 = std::min(size-read_len, ep->getSize());
va009039 7:9a20482c9a7a 290 int result = token_in(ep, data+read_len, size2, retryLimit);
va009039 7:9a20482c9a7a 291 if (result < 0) {
va009039 7:9a20482c9a7a 292 if (LastStatus == NAK) {
va009039 7:9a20482c9a7a 293 if (n == 0) {
va009039 7:9a20482c9a7a 294 return -1;
va009039 7:9a20482c9a7a 295 }
va009039 7:9a20482c9a7a 296 break;
va009039 7:9a20482c9a7a 297 }
va009039 7:9a20482c9a7a 298 USB_DBG("token_in result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 299 return result;
va009039 7:9a20482c9a7a 300 }
va009039 7:9a20482c9a7a 301 read_len += result;
va009039 7:9a20482c9a7a 302 if (result < ep->getSize()) {
va009039 7:9a20482c9a7a 303 break;
va009039 7:9a20482c9a7a 304 }
va009039 7:9a20482c9a7a 305 if (timeout_ms > 0 && t.read_ms() > timeout_ms) {
va009039 7:9a20482c9a7a 306 USB_DBG("timeout_ms: %d", timeout_ms);
va009039 7:9a20482c9a7a 307 break;
va009039 7:9a20482c9a7a 308 }
va009039 7:9a20482c9a7a 309 }
va009039 7:9a20482c9a7a 310 return read_len;
va009039 7:9a20482c9a7a 311 }
va009039 7:9a20482c9a7a 312
va009039 7:9a20482c9a7a 313 int USBHost::BulkWrite(const uint8_t* data, int size) {
va009039 7:9a20482c9a7a 314 USBEndpoint* ep = &ep_bulk_out;
va009039 7:9a20482c9a7a 315 setAddr(dev.addr);
va009039 7:9a20482c9a7a 316 setEndpoint();
va009039 7:9a20482c9a7a 317 int write_len = 0;
va009039 7:9a20482c9a7a 318 for(int n = 0; write_len < size; n++) {
va009039 7:9a20482c9a7a 319 int size2 = std::min(size-write_len, ep->getSize());
va009039 7:9a20482c9a7a 320 int result = token_out(ep, data+write_len, size2);
va009039 7:9a20482c9a7a 321 if (result < 0) {
va009039 7:9a20482c9a7a 322 if (LastStatus == NAK) {
va009039 7:9a20482c9a7a 323 if (n == 0) {
va009039 7:9a20482c9a7a 324 return -1;
va009039 7:9a20482c9a7a 325 }
va009039 7:9a20482c9a7a 326 break;
va009039 7:9a20482c9a7a 327 }
va009039 7:9a20482c9a7a 328 USB_DBG("token_out result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 329 return result;
va009039 7:9a20482c9a7a 330 }
va009039 7:9a20482c9a7a 331 write_len += result;
va009039 7:9a20482c9a7a 332 if (result < ep->getSize()) {
va009039 7:9a20482c9a7a 333 break;
va009039 7:9a20482c9a7a 334 }
va009039 7:9a20482c9a7a 335 }
va009039 7:9a20482c9a7a 336 return write_len;
va009039 7:9a20482c9a7a 337 }
va009039 7:9a20482c9a7a 338
va009039 7:9a20482c9a7a 339 int USBHost::IsochronousRead(USBEndpoint* ep, uint8_t* data, int size) {
va009039 7:9a20482c9a7a 340 setAddr(dev.addr);
va009039 7:9a20482c9a7a 341 return token_iso_in(ep, data, size);
va009039 7:9a20482c9a7a 342 }
va009039 7:9a20482c9a7a 343