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
;