1 /* Copyright (c) 2010-2011 mbed.org, MIT License
3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
4 * and associated documentation files (the "Software"), to deal in the Software without
5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
7 * Software is furnished to do so, subject to the following conditions:
9 * The above copyright notice and this permission notice shall be included in all copies or
10 * substantial portions of the Software.
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 #include "USBEndpoints.h"
22 #include "USBDevice.h"
23 #include "USBDescriptor.h"
28 #define DEVICE_STATUS_SELF_POWERED (1U<<0)
29 #define DEVICE_STATUS_REMOTE_WAKEUP (1U<<1)
32 #define ENDPOINT_STATUS_HALT (1U<<0)
34 /* Standard feature selectors */
35 #define DEVICE_REMOTE_WAKEUP (1)
36 #define ENDPOINT_HALT (0)
38 /* Macro to convert wIndex endpoint number to physical endpoint number */
39 #define WINDEX_TO_PHYSICAL(endpoint) (((endpoint & 0x0f) << 1) + \
40 ((endpoint & 0x80) ? 1 : 0))
43 bool USBDevice::requestGetDescriptor(void)
47 printf("get descr: type: %d\r\n", DESCRIPTOR_TYPE(transfer.setup.wValue));
49 switch (DESCRIPTOR_TYPE(transfer.setup.wValue))
51 case DEVICE_DESCRIPTOR:
52 if (deviceDesc() != NULL)
54 if ((deviceDesc()[0] == DEVICE_DESCRIPTOR_LENGTH) \
55 && (deviceDesc()[1] == DEVICE_DESCRIPTOR))
58 printf("device descr\r\n");
60 transfer.remaining = DEVICE_DESCRIPTOR_LENGTH;
61 transfer.ptr = deviceDesc();
62 transfer.direction = DEVICE_TO_HOST;
67 case CONFIGURATION_DESCRIPTOR:
68 if (configurationDesc() != NULL)
70 if ((configurationDesc()[0] == CONFIGURATION_DESCRIPTOR_LENGTH) \
71 && (configurationDesc()[1] == CONFIGURATION_DESCRIPTOR))
74 printf("conf descr request\r\n");
76 /* Get wTotalLength */
77 transfer.remaining = configurationDesc()[2] \
78 | (configurationDesc()[3] << 8);
80 transfer.ptr = configurationDesc();
81 transfer.direction = DEVICE_TO_HOST;
86 case STRING_DESCRIPTOR:
88 printf("str descriptor\r\n");
90 switch (DESCRIPTOR_INDEX(transfer.setup.wValue))
92 case STRING_OFFSET_LANGID:
96 transfer.remaining = stringLangidDesc()[0];
97 transfer.ptr = stringLangidDesc();
98 transfer.direction = DEVICE_TO_HOST;
101 case STRING_OFFSET_IMANUFACTURER:
105 transfer.remaining = stringImanufacturerDesc()[0];
106 transfer.ptr = stringImanufacturerDesc();
107 transfer.direction = DEVICE_TO_HOST;
110 case STRING_OFFSET_IPRODUCT:
114 transfer.remaining = stringIproductDesc()[0];
115 transfer.ptr = stringIproductDesc();
116 transfer.direction = DEVICE_TO_HOST;
119 case STRING_OFFSET_ISERIAL:
123 transfer.remaining = stringIserialDesc()[0];
124 transfer.ptr = stringIserialDesc();
125 transfer.direction = DEVICE_TO_HOST;
128 case STRING_OFFSET_ICONFIGURATION:
132 transfer.remaining = stringIConfigurationDesc()[0];
133 transfer.ptr = stringIConfigurationDesc();
134 transfer.direction = DEVICE_TO_HOST;
137 case STRING_OFFSET_IINTERFACE:
141 transfer.remaining = stringIinterfaceDesc()[0];
142 transfer.ptr = stringIinterfaceDesc();
143 transfer.direction = DEVICE_TO_HOST;
148 case INTERFACE_DESCRIPTOR:
150 printf("interface descr\r\n");
152 case ENDPOINT_DESCRIPTOR:
154 printf("endpoint descr\r\n");
156 /* TODO: Support is optional, not implemented here */
168 void USBDevice::decodeSetupPacket(uint8_t *data, SETUP_PACKET *packet)
170 /* Fill in the elements of a SETUP_PACKET structure from raw data */
171 packet->bmRequestType.dataTransferDirection = (data[0] & 0x80) >> 7;
172 packet->bmRequestType.Type = (data[0] & 0x60) >> 5;
173 packet->bmRequestType.Recipient = data[0] & 0x1f;
174 packet->bRequest = data[1];
175 packet->wValue = (data[2] | (uint16_t)data[3] << 8);
176 packet->wIndex = (data[4] | (uint16_t)data[5] << 8);
177 packet->wLength = (data[6] | (uint16_t)data[7] << 8);
181 bool USBDevice::controlOut(void)
183 /* Control transfer data OUT stage */
184 uint8_t buffer[MAX_PACKET_SIZE_EP0];
187 /* Check we should be transferring data OUT */
188 if (transfer.direction != HOST_TO_DEVICE)
190 #if defined(TARGET_KL25Z) | defined(TARGET_KL43Z) | defined(TARGET_KL46Z) | defined(TARGET_K20D5M) | defined(TARGET_K64F) | defined(TARGET_K22F) | defined(TARGET_TEENSY3_1)
192 * We seem to have a pending device-to-host transfer. The host must have
193 * sent a new control request without waiting for us to finish processing
194 * the previous one. This appears to happen when we're connected to certain
195 * USB 3.0 host chip set. Do a zeor-length send to tell the host we're not
196 * ready for the new request - that'll make it resend - and then just
197 * pretend we were successful here so that the pending transfer can finish.
199 uint8_t buf[1] = { 0 };
202 /* execute our pending ttransfer */
205 /* indicate success */
208 /* for other platforms, count on the HAL to handle this case */
213 /* Read from endpoint */
214 packetSize = EP0getReadResult(buffer);
216 /* Check if transfer size is valid */
217 if (packetSize > transfer.remaining)
223 /* Update transfer */
224 transfer.ptr += packetSize;
225 transfer.remaining -= packetSize;
227 /* Check if transfer has completed */
228 if (transfer.remaining == 0)
230 /* Transfer completed */
233 /* Notify class layer. */
234 USBCallback_requestCompleted(buffer, packetSize);
235 transfer.notify = false;
248 bool USBDevice::controlIn(void)
250 /* Control transfer data IN stage */
253 /* Check if transfer has completed (status stage transactions */
254 /* also have transfer.remaining == 0) */
255 if (transfer.remaining == 0)
259 /* Send zero length packet */
261 transfer.zlp = false;
264 /* Transfer completed */
267 /* Notify class layer. */
268 USBCallback_requestCompleted(NULL, 0);
269 transfer.notify = false;
279 /* Check we should be transferring data IN */
280 if (transfer.direction != DEVICE_TO_HOST)
285 packetSize = transfer.remaining;
287 if (packetSize > MAX_PACKET_SIZE_EP0)
289 packetSize = MAX_PACKET_SIZE_EP0;
292 /* Write to endpoint */
293 EP0write(transfer.ptr, packetSize);
295 /* Update transfer */
296 transfer.ptr += packetSize;
297 transfer.remaining -= packetSize;
302 bool USBDevice::requestSetAddress(void)
304 /* Set the device address */
305 setAddress(transfer.setup.wValue);
307 if (transfer.setup.wValue == 0)
309 device.state = DEFAULT;
313 device.state = ADDRESS;
319 bool USBDevice::requestSetConfiguration(void)
322 device.configuration = transfer.setup.wValue;
323 /* Set the device configuration */
324 if (device.configuration == 0)
328 device.state = ADDRESS;
332 if (USBCallback_setConfiguration(device.configuration))
334 /* Valid configuration */
336 device.state = CONFIGURED;
347 bool USBDevice::requestGetConfiguration(void)
349 /* Send the device configuration */
350 transfer.ptr = &device.configuration;
351 transfer.remaining = sizeof(device.configuration);
352 transfer.direction = DEVICE_TO_HOST;
356 bool USBDevice::requestGetInterface(void)
358 /* Return the selected alternate setting for an interface */
360 if (device.state != CONFIGURED)
365 /* Send the alternate setting */
366 transfer.setup.wIndex = currentInterface;
367 transfer.ptr = ¤tAlternate;
368 transfer.remaining = sizeof(currentAlternate);
369 transfer.direction = DEVICE_TO_HOST;
373 bool USBDevice::requestSetInterface(void)
375 bool success = false;
376 if(USBCallback_setInterface(transfer.setup.wIndex, transfer.setup.wValue))
379 currentInterface = transfer.setup.wIndex;
380 currentAlternate = transfer.setup.wValue;
385 bool USBDevice::requestSetFeature()
387 bool success = false;
389 if (device.state != CONFIGURED)
391 /* Endpoint or interface must be zero */
392 if (transfer.setup.wIndex != 0)
398 switch (transfer.setup.bmRequestType.Recipient)
400 case DEVICE_RECIPIENT:
401 /* TODO: Remote wakeup feature not supported */
403 case ENDPOINT_RECIPIENT:
404 if (transfer.setup.wValue == ENDPOINT_HALT)
406 /* TODO: We should check that the endpoint number is valid */
408 WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
419 bool USBDevice::requestClearFeature()
421 bool success = false;
423 if (device.state != CONFIGURED)
425 /* Endpoint or interface must be zero */
426 if (transfer.setup.wIndex != 0)
432 switch (transfer.setup.bmRequestType.Recipient)
434 case DEVICE_RECIPIENT:
435 /* TODO: Remote wakeup feature not supported */
437 case ENDPOINT_RECIPIENT:
438 /* TODO: We should check that the endpoint number is valid */
439 if (transfer.setup.wValue == ENDPOINT_HALT)
441 unstallEndpoint( WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
452 bool USBDevice::requestGetStatus(void)
454 static uint16_t status;
455 bool success = false;
457 if (device.state != CONFIGURED)
459 /* Endpoint or interface must be zero */
460 if (transfer.setup.wIndex != 0)
466 switch (transfer.setup.bmRequestType.Recipient)
468 case DEVICE_RECIPIENT:
469 /* TODO: Currently only supports self powered devices */
470 status = DEVICE_STATUS_SELF_POWERED;
473 case INTERFACE_RECIPIENT:
477 case ENDPOINT_RECIPIENT:
478 /* TODO: We should check that the endpoint number is valid */
479 if (getEndpointStallState(
480 WINDEX_TO_PHYSICAL(transfer.setup.wIndex)))
482 status = ENDPOINT_STATUS_HALT;
496 /* Send the status */
497 transfer.ptr = (uint8_t *)&status; /* Assumes little endian */
498 transfer.remaining = sizeof(status);
499 transfer.direction = DEVICE_TO_HOST;
505 bool USBDevice::requestSetup(void)
507 bool success = false;
509 /* Process standard requests */
510 if ((transfer.setup.bmRequestType.Type == STANDARD_TYPE))
512 switch (transfer.setup.bRequest)
515 success = requestGetStatus();
518 success = requestClearFeature();
521 success = requestSetFeature();
524 success = requestSetAddress();
527 success = requestGetDescriptor();
530 /* TODO: Support is optional, not implemented here */
533 case GET_CONFIGURATION:
534 success = requestGetConfiguration();
536 case SET_CONFIGURATION:
537 success = requestSetConfiguration();
540 success = requestGetInterface();
543 success = requestSetInterface();
553 bool USBDevice::controlSetup(void)
555 bool success = false;
557 /* Control transfer setup stage */
558 uint8_t buffer[MAX_PACKET_SIZE_EP0];
562 /* Initialise control transfer state */
563 decodeSetupPacket(buffer, &transfer.setup);
565 transfer.remaining = 0;
566 transfer.direction = 0;
567 transfer.zlp = false;
568 transfer.notify = false;
571 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,
572 transfer.setup.bmRequestType.Type,
573 transfer.setup.bmRequestType.Recipient,
574 transfer.setup.bRequest,
575 transfer.setup.wValue,
576 transfer.setup.wIndex,
577 transfer.setup.wLength);
580 /* Class / vendor specific */
581 success = USBCallback_request();
585 /* Standard requests */
589 printf("fail!!!!\r\n");
595 /* Check transfer size and direction */
596 if (transfer.setup.wLength>0)
598 if (transfer.setup.bmRequestType.dataTransferDirection \
601 /* IN data stage is required */
602 if (transfer.direction != DEVICE_TO_HOST)
607 /* Transfer must be less than or equal to the size */
608 /* requested by the host */
609 if (transfer.remaining > transfer.setup.wLength)
611 transfer.remaining = transfer.setup.wLength;
617 /* OUT data stage is required */
618 if (transfer.direction != HOST_TO_DEVICE)
623 /* Transfer must be equal to the size requested by the host */
624 if (transfer.remaining != transfer.setup.wLength)
632 /* No data stage; transfer size must be zero */
633 if (transfer.remaining != 0)
639 /* Data or status stage if applicable */
640 if (transfer.setup.wLength>0)
642 if (transfer.setup.bmRequestType.dataTransferDirection \
645 /* Check if we'll need to send a zero length packet at */
646 /* the end of this transfer */
647 if (transfer.setup.wLength > transfer.remaining)
649 /* Device wishes to transfer less than host requested */
650 if ((transfer.remaining % MAX_PACKET_SIZE_EP0) == 0)
652 /* Transfer is a multiple of EP0 max packet size */
675 void USBDevice::busReset(void)
677 device.state = DEFAULT;
678 device.configuration = 0;
679 device.suspended = false;
681 /* Call class / vendor specific busReset function */
682 USBCallback_busReset();
685 void USBDevice::EP0setupCallback(void)
687 /* Endpoint 0 setup event */
694 /* Return true if an OUT data stage is expected */
697 void USBDevice::EP0out(void)
699 /* Endpoint 0 OUT data event */
702 /* Protocol stall; this will stall both endpoints */
707 void USBDevice::EP0in(void)
712 /* Endpoint 0 IN data event */
715 /* Protocol stall; this will stall both endpoints */
720 bool USBDevice::configured(void)
722 /* Returns true if device is in the CONFIGURED state */
723 return (device.state == CONFIGURED);
726 void USBDevice::connect(bool blocking)
732 /* Block if not configured */
733 while (!configured());
737 void USBDevice::disconnect(void)
739 /* Disconnect device */
740 USBHAL::disconnect();
742 /* Set initial device state */
743 device.state = POWERED;
744 device.configuration = 0;
745 device.suspended = false;
748 CONTROL_TRANSFER * USBDevice::getTransferPtr(void)
753 bool USBDevice::addEndpoint(uint8_t endpoint, uint32_t maxPacket)
755 return realiseEndpoint(endpoint, maxPacket, 0);
758 bool USBDevice::addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket)
760 /* For interrupt endpoints only */
761 return realiseEndpoint(endpoint, maxPacket, RATE_FEEDBACK_MODE);
764 uint8_t * USBDevice::findDescriptor(uint8_t descriptorType)
766 /* Find a descriptor within the list of descriptors */
767 /* following a configuration descriptor. */
768 uint16_t wTotalLength;
771 if (configurationDesc() == NULL)
776 /* Check this is a configuration descriptor */
777 if ((configurationDesc()[0] != CONFIGURATION_DESCRIPTOR_LENGTH) \
778 || (configurationDesc()[1] != CONFIGURATION_DESCRIPTOR))
783 wTotalLength = configurationDesc()[2] | (configurationDesc()[3] << 8);
785 /* Check there are some more descriptors to follow */
786 if (wTotalLength <= (CONFIGURATION_DESCRIPTOR_LENGTH+2))
787 /* +2 is for bLength and bDescriptorType of next descriptor */
792 /* Start at first descriptor after the configuration descriptor */
793 ptr = &(configurationDesc()[CONFIGURATION_DESCRIPTOR_LENGTH]);
796 if (ptr[1] /* bDescriptorType */ == descriptorType)
802 /* Skip to next descriptor */
803 ptr += ptr[0]; /* bLength */
804 } while (ptr < (configurationDesc() + wTotalLength));
806 /* Reached end of the descriptors - not found */
811 void USBDevice::connectStateChanged(unsigned int connected)
815 void USBDevice::suspendStateChanged(unsigned int suspended)
820 USBDevice::USBDevice(uint16_t vendor_id, uint16_t product_id, uint16_t product_release){
821 VENDOR_ID = vendor_id;
822 PRODUCT_ID = product_id;
823 PRODUCT_RELEASE = product_release;
825 /* Set initial device state */
826 device.state = POWERED;
827 device.configuration = 0;
828 device.suspended = false;
832 bool USBDevice::readStart(uint8_t endpoint, uint32_t maxSize)
834 return endpointRead(endpoint, maxSize) == EP_PENDING;
838 bool USBDevice::write(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize)
853 result = endpointWrite(endpoint, buffer, size);
855 if (result != EP_PENDING)
860 /* Wait for completion */
862 result = endpointWriteResult(endpoint);
863 } while ((result == EP_PENDING) && configured());
865 return (result == EP_COMPLETED);
869 bool USBDevice::writeNB(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize)
883 result = endpointWrite(endpoint, buffer, size);
885 if (result != EP_PENDING)
890 result = endpointWriteResult(endpoint);
892 return (result == EP_COMPLETED);
897 bool USBDevice::readEP(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize)
905 /* Wait for completion */
907 result = endpointReadResult(endpoint, buffer, size);
908 } while ((result == EP_PENDING) && configured());
910 return (result == EP_COMPLETED);
914 bool USBDevice::readEP_NB(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize)
922 result = endpointReadResult(endpoint, buffer, size);
924 return (result == EP_COMPLETED);
929 uint8_t * USBDevice::deviceDesc() {
930 static uint8_t deviceDescriptor[] = {
931 DEVICE_DESCRIPTOR_LENGTH, /* bLength */
932 DEVICE_DESCRIPTOR, /* bDescriptorType */
933 LSB(USB_VERSION_2_0), /* bcdUSB (LSB) */
934 MSB(USB_VERSION_2_0), /* bcdUSB (MSB) */
935 0x00, /* bDeviceClass */
936 0x00, /* bDeviceSubClass */
937 0x00, /* bDeviceprotocol */
938 MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */
939 (uint8_t)(LSB(VENDOR_ID)), /* idVendor (LSB) */
940 (uint8_t)(MSB(VENDOR_ID)), /* idVendor (MSB) */
941 (uint8_t)(LSB(PRODUCT_ID)), /* idProduct (LSB) */
942 (uint8_t)(MSB(PRODUCT_ID)), /* idProduct (MSB) */
943 (uint8_t)(LSB(PRODUCT_RELEASE)), /* bcdDevice (LSB) */
944 (uint8_t)(MSB(PRODUCT_RELEASE)), /* bcdDevice (MSB) */
945 STRING_OFFSET_IMANUFACTURER, /* iManufacturer */
946 STRING_OFFSET_IPRODUCT, /* iProduct */
947 STRING_OFFSET_ISERIAL, /* iSerialNumber */
948 0x01 /* bNumConfigurations */
950 return deviceDescriptor;
953 uint8_t * USBDevice::stringLangidDesc() {
954 static uint8_t stringLangidDescriptor[] = {
956 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
957 0x09,0x04, /*bString Lang ID - 0x0409 - English*/
959 return stringLangidDescriptor;
962 uint8_t * USBDevice::stringImanufacturerDesc() {
963 static uint8_t stringImanufacturerDescriptor[] = {
965 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
966 'm',0,'b',0,'e',0,'d',0,'.',0,'o',0,'r',0,'g',0, /*bString iManufacturer - mbed.org*/
968 return stringImanufacturerDescriptor;
971 uint8_t * USBDevice::stringIserialDesc() {
972 static uint8_t stringIserialDescriptor[] = {
974 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
975 '0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0, /*bString iSerial - 0123456789*/
977 return stringIserialDescriptor;
980 uint8_t * USBDevice::stringIConfigurationDesc() {
981 static uint8_t stringIconfigurationDescriptor[] = {
983 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
984 '0',0,'1',0, /*bString iConfiguration - 01*/
986 return stringIconfigurationDescriptor;
989 uint8_t * USBDevice::stringIinterfaceDesc() {
990 static uint8_t stringIinterfaceDescriptor[] = {
992 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
993 'U',0,'S',0,'B',0, /*bString iInterface - USB*/
995 return stringIinterfaceDescriptor;
998 uint8_t * USBDevice::stringIproductDesc() {
999 static uint8_t stringIproductDescriptor[] = {
1001 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
1002 'U',0,'S',0,'B',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 /*bString iProduct - USB DEVICE*/
1004 return stringIproductDescriptor;