Usb read
Dependencies: FATFileSystem
Fork of F401RE-USBHost by
USBHost.cpp
00001 // Simple USBHost for FRDM-KL46Z 00002 #include "USBHost.h" 00003 #include <algorithm> 00004 00005 USBHost* USBHost::inst = NULL; 00006 00007 USBHost* USBHost::getHostInst() 00008 { 00009 if (inst == NULL) { 00010 inst = new USBHost(); 00011 inst->init(); 00012 } 00013 return inst; 00014 } 00015 00016 void USBHost::poll() 00017 { 00018 if (inst) { 00019 inst->task(); 00020 } 00021 } 00022 00023 USBHost::USBHost() { 00024 } 00025 00026 /* virtual */ bool USBHost::addDevice(USBDeviceConnected* parent, int port, bool lowSpeed) { 00027 USBDeviceConnected* dev = new USBDeviceConnected; 00028 USBEndpoint* ep = new USBEndpoint(dev); 00029 dev->init(0, port, lowSpeed); 00030 dev->setAddress(0); 00031 dev->setEpCtl(ep); 00032 uint8_t desc[18]; 00033 wait_ms(100); 00034 00035 int rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 1<<8, 0, desc, 8); 00036 USB_TEST_ASSERT(rc == USB_TYPE_OK); 00037 if (rc != USB_TYPE_OK) { 00038 USB_ERR("ADD DEVICE FAILD"); 00039 } 00040 USB_DBG_HEX(desc, 8); 00041 DeviceDescriptor* dev_desc = reinterpret_cast<DeviceDescriptor*>(desc); 00042 ep->setSize(dev_desc->bMaxPacketSize); 00043 00044 int new_addr = USBDeviceConnected::getNewAddress(); 00045 rc = controlWrite(dev, 0x00, SET_ADDRESS, new_addr, 0, NULL, 0); 00046 USB_TEST_ASSERT(rc == USB_TYPE_OK); 00047 dev->setAddress(new_addr); 00048 wait_ms(100); 00049 00050 rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 1<<8, 0, desc, sizeof(desc)); 00051 USB_TEST_ASSERT(rc == USB_TYPE_OK); 00052 USB_DBG_HEX(desc, sizeof(desc)); 00053 00054 dev->setVid(dev_desc->idVendor); 00055 dev->setPid(dev_desc->idProduct); 00056 dev->setClass(dev_desc->bDeviceClass); 00057 USB_INFO("parent:%p port:%d speed:%s VID:%04x PID:%04x class:%02x addr:%d", 00058 parent, port, (lowSpeed ? "low " : "full"), dev->getVid(), dev->getPid(), dev->getClass(), 00059 dev->getAddress()); 00060 00061 DeviceLists.push_back(dev); 00062 00063 if (dev->getClass() == HUB_CLASS) { 00064 const int config = 1; 00065 int rc = controlWrite(dev, 0x00, SET_CONFIGURATION, config, 0, NULL, 0); 00066 USB_TEST_ASSERT(rc == USB_TYPE_OK); 00067 wait_ms(100); 00068 Hub(dev); 00069 } 00070 return true; 00071 } 00072 00073 // enumerate a device with the control USBEndpoint 00074 USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerator) 00075 { 00076 if (dev->getClass() == HUB_CLASS) { // skip hub class 00077 return USB_TYPE_OK; 00078 } 00079 uint8_t desc[18]; 00080 USB_TYPE rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 1<<8, 0, desc, sizeof(desc)); 00081 USB_TEST_ASSERT(rc == USB_TYPE_OK); 00082 USB_DBG_HEX(desc, sizeof(desc)); 00083 if (rc != USB_TYPE_OK) { 00084 return rc; 00085 } 00086 DeviceDescriptor* dev_desc = reinterpret_cast<DeviceDescriptor*>(desc); 00087 dev->setClass(dev_desc->bDeviceClass); 00088 pEnumerator->setVidPid(dev->getVid(), dev->getPid()); 00089 00090 rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 2<<8, 0, desc, 4); 00091 USB_TEST_ASSERT(rc == USB_TYPE_OK); 00092 USB_DBG_HEX(desc, 4); 00093 00094 int TotalLength = desc[2]|desc[3]<<8; 00095 uint8_t* buf = new uint8_t[TotalLength]; 00096 rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 2<<8, 0, buf, TotalLength); 00097 USB_TEST_ASSERT(rc == USB_TYPE_OK); 00098 //USB_DBG_HEX(buf, TotalLength); 00099 00100 // Parse the configuration descriptor 00101 parseConfDescr(dev, buf, TotalLength, pEnumerator); 00102 delete[] buf; 00103 // only set configuration if not enumerated before 00104 if (!dev->isEnumerated()) { 00105 USB_DBG("Set configuration 1 on dev: %p", dev); 00106 // sixth step: set configuration (only 1 supported) 00107 int config = 1; 00108 USB_TYPE res = controlWrite(dev, 0x00, SET_CONFIGURATION, config, 0, NULL, 0); 00109 if (res != USB_TYPE_OK) { 00110 USB_ERR("SET CONF FAILED"); 00111 return res; 00112 } 00113 // Some devices may require this delay 00114 wait_ms(100); 00115 dev->setEnumerated(); 00116 // Now the device is enumerated! 00117 USB_DBG("dev %p is enumerated", dev); 00118 } 00119 return USB_TYPE_OK; 00120 } 00121 00122 // this method fills the USBDeviceConnected object: class,.... . It also add endpoints found in the descriptor. 00123 void USBHost::parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len, IUSBEnumerator* pEnumerator) 00124 { 00125 uint32_t index = 0; 00126 uint32_t len_desc = 0; 00127 uint8_t id = 0; 00128 USBEndpoint * ep = NULL; 00129 uint8_t intf_nb = 0; 00130 bool parsing_intf = false; 00131 uint8_t current_intf = 0; 00132 EndpointDescriptor* ep_desc; 00133 00134 while (index < len) { 00135 len_desc = conf_descr[index]; 00136 id = conf_descr[index+1]; 00137 USB_DBG_HEX(conf_descr+index, len_desc); 00138 switch (id) { 00139 case CONFIGURATION_DESCRIPTOR: 00140 USB_DBG("dev: %p has %d intf", dev, conf_descr[4]); 00141 dev->setNbIntf(conf_descr[4]); 00142 break; 00143 case INTERFACE_DESCRIPTOR: 00144 if(pEnumerator->parseInterface(conf_descr[index + 2], conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7])) { 00145 intf_nb++; 00146 current_intf = conf_descr[index + 2]; 00147 dev->addInterface(current_intf, conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7]); 00148 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]); 00149 parsing_intf = true; 00150 } else { 00151 parsing_intf = false; 00152 } 00153 break; 00154 case ENDPOINT_DESCRIPTOR: 00155 ep_desc = reinterpret_cast<EndpointDescriptor*>(conf_descr+index); 00156 if (parsing_intf && (intf_nb <= MAX_INTF) ) { 00157 ENDPOINT_TYPE type = (ENDPOINT_TYPE)(ep_desc->bmAttributes & 0x03); 00158 ENDPOINT_DIRECTION dir = (ep_desc->bEndpointAddress & 0x80) ? IN : OUT; 00159 if(pEnumerator->useEndpoint(current_intf, type, dir)) { 00160 ep = new USBEndpoint(dev); 00161 ep->init(type, dir, ep_desc->wMaxPacketSize, ep_desc->bEndpointAddress); 00162 USB_DBG("ADD USBEndpoint %p, on interf %d on device %p", ep, current_intf, dev); 00163 dev->addEndpoint(current_intf, ep); 00164 } 00165 } 00166 break; 00167 case HID_DESCRIPTOR: 00168 //lenReportDescr = conf_descr[index + 7] | (conf_descr[index + 8] << 8); 00169 break; 00170 default: 00171 break; 00172 } 00173 index += len_desc; 00174 } 00175 } 00176 00177 USB_TYPE USBHost::controlRead(USBDeviceConnected* dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) { 00178 SETUP_PACKET setup = {requestType, request, value, index}; 00179 int result = ControlRead(dev, &setup, buf, len); 00180 //USB_DBG2("result=%d %02x", result, LastStatus); 00181 return (result >= 0) ? USB_TYPE_OK : USB_TYPE_ERROR; 00182 } 00183 00184 USB_TYPE USBHost::controlWrite(USBDeviceConnected* dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) { 00185 SETUP_PACKET setup = {requestType, request, value, index}; 00186 int result = ControlWrite(dev, &setup, buf, len); 00187 if (result >= 0) { 00188 return USB_TYPE_OK; 00189 } 00190 USB_DBG("result=%d %02x", result, LastStatus); 00191 USB_DBG_HEX(buf, len); 00192 return USB_TYPE_ERROR; 00193 } 00194 00195 USB_TYPE USBHost::bulkRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) { 00196 if (blocking == false) { 00197 ep->setBuffer(buf, len); 00198 ep_queue.push(ep); 00199 return USB_TYPE_PROCESSING; 00200 } 00201 int result = bulkReadBLOCK(ep, buf, len, -1); 00202 if (result >= 0) { 00203 return USB_TYPE_OK; 00204 } 00205 //USB_DBG2("result=%d %02x", result, host->LastStatus); 00206 return USB_TYPE_ERROR; 00207 } 00208 00209 USB_TYPE USBHost::bulkWrite(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) { 00210 USB_TEST_ASSERT(blocking); 00211 int result = bulkWriteNB(ep, buf, len); 00212 if (result >= 0) { 00213 return USB_TYPE_OK; 00214 } 00215 USB_DBG2("result=%d %02x", result, LastStatus); 00216 return USB_TYPE_ERROR; 00217 } 00218 00219 USB_TYPE USBHost::interruptRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) { 00220 if (blocking == false) { 00221 ep->setBuffer(buf, len); 00222 ep_queue.push(ep); 00223 return USB_TYPE_PROCESSING; 00224 } 00225 interruptReadNB(ep, buf, len); 00226 return USB_TYPE_OK; 00227 } 00228 00229 USB_TYPE USBHost::interruptWrite(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) { 00230 USB_TEST_ASSERT(blocking); 00231 interruptWriteNB(ep, buf, len); 00232 return USB_TYPE_OK; 00233 } 00234 00235 USB_TYPE USBHost::isochronousRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) { 00236 if (blocking == false) { 00237 ep->setBuffer(buf, len); 00238 ep_queue.push(ep); 00239 return USB_TYPE_PROCESSING; 00240 } 00241 isochronousReadNB(ep, buf, len); 00242 return USB_TYPE_OK; 00243 } 00244 00245 int USBHost::ControlRead(USBDeviceConnected* dev, SETUP_PACKET* setup, uint8_t* data, int size) { 00246 USB_TEST_ASSERT(dev); 00247 USBEndpoint* ep = dev->getEpCtl(); 00248 USB_TEST_ASSERT(ep); 00249 setAddr(dev->getAddress(), dev->getSpeed()); 00250 token_setup(ep, setup, size); // setup stage 00251 if (LastStatus != ACK) { 00252 USB_DBG("setup %02x", LastStatus); 00253 return -1; 00254 } 00255 int read_len = 0; 00256 while(read_len < size) { 00257 int size2 = std::min(size-read_len, ep->getSize()); 00258 int result = token_in(ep, data+read_len, size2); 00259 //USB_DBG("token_in result=%d %02x", result, LastStatus); 00260 if (result < 0) { 00261 USB_DBG("token_in %d/%d %02x", read_len, size, LastStatus); 00262 return result; 00263 } 00264 read_len += result; 00265 if (result < ep->getSize()) { 00266 break; 00267 } 00268 } 00269 ep->setData01(DATA1); 00270 int result = token_out(ep); // status stage 00271 if (result < 0) { 00272 USB_DBG("status token_out %02x", LastStatus); 00273 if (LastStatus == STALL) { 00274 ep->setLengthTransferred(read_len); 00275 return read_len; 00276 } 00277 return result; 00278 } 00279 ep->setLengthTransferred(read_len); 00280 return read_len; 00281 } 00282 00283 int USBHost::ControlWrite(USBDeviceConnected* dev, SETUP_PACKET* setup, uint8_t* data, int size) { 00284 USB_TEST_ASSERT(dev); 00285 USBEndpoint* ep = dev->getEpCtl(); 00286 USB_TEST_ASSERT(ep); 00287 setAddr(dev->getAddress(), dev->getSpeed()); 00288 token_setup(ep, setup, size); // setup stage 00289 if (LastStatus != ACK) { 00290 USB_DBG("setup %02x", LastStatus); 00291 return -1; 00292 } 00293 int write_len = 0; 00294 if (data != NULL) { 00295 write_len = token_out(ep, data, size); 00296 if (write_len < 0) { 00297 return -1; 00298 } 00299 } 00300 ep->setData01(DATA1); 00301 int result = token_in(ep); // status stage 00302 if (result < 0) { 00303 USB_DBG("result=%d %02x", result, LastStatus); 00304 //return result; 00305 } 00306 ep->setLengthTransferred(write_len); 00307 return write_len; 00308 } 00309 00310 int USBHost::interruptReadNB(USBEndpoint* ep, uint8_t* data, int size) 00311 { 00312 USB_TEST_ASSERT(ep); 00313 USBDeviceConnected* dev = ep->getDevice(); 00314 USB_TEST_ASSERT(dev); 00315 setAddr(dev->getAddress(), dev->getSpeed()); 00316 setEndpoint(); 00317 const int retryLimit = 0; 00318 int read_len = 0; 00319 for(int n = 0; read_len < size; n++) { 00320 int size2 = std::min(size-read_len, ep->getSize()); 00321 int result = token_in(ep, data+read_len, size2, retryLimit); 00322 if (result < 0) { 00323 if (LastStatus == NAK) { 00324 if (n == 0) { 00325 return -1; 00326 } 00327 break; 00328 } 00329 //USB_DBG("token_in result=%d %02x", result, LastStatus); 00330 return result; 00331 } 00332 read_len += result; 00333 if (result < ep->getSize()) { 00334 break; 00335 } 00336 } 00337 ep->setLengthTransferred(read_len); 00338 return read_len; 00339 } 00340 00341 int USBHost::interruptWriteNB(USBEndpoint* ep, const uint8_t* data, int size) 00342 { 00343 USB_TEST_ASSERT(ep); 00344 USBDeviceConnected* dev = ep->getDevice(); 00345 USB_TEST_ASSERT(dev); 00346 setAddr(dev->getAddress(), dev->getSpeed()); 00347 setEndpoint(); 00348 const int retryLimit = 0; 00349 int transferred_len = 0; 00350 for(int n = 0; transferred_len < size; n++) { 00351 int size2 = std::min(size-transferred_len, ep->getSize()); 00352 int result = token_out(ep, data+transferred_len, size2, retryLimit); 00353 if (result < 0) { 00354 if (LastStatus == NAK) { 00355 if (n == 0) { 00356 return -1; 00357 } 00358 break; 00359 } 00360 //USB_DBG("token_in result=%d %02x", result, LastStatus); 00361 return result; 00362 } 00363 transferred_len += result; 00364 if (result < ep->getSize()) { 00365 break; 00366 } 00367 } 00368 ep->setLengthTransferred(transferred_len); 00369 return transferred_len; 00370 } 00371 00372 int USBHost::bulkReadNB(USBEndpoint* ep, uint8_t* data, int size) 00373 { 00374 return bulkReadBLOCK(ep, data, size, 0); 00375 } 00376 00377 int USBHost::bulkReadBLOCK(USBEndpoint* ep, uint8_t* data, int size, int timeout_ms) { 00378 USB_TEST_ASSERT(ep); 00379 USBDeviceConnected* dev = ep->getDevice(); 00380 USB_TEST_ASSERT(dev); 00381 setAddr(dev->getAddress()); 00382 setEndpoint(); 00383 int retryLimit = (timeout_ms == 0) ? 0 : 10; 00384 int read_len = 0; 00385 Timer t; 00386 for(int n = 0; read_len < size; n++) { 00387 int size2 = std::min(size-read_len, ep->getSize()); 00388 int result = token_in(ep, data+read_len, size2, retryLimit); 00389 if (result < 0) { 00390 if (LastStatus == NAK) { 00391 if (n == 0) { 00392 return -1; 00393 } 00394 break; 00395 } 00396 //USB_DBG("token_in result=%d %02x", result, LastStatus); 00397 return result; 00398 } 00399 read_len += result; 00400 if (result < ep->getSize()) { 00401 break; 00402 } 00403 if (timeout_ms > 0 && t.read_ms() > timeout_ms) { 00404 USB_DBG("timeout_ms: %d", timeout_ms); 00405 break; 00406 } 00407 } 00408 ep->setLengthTransferred(read_len); 00409 return read_len; 00410 } 00411 00412 int USBHost::bulkWriteNB(USBEndpoint* ep, const uint8_t* data, int size) { 00413 USB_TEST_ASSERT(ep); 00414 USBDeviceConnected* dev = ep->getDevice(); 00415 USB_TEST_ASSERT(dev); 00416 setAddr(dev->getAddress()); 00417 setEndpoint(); 00418 int write_len = 0; 00419 for(int n = 0; write_len < size; n++) { 00420 int size2 = std::min(size-write_len, ep->getSize()); 00421 int result = token_out(ep, data+write_len, size2); 00422 if (result < 0) { 00423 if (LastStatus == NAK) { 00424 if (n == 0) { 00425 return -1; 00426 } 00427 break; 00428 } 00429 USB_DBG("token_out result=%d %02x", result, LastStatus); 00430 return result; 00431 } 00432 write_len += result; 00433 if (result < ep->getSize()) { 00434 break; 00435 } 00436 } 00437 ep->setLengthTransferred(write_len); 00438 return write_len; 00439 } 00440 00441 int USBHost::isochronousReadNB(USBEndpoint* ep, uint8_t* data, int size) { 00442 USBDeviceConnected* dev = ep->getDevice(); 00443 USB_TEST_ASSERT(dev); 00444 setAddr(dev->getAddress()); 00445 int result = token_iso_in(ep, data, size); 00446 if (result >= 0) { 00447 ep->setLengthTransferred(result); 00448 } 00449 return result; 00450 } 00451 00452 void USBHost::task() 00453 { 00454 if (ep_queue.empty()) { 00455 return; 00456 } 00457 USBEndpoint* ep = ep_queue.pop(); 00458 USB_TEST_ASSERT(ep); 00459 ep->setLengthTransferred(0); 00460 switch(ep->getType()) { 00461 case INTERRUPT_ENDPOINT: 00462 if (ep->getDir() == IN) { 00463 interruptReadNB(ep, ep->getBufStart(), ep->getBufSize()); 00464 } 00465 break; 00466 case BULK_ENDPOINT: 00467 if (ep->getDir() == IN) { 00468 bulkReadNB(ep, ep->getBufStart(), ep->getBufSize()); 00469 } 00470 break; 00471 case ISOCHRONOUS_ENDPOINT: 00472 if (ep->getDir() == IN) { 00473 isochronousReadNB(ep, ep->getBufStart(), ep->getBufSize()); 00474 } 00475 break; 00476 } 00477 ep->call(); 00478 }
Generated on Tue Jul 12 2022 19:09:12 by
![doxygen](doxygen.png)