Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Smoothie by
USB.cpp
00001 #include "USB.h" 00002 00003 #include <cstdio> 00004 00005 #include "descriptor_cdc.h" 00006 #include "descriptor_msc.h" 00007 00008 #define iprintf(...) do { } while (0) 00009 00010 usbdesc_base *USB::descriptors[N_DESCRIPTORS]; 00011 00012 usbdesc_device USB::device = { 00013 DL_DEVICE, 00014 DT_DEVICE, 00015 USB_VERSION_2_0, // .bcdUSB 00016 UC_MISC, // .bDeviceClass 00017 SUBCLASS_IAD, // .bDeviceSubClass 00018 PROTOCOL_IAD, // .bDeviceProtocol 00019 64, // .bMaxPacketSize0 00020 0x1d50, // .idVendor 00021 0x6015, // .idProduct 00022 0x0100, // .bcdDevice 00023 0, // .iManufacturer 00024 0, // .iProduct 00025 0, // .iSerialNumber 00026 1, // .bNumConfigurations 00027 }; 00028 00029 static usbdesc_language lang = { 00030 DL_LANGUAGE, 00031 DT_LANGUAGE, 00032 { SL_USENGLISH, }, 00033 }; 00034 00035 static usbstring_const_init(manufacturer, "Uberclock"); 00036 00037 static usbstring_const_init(product, "Smoothieboard"); 00038 00039 static usbstring_init(serial, "01234567abcdefgh01234567abcdefgh"); 00040 00041 static usbstring_const_init(str_default, "Default"); 00042 00043 00044 usbdesc_configuration USB::conf = { 00045 DL_CONFIGURATION, 00046 DT_CONFIGURATION, 00047 sizeof(usbdesc_configuration), 00048 0, // .bNumInterfaces 00049 1, // .bConfigurationValue 00050 0, // .iConfiguration 00051 CA_BUSPOWERED, // .bmAttributes 00052 500 mA, // .bMaxPower 00053 }; 00054 00055 USB::USB() { 00056 int i; 00057 00058 i = 0; 00059 descriptors[i++] = (usbdesc_base *) &device; 00060 descriptors[i++] = (usbdesc_base *) &conf; 00061 for (;i < N_DESCRIPTORS; i++) 00062 descriptors[i] = (usbdesc_base *) 0; 00063 00064 addString(&lang); 00065 device.iManufacturer = addString(&manufacturer); 00066 device.iProduct = addString(&product); 00067 device.iSerialNumber = addString(&serial); 00068 conf.iConfiguration = addString(&str_default); 00069 } 00070 00071 USB::USB(uint16_t idVendor, uint16_t idProduct, uint16_t bcdFirmwareRevision) { 00072 USB(); 00073 device.idVendor = idVendor; 00074 device.idProduct = idProduct; 00075 device.bcdDevice = bcdFirmwareRevision; 00076 } 00077 00078 void USB::init() { 00079 iprintf("init\n"); 00080 00081 uint32_t chip_serial[4]; 00082 getSerialNumber(4, chip_serial); 00083 for (int j = 0; j < 4; j++) { 00084 for (int i = 0; i < 8; i++) { 00085 uint8_t c = (chip_serial[j] & 15); 00086 serial.str[j * 8 + 7 - i] = (c < 10)?(c + '0'):(c - 10 + 'A'); 00087 chip_serial[j] >>= 4; 00088 } 00089 } 00090 00091 setDescriptors(descriptors); 00092 00093 USBHAL::init(); 00094 00095 iprintf("OK\n"); 00096 } 00097 00098 bool USB::USBCallback_setConfiguration(uint8_t configuration) 00099 { 00100 iprintf("[CONFIGURE %d]", configuration); 00101 int i = findDescriptorIndex(0, DT_CONFIGURATION, configuration, 0); 00102 if (i > 0) 00103 { 00104 iprintf("[FOUND at %d]", i); 00105 uint8_t lastAlternate = 0; 00106 i++; 00107 for (; descriptors[i] != (usbdesc_base *) 0 && descriptors[i]->bDescType != DT_CONFIGURATION; i++) { 00108 switch(descriptors[i]->bDescType) 00109 { 00110 case DT_INTERFACE: { 00111 usbdesc_interface *interface = (usbdesc_interface *) descriptors[i]; 00112 iprintf("[INTERFACE %d:%d]",interface->bInterfaceNumber, interface->bAlternateSetting); 00113 interface->selectedAlternate = 0; 00114 lastAlternate = interface->bAlternateSetting; 00115 break; 00116 }; 00117 case DT_ENDPOINT: { 00118 usbdesc_endpoint *ep = (usbdesc_endpoint *) descriptors[i]; 00119 iprintf("[EP 0x%02X](%d)", ep->bEndpointAddress, lastAlternate); 00120 if (lastAlternate == 0) { 00121 iprintf("[Realised!]\n"); 00122 realiseEndpoint(ep->bEndpointAddress, ep->wMaxPacketSize, ((ep->bmAttributes & 3) == EA_ISOCHRONOUS)?ISOCHRONOUS:0); 00123 } 00124 break; 00125 }; 00126 } 00127 } 00128 return true; 00129 } 00130 return false; 00131 } 00132 00133 bool USB::USBCallback_setInterface(uint16_t interface, uint8_t alternate) { 00134 int i = findDescriptorIndex(0, DT_INTERFACE, interface, alternate); 00135 if (i > 0) 00136 { 00137 int j = findDescriptorIndex(0, DT_INTERFACE, interface, 0); 00138 if (j > 0) { 00139 ((usbdesc_interface *) descriptors[j])->selectedAlternate = alternate; 00140 for (; (descriptors[i]->bDescType != DT_INTERFACE) && (descriptors[i]->bDescType != DT_CONFIGURATION); i++) { 00141 if (descriptors[i]->bDescType == DT_ENDPOINT) { 00142 usbdesc_endpoint *ep = (usbdesc_endpoint *) descriptors[i]; 00143 realiseEndpoint(ep->bEndpointAddress, ep->wMaxPacketSize, ((ep->bmAttributes & 3) == EA_ISOCHRONOUS)?ISOCHRONOUS:0); 00144 } 00145 } 00146 } 00147 } 00148 return false; 00149 } 00150 00151 bool USB::USBEvent_busReset(void) 00152 { 00153 iprintf("USB:Bus Reset\n"); 00154 USBDevice::USBEvent_busReset(); 00155 00156 return false; 00157 } 00158 00159 bool USB::USBEvent_connectStateChanged(bool connected) 00160 { 00161 // TODO: something useful 00162 if (connected) 00163 { 00164 iprintf("USB:Connected\n"); 00165 connect(); 00166 } 00167 else 00168 { 00169 iprintf("USB:Disconnected\n"); 00170 disconnect(); 00171 } 00172 return true; 00173 }; 00174 00175 bool USB::USBEvent_suspendStateChanged(bool suspended) 00176 { 00177 // TODO: something useful 00178 if (suspended) 00179 { 00180 iprintf("USB:Suspended\n"); 00181 } 00182 else 00183 { 00184 iprintf("USB:Unsuspended\n"); 00185 } 00186 return true; 00187 }; 00188 00189 bool USB::USBEvent_Request(CONTROL_TRANSFER& transfer) 00190 { 00191 /* if (transfer.setup.bmRequestType.Type == CLASS_TYPE) 00192 iprintf("[CLASS]"); 00193 if (transfer.setup.bmRequestType.Type == VENDOR_TYPE) 00194 iprintf("[VENDOR]")*/; 00195 if ( 00196 (transfer.setup.bmRequestType.Type == CLASS_TYPE) 00197 || 00198 (transfer.setup.bmRequestType.Type == VENDOR_TYPE) 00199 ) 00200 { 00201 // decode request destination 00202 switch(transfer.setup.bmRequestType.Recipient) 00203 { 00204 case INTERFACE_RECIPIENT: { 00205 // iprintf("[INTERFACE %d]", transfer.setup.wIndex); 00206 int i = findDescriptorIndex(0, DT_INTERFACE, transfer.setup.wIndex, 0); 00207 if (i >.0) 00208 { 00209 usbdesc_interface *interface = (usbdesc_interface *) descriptors[i]; 00210 // iprintf("[FOUND at %d, handler is %p]", i, interface->classReceiver); 00211 bool r = interface->classReceiver->USBEvent_Request(transfer); 00212 // if (r) 00213 // iprintf("[HANDLED]\n"); 00214 // else 00215 // iprintf("[NOT handled]\n"); 00216 return r; 00217 } 00218 break; 00219 }; 00220 case ENDPOINT_RECIPIENT: { 00221 // iprintf("[ENDPOINT 0x%02X]", transfer.setup.wIndex); 00222 int i = findDescriptorIndex(0, DT_ENDPOINT, transfer.setup.wIndex, 0); 00223 if (i >.0) 00224 { 00225 usbdesc_endpoint *ep = (usbdesc_endpoint *) descriptors[i]; 00226 // iprintf("[FOUND at %d, handler is %p]", i, ep->epReceiver); 00227 bool r = ep->epReceiver->USBEvent_Request(transfer); 00228 // if (r) 00229 // iprintf("[HANDLED]\n"); 00230 // else 00231 // iprintf("[NOT handled]\n"); 00232 return r; 00233 } 00234 break; 00235 } 00236 } 00237 } 00238 // iprintf("\n"); 00239 return false; 00240 }; 00241 00242 bool USB::USBEvent_RequestComplete(CONTROL_TRANSFER& transfer, uint8_t *buf, uint32_t length) 00243 { 00244 if ((transfer.setup.bmRequestType.Type == CLASS_TYPE) || 00245 (transfer.setup.bmRequestType.Type == VENDOR_TYPE)) 00246 { 00247 // decode request destination 00248 switch(transfer.setup.bmRequestType.Recipient) 00249 { 00250 case INTERFACE_RECIPIENT: { 00251 int i = findDescriptorIndex(0, DT_INTERFACE, transfer.setup.wIndex, 0); 00252 if (i >.0) 00253 { 00254 usbdesc_interface *interface = (usbdesc_interface *) descriptors[i]; 00255 interface->classReceiver->USBEvent_RequestComplete(transfer, buf, length); 00256 } 00257 break; 00258 }; 00259 case ENDPOINT_RECIPIENT: { 00260 int i = findDescriptorIndex(0, DT_ENDPOINT, transfer.setup.wIndex, 0); 00261 if (i >.0) 00262 { 00263 usbdesc_endpoint *ep = (usbdesc_endpoint *) descriptors[i]; 00264 ep->epReceiver->USBEvent_RequestComplete(transfer, buf, length); 00265 } 00266 break; 00267 } 00268 } 00269 } 00270 return false; 00271 return false; 00272 }; 00273 00274 bool USB::USBEvent_EPIn(uint8_t bEP, uint8_t bEPStatus) 00275 { 00276 int i = findDescriptorIndex(0, DT_ENDPOINT, bEP, 0); 00277 if (i > 0) 00278 { 00279 usbdesc_endpoint *ep = (usbdesc_endpoint *) descriptors[i]; 00280 // iprintf("[EPIn 0x%02X ST 0x%02X Handler %p]", bEP, bEPStatus, ep->epReceiver); 00281 return ep->epReceiver->USBEvent_EPIn(bEP, bEPStatus); 00282 } 00283 return false; 00284 00285 }; 00286 00287 bool USB::USBEvent_EPOut(uint8_t bEP, uint8_t bEPStatus) 00288 { 00289 // iprintf("[EPOut 0x%02X ST 0x%02X]\n", bEP, bEPStatus); 00290 int i = findDescriptorIndex(0, DT_ENDPOINT, bEP, 0); 00291 if (i > 0) 00292 { 00293 // iprintf("[@%d ", i); 00294 usbdesc_endpoint *ep = (usbdesc_endpoint *) descriptors[i]; 00295 // iprintf("Handler %p]\n", ep->epReceiver); 00296 return ep->epReceiver->USBEvent_EPOut(bEP, bEPStatus); 00297 } 00298 return false; 00299 }; 00300 00301 00302 int USB::addDescriptor(usbdesc_base *descriptor) { 00303 for (int i = 0; i < N_DESCRIPTORS; i++) { 00304 if (descriptors[i] == (usbdesc_base *) 0) { 00305 descriptors[i] = descriptor; 00306 conf.wTotalLength += descriptor->bLength; 00307 return i; 00308 } 00309 } 00310 return -1; 00311 } 00312 00313 int USB::addDescriptor(void *descriptor) 00314 { 00315 return addDescriptor((usbdesc_base *) descriptor); 00316 } 00317 00318 int USB::addInterface(usbdesc_interface *ifp) { 00319 usbdesc_interface *lastif = (usbdesc_interface *) 0; 00320 uint8_t i; 00321 for (i = 0; i < N_DESCRIPTORS; i++) { 00322 if (descriptors[i] == (usbdesc_base *) 0) 00323 break; 00324 if (descriptors[i]->bDescType == DT_INTERFACE) 00325 lastif = (usbdesc_interface *) descriptors[i]; 00326 } 00327 if (i >= N_DESCRIPTORS) return -1; 00328 00329 uint8_t n = conf.bNumInterfaces; 00330 00331 if (lastif) 00332 if (ifp->bAlternateSetting != lastif->bAlternateSetting) 00333 n--; 00334 00335 ifp->bInterfaceNumber = n; 00336 // iprintf("[inserting Interface %p at %d]\n", ifp, i); 00337 descriptors[i] = (usbdesc_base *) ifp; 00338 conf.bNumInterfaces = n + 1; 00339 conf.wTotalLength += descriptors[i]->bLength; 00340 00341 return n; 00342 } 00343 00344 int USB::getFreeEndpoint() { 00345 uint8_t i; 00346 uint8_t lastii = 0; 00347 usbdesc_interface *lastif = (usbdesc_interface *) 0; 00348 00349 for (i = 0; i < N_DESCRIPTORS; i++) { 00350 if (descriptors[i] == (usbdesc_base *) 0) 00351 break; 00352 if (descriptors[i]->bDescType == DT_INTERFACE) { 00353 lastif = (usbdesc_interface *) descriptors[i]; 00354 lastii = i; 00355 } 00356 } 00357 if (i >= N_DESCRIPTORS) return -1; 00358 if (lastif == (usbdesc_interface *) 0) return -1; 00359 if (lastii == 0) return -1; 00360 00361 uint8_t ep_count = 0; 00362 for (i = lastii; i < N_DESCRIPTORS; i++) { 00363 if (descriptors[i] == (usbdesc_base *) 0) 00364 return ep_count; 00365 if (descriptors[i]->bDescType == DT_ENDPOINT) 00366 ep_count++; 00367 } 00368 return ep_count; 00369 } 00370 00371 int USB::addEndpoint(usbdesc_endpoint *epp) { 00372 // iprintf("[EP "); 00373 uint8_t i; 00374 usbdesc_interface *lastif = (usbdesc_interface *) 0; 00375 for (i = 0; i < N_DESCRIPTORS; i++) { 00376 if (descriptors[i] == (usbdesc_base *) 0) 00377 break; 00378 if (descriptors[i]->bDescType == DT_INTERFACE) 00379 lastif = (usbdesc_interface *) descriptors[i]; 00380 } 00381 // iprintf("%d:%p ", i, lastif); 00382 if (i >= N_DESCRIPTORS) return -1; 00383 if (lastif == (usbdesc_interface *) 0) return -1; 00384 00385 int n = getFreeEndpoint(); 00386 00387 // TODO: move this to the hardware-specific class 00388 // we need to scan through our descriptors, and find the first unused logical endpoint of the appropriate type 00389 // the LPC17xx has 16 logical endpoints mapped to 32 "physical" endpoints, looks like this means we have 16 endpoints to use and we get to pick direction 00390 // SO, let's first find all the endpoints in our list of the same type, pick the highest address then go find the next one 00391 00392 // pick a starting logical endpoint- interrupt = 1, bulk = 2, iso = 3 then subtract 3 so we pick the first one later on 00393 int lepaddr = (4 - epp->bmAttributes) - 3; 00394 00395 for (i = 0; i < N_DESCRIPTORS; i++) { 00396 if (descriptors[i] == (usbdesc_base *) 0) 00397 break; 00398 if (descriptors[i]->bDescType == DT_ENDPOINT) { 00399 usbdesc_endpoint *x = (usbdesc_endpoint *) descriptors[i]; 00400 if (x->bmAttributes == epp->bmAttributes && ((x->bEndpointAddress & 0x80) == (epp->bEndpointAddress & 0x80))) 00401 if ((x->bEndpointAddress & 0x0F) > lepaddr) 00402 lepaddr = (x->bEndpointAddress & 0x0F); 00403 } 00404 } 00405 00406 // now, lepaddr is the last logical endpoint of appropriate type 00407 // the endpoints go in groups of 3, except for the last one which is a bulk instead of isochronous 00408 // find the next free lep using this simple pattern 00409 if (epp->bmAttributes == EA_BULK && lepaddr == 14) 00410 lepaddr = 15; 00411 else 00412 lepaddr += 3; 00413 // now we have the next free logical endpoint of the appropriate type 00414 00415 // if it's >15 we've run out, spit an error 00416 if (lepaddr > 15) return -1; 00417 00418 // store logical address and direction bit 00419 epp->bEndpointAddress = lepaddr | (epp->bEndpointAddress & 0x80); 00420 00421 descriptors[i] = (usbdesc_base *) epp; 00422 // lastif->bNumEndPoints = n + 1; 00423 00424 conf.wTotalLength += descriptors[i]->bLength; 00425 00426 return n; 00427 } 00428 00429 int USB::addString(const void *ss) { 00430 const usbdesc_base *s = (const usbdesc_base *) ss; 00431 if (s->bDescType == DT_STRING) { 00432 uint8_t i; 00433 uint8_t stringcount = 0; 00434 for (i = 0; i < N_DESCRIPTORS; i++) { 00435 if (descriptors[i] == (usbdesc_base *) 0) 00436 break; 00437 if (descriptors[i]->bDescType == DT_STRING) 00438 stringcount++; 00439 } 00440 if (i >= N_DESCRIPTORS) return -1; 00441 00442 descriptors[i] = const_cast<usbdesc_base*>(s); 00443 00444 return stringcount; 00445 } 00446 return -1; 00447 } 00448 00449 int USB::findStringIndex(uint8_t strid) { 00450 uint8_t i; 00451 uint8_t strcounter = 0; 00452 for (i = 0; i < N_DESCRIPTORS; i++) { 00453 if (descriptors[i] == (usbdesc_base *) 0) 00454 return -1; 00455 if (descriptors[i]->bDescType == DT_STRING) { 00456 if (strcounter == strid) 00457 return i; 00458 strcounter++; 00459 } 00460 } 00461 return -1; 00462 } 00463 00464 void USB::dumpDevice(usbdesc_device *d) { 00465 iprintf("Device:\n"); 00466 iprintf("\tUSB Version: %d.%d\n", d->bcdUSB >> 8, (d->bcdUSB & 0xFF) >> 4); 00467 iprintf("\tClass: 0x%04X\n", d->bDeviceClass); 00468 iprintf("\tSubClass: 0x%04X\n", d->bDeviceSubClass); 00469 iprintf("\tProtocol: 0x%04X\n", d->bDeviceProtocol); 00470 iprintf("\tMax Packet: %d\n", d->bMaxPacketSize); 00471 iprintf("\tVendor: 0x%04X\n", d->idVendor); 00472 iprintf("\tProduct: 0x%04X\n", d->idProduct); 00473 iprintf("\tManufacturer: "); dumpString(d->iManufacturer); 00474 iprintf("\tProduct: "); dumpString(d->iProduct); 00475 iprintf("\tSerial: "); dumpString(d->iSerialNumber); 00476 iprintf("\tNum Configs: %d\n", d->bNumConfigurations); 00477 } 00478 00479 void USB::dumpConfiguration(usbdesc_configuration *c) { 00480 iprintf("Configuration:\n"); 00481 iprintf("\tTotal Length: %db\n", c->wTotalLength); 00482 iprintf("\tNum Interfaces: %d\n", c->bNumInterfaces); 00483 iprintf("\tConfiguration Value: %d\n", c->bConfigurationValue); 00484 iprintf("\tConfiguration: "); dumpString(c->iConfiguration); 00485 iprintf("\tAttributes: %s\n", ((c->bmAttributes & 0x80)?"Bus Powered":"Self Powered")); 00486 iprintf("\tMax Power: %dmA\n", c->bMaxPower * 2); 00487 } 00488 00489 void USB::dumpInterface(usbdesc_interface *i) { 00490 iprintf("\t*Interface\n"); 00491 iprintf("\t\tNumber: %d\n", i->bInterfaceNumber); 00492 iprintf("\t\tAlternate: %d\n", i->bAlternateSetting); 00493 iprintf("\t\tNum Endpoints: %d\n", i->bNumEndPoints); 00494 iprintf("\t\tClass: 0x%02X ", i->bInterfaceClass); 00495 switch(i->bInterfaceClass) { 00496 case UC_COMM: 00497 iprintf("(COMM)"); 00498 break; 00499 case UC_MASS_STORAGE: 00500 iprintf("(MSC)"); 00501 break; 00502 case UC_CDC_DATA: 00503 iprintf("(CDC DATA)"); 00504 break; 00505 } 00506 iprintf("\n"); 00507 iprintf("\t\tSubClass: 0x%02X ", i->bInterfaceSubClass); 00508 switch(i->bInterfaceClass) { 00509 case UC_COMM: { 00510 switch(i->bInterfaceSubClass) { 00511 case USB_CDC_SUBCLASS_ACM: 00512 iprintf("(ACM)"); 00513 break; 00514 case USB_CDC_SUBCLASS_ETHERNET: 00515 iprintf("(ETHERNET)"); 00516 break; 00517 } 00518 break; 00519 } 00520 case UC_MASS_STORAGE: { 00521 switch(i->bInterfaceSubClass) { 00522 case MSC_SUBCLASS_SCSI: 00523 iprintf("(SCSI)"); 00524 break; 00525 } 00526 break; 00527 } 00528 } 00529 iprintf("\n"); 00530 iprintf("\t\tProtocol: 0x%02X ", i->bInterfaceProtocol); 00531 iprintf("\n"); 00532 iprintf("\t\tInterface: "); dumpString(i->iInterface); 00533 } 00534 void USB::dumpEndpoint(usbdesc_endpoint *e) { 00535 static const char* const attr[4] __attribute__ ((used)) = { "", "Isochronous", "Bulk", "Interrupt" }; 00536 iprintf("\t\t*Endpoint\n"); 00537 iprintf("\t\t\tAddress: 0x%02X (%s)\n", e->bEndpointAddress, ((e->bEndpointAddress & EP_DIR_IN)?"IN":"OUT")); 00538 iprintf("\t\t\tAttributes: 0x%02X (%s)\n", e->bmAttributes, attr[e->bmAttributes]); 00539 iprintf("\t\t\tMax Packet: %d\n", e->wMaxPacketSize); 00540 iprintf("\t\t\tInterval: %d\n", e->bInterval); 00541 } 00542 00543 void USB::dumpString(int i) { 00544 if (i > 0) { 00545 uint8_t j = findStringIndex(i); 00546 if (j > 0) { 00547 iprintf("[%d] ", i); 00548 dumpString((usbdesc_string *) descriptors[j]); 00549 return; 00550 } 00551 } 00552 iprintf("-none-\n"); 00553 } 00554 00555 void USB::dumpString(usbdesc_string *s) { 00556 uint8_t i; 00557 for (i = 0; i < (s->bLength - 2) / 2; i++) { 00558 if (s->str[i] >= 32 && s->str[i] < 128) 00559 putchar(s->str[i]); 00560 else 00561 iprintf("\\0x%02X", s->str[i]); 00562 } 00563 putchar('\n'); 00564 } 00565 00566 void USB::dumpCDC(uint8_t *d) { 00567 switch(d[2]) { 00568 case USB_CDC_SUBTYPE_HEADER: { 00569 usbcdc_header *h = (usbcdc_header *) d; 00570 if (h) 00571 { 00572 iprintf("\t\t*CDC header\n"); 00573 iprintf("\t\t\tbcdCDC: 0x%04X\n", h->bcdCDC); 00574 } 00575 break; 00576 } 00577 case USB_CDC_SUBTYPE_UNION: { 00578 usbcdc_union *u = (usbcdc_union *) d; 00579 if (u) 00580 { 00581 iprintf("\t\t*CDC union\n"); 00582 iprintf("\t\t\tMaster: %d\n", u->bMasterInterface); 00583 iprintf("\t\t\tSlave: %d\n", u->bSlaveInterface0); 00584 } 00585 break; 00586 } 00587 case USB_CDC_SUBTYPE_CALL_MANAGEMENT: { 00588 usbcdc_callmgmt *m = (usbcdc_callmgmt *) d; 00589 iprintf("\t\t*CDC Call Management\n"); 00590 iprintf("\t\t\tCapabilities: 0x%02X ", m->bmCapabilities); 00591 if (m->bmCapabilities & USB_CDC_CALLMGMT_CAP_CALLMGMT) 00592 iprintf("(CALLMGMT)"); 00593 if (m->bmCapabilities & USB_CDC_CALLMGMT_CAP_DATAINTF) 00594 iprintf("(DATAINTF)"); 00595 iprintf("\n"); 00596 iprintf("\t\t\tData Interface: %d\n", m->bDataInterface); 00597 break; 00598 } 00599 case USB_CDC_SUBTYPE_ACM: { 00600 usbcdc_acm *a = (usbcdc_acm *) d; 00601 iprintf("\t\t*CDC ACM\n"); 00602 iprintf("\t\t\tCapabilities: 0x%02X ", a->bmCapabilities); 00603 if (a->bmCapabilities & USB_CDC_ACM_CAP_COMM) 00604 iprintf("(COMM)"); 00605 if (a->bmCapabilities & USB_CDC_ACM_CAP_LINE) 00606 iprintf("(LINE)"); 00607 if (a->bmCapabilities & USB_CDC_ACM_CAP_BRK) 00608 iprintf("(BRK)"); 00609 if (a->bmCapabilities & USB_CDC_ACM_CAP_NOTIFY) 00610 iprintf("(NOTIFY)"); 00611 iprintf("\n"); 00612 break; 00613 } 00614 case USB_CDC_SUBTYPE_ETHERNET: { 00615 usbcdc_ether *e = (usbcdc_ether *) d; 00616 iprintf("\t\t*CDC Ethernet\n"); 00617 iprintf("\t\t\tMAC address: "); dumpString(e->iMacAddress); 00618 iprintf("\t\t\tStatistics: 0x%02lX\n", e->bmEthernetStatistics); 00619 iprintf("\t\t\tMax Segment Size: %d\n", e->wMaxSegmentSize); 00620 iprintf("\t\t\tMC Filters: %d\n", e->wNumberMCFilters); 00621 iprintf("\t\t\tPower Filters: %d\n", e->bNumberPowerFilters); 00622 break; 00623 } 00624 } 00625 } 00626 00627 void USB::dumpDescriptors() { 00628 uint8_t i; 00629 for (i = 0; i < N_DESCRIPTORS; i++) { 00630 if (descriptors[i] == (usbdesc_base *) 0) { 00631 iprintf("--- FIN at %d\n", i); 00632 return; 00633 } 00634 iprintf("[%d:+%d]", i, descriptors[i]->bLength); 00635 switch (descriptors[i]->bDescType) { 00636 case DT_DEVICE: { 00637 dumpDevice((usbdesc_device *) descriptors[i]); 00638 break; 00639 } 00640 case DT_CONFIGURATION: { 00641 dumpConfiguration((usbdesc_configuration *) descriptors[i]); 00642 break; 00643 } 00644 case DT_INTERFACE: { 00645 dumpInterface((usbdesc_interface *) descriptors[i]); 00646 break; 00647 } 00648 case DT_ENDPOINT: { 00649 dumpEndpoint((usbdesc_endpoint *) descriptors[i]); 00650 break; 00651 } 00652 case DT_STRING: { 00653 dumpString((usbdesc_string *) descriptors[i]); 00654 break; 00655 } 00656 case DT_CDC_DESCRIPTOR: { 00657 dumpCDC((uint8_t *) descriptors[i]); 00658 break; 00659 } 00660 } 00661 } 00662 } 00663 00664 void USB::on_module_loaded() 00665 { 00666 register_for_event(ON_IDLE); 00667 connect(); 00668 } 00669 00670 void USB::on_idle(void*) 00671 { 00672 USBHAL::usbisr(); 00673 }
Generated on Tue Jul 12 2022 20:09:03 by
1.7.2
