123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005 |
- /* Copyright (c) 2010-2011 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
- #include "stdint.h"
-
- #include "USBEndpoints.h"
- #include "USBDevice.h"
- #include "USBDescriptor.h"
-
- //#define DEBUG
-
- /* Device status */
- #define DEVICE_STATUS_SELF_POWERED (1U<<0)
- #define DEVICE_STATUS_REMOTE_WAKEUP (1U<<1)
-
- /* Endpoint status */
- #define ENDPOINT_STATUS_HALT (1U<<0)
-
- /* Standard feature selectors */
- #define DEVICE_REMOTE_WAKEUP (1)
- #define ENDPOINT_HALT (0)
-
- /* Macro to convert wIndex endpoint number to physical endpoint number */
- #define WINDEX_TO_PHYSICAL(endpoint) (((endpoint & 0x0f) << 1) + \
- ((endpoint & 0x80) ? 1 : 0))
-
-
- bool USBDevice::requestGetDescriptor(void)
- {
- bool success = false;
- #ifdef DEBUG
- printf("get descr: type: %d\r\n", DESCRIPTOR_TYPE(transfer.setup.wValue));
- #endif
- switch (DESCRIPTOR_TYPE(transfer.setup.wValue))
- {
- case DEVICE_DESCRIPTOR:
- if (deviceDesc() != NULL)
- {
- if ((deviceDesc()[0] == DEVICE_DESCRIPTOR_LENGTH) \
- && (deviceDesc()[1] == DEVICE_DESCRIPTOR))
- {
- #ifdef DEBUG
- printf("device descr\r\n");
- #endif
- transfer.remaining = DEVICE_DESCRIPTOR_LENGTH;
- transfer.ptr = deviceDesc();
- transfer.direction = DEVICE_TO_HOST;
- success = true;
- }
- }
- break;
- case CONFIGURATION_DESCRIPTOR:
- if (configurationDesc() != NULL)
- {
- if ((configurationDesc()[0] == CONFIGURATION_DESCRIPTOR_LENGTH) \
- && (configurationDesc()[1] == CONFIGURATION_DESCRIPTOR))
- {
- #ifdef DEBUG
- printf("conf descr request\r\n");
- #endif
- /* Get wTotalLength */
- transfer.remaining = configurationDesc()[2] \
- | (configurationDesc()[3] << 8);
-
- transfer.ptr = configurationDesc();
- transfer.direction = DEVICE_TO_HOST;
- success = true;
- }
- }
- break;
- case STRING_DESCRIPTOR:
- #ifdef DEBUG
- printf("str descriptor\r\n");
- #endif
- switch (DESCRIPTOR_INDEX(transfer.setup.wValue))
- {
- case STRING_OFFSET_LANGID:
- #ifdef DEBUG
- printf("1\r\n");
- #endif
- transfer.remaining = stringLangidDesc()[0];
- transfer.ptr = stringLangidDesc();
- transfer.direction = DEVICE_TO_HOST;
- success = true;
- break;
- case STRING_OFFSET_IMANUFACTURER:
- #ifdef DEBUG
- printf("2\r\n");
- #endif
- transfer.remaining = stringImanufacturerDesc()[0];
- transfer.ptr = stringImanufacturerDesc();
- transfer.direction = DEVICE_TO_HOST;
- success = true;
- break;
- case STRING_OFFSET_IPRODUCT:
- #ifdef DEBUG
- printf("3\r\n");
- #endif
- transfer.remaining = stringIproductDesc()[0];
- transfer.ptr = stringIproductDesc();
- transfer.direction = DEVICE_TO_HOST;
- success = true;
- break;
- case STRING_OFFSET_ISERIAL:
- #ifdef DEBUG
- printf("4\r\n");
- #endif
- transfer.remaining = stringIserialDesc()[0];
- transfer.ptr = stringIserialDesc();
- transfer.direction = DEVICE_TO_HOST;
- success = true;
- break;
- case STRING_OFFSET_ICONFIGURATION:
- #ifdef DEBUG
- printf("5\r\n");
- #endif
- transfer.remaining = stringIConfigurationDesc()[0];
- transfer.ptr = stringIConfigurationDesc();
- transfer.direction = DEVICE_TO_HOST;
- success = true;
- break;
- case STRING_OFFSET_IINTERFACE:
- #ifdef DEBUG
- printf("6\r\n");
- #endif
- transfer.remaining = stringIinterfaceDesc()[0];
- transfer.ptr = stringIinterfaceDesc();
- transfer.direction = DEVICE_TO_HOST;
- success = true;
- break;
- }
- break;
- case INTERFACE_DESCRIPTOR:
- #ifdef DEBUG
- printf("interface descr\r\n");
- #endif
- case ENDPOINT_DESCRIPTOR:
- #ifdef DEBUG
- printf("endpoint descr\r\n");
- #endif
- /* TODO: Support is optional, not implemented here */
- break;
- default:
- #ifdef DEBUG
- printf("ERROR\r\n");
- #endif
- break;
- }
-
- return success;
- }
-
- void USBDevice::decodeSetupPacket(uint8_t *data, SETUP_PACKET *packet)
- {
- /* Fill in the elements of a SETUP_PACKET structure from raw data */
- packet->bmRequestType.dataTransferDirection = (data[0] & 0x80) >> 7;
- packet->bmRequestType.Type = (data[0] & 0x60) >> 5;
- packet->bmRequestType.Recipient = data[0] & 0x1f;
- packet->bRequest = data[1];
- packet->wValue = (data[2] | (uint16_t)data[3] << 8);
- packet->wIndex = (data[4] | (uint16_t)data[5] << 8);
- packet->wLength = (data[6] | (uint16_t)data[7] << 8);
- }
-
-
- bool USBDevice::controlOut(void)
- {
- /* Control transfer data OUT stage */
- uint8_t buffer[MAX_PACKET_SIZE_EP0];
- uint32_t packetSize;
-
- /* Check we should be transferring data OUT */
- if (transfer.direction != HOST_TO_DEVICE)
- {
- #if defined(TARGET_KL25Z) | defined(TARGET_KL43Z) | defined(TARGET_KL46Z) | defined(TARGET_K20D5M) | defined(TARGET_K64F) | defined(TARGET_K22F) | defined(TARGET_TEENSY3_1)
- /*
- * We seem to have a pending device-to-host transfer. The host must have
- * sent a new control request without waiting for us to finish processing
- * the previous one. This appears to happen when we're connected to certain
- * USB 3.0 host chip set. Do a zeor-length send to tell the host we're not
- * ready for the new request - that'll make it resend - and then just
- * pretend we were successful here so that the pending transfer can finish.
- */
- uint8_t buf[1] = { 0 };
- EP0write(buf, 0);
-
- /* execute our pending ttransfer */
- controlIn();
-
- /* indicate success */
- return true;
- #else
- /* for other platforms, count on the HAL to handle this case */
- return false;
- #endif
- }
-
- /* Read from endpoint */
- packetSize = EP0getReadResult(buffer);
-
- /* Check if transfer size is valid */
- if (packetSize > transfer.remaining)
- {
- /* Too big */
- return false;
- }
-
- /* Update transfer */
- transfer.ptr += packetSize;
- transfer.remaining -= packetSize;
-
- /* Check if transfer has completed */
- if (transfer.remaining == 0)
- {
- /* Transfer completed */
- if (transfer.notify)
- {
- /* Notify class layer. */
- USBCallback_requestCompleted(buffer, packetSize);
- transfer.notify = false;
- }
- /* Status stage */
- EP0write(NULL, 0);
- }
- else
- {
- EP0read();
- }
-
- return true;
- }
-
- bool USBDevice::controlIn(void)
- {
- /* Control transfer data IN stage */
- uint32_t packetSize;
-
- /* Check if transfer has completed (status stage transactions */
- /* also have transfer.remaining == 0) */
- if (transfer.remaining == 0)
- {
- if (transfer.zlp)
- {
- /* Send zero length packet */
- EP0write(NULL, 0);
- transfer.zlp = false;
- }
-
- /* Transfer completed */
- if (transfer.notify)
- {
- /* Notify class layer. */
- USBCallback_requestCompleted(NULL, 0);
- transfer.notify = false;
- }
-
- EP0read();
- EP0readStage();
-
- /* Completed */
- return true;
- }
-
- /* Check we should be transferring data IN */
- if (transfer.direction != DEVICE_TO_HOST)
- {
- return false;
- }
-
- packetSize = transfer.remaining;
-
- if (packetSize > MAX_PACKET_SIZE_EP0)
- {
- packetSize = MAX_PACKET_SIZE_EP0;
- }
-
- /* Write to endpoint */
- EP0write(transfer.ptr, packetSize);
-
- /* Update transfer */
- transfer.ptr += packetSize;
- transfer.remaining -= packetSize;
-
- return true;
- }
-
- bool USBDevice::requestSetAddress(void)
- {
- /* Set the device address */
- setAddress(transfer.setup.wValue);
-
- if (transfer.setup.wValue == 0)
- {
- device.state = DEFAULT;
- }
- else
- {
- device.state = ADDRESS;
- }
-
- return true;
- }
-
- bool USBDevice::requestSetConfiguration(void)
- {
-
- device.configuration = transfer.setup.wValue;
- /* Set the device configuration */
- if (device.configuration == 0)
- {
- /* Not configured */
- unconfigureDevice();
- device.state = ADDRESS;
- }
- else
- {
- if (USBCallback_setConfiguration(device.configuration))
- {
- /* Valid configuration */
- configureDevice();
- device.state = CONFIGURED;
- }
- else
- {
- return false;
- }
- }
-
- return true;
- }
-
- bool USBDevice::requestGetConfiguration(void)
- {
- /* Send the device configuration */
- transfer.ptr = &device.configuration;
- transfer.remaining = sizeof(device.configuration);
- transfer.direction = DEVICE_TO_HOST;
- return true;
- }
-
- bool USBDevice::requestGetInterface(void)
- {
- /* Return the selected alternate setting for an interface */
-
- if (device.state != CONFIGURED)
- {
- return false;
- }
-
- /* Send the alternate setting */
- transfer.setup.wIndex = currentInterface;
- transfer.ptr = ¤tAlternate;
- transfer.remaining = sizeof(currentAlternate);
- transfer.direction = DEVICE_TO_HOST;
- return true;
- }
-
- bool USBDevice::requestSetInterface(void)
- {
- bool success = false;
- if(USBCallback_setInterface(transfer.setup.wIndex, transfer.setup.wValue))
- {
- success = true;
- currentInterface = transfer.setup.wIndex;
- currentAlternate = transfer.setup.wValue;
- }
- return success;
- }
-
- bool USBDevice::requestSetFeature()
- {
- bool success = false;
-
- if (device.state != CONFIGURED)
- {
- /* Endpoint or interface must be zero */
- if (transfer.setup.wIndex != 0)
- {
- return false;
- }
- }
-
- switch (transfer.setup.bmRequestType.Recipient)
- {
- case DEVICE_RECIPIENT:
- /* TODO: Remote wakeup feature not supported */
- break;
- case ENDPOINT_RECIPIENT:
- if (transfer.setup.wValue == ENDPOINT_HALT)
- {
- /* TODO: We should check that the endpoint number is valid */
- stallEndpoint(
- WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
- success = true;
- }
- break;
- default:
- break;
- }
-
- return success;
- }
-
- bool USBDevice::requestClearFeature()
- {
- bool success = false;
-
- if (device.state != CONFIGURED)
- {
- /* Endpoint or interface must be zero */
- if (transfer.setup.wIndex != 0)
- {
- return false;
- }
- }
-
- switch (transfer.setup.bmRequestType.Recipient)
- {
- case DEVICE_RECIPIENT:
- /* TODO: Remote wakeup feature not supported */
- break;
- case ENDPOINT_RECIPIENT:
- /* TODO: We should check that the endpoint number is valid */
- if (transfer.setup.wValue == ENDPOINT_HALT)
- {
- unstallEndpoint( WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
- success = true;
- }
- break;
- default:
- break;
- }
-
- return success;
- }
-
- bool USBDevice::requestGetStatus(void)
- {
- static uint16_t status;
- bool success = false;
-
- if (device.state != CONFIGURED)
- {
- /* Endpoint or interface must be zero */
- if (transfer.setup.wIndex != 0)
- {
- return false;
- }
- }
-
- switch (transfer.setup.bmRequestType.Recipient)
- {
- case DEVICE_RECIPIENT:
- /* TODO: Currently only supports self powered devices */
- status = DEVICE_STATUS_SELF_POWERED;
- success = true;
- break;
- case INTERFACE_RECIPIENT:
- status = 0;
- success = true;
- break;
- case ENDPOINT_RECIPIENT:
- /* TODO: We should check that the endpoint number is valid */
- if (getEndpointStallState(
- WINDEX_TO_PHYSICAL(transfer.setup.wIndex)))
- {
- status = ENDPOINT_STATUS_HALT;
- }
- else
- {
- status = 0;
- }
- success = true;
- break;
- default:
- break;
- }
-
- if (success)
- {
- /* Send the status */
- transfer.ptr = (uint8_t *)&status; /* Assumes little endian */
- transfer.remaining = sizeof(status);
- transfer.direction = DEVICE_TO_HOST;
- }
-
- return success;
- }
-
- bool USBDevice::requestSetup(void)
- {
- bool success = false;
-
- /* Process standard requests */
- if ((transfer.setup.bmRequestType.Type == STANDARD_TYPE))
- {
- switch (transfer.setup.bRequest)
- {
- case GET_STATUS:
- success = requestGetStatus();
- break;
- case CLEAR_FEATURE:
- success = requestClearFeature();
- break;
- case SET_FEATURE:
- success = requestSetFeature();
- break;
- case SET_ADDRESS:
- success = requestSetAddress();
- break;
- case GET_DESCRIPTOR:
- success = requestGetDescriptor();
- break;
- case SET_DESCRIPTOR:
- /* TODO: Support is optional, not implemented here */
- success = false;
- break;
- case GET_CONFIGURATION:
- success = requestGetConfiguration();
- break;
- case SET_CONFIGURATION:
- success = requestSetConfiguration();
- break;
- case GET_INTERFACE:
- success = requestGetInterface();
- break;
- case SET_INTERFACE:
- success = requestSetInterface();
- break;
- default:
- break;
- }
- }
-
- return success;
- }
-
- bool USBDevice::controlSetup(void)
- {
- bool success = false;
-
- /* Control transfer setup stage */
- uint8_t buffer[MAX_PACKET_SIZE_EP0];
-
- EP0setup(buffer);
-
- /* Initialise control transfer state */
- decodeSetupPacket(buffer, &transfer.setup);
- transfer.ptr = NULL;
- transfer.remaining = 0;
- transfer.direction = 0;
- transfer.zlp = false;
- transfer.notify = false;
-
- #ifdef DEBUG
- 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,
- transfer.setup.bmRequestType.Type,
- transfer.setup.bmRequestType.Recipient,
- transfer.setup.bRequest,
- transfer.setup.wValue,
- transfer.setup.wIndex,
- transfer.setup.wLength);
- #endif
-
- /* Class / vendor specific */
- success = USBCallback_request();
-
- if (!success)
- {
- /* Standard requests */
- if (!requestSetup())
- {
- #ifdef DEBUG
- printf("fail!!!!\r\n");
- #endif
- return false;
- }
- }
-
- /* Check transfer size and direction */
- if (transfer.setup.wLength>0)
- {
- if (transfer.setup.bmRequestType.dataTransferDirection \
- == DEVICE_TO_HOST)
- {
- /* IN data stage is required */
- if (transfer.direction != DEVICE_TO_HOST)
- {
- return false;
- }
-
- /* Transfer must be less than or equal to the size */
- /* requested by the host */
- if (transfer.remaining > transfer.setup.wLength)
- {
- transfer.remaining = transfer.setup.wLength;
- }
- }
- else
- {
-
- /* OUT data stage is required */
- if (transfer.direction != HOST_TO_DEVICE)
- {
- return false;
- }
-
- /* Transfer must be equal to the size requested by the host */
- if (transfer.remaining != transfer.setup.wLength)
- {
- return false;
- }
- }
- }
- else
- {
- /* No data stage; transfer size must be zero */
- if (transfer.remaining != 0)
- {
- return false;
- }
- }
-
- /* Data or status stage if applicable */
- if (transfer.setup.wLength>0)
- {
- if (transfer.setup.bmRequestType.dataTransferDirection \
- == DEVICE_TO_HOST)
- {
- /* Check if we'll need to send a zero length packet at */
- /* the end of this transfer */
- if (transfer.setup.wLength > transfer.remaining)
- {
- /* Device wishes to transfer less than host requested */
- if ((transfer.remaining % MAX_PACKET_SIZE_EP0) == 0)
- {
- /* Transfer is a multiple of EP0 max packet size */
- transfer.zlp = true;
- }
- }
-
- /* IN stage */
- controlIn();
- }
- else
- {
- /* OUT stage */
- EP0read();
- }
- }
- else
- {
- /* Status stage */
- EP0write(NULL, 0);
- }
-
- return true;
- }
-
- void USBDevice::busReset(void)
- {
- device.state = DEFAULT;
- device.configuration = 0;
- device.suspended = false;
-
- /* Call class / vendor specific busReset function */
- USBCallback_busReset();
- }
-
- void USBDevice::EP0setupCallback(void)
- {
- /* Endpoint 0 setup event */
- if (!controlSetup())
- {
- /* Protocol stall */
- EP0stall();
- }
-
- /* Return true if an OUT data stage is expected */
- }
-
- void USBDevice::EP0out(void)
- {
- /* Endpoint 0 OUT data event */
- if (!controlOut())
- {
- /* Protocol stall; this will stall both endpoints */
- EP0stall();
- }
- }
-
- void USBDevice::EP0in(void)
- {
- #ifdef DEBUG
- printf("EP0IN\r\n");
- #endif
- /* Endpoint 0 IN data event */
- if (!controlIn())
- {
- /* Protocol stall; this will stall both endpoints */
- EP0stall();
- }
- }
-
- bool USBDevice::configured(void)
- {
- /* Returns true if device is in the CONFIGURED state */
- return (device.state == CONFIGURED);
- }
-
- void USBDevice::connect(bool blocking)
- {
- /* Connect device */
- USBHAL::connect();
-
- if (blocking) {
- /* Block if not configured */
- while (!configured());
- }
- }
-
- void USBDevice::disconnect(void)
- {
- /* Disconnect device */
- USBHAL::disconnect();
-
- /* Set initial device state */
- device.state = POWERED;
- device.configuration = 0;
- device.suspended = false;
- }
-
- CONTROL_TRANSFER * USBDevice::getTransferPtr(void)
- {
- return &transfer;
- }
-
- bool USBDevice::addEndpoint(uint8_t endpoint, uint32_t maxPacket)
- {
- return realiseEndpoint(endpoint, maxPacket, 0);
- }
-
- bool USBDevice::addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket)
- {
- /* For interrupt endpoints only */
- return realiseEndpoint(endpoint, maxPacket, RATE_FEEDBACK_MODE);
- }
-
- uint8_t * USBDevice::findDescriptor(uint8_t descriptorType)
- {
- /* Find a descriptor within the list of descriptors */
- /* following a configuration descriptor. */
- uint16_t wTotalLength;
- uint8_t *ptr;
-
- if (configurationDesc() == NULL)
- {
- return NULL;
- }
-
- /* Check this is a configuration descriptor */
- if ((configurationDesc()[0] != CONFIGURATION_DESCRIPTOR_LENGTH) \
- || (configurationDesc()[1] != CONFIGURATION_DESCRIPTOR))
- {
- return NULL;
- }
-
- wTotalLength = configurationDesc()[2] | (configurationDesc()[3] << 8);
-
- /* Check there are some more descriptors to follow */
- if (wTotalLength <= (CONFIGURATION_DESCRIPTOR_LENGTH+2))
- /* +2 is for bLength and bDescriptorType of next descriptor */
- {
- return NULL;
- }
-
- /* Start at first descriptor after the configuration descriptor */
- ptr = &(configurationDesc()[CONFIGURATION_DESCRIPTOR_LENGTH]);
-
- do {
- if (ptr[1] /* bDescriptorType */ == descriptorType)
- {
- /* Found */
- return ptr;
- }
-
- /* Skip to next descriptor */
- ptr += ptr[0]; /* bLength */
- } while (ptr < (configurationDesc() + wTotalLength));
-
- /* Reached end of the descriptors - not found */
- return NULL;
- }
-
-
- void USBDevice::connectStateChanged(unsigned int connected)
- {
- }
-
- void USBDevice::suspendStateChanged(unsigned int suspended)
- {
- }
-
-
- USBDevice::USBDevice(uint16_t vendor_id, uint16_t product_id, uint16_t product_release){
- VENDOR_ID = vendor_id;
- PRODUCT_ID = product_id;
- PRODUCT_RELEASE = product_release;
-
- /* Set initial device state */
- device.state = POWERED;
- device.configuration = 0;
- device.suspended = false;
- };
-
-
- bool USBDevice::readStart(uint8_t endpoint, uint32_t maxSize)
- {
- return endpointRead(endpoint, maxSize) == EP_PENDING;
- }
-
-
- bool USBDevice::write(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize)
- {
- EP_STATUS result;
-
- if (size > maxSize)
- {
- return false;
- }
-
-
- if(!configured()) {
- return false;
- }
-
- /* Send report */
- result = endpointWrite(endpoint, buffer, size);
-
- if (result != EP_PENDING)
- {
- return false;
- }
-
- /* Wait for completion */
- do {
- result = endpointWriteResult(endpoint);
- } while ((result == EP_PENDING) && configured());
-
- return (result == EP_COMPLETED);
- }
-
-
- bool USBDevice::writeNB(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize)
- {
- EP_STATUS result;
-
- if (size > maxSize)
- {
- return false;
- }
-
- if(!configured()) {
- return false;
- }
-
- /* Send report */
- result = endpointWrite(endpoint, buffer, size);
-
- if (result != EP_PENDING)
- {
- return false;
- }
-
- result = endpointWriteResult(endpoint);
-
- return (result == EP_COMPLETED);
- }
-
-
-
- bool USBDevice::readEP(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize)
- {
- EP_STATUS result;
-
- if(!configured()) {
- return false;
- }
-
- /* Wait for completion */
- do {
- result = endpointReadResult(endpoint, buffer, size);
- } while ((result == EP_PENDING) && configured());
-
- return (result == EP_COMPLETED);
- }
-
-
- bool USBDevice::readEP_NB(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize)
- {
- EP_STATUS result;
-
- if(!configured()) {
- return false;
- }
-
- result = endpointReadResult(endpoint, buffer, size);
-
- return (result == EP_COMPLETED);
- }
-
-
-
- uint8_t * USBDevice::deviceDesc() {
- static uint8_t deviceDescriptor[] = {
- DEVICE_DESCRIPTOR_LENGTH, /* bLength */
- DEVICE_DESCRIPTOR, /* bDescriptorType */
- LSB(USB_VERSION_2_0), /* bcdUSB (LSB) */
- MSB(USB_VERSION_2_0), /* bcdUSB (MSB) */
- 0x00, /* bDeviceClass */
- 0x00, /* bDeviceSubClass */
- 0x00, /* bDeviceprotocol */
- MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */
- (uint8_t)(LSB(VENDOR_ID)), /* idVendor (LSB) */
- (uint8_t)(MSB(VENDOR_ID)), /* idVendor (MSB) */
- (uint8_t)(LSB(PRODUCT_ID)), /* idProduct (LSB) */
- (uint8_t)(MSB(PRODUCT_ID)), /* idProduct (MSB) */
- (uint8_t)(LSB(PRODUCT_RELEASE)), /* bcdDevice (LSB) */
- (uint8_t)(MSB(PRODUCT_RELEASE)), /* bcdDevice (MSB) */
- STRING_OFFSET_IMANUFACTURER, /* iManufacturer */
- STRING_OFFSET_IPRODUCT, /* iProduct */
- STRING_OFFSET_ISERIAL, /* iSerialNumber */
- 0x01 /* bNumConfigurations */
- };
- return deviceDescriptor;
- }
-
- uint8_t * USBDevice::stringLangidDesc() {
- static uint8_t stringLangidDescriptor[] = {
- 0x04, /*bLength*/
- STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
- 0x09,0x04, /*bString Lang ID - 0x0409 - English*/
- };
- return stringLangidDescriptor;
- }
-
- uint8_t * USBDevice::stringImanufacturerDesc() {
- static uint8_t stringImanufacturerDescriptor[] = {
- 0x12, /*bLength*/
- STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
- 'm',0,'b',0,'e',0,'d',0,'.',0,'o',0,'r',0,'g',0, /*bString iManufacturer - mbed.org*/
- };
- return stringImanufacturerDescriptor;
- }
-
- uint8_t * USBDevice::stringIserialDesc() {
- static uint8_t stringIserialDescriptor[] = {
- 0x16, /*bLength*/
- STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
- '0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0, /*bString iSerial - 0123456789*/
- };
- return stringIserialDescriptor;
- }
-
- uint8_t * USBDevice::stringIConfigurationDesc() {
- static uint8_t stringIconfigurationDescriptor[] = {
- 0x06, /*bLength*/
- STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
- '0',0,'1',0, /*bString iConfiguration - 01*/
- };
- return stringIconfigurationDescriptor;
- }
-
- uint8_t * USBDevice::stringIinterfaceDesc() {
- static uint8_t stringIinterfaceDescriptor[] = {
- 0x08, /*bLength*/
- STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
- 'U',0,'S',0,'B',0, /*bString iInterface - USB*/
- };
- return stringIinterfaceDescriptor;
- }
-
- uint8_t * USBDevice::stringIproductDesc() {
- static uint8_t stringIproductDescriptor[] = {
- 0x16, /*bLength*/
- STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
- 'U',0,'S',0,'B',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 /*bString iProduct - USB DEVICE*/
- };
- return stringIproductDescriptor;
- }
|