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