Fork of Smoothie to port to mbed non-LPC targets.
Fork of Smoothie by
USBDevice.cpp
00001 /* Copyright (c) 2010-2011 mbed.org, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without 00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish, 00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 00007 * Software is furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 #include <stdint.h> 00020 00021 // for memcpy 00022 #include <cstring> 00023 // for iprintf 00024 #include <cstdio> 00025 00026 #include "USBEndpoints.h" 00027 #include "USBDevice.h" 00028 #include "USBDescriptor.h" 00029 00030 #define DEBUG 1 00031 #define printf iprintf 00032 00033 /* Device status */ 00034 #define DEVICE_STATUS_SELF_POWERED (1U<<0) 00035 #define DEVICE_STATUS_REMOTE_WAKEUP (1U<<1) 00036 00037 /* Endpoint status */ 00038 #define ENDPOINT_STATUS_HALT (1U<<0) 00039 00040 /* Standard feature selectors */ 00041 #define DEVICE_REMOTE_WAKEUP (1) 00042 #define ENDPOINT_HALT (0) 00043 00044 /* Macro to convert wIndex endpoint number to physical endpoint number */ 00045 #define WINDEX_TO_PHYSICAL(endpoint) (((endpoint & 0x0f) << 1) + \ 00046 ((endpoint & 0x80) ? 1 : 0)) 00047 00048 #define iprintf(...) 00049 00050 #define setled(a, b) do {} while (0) 00051 // extern void setled(int, bool); 00052 00053 bool USBDevice::setDescriptors(usbdesc_base ** newDescriptors) 00054 { 00055 if (configured() == false) 00056 { 00057 descriptors = newDescriptors; 00058 return true; 00059 } 00060 00061 if (descriptors == newDescriptors) 00062 return true; 00063 00064 return false; 00065 } 00066 00067 bool USBDevice::assembleConfigDescriptor() 00068 { 00069 static uint8_t confBuffer[MAX_PACKET_SIZE_EP0]; 00070 static uint8_t confIndex = 0; 00071 static uint8_t confSubIndex = 0; 00072 00073 uint8_t confBufferPtr = 0; 00074 transfer.ptr = confBuffer; 00075 00076 iprintf("ASSEMBLE CONFIG\n"); 00077 00078 // magic number to reset descriptor assembler 00079 if (transfer.remaining == -1) 00080 { 00081 iprintf("CONFIG:RESET\n"); 00082 // loop through descriptors, find matching configuration descriptor 00083 for (int i = 0; descriptors[i] != (usbdesc_base *) 0; i++) 00084 { 00085 if (descriptors[i]->bDescType == DT_CONFIGURATION) 00086 { 00087 usbdesc_configuration *conf = (usbdesc_configuration *) descriptors[i]; 00088 iprintf("CONFIG:FOUND %d(%d) @%d\n", conf->bConfigurationValue, DESCRIPTOR_INDEX(transfer.setup.wValue), i); 00089 00090 if ( 00091 (conf->bConfigurationValue == DESCRIPTOR_INDEX(transfer.setup.wValue)) 00092 || 00093 ( 00094 (conf->bConfigurationValue == 1) 00095 && 00096 (DESCRIPTOR_INDEX(transfer.setup.wValue) == 0) 00097 ) 00098 ) 00099 { 00100 // we're going to transmit wTotalLength to the host 00101 transfer.remaining = conf->wTotalLength; 00102 // limit length 00103 if (transfer.remaining > transfer.setup.wLength) 00104 transfer.remaining = transfer.setup.wLength; 00105 // start at index of this config descriptor 00106 confIndex = i; 00107 // reset counters 00108 confSubIndex = 0; 00109 iprintf("CONFIG:Sending %ld bytes\n", transfer.remaining); 00110 break; 00111 } 00112 } 00113 } 00114 } 00115 00116 if (transfer.remaining == -1) 00117 return false; 00118 00119 int remaining = transfer.remaining; 00120 00121 // assemble a packet 00122 while ((confBufferPtr < MAX_PACKET_SIZE_EP0) && (remaining > 0)) 00123 { 00124 iprintf("CONFIG:%d bytes to go, at %d:%d\n", remaining, confIndex, confSubIndex); 00125 // if we haven't finished the current descriptor, copy the rest into the buffer 00126 if (descriptors[confIndex]->bLength > confSubIndex) 00127 { 00128 uint8_t *descriptorBuf = (uint8_t *) descriptors[confIndex]; 00129 // destination - appropriate position in confBuffer 00130 uint8_t *dst = &confBuffer[confBufferPtr]; 00131 // source - appropriate position in current descriptor 00132 uint8_t *src = &descriptorBuf[confSubIndex]; 00133 // length - rest of descriptor 00134 uint8_t len = descriptors[confIndex]->bLength - confSubIndex; 00135 // max length - amount of space left in confBuffer 00136 uint8_t maxlen = MAX_PACKET_SIZE_EP0 - confBufferPtr; 00137 // max length - remaining size of configuration descriptor 00138 if (maxlen > remaining) 00139 maxlen = remaining; 00140 // limit length to max length 00141 if (len > maxlen) 00142 len = maxlen; 00143 // copy to buffer 00144 iprintf("CONFIG:cpy %d from %p to %p\n", len, src, dst); 00145 memcpy(dst, src, len); 00146 // advance position pointer 00147 confSubIndex += len; 00148 confBufferPtr += len; 00149 remaining -= len; 00150 } 00151 // this descriptor complete, move to next descriptor 00152 if (descriptors[confIndex]->bLength <= confSubIndex) 00153 { 00154 iprintf("CONFIG:next\n"); 00155 do { 00156 confIndex += 1; 00157 } while ((descriptors[confIndex] != NULL) && (descriptors[confIndex]->bDescType == DT_STRING)); 00158 confSubIndex = 0; 00159 if (descriptors[confIndex] == 0) 00160 return false; 00161 } 00162 } 00163 if (remaining < transfer.remaining) 00164 return true; 00165 return false; 00166 } 00167 00168 bool USBDevice::requestGetDescriptor(void) 00169 { 00170 uint8_t bType, bIndex; 00171 // int iCurIndex; 00172 00173 bType = DESCRIPTOR_TYPE(transfer.setup.wValue); 00174 bIndex = DESCRIPTOR_INDEX(transfer.setup.wValue); 00175 00176 iprintf("GET DESCRIPTOR %02Xh %02Xh\n", bType, bIndex); 00177 int i = findDescriptorIndex(bType, bIndex); 00178 if (i >= 0) { 00179 iprintf("FOUND at %d\n", i); 00180 if (bType == DT_CONFIGURATION) 00181 { 00182 transfer.remaining = -1; 00183 assembleConfigDescriptor(); 00184 iprintf("Assembling CONFIG descriptor: %ldb\n", transfer.remaining); 00185 } 00186 else 00187 { 00188 transfer.remaining = descriptors[i]->bLength; 00189 transfer.ptr = (uint8_t *) descriptors[i]; 00190 iprintf("Assembling descriptor %d(%d): %ldb\n", bType, bIndex, transfer.remaining); 00191 } 00192 transfer.direction = DEVICE_TO_HOST; 00193 return true; 00194 } 00195 00196 return false; 00197 } 00198 00199 void USBDevice::decodeSetupPacket(uint8_t *data, SETUP_PACKET *packet) 00200 { 00201 /* Fill in the elements of a SETUP_PACKET structure from raw data */ 00202 packet->bmRequestType.dataTransferDirection = (data[0] & 0x80) >> 7; 00203 packet->bmRequestType.Type = (data[0] & 0x60) >> 5; 00204 packet->bmRequestType.Recipient = data[0] & 0x1f; 00205 packet->bRequest = data[1]; 00206 packet->wValue = (data[2] | (uint16_t)data[3] << 8); 00207 packet->wIndex = (data[4] | (uint16_t)data[5] << 8); 00208 packet->wLength = (data[6] | (uint16_t)data[7] << 8); 00209 } 00210 00211 bool USBDevice::controlOut(void) 00212 { 00213 iprintf("{ControlOUT}"); 00214 /* Control transfer data OUT stage */ 00215 // uint8_t buffer[MAX_PACKET_SIZE_EP0]; 00216 int32_t packetSize; 00217 00218 /* Check we should be transferring data OUT */ 00219 if (transfer.direction != HOST_TO_DEVICE) 00220 { 00221 return false; 00222 } 00223 00224 /* Read from endpoint */ 00225 packetSize = EP0getReadResult(transfer.ptr); 00226 00227 /* Check if transfer size is valid */ 00228 if (packetSize > transfer.remaining) 00229 { 00230 /* Too big */ 00231 return false; 00232 } 00233 00234 /* Update transfer */ 00235 transfer.ptr += packetSize; 00236 transfer.remaining -= packetSize; 00237 00238 /* Check if transfer has completed */ 00239 if (transfer.remaining == 0) 00240 { 00241 /* Transfer completed */ 00242 if (transfer.notify) 00243 { 00244 /* Notify class layer. */ 00245 // USBCallback_requestCompleted(buffer, packetSize); 00246 USBEvent_RequestComplete(transfer, transfer.ptr, packetSize); 00247 transfer.notify = false; 00248 } 00249 /* Status stage */ 00250 EP0write(NULL, 0); 00251 } 00252 else 00253 { 00254 EP0read(); 00255 } 00256 00257 return true; 00258 } 00259 00260 bool USBDevice::controlIn(void) 00261 { 00262 iprintf("{ControlIN}"); 00263 /* Control transfer data IN stage */ 00264 uint32_t packetSize; 00265 00266 /* Check if transfer has completed (status stage transactions */ 00267 /* also have transfer.remaining == 0) */ 00268 if (transfer.remaining == 0) 00269 { 00270 if (transfer.zlp) 00271 { 00272 /* Send zero length packet */ 00273 EP0write(NULL, 0); 00274 transfer.zlp = false; 00275 } 00276 00277 /* Transfer completed */ 00278 if (transfer.notify) 00279 { 00280 /* Notify class layer. */ 00281 // USBCallback_requestCompleted(NULL, 0); 00282 USBEvent_RequestComplete(transfer, NULL, 0); 00283 transfer.notify = false; 00284 } 00285 00286 EP0read(); 00287 00288 iprintf("{z}"); 00289 /* Completed */ 00290 return true; 00291 } 00292 00293 /* Check we should be transferring data IN */ 00294 if (transfer.direction != DEVICE_TO_HOST) 00295 { 00296 iprintf("WRONG DIR"); 00297 return false; 00298 } 00299 00300 packetSize = transfer.remaining; 00301 00302 if (packetSize > MAX_PACKET_SIZE_EP0) 00303 { 00304 packetSize = MAX_PACKET_SIZE_EP0; 00305 } 00306 00307 iprintf("[W:%ld]", packetSize); 00308 00309 /* Write to endpoint */ 00310 EP0write(transfer.ptr, packetSize); 00311 00312 iprintf(","); 00313 00314 transfer.remaining -= packetSize; 00315 00316 /* Update transfer */ 00317 if ((transfer.setup.bRequest == GET_DESCRIPTOR) && 00318 (transfer.setup.bmRequestType.Type == STANDARD_TYPE) && 00319 (DESCRIPTOR_TYPE(transfer.setup.wValue) == DT_CONFIGURATION) ) 00320 { 00321 assembleConfigDescriptor(); 00322 } 00323 else 00324 { 00325 transfer.ptr += packetSize; 00326 } 00327 iprintf("[RM:%ld]\n", transfer.remaining); 00328 00329 return true; 00330 } 00331 00332 bool USBDevice::requestSetAddress(void) 00333 { 00334 /* Set the device address */ 00335 setAddress(transfer.setup.wValue); 00336 00337 if (transfer.setup.wValue == 0) 00338 { 00339 device.state = DEFAULT; 00340 } 00341 else 00342 { 00343 device.state = ADDRESS; 00344 } 00345 00346 iprintf("ADDRESS is 0x%02X!\n", transfer.setup.wValue); 00347 00348 return true; 00349 } 00350 00351 bool USBDevice::requestSetConfiguration(void) 00352 { 00353 device.configuration = transfer.setup.wValue; 00354 iprintf("SET CONFIGURATION: %d\n", transfer.setup.wValue); 00355 /* Set the device configuration */ 00356 if (device.configuration == 0) 00357 { 00358 iprintf("DECONFIGURED\n"); 00359 /* Not configured */ 00360 unconfigureDevice(); 00361 device.state = ADDRESS; 00362 } 00363 else 00364 { 00365 if (USBCallback_setConfiguration(device.configuration)) 00366 { 00367 iprintf("SET CONFIGURATION:SUCCESS!\n"); 00368 /* Valid configuration */ 00369 configureDevice(); 00370 device.state = CONFIGURED; 00371 } 00372 else 00373 { 00374 iprintf("SET CONFIGURATION:failure!\n"); 00375 return false; 00376 } 00377 } 00378 00379 return true; 00380 } 00381 00382 bool USBDevice::requestGetConfiguration(void) 00383 { 00384 /* Send the device configuration */ 00385 transfer.ptr = &device.configuration; 00386 transfer.remaining = sizeof(device.configuration); 00387 transfer.direction = DEVICE_TO_HOST; 00388 return true; 00389 } 00390 00391 bool USBDevice::requestGetInterface(void) 00392 { 00393 /* Return the selected alternate setting for an interface */ 00394 00395 if (device.state != CONFIGURED) 00396 { 00397 return false; 00398 } 00399 00400 /* Send the alternate setting */ 00401 transfer.setup.wIndex = currentInterface; 00402 transfer.ptr = ¤tAlternate; 00403 transfer.remaining = sizeof(currentAlternate); 00404 transfer.direction = DEVICE_TO_HOST; 00405 return true; 00406 } 00407 00408 bool USBDevice::requestSetInterface(void) 00409 { 00410 bool success = false; 00411 if(USBCallback_setInterface(transfer.setup.wIndex, transfer.setup.wValue)) 00412 { 00413 success = true; 00414 currentInterface = transfer.setup.wIndex; 00415 currentAlternate = transfer.setup.wValue; 00416 } 00417 return success; 00418 } 00419 00420 bool USBDevice::requestSetFeature() 00421 { 00422 bool success = false; 00423 00424 if (device.state != CONFIGURED) 00425 { 00426 /* Endpoint or interface must be zero */ 00427 if (transfer.setup.wIndex != 0) 00428 { 00429 return false; 00430 } 00431 } 00432 00433 switch (transfer.setup.bmRequestType.Recipient) 00434 { 00435 case DEVICE_RECIPIENT: 00436 /* TODO: Remote wakeup feature not supported */ 00437 break; 00438 case ENDPOINT_RECIPIENT: 00439 if (transfer.setup.wValue == ENDPOINT_HALT) 00440 { 00441 /* TODO: We should check that the endpoint number is valid */ 00442 stallEndpoint( 00443 WINDEX_TO_PHYSICAL(transfer.setup.wIndex)); 00444 success = true; 00445 } 00446 break; 00447 default: 00448 break; 00449 } 00450 00451 return success; 00452 } 00453 00454 bool USBDevice::requestClearFeature() 00455 { 00456 bool success = false; 00457 00458 if (device.state != CONFIGURED) 00459 { 00460 /* Endpoint or interface must be zero */ 00461 if (transfer.setup.wIndex != 0) 00462 { 00463 return false; 00464 } 00465 } 00466 00467 switch (transfer.setup.bmRequestType.Recipient) 00468 { 00469 case DEVICE_RECIPIENT: 00470 /* TODO: Remote wakeup feature not supported */ 00471 break; 00472 case ENDPOINT_RECIPIENT: 00473 /* TODO: We should check that the endpoint number is valid */ 00474 if (transfer.setup.wValue == ENDPOINT_HALT) 00475 { 00476 unstallEndpoint(transfer.setup.wIndex); 00477 success = true; 00478 } 00479 break; 00480 default: 00481 break; 00482 } 00483 00484 return success; 00485 } 00486 00487 bool USBDevice::requestGetStatus(void) 00488 { 00489 static uint16_t status; 00490 bool success = false; 00491 00492 if (device.state != CONFIGURED) 00493 { 00494 /* Endpoint or interface must be zero */ 00495 if (transfer.setup.wIndex != 0) 00496 { 00497 return false; 00498 } 00499 } 00500 00501 switch (transfer.setup.bmRequestType.Recipient) 00502 { 00503 case DEVICE_RECIPIENT: 00504 /* TODO: Currently only supports self powered devices */ 00505 status = DEVICE_STATUS_SELF_POWERED; 00506 success = true; 00507 break; 00508 case INTERFACE_RECIPIENT: 00509 status = 0; 00510 success = true; 00511 break; 00512 case ENDPOINT_RECIPIENT: 00513 /* TODO: We should check that the endpoint number is valid */ 00514 if (getEndpointStallState(transfer.setup.wIndex)) 00515 { 00516 status = ENDPOINT_STATUS_HALT; 00517 } 00518 else 00519 { 00520 status = 0; 00521 } 00522 success = true; 00523 break; 00524 default: 00525 break; 00526 } 00527 00528 if (success) 00529 { 00530 /* Send the status */ 00531 transfer.ptr = (uint8_t *)&status; /* Assumes little endian */ 00532 transfer.remaining = sizeof(status); 00533 transfer.direction = DEVICE_TO_HOST; 00534 } 00535 00536 return success; 00537 } 00538 00539 bool USBDevice::requestSetup(void) 00540 { 00541 // bool success = false; 00542 00543 /* Process standard requests */ 00544 if ((transfer.setup.bmRequestType.Type == STANDARD_TYPE)) 00545 { 00546 switch (transfer.setup.bRequest) 00547 { 00548 case GET_STATUS: 00549 return requestGetStatus(); 00550 case CLEAR_FEATURE: 00551 return requestClearFeature(); 00552 case SET_FEATURE: 00553 return requestSetFeature(); 00554 case SET_ADDRESS: 00555 return requestSetAddress(); 00556 case GET_DESCRIPTOR: 00557 return requestGetDescriptor(); 00558 case SET_DESCRIPTOR: 00559 /* TODO: Support is optional, not implemented here */ 00560 return false; 00561 case GET_CONFIGURATION: 00562 return requestGetConfiguration(); 00563 case SET_CONFIGURATION: 00564 return requestSetConfiguration(); 00565 case GET_INTERFACE: 00566 return requestGetInterface(); 00567 case SET_INTERFACE: 00568 return requestSetInterface(); 00569 00570 default: 00571 return false; 00572 } 00573 } 00574 00575 return false; 00576 } 00577 00578 bool USBDevice::controlSetup(void) 00579 { 00580 iprintf("{ControlSETUP}"); 00581 /* Control transfer setup stage */ 00582 00583 EP0setup(control_buffer); 00584 00585 /* Initialise control transfer state */ 00586 decodeSetupPacket(control_buffer, &transfer.setup); 00587 transfer.ptr = control_buffer; 00588 transfer.remaining = 0; 00589 transfer.direction = 0; 00590 transfer.zlp = false; 00591 transfer.notify = false; 00592 00593 #ifdef DEBUG 00594 printf("dataTransferDirection: %d\r\nType: %d\r\nRecipient: %d\r\nbRequest: %d\r\nwValue: %d\r\nwIndex: %d\r\nwLength: %d\r\n",transfer.setup.bmRequestType.dataTransferDirection, 00595 transfer.setup.bmRequestType.Type, 00596 transfer.setup.bmRequestType.Recipient, 00597 transfer.setup.bRequest, 00598 transfer.setup.wValue, 00599 transfer.setup.wIndex, 00600 transfer.setup.wLength); 00601 #endif 00602 00603 /* Class / vendor specific */ 00604 if (!USBEvent_Request(transfer)) 00605 { 00606 /* Standard requests */ 00607 if (!requestSetup()) 00608 { 00609 #ifdef DEBUG 00610 printf("fail!!!!\n"); 00611 #endif 00612 return false; 00613 } 00614 iprintf("OK\n"); 00615 } 00616 00617 /* Check transfer size and direction */ 00618 if (transfer.setup.wLength > 0) 00619 { 00620 if (transfer.setup.bmRequestType.dataTransferDirection == DEVICE_TO_HOST) 00621 { 00622 /* IN data stage is required */ 00623 if (transfer.direction != DEVICE_TO_HOST) 00624 { 00625 iprintf("<a\n"); 00626 return false; 00627 } 00628 00629 /* Transfer must be less than or equal to the size */ 00630 /* requested by the host */ 00631 if (transfer.remaining > transfer.setup.wLength) 00632 { 00633 transfer.remaining = transfer.setup.wLength; 00634 } 00635 } 00636 else 00637 { 00638 /* OUT data stage is required */ 00639 if (transfer.direction != HOST_TO_DEVICE) 00640 { 00641 iprintf("<b\n"); 00642 return false; 00643 } 00644 00645 /* Transfer must be equal to the size requested by the host */ 00646 if (transfer.remaining != transfer.setup.wLength) 00647 { 00648 iprintf("<c\n"); 00649 return false; 00650 } 00651 } 00652 } 00653 else 00654 { 00655 /* No data stage; transfer size must be zero */ 00656 if (transfer.remaining != 0) 00657 { 00658 iprintf("<d\n"); 00659 return false; 00660 } 00661 } 00662 00663 /* Data or status stage if applicable */ 00664 if (transfer.setup.wLength > 0) 00665 { 00666 if (transfer.setup.bmRequestType.dataTransferDirection == DEVICE_TO_HOST) 00667 { 00668 /* Check if we'll need to send a zero length packet at */ 00669 /* the end of this transfer */ 00670 if (transfer.setup.wLength > transfer.remaining) 00671 { 00672 /* Device wishes to transfer less than host requested */ 00673 if ((transfer.remaining % MAX_PACKET_SIZE_EP0) == 0) 00674 { 00675 /* Transfer is a multiple of EP0 max packet size */ 00676 transfer.zlp = true; 00677 } 00678 } 00679 00680 /* IN stage */ 00681 controlIn(); 00682 } 00683 else 00684 { 00685 iprintf(">f"); 00686 /* OUT stage */ 00687 EP0read(); 00688 } 00689 } 00690 else 00691 { 00692 iprintf(">g"); 00693 /* Status stage */ 00694 EP0write(NULL, 0); 00695 } 00696 00697 iprintf("<e\n"); 00698 return true; 00699 } 00700 00701 bool USBDevice::USBEvent_busReset(void) 00702 { 00703 device.state = DEFAULT; 00704 device.configuration = 0; 00705 device.suspended = false; 00706 00707 return true; 00708 } 00709 00710 bool USBDevice::USBEvent_Frame(uint16_t Frame) 00711 { 00712 lastFrameIndex = Frame; 00713 return true; 00714 } 00715 00716 void USBDevice::EP0setupCallback(void) 00717 { 00718 #ifdef DEBUG 00719 iprintf("EP0Setup\n"); 00720 #endif 00721 /* Endpoint 0 setup event */ 00722 if (!controlSetup()) 00723 { 00724 /* Protocol stall */ 00725 EP0stall(); 00726 } 00727 } 00728 00729 void USBDevice::EP0out(void) 00730 { 00731 #ifdef DEBUG 00732 iprintf("EP0OUT\n"); 00733 #endif 00734 /* Endpoint 0 OUT data event */ 00735 if (!controlOut()) 00736 { 00737 /* Protocol stall; this will stall both endpoints */ 00738 EP0stall(); 00739 } 00740 } 00741 00742 void USBDevice::EP0in(void) 00743 { 00744 #ifdef DEBUG 00745 printf("EP0IN\r\n"); 00746 #endif 00747 /* Endpoint 0 IN data event */ 00748 if (!controlIn()) 00749 { 00750 /* Protocol stall; this will stall both endpoints */ 00751 EP0stall(); 00752 } 00753 } 00754 00755 bool USBDevice::configured(void) 00756 { 00757 /* Returns true if device is in the CONFIGURED state */ 00758 return (device.state == CONFIGURED); 00759 } 00760 00761 void USBDevice::connect(void) 00762 { 00763 // iprintf("USBDevice::connect\n"); 00764 /* Connect device */ 00765 USBHAL::connect(); 00766 // iprintf("USBDevice::connect OK\n"); 00767 00768 /* Block if not configured */ 00769 // while (!configured()); 00770 } 00771 00772 void USBDevice::disconnect(void) 00773 { 00774 /* Disconnect device */ 00775 USBHAL::disconnect(); 00776 } 00777 00778 CONTROL_TRANSFER * USBDevice::getTransferPtr(void) 00779 { 00780 return &transfer; 00781 } 00782 00783 bool USBDevice::addEndpoint(uint8_t endpoint, uint32_t maxPacket) 00784 { 00785 return realiseEndpoint(endpoint, maxPacket, 0); 00786 } 00787 00788 bool USBDevice::addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket) 00789 { 00790 /* For interrupt endpoints only */ 00791 return realiseEndpoint(endpoint, maxPacket, RATE_FEEDBACK_MODE); 00792 } 00793 00794 int USBDevice::findDescriptorIndex(uint8_t start, uint8_t descriptorType, uint8_t descriptorIndex, uint8_t alternate) 00795 { 00796 // uint8_t currentConfiguration = 0; 00797 uint8_t index = 0; 00798 00799 if (descriptorType == DT_DEVICE) 00800 return 0; 00801 00802 if (descriptorType == DT_CONFIGURATION) 00803 return 1; 00804 00805 int i; 00806 for (i = start; descriptors[i] != NULL; i++) { 00807 if (descriptors[i]->bDescType == DT_CONFIGURATION) { 00808 // usbdesc_configuration *conf = (usbdesc_configuration *) descriptors[i]; 00809 // currentConfiguration = conf->bConfigurationValue; 00810 // iprintf("CONF{%d/%d}\n", currentConfiguration, device.configuration); 00811 index = 0; 00812 } 00813 // if ((currentConfiguration == device.configuration) || (descriptorType == DT_CONFIGURATION)) { 00814 if (descriptors[i]->bDescType == descriptorType) { 00815 switch(descriptorType) { 00816 case DT_CONFIGURATION: { 00817 index = ((usbdesc_configuration *) descriptors[i])->bConfigurationValue; 00818 }; 00819 case DT_INTERFACE: { 00820 index = ((usbdesc_interface *) descriptors[i])->bInterfaceNumber; 00821 }; 00822 case DT_ENDPOINT: { 00823 index = ((usbdesc_endpoint *) descriptors[i])->bEndpointAddress; 00824 }; 00825 } 00826 iprintf("FOUND %d:%d at %d, looking for %d\n", descriptorType, index, i, descriptorIndex); 00827 if (index == descriptorIndex) 00828 { 00829 if ( 00830 (descriptorType != DT_INTERFACE) 00831 || 00832 (((usbdesc_interface *) descriptors[i])->bAlternateSetting == alternate) 00833 ) 00834 { 00835 iprintf("Descriptor Found at %d!\n", i); 00836 return i; 00837 } 00838 } 00839 index++; 00840 } 00841 // } 00842 } 00843 iprintf("Descriptor not found\n"); 00844 return -1; 00845 } 00846 00847 int USBDevice::findDescriptorIndex(uint8_t descriptorType, uint8_t descriptorIndex) 00848 { 00849 return findDescriptorIndex(0, descriptorType, descriptorIndex, 0); 00850 } 00851 00852 uint8_t * USBDevice::findDescriptor(uint8_t descriptorType, uint8_t descriptorIndex) 00853 { 00854 int i = findDescriptorIndex(descriptorType, descriptorIndex); 00855 if (i >= 0) 00856 return (uint8_t *) descriptors[i]; 00857 return NULL; 00858 } 00859 00860 uint8_t * USBDevice::findDescriptor(uint8_t descriptorType) 00861 { 00862 if (descriptorType == DT_CONFIGURATION) 00863 return findDescriptor(descriptorType, 1); 00864 else 00865 return findDescriptor(descriptorType, 0); 00866 /* Reached end of the descriptors - not found */ 00867 return NULL; 00868 } 00869 00870 USBDevice::USBDevice() 00871 { 00872 device.state = POWERED; 00873 device.configuration = 0; 00874 device.suspended = false; 00875 }; 00876 00877 00878 bool USBDevice::readStart(uint8_t endpoint, uint32_t maxSize) 00879 { 00880 endpointSetInterrupt(endpoint, true); 00881 return endpointRead(endpoint, maxSize) == EP_PENDING; 00882 } 00883 00884 bool USBDevice::write(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize) 00885 { 00886 EP_STATUS result; 00887 00888 if (size > maxSize) 00889 { 00890 return false; 00891 } 00892 00893 00894 if(!configured()) { 00895 return false; 00896 } 00897 00898 /* Send report */ 00899 result = endpointWrite(endpoint, buffer, size); 00900 00901 if (result != EP_PENDING) 00902 { 00903 return false; 00904 } 00905 00906 /* Wait for completion */ 00907 setled(4, 1); 00908 do { 00909 result = endpointWriteResult(endpoint); 00910 } while ((result == EP_PENDING) && configured()); 00911 setled(4, 0); 00912 00913 return (result == EP_COMPLETED); 00914 } 00915 00916 bool USBDevice::writeNB(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize) 00917 { 00918 EP_STATUS result; 00919 00920 if (size > maxSize) 00921 { 00922 return false; 00923 } 00924 00925 if(!configured()) { 00926 return false; 00927 } 00928 00929 /* Send report */ 00930 result = endpointWrite(endpoint, buffer, size); 00931 00932 if (result != EP_PENDING) 00933 { 00934 return false; 00935 } 00936 00937 result = endpointWriteResult(endpoint); 00938 00939 return (result == EP_COMPLETED); 00940 } 00941 00942 bool USBDevice::readEP(uint8_t bEP, uint8_t * buffer, uint32_t * size, uint32_t maxSize) 00943 { 00944 EP_STATUS result; 00945 00946 if(!configured()) { 00947 return false; 00948 } 00949 00950 setled(4, 1); 00951 /* Wait for completion */ 00952 do { 00953 result = endpointReadResult(bEP, buffer, size); 00954 } while ((result == EP_PENDING) && configured()); 00955 setled(4, 0); 00956 00957 return (result == EP_COMPLETED); 00958 } 00959 00960 bool USBDevice::readEP_NB(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize) 00961 { 00962 EP_STATUS result; 00963 00964 if(!configured()) { 00965 return false; 00966 } 00967 00968 result = endpointReadResult(endpoint, buffer, size); 00969 00970 return (result == EP_COMPLETED); 00971 }
Generated on Tue Jul 12 2022 20:09:03 by 1.7.2