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:
Sat Jan 25 12:51:44 2014 +0000
Revision:
3:a3872f7593e2
fix max packet size

Who changed what in which revision?

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