Fork of Smoothie to port to mbed non-LPC targets.

Dependencies:   mbed

Fork of Smoothie by Stéphane Cachat

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBDevice.cpp Source File

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 = &currentAlternate;
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 }