]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/USBDevice/USBDevice/USBDevice.cpp
Merge commit 'f6d56675f9f981c5464f0ca7a1fbb0162154e8c5'
[max/tmk_keyboard.git] / tmk_core / tool / mbed / mbed-sdk / libraries / USBDevice / USBDevice / USBDevice.cpp
1 /* Copyright (c) 2010-2011 mbed.org, MIT License
2 *
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:
8 *
9 * The above copyright notice and this permission notice shall be included in all copies or
10 * substantial portions of the Software.
11 *
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.
17 */
18
19 #include "stdint.h"
20
21 #include "USBEndpoints.h"
22 #include "USBDevice.h"
23 #include "USBDescriptor.h"
24
25 //#define DEBUG
26
27 /* Device status */
28 #define DEVICE_STATUS_SELF_POWERED  (1U<<0)
29 #define DEVICE_STATUS_REMOTE_WAKEUP (1U<<1)
30
31 /* Endpoint status */
32 #define ENDPOINT_STATUS_HALT        (1U<<0)
33
34 /* Standard feature selectors */
35 #define DEVICE_REMOTE_WAKEUP        (1)
36 #define ENDPOINT_HALT               (0)
37
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))
41
42
43 bool USBDevice::requestGetDescriptor(void)
44 {
45     bool success = false;
46 #ifdef DEBUG
47     printf("get descr: type: %d\r\n", DESCRIPTOR_TYPE(transfer.setup.wValue));
48 #endif
49     switch (DESCRIPTOR_TYPE(transfer.setup.wValue))
50     {
51         case DEVICE_DESCRIPTOR:
52             if (deviceDesc() != NULL)
53             {
54                 if ((deviceDesc()[0] == DEVICE_DESCRIPTOR_LENGTH) \
55                     && (deviceDesc()[1] == DEVICE_DESCRIPTOR))
56                 {
57 #ifdef DEBUG
58                     printf("device descr\r\n");
59 #endif
60                     transfer.remaining = DEVICE_DESCRIPTOR_LENGTH;
61                     transfer.ptr = deviceDesc();
62                     transfer.direction = DEVICE_TO_HOST;
63                     success = true;
64                 }
65             }
66             break;
67         case CONFIGURATION_DESCRIPTOR:
68             if (configurationDesc() != NULL)
69             {
70                 if ((configurationDesc()[0] == CONFIGURATION_DESCRIPTOR_LENGTH) \
71                     && (configurationDesc()[1] == CONFIGURATION_DESCRIPTOR))
72                 {
73 #ifdef DEBUG
74                     printf("conf descr request\r\n");
75 #endif
76                     /* Get wTotalLength */
77                     transfer.remaining = configurationDesc()[2] \
78                         | (configurationDesc()[3] << 8);
79
80                     transfer.ptr = configurationDesc();
81                     transfer.direction = DEVICE_TO_HOST;
82                     success = true;
83                 }
84             }
85             break;
86         case STRING_DESCRIPTOR:
87 #ifdef DEBUG
88             printf("str descriptor\r\n");
89 #endif
90             switch (DESCRIPTOR_INDEX(transfer.setup.wValue))
91             {
92                             case STRING_OFFSET_LANGID:
93 #ifdef DEBUG
94                                 printf("1\r\n");
95 #endif
96                                 transfer.remaining = stringLangidDesc()[0];
97                                 transfer.ptr = stringLangidDesc();
98                                 transfer.direction = DEVICE_TO_HOST;
99                                 success = true;
100                                 break;
101                             case STRING_OFFSET_IMANUFACTURER:
102 #ifdef DEBUG
103                                 printf("2\r\n");
104 #endif
105                                 transfer.remaining =  stringImanufacturerDesc()[0];
106                                 transfer.ptr = stringImanufacturerDesc();
107                                 transfer.direction = DEVICE_TO_HOST;
108                                 success = true;
109                                 break;
110                             case STRING_OFFSET_IPRODUCT:
111 #ifdef DEBUG
112                                 printf("3\r\n");
113 #endif
114                                 transfer.remaining = stringIproductDesc()[0];
115                                 transfer.ptr = stringIproductDesc();
116                                 transfer.direction = DEVICE_TO_HOST;
117                                 success = true;
118                                 break;
119                             case STRING_OFFSET_ISERIAL:
120 #ifdef DEBUG
121                                 printf("4\r\n");
122 #endif
123                                 transfer.remaining = stringIserialDesc()[0];
124                                 transfer.ptr = stringIserialDesc();
125                                 transfer.direction = DEVICE_TO_HOST;
126                                 success = true;
127                                 break;
128                             case STRING_OFFSET_ICONFIGURATION:
129 #ifdef DEBUG
130                                 printf("5\r\n");
131 #endif
132                                 transfer.remaining = stringIConfigurationDesc()[0];
133                                 transfer.ptr = stringIConfigurationDesc();
134                                 transfer.direction = DEVICE_TO_HOST;
135                                 success = true;
136                                 break;
137                             case STRING_OFFSET_IINTERFACE:
138 #ifdef DEBUG
139                                 printf("6\r\n");
140 #endif
141                                 transfer.remaining = stringIinterfaceDesc()[0];
142                                 transfer.ptr = stringIinterfaceDesc();
143                                 transfer.direction = DEVICE_TO_HOST;
144                                 success = true;
145                                 break;
146             }
147             break;
148         case INTERFACE_DESCRIPTOR:
149 #ifdef DEBUG
150             printf("interface descr\r\n");
151 #endif
152         case ENDPOINT_DESCRIPTOR:
153 #ifdef DEBUG
154             printf("endpoint descr\r\n");
155 #endif
156             /* TODO: Support is optional, not implemented here */
157             break;
158         default:
159 #ifdef DEBUG
160             printf("ERROR\r\n");
161 #endif
162             break;
163     }
164
165     return success;
166 }
167
168 void USBDevice::decodeSetupPacket(uint8_t *data, SETUP_PACKET *packet)
169 {
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);
178 }
179
180
181 bool USBDevice::controlOut(void)
182 {
183     /* Control transfer data OUT stage */
184     uint8_t buffer[MAX_PACKET_SIZE_EP0];
185     uint32_t packetSize;
186
187     /* Check we should be transferring data OUT */
188     if (transfer.direction != HOST_TO_DEVICE)
189     {
190 #if defined(TARGET_KL25Z) | defined(TARGET_KL43Z) | defined(TARGET_KL46Z) | defined(TARGET_K20D5M) | defined(TARGET_K64F) | defined(TARGET_K22F) | defined(TARGET_TEENSY3_1)
191         /*
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.
198          */
199          uint8_t buf[1] = { 0 };
200          EP0write(buf, 0);
201          
202          /* execute our pending ttransfer */
203          controlIn();
204          
205          /* indicate success */
206          return true;
207  #else
208          /* for other platforms, count on the HAL to handle this case */
209          return false;
210  #endif
211     }
212
213     /* Read from endpoint */
214     packetSize = EP0getReadResult(buffer);
215
216     /* Check if transfer size is valid */
217     if (packetSize > transfer.remaining)
218     {
219         /* Too big */
220         return false;
221     }
222
223     /* Update transfer */
224     transfer.ptr += packetSize;
225     transfer.remaining -= packetSize;
226
227     /* Check if transfer has completed */
228     if (transfer.remaining == 0)
229     {
230         /* Transfer completed */
231         if (transfer.notify)
232         {
233             /* Notify class layer. */
234             USBCallback_requestCompleted(buffer, packetSize);
235             transfer.notify = false;
236         }
237         /* Status stage */
238         EP0write(NULL, 0);
239     }
240     else
241     {
242         EP0read();
243     }
244
245     return true;
246 }
247
248 bool USBDevice::controlIn(void)
249 {
250     /* Control transfer data IN stage */
251     uint32_t packetSize;
252
253     /* Check if transfer has completed (status stage transactions */
254     /* also have transfer.remaining == 0) */
255     if (transfer.remaining == 0)
256     {
257         if (transfer.zlp)
258         {
259             /* Send zero length packet */
260             EP0write(NULL, 0);
261             transfer.zlp = false;
262         }
263
264         /* Transfer completed */
265         if (transfer.notify)
266         {
267             /* Notify class layer. */
268             USBCallback_requestCompleted(NULL, 0);
269             transfer.notify = false;
270         }
271
272         EP0read();
273         EP0readStage();
274
275         /* Completed */
276         return true;
277     }
278
279     /* Check we should be transferring data IN */
280     if (transfer.direction != DEVICE_TO_HOST)
281     {
282         return false;
283     }
284
285     packetSize = transfer.remaining;
286
287     if (packetSize > MAX_PACKET_SIZE_EP0)
288     {
289         packetSize = MAX_PACKET_SIZE_EP0;
290     }
291
292     /* Write to endpoint */
293     EP0write(transfer.ptr, packetSize);
294
295     /* Update transfer */
296     transfer.ptr += packetSize;
297     transfer.remaining -= packetSize;
298
299     return true;
300 }
301
302 bool USBDevice::requestSetAddress(void)
303 {
304     /* Set the device address */
305     setAddress(transfer.setup.wValue);
306
307     if (transfer.setup.wValue == 0)
308     {
309         device.state = DEFAULT;
310     }
311     else
312     {
313         device.state = ADDRESS;
314     }
315
316     return true;
317 }
318
319 bool USBDevice::requestSetConfiguration(void)
320 {
321
322     device.configuration = transfer.setup.wValue;
323     /* Set the device configuration */
324     if (device.configuration == 0)
325     {
326         /* Not configured */
327         unconfigureDevice();
328         device.state = ADDRESS;
329     }
330     else
331     {
332         if (USBCallback_setConfiguration(device.configuration))
333         {
334             /* Valid configuration */
335             configureDevice();
336             device.state = CONFIGURED;
337         }
338         else
339         {
340             return false;
341         }
342     }
343
344     return true;
345 }
346
347 bool USBDevice::requestGetConfiguration(void)
348 {
349     /* Send the device configuration */
350     transfer.ptr = &device.configuration;
351     transfer.remaining = sizeof(device.configuration);
352     transfer.direction = DEVICE_TO_HOST;
353     return true;
354 }
355
356 bool USBDevice::requestGetInterface(void)
357 {
358     /* Return the selected alternate setting for an interface */
359
360     if (device.state != CONFIGURED)
361     {
362         return false;
363     }
364
365     /* Send the alternate setting */
366     transfer.setup.wIndex = currentInterface;
367     transfer.ptr = &currentAlternate;
368     transfer.remaining = sizeof(currentAlternate);
369     transfer.direction = DEVICE_TO_HOST;
370     return true;
371 }
372
373 bool USBDevice::requestSetInterface(void)
374 {
375     bool success = false;
376     if(USBCallback_setInterface(transfer.setup.wIndex, transfer.setup.wValue))
377     {
378         success = true;
379         currentInterface = transfer.setup.wIndex;
380         currentAlternate = transfer.setup.wValue;
381     }
382     return success;
383 }
384
385 bool USBDevice::requestSetFeature()
386 {
387     bool success = false;
388
389     if (device.state != CONFIGURED)
390     {
391         /* Endpoint or interface must be zero */
392         if (transfer.setup.wIndex != 0)
393         {
394             return false;
395         }
396     }
397
398     switch (transfer.setup.bmRequestType.Recipient)
399     {
400         case DEVICE_RECIPIENT:
401             /* TODO: Remote wakeup feature not supported */
402             break;
403         case ENDPOINT_RECIPIENT:
404             if (transfer.setup.wValue == ENDPOINT_HALT)
405             {
406                 /* TODO: We should check that the endpoint number is valid */
407                 stallEndpoint(
408                     WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
409                 success = true;
410             }
411             break;
412         default:
413             break;
414     }
415
416     return success;
417 }
418
419 bool USBDevice::requestClearFeature()
420 {
421     bool success = false;
422
423     if (device.state != CONFIGURED)
424     {
425         /* Endpoint or interface must be zero */
426         if (transfer.setup.wIndex != 0)
427         {
428             return false;
429         }
430     }
431
432     switch (transfer.setup.bmRequestType.Recipient)
433     {
434         case DEVICE_RECIPIENT:
435             /* TODO: Remote wakeup feature not supported */
436             break;
437         case ENDPOINT_RECIPIENT:
438             /* TODO: We should check that the endpoint number is valid */
439             if (transfer.setup.wValue == ENDPOINT_HALT)
440             {
441                 unstallEndpoint( WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
442                 success = true;
443             }
444             break;
445         default:
446             break;
447     }
448
449     return success;
450 }
451
452 bool USBDevice::requestGetStatus(void)
453 {
454     static uint16_t status;
455     bool success = false;
456
457     if (device.state != CONFIGURED)
458     {
459         /* Endpoint or interface must be zero */
460         if (transfer.setup.wIndex != 0)
461         {
462             return false;
463         }
464     }
465
466     switch (transfer.setup.bmRequestType.Recipient)
467     {
468         case DEVICE_RECIPIENT:
469             /* TODO: Currently only supports self powered devices */
470             status = DEVICE_STATUS_SELF_POWERED;
471             success = true;
472             break;
473         case INTERFACE_RECIPIENT:
474             status = 0;
475             success = true;
476             break;
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)))
481             {
482                 status = ENDPOINT_STATUS_HALT;
483             }
484             else
485             {
486                 status = 0;
487             }
488             success = true;
489             break;
490         default:
491             break;
492     }
493
494     if (success)
495     {
496         /* Send the status */
497         transfer.ptr = (uint8_t *)&status; /* Assumes little endian */
498         transfer.remaining = sizeof(status);
499         transfer.direction = DEVICE_TO_HOST;
500     }
501
502     return success;
503 }
504
505 bool USBDevice::requestSetup(void)
506 {
507     bool success = false;
508
509     /* Process standard requests */
510     if ((transfer.setup.bmRequestType.Type == STANDARD_TYPE))
511     {
512         switch (transfer.setup.bRequest)
513         {
514              case GET_STATUS:
515                  success = requestGetStatus();
516                  break;
517              case CLEAR_FEATURE:
518                  success = requestClearFeature();
519                  break;
520              case SET_FEATURE:
521                  success = requestSetFeature();
522                  break;
523              case SET_ADDRESS:
524                 success = requestSetAddress();
525                  break;
526              case GET_DESCRIPTOR:
527                  success = requestGetDescriptor();
528                  break;
529              case SET_DESCRIPTOR:
530                  /* TODO: Support is optional, not implemented here */
531                  success = false;
532                  break;
533              case GET_CONFIGURATION:
534                  success = requestGetConfiguration();
535                  break;
536              case SET_CONFIGURATION:
537                  success = requestSetConfiguration();
538                  break;
539              case GET_INTERFACE:
540                  success = requestGetInterface();
541                  break;
542              case SET_INTERFACE:
543                  success = requestSetInterface();
544                  break;
545              default:
546                  break;
547         }
548     }
549
550     return success;
551 }
552
553 bool USBDevice::controlSetup(void)
554 {
555     bool success = false;
556
557     /* Control transfer setup stage */
558     uint8_t buffer[MAX_PACKET_SIZE_EP0];
559
560     EP0setup(buffer);
561
562     /* Initialise control transfer state */
563     decodeSetupPacket(buffer, &transfer.setup);
564     transfer.ptr = NULL;
565     transfer.remaining = 0;
566     transfer.direction = 0;
567     transfer.zlp = false;
568     transfer.notify = false;
569
570 #ifdef DEBUG
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);
578 #endif
579
580     /* Class / vendor specific */
581     success = USBCallback_request();
582
583     if (!success)
584     {
585         /* Standard requests */
586         if (!requestSetup())
587         {
588 #ifdef DEBUG
589             printf("fail!!!!\r\n");
590 #endif
591             return false;
592         }
593     }
594
595     /* Check transfer size and direction */
596     if (transfer.setup.wLength>0)
597     {
598         if (transfer.setup.bmRequestType.dataTransferDirection \
599             == DEVICE_TO_HOST)
600         {
601             /* IN data stage is required */
602             if (transfer.direction != DEVICE_TO_HOST)
603             {
604                 return false;
605             }
606
607             /* Transfer must be less than or equal to the size */
608             /* requested by the host */
609             if (transfer.remaining > transfer.setup.wLength)
610             {
611                 transfer.remaining = transfer.setup.wLength;
612             }
613         }
614         else
615         {
616
617             /* OUT data stage is required */
618             if (transfer.direction != HOST_TO_DEVICE)
619             {
620                 return false;
621             }
622
623             /* Transfer must be equal to the size requested by the host */
624             if (transfer.remaining != transfer.setup.wLength)
625             {
626                 return false;
627             }
628         }
629     }
630     else
631     {
632         /* No data stage; transfer size must be zero */
633         if (transfer.remaining != 0)
634         {
635             return false;
636         }
637     }
638
639     /* Data or status stage if applicable */
640     if (transfer.setup.wLength>0)
641     {
642         if (transfer.setup.bmRequestType.dataTransferDirection \
643             == DEVICE_TO_HOST)
644         {
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)
648             {
649                 /* Device wishes to transfer less than host requested */
650                 if ((transfer.remaining % MAX_PACKET_SIZE_EP0) == 0)
651                 {
652                     /* Transfer is a multiple of EP0 max packet size */
653                     transfer.zlp = true;
654                 }
655             }
656
657             /* IN stage */
658             controlIn();
659         }
660         else
661         {
662             /* OUT stage */
663             EP0read();
664         }
665     }
666     else
667     {
668         /* Status stage */
669         EP0write(NULL, 0);
670     }
671
672     return true;
673 }
674
675 void USBDevice::busReset(void)
676 {
677     device.state = DEFAULT;
678     device.configuration = 0;
679     device.suspended = false;
680
681     /* Call class / vendor specific busReset function */
682     USBCallback_busReset();
683 }
684
685 void USBDevice::EP0setupCallback(void)
686 {
687     /* Endpoint 0 setup event */
688     if (!controlSetup())
689     {
690         /* Protocol stall */
691         EP0stall();
692     }
693
694     /* Return true if an OUT data stage is expected */
695 }
696
697 void USBDevice::EP0out(void)
698 {
699     /* Endpoint 0 OUT data event */
700     if (!controlOut())
701     {
702         /* Protocol stall; this will stall both endpoints */
703         EP0stall();
704     }
705 }
706
707 void USBDevice::EP0in(void)
708 {
709 #ifdef DEBUG
710     printf("EP0IN\r\n");
711 #endif
712     /* Endpoint 0 IN data event */
713     if (!controlIn())
714     {
715         /* Protocol stall; this will stall both endpoints */
716         EP0stall();
717     }
718 }
719
720 bool USBDevice::configured(void)
721 {
722     /* Returns true if device is in the CONFIGURED state */
723     return (device.state == CONFIGURED);
724 }
725
726 void USBDevice::connect(bool blocking)
727 {
728     /* Connect device */
729     USBHAL::connect();
730
731     if (blocking) {
732         /* Block if not configured */
733         while (!configured());
734     }
735 }
736
737 void USBDevice::disconnect(void)
738 {
739     /* Disconnect device */
740     USBHAL::disconnect();
741     
742     /* Set initial device state */
743     device.state = POWERED;
744     device.configuration = 0;
745     device.suspended = false;
746 }
747
748 CONTROL_TRANSFER * USBDevice::getTransferPtr(void)
749 {
750     return &transfer;
751 }
752
753 bool USBDevice::addEndpoint(uint8_t endpoint, uint32_t maxPacket)
754 {
755     return realiseEndpoint(endpoint, maxPacket, 0);
756 }
757
758 bool USBDevice::addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket)
759 {
760     /* For interrupt endpoints only */
761     return realiseEndpoint(endpoint, maxPacket, RATE_FEEDBACK_MODE);
762 }
763
764 uint8_t * USBDevice::findDescriptor(uint8_t descriptorType)
765 {
766     /* Find a descriptor within the list of descriptors */
767     /* following a configuration descriptor. */
768     uint16_t wTotalLength;
769     uint8_t *ptr;
770
771     if (configurationDesc() == NULL)
772     {
773         return NULL;
774     }
775
776     /* Check this is a configuration descriptor */
777     if ((configurationDesc()[0] != CONFIGURATION_DESCRIPTOR_LENGTH) \
778             || (configurationDesc()[1] != CONFIGURATION_DESCRIPTOR))
779     {
780         return NULL;
781     }
782
783     wTotalLength = configurationDesc()[2] | (configurationDesc()[3] << 8);
784
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 */
788     {
789         return NULL;
790     }
791
792     /* Start at first descriptor after the configuration descriptor */
793     ptr = &(configurationDesc()[CONFIGURATION_DESCRIPTOR_LENGTH]);
794
795     do {
796         if (ptr[1] /* bDescriptorType */ == descriptorType)
797         {
798             /* Found */
799             return ptr;
800         }
801
802         /* Skip to next descriptor */
803         ptr += ptr[0]; /* bLength */
804     } while (ptr < (configurationDesc() + wTotalLength));
805
806     /* Reached end of the descriptors - not found */
807     return NULL;
808 }
809
810
811 void USBDevice::connectStateChanged(unsigned int connected)
812 {
813 }
814
815 void USBDevice::suspendStateChanged(unsigned int suspended)
816 {
817 }
818
819
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;
824
825     /* Set initial device state */
826     device.state = POWERED;
827     device.configuration = 0;
828     device.suspended = false;
829 };
830
831
832 bool USBDevice::readStart(uint8_t endpoint, uint32_t maxSize)
833 {
834     return endpointRead(endpoint, maxSize) == EP_PENDING;
835 }
836
837
838 bool USBDevice::write(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize)
839 {
840     EP_STATUS result;
841
842     if (size > maxSize)
843     {
844         return false;
845     }
846
847
848     if(!configured()) {
849         return false;
850     }
851
852     /* Send report */
853     result = endpointWrite(endpoint, buffer, size);
854
855     if (result != EP_PENDING)
856     {
857         return false;
858     }
859
860     /* Wait for completion */
861     do {
862         result = endpointWriteResult(endpoint);
863     } while ((result == EP_PENDING) && configured());
864
865     return (result == EP_COMPLETED);
866 }
867
868
869 bool USBDevice::writeNB(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize)
870 {
871     EP_STATUS result;
872
873     if (size > maxSize)
874     {
875         return false;
876     }
877
878     if(!configured()) {
879         return false;
880     }
881
882     /* Send report */
883     result = endpointWrite(endpoint, buffer, size);
884
885     if (result != EP_PENDING)
886     {
887         return false;
888     }
889
890     result = endpointWriteResult(endpoint);
891
892     return (result == EP_COMPLETED);
893 }
894
895
896
897 bool USBDevice::readEP(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize)
898 {
899     EP_STATUS result;
900
901     if(!configured()) {
902         return false;
903     }
904
905     /* Wait for completion */
906     do {
907         result = endpointReadResult(endpoint, buffer, size);
908     } while ((result == EP_PENDING) && configured());
909
910     return (result == EP_COMPLETED);
911 }
912
913
914 bool USBDevice::readEP_NB(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize)
915 {
916     EP_STATUS result;
917
918     if(!configured()) {
919         return false;
920     }
921
922     result = endpointReadResult(endpoint, buffer, size);
923
924     return (result == EP_COMPLETED);
925 }
926
927
928
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 */
949     };
950     return deviceDescriptor;
951 }
952
953 uint8_t * USBDevice::stringLangidDesc() {
954     static uint8_t stringLangidDescriptor[] = {
955         0x04,               /*bLength*/
956         STRING_DESCRIPTOR,  /*bDescriptorType 0x03*/
957         0x09,0x04,          /*bString Lang ID - 0x0409 - English*/
958     };
959     return stringLangidDescriptor;
960 }
961
962 uint8_t * USBDevice::stringImanufacturerDesc() {
963     static uint8_t stringImanufacturerDescriptor[] = {
964         0x12,                                            /*bLength*/
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*/
967     };
968     return stringImanufacturerDescriptor;
969 }
970
971 uint8_t * USBDevice::stringIserialDesc() {
972     static uint8_t stringIserialDescriptor[] = {
973         0x16,                                                           /*bLength*/
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*/
976     };
977     return stringIserialDescriptor;
978 }
979
980 uint8_t * USBDevice::stringIConfigurationDesc() {
981     static uint8_t stringIconfigurationDescriptor[] = {
982         0x06,               /*bLength*/
983         STRING_DESCRIPTOR,  /*bDescriptorType 0x03*/
984         '0',0,'1',0,        /*bString iConfiguration - 01*/
985     };
986     return stringIconfigurationDescriptor;
987 }
988
989 uint8_t * USBDevice::stringIinterfaceDesc() {
990     static uint8_t stringIinterfaceDescriptor[] = {
991         0x08,               /*bLength*/
992         STRING_DESCRIPTOR,  /*bDescriptorType 0x03*/
993         'U',0,'S',0,'B',0,  /*bString iInterface - USB*/
994     };
995     return stringIinterfaceDescriptor;
996 }
997
998 uint8_t * USBDevice::stringIproductDesc() {
999     static uint8_t stringIproductDescriptor[] = {
1000         0x16,                                                       /*bLength*/
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*/
1003     };
1004     return stringIproductDescriptor;
1005 }