STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
usbd_core.c
Go to the documentation of this file.
1/**
2 ******************************************************************************
3 * @file usbd_core.c
4 * @author MCD Application Team
5 * @brief This file provides all the USBD core functions.
6 ******************************************************************************
7 * @attention
8 *
9 * Copyright (c) 2015 STMicroelectronics.
10 * All rights reserved.
11 *
12 * This software is licensed under terms that can be found in the LICENSE file
13 * in the root directory of this software component.
14 * If no LICENSE file comes with this software, it is provided AS-IS.
15 *
16 ******************************************************************************
17 */
18
19/* Includes ------------------------------------------------------------------*/
20#include "usbd_core.h"
21
22#ifdef USE_USBD_COMPOSITE
23#include "usbd_composite_builder.h"
24#endif /* USE_USBD_COMPOSITE */
25
26/** @addtogroup STM32_USBD_DEVICE_LIBRARY
27 * @{
28 */
29
30
31/** @defgroup USBD_CORE
32 * @brief usbd core module
33 * @{
34 */
35
36/** @defgroup USBD_CORE_Private_TypesDefinitions
37 * @{
38 */
39
40/**
41 * @}
42 */
43
44
45/** @defgroup USBD_CORE_Private_Defines
46 * @{
47 */
48
49/**
50 * @}
51 */
52
53
54/** @defgroup USBD_CORE_Private_Macros
55 * @{
56 */
57
58/**
59 * @}
60 */
61
62
63/** @defgroup USBD_CORE_Private_FunctionPrototypes
64 * @{
65 */
66
67/**
68 * @}
69 */
70
71/** @defgroup USBD_CORE_Private_Variables
72 * @{
73 */
74
75/**
76 * @}
77 */
78
79
80/** @defgroup USBD_CORE_Private_Functions
81 * @{
82 */
83
84/**
85 * @brief USBD_Init
86 * Initialize the device stack and load the class driver
87 * @param pdev: device instance
88 * @param pdesc: Descriptor structure address
89 * @param id: Low level core index
90 * @retval status: USBD Status
91 */
93 USBD_DescriptorsTypeDef *pdesc, uint8_t id)
94{
96
97 /* Check whether the USB Host handle is valid */
98 if (pdev == NULL)
99 {
100#if (USBD_DEBUG_LEVEL > 1U)
101 USBD_ErrLog("Invalid Device handle");
102#endif /* (USBD_DEBUG_LEVEL > 1U) */
103 return USBD_FAIL;
104 }
105
106#ifdef USE_USBD_COMPOSITE
107 /* Parse the table of classes in use */
108 for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++)
109 {
110 /* Unlink previous class*/
111 pdev->pClass[i] = NULL;
112 pdev->pUserData[i] = NULL;
113
114 /* Set class as inactive */
115 pdev->tclasslist[i].Active = 0;
116 pdev->NumClasses = 0;
117 pdev->classId = 0;
118 }
119#else
120 /* Unlink previous class*/
121 pdev->pClass[0] = NULL;
122 pdev->pUserData[0] = NULL;
123#endif /* USE_USBD_COMPOSITE */
124
125 pdev->pConfDesc = NULL;
126
127 /* Assign USBD Descriptors */
128 if (pdesc != NULL)
129 {
130 pdev->pDesc = pdesc;
131 }
132
133 /* Set Device initial State */
135 pdev->id = id;
136
137 /* Initialize low level driver */
138 ret = USBD_LL_Init(pdev);
139
140 return ret;
141}
142
143/**
144 * @brief USBD_DeInit
145 * De-Initialize the device library
146 * @param pdev: device instance
147 * @retval status: USBD Status
148 */
150{
152
153 /* Disconnect the USB Device */
154 (void)USBD_LL_Stop(pdev);
155
156 /* Set Default State */
158
159#ifdef USE_USBD_COMPOSITE
160 /* Parse the table of classes in use */
161 for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++)
162 {
163 /* Check if current class is in use */
164 if ((pdev->tclasslist[i].Active) == 1U)
165 {
166 if (pdev->pClass[i] != NULL)
167 {
168 pdev->classId = i;
169 /* Free Class Resources */
170 pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config);
171 }
172 }
173 }
174#else
175 /* Free Class Resources */
176 if (pdev->pClass[0] != NULL)
177 {
178 pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config);
179 }
180
181 pdev->pUserData[0] = NULL;
182
183#endif /* USE_USBD_COMPOSITE */
184
185 /* Free Device descriptors resources */
186 pdev->pDesc = NULL;
187 pdev->pConfDesc = NULL;
188
189 /* DeInitialize low level driver */
190 ret = USBD_LL_DeInit(pdev);
191
192 return ret;
193}
194
195/**
196 * @brief USBD_RegisterClass
197 * Link class driver to Device Core.
198 * @param pdev: Device Handle
199 * @param pclass: Class handle
200 * @retval USBD Status
201 */
203{
204 uint16_t len = 0U;
205
206 if (pclass == NULL)
207 {
208#if (USBD_DEBUG_LEVEL > 1U)
209 USBD_ErrLog("Invalid Class handle");
210#endif /* (USBD_DEBUG_LEVEL > 1U) */
211 return USBD_FAIL;
212 }
213
214 /* link the class to the USB Device handle */
215 pdev->pClass[0] = pclass;
216
217 /* Get Device Configuration Descriptor */
218#ifdef USE_USB_HS
219 if (pdev->pClass[pdev->classId]->GetHSConfigDescriptor != NULL)
220 {
221 pdev->pConfDesc = (void *)pdev->pClass[pdev->classId]->GetHSConfigDescriptor(&len);
222 }
223#else /* Default USE_USB_FS */
224 if (pdev->pClass[pdev->classId]->GetFSConfigDescriptor != NULL)
225 {
226 pdev->pConfDesc = (void *)pdev->pClass[pdev->classId]->GetFSConfigDescriptor(&len);
227 }
228#endif /* USE_USB_FS */
229
230 /* Increment the NumClasses */
231 pdev->NumClasses++;
232
233 return USBD_OK;
234}
235
236#ifdef USE_USBD_COMPOSITE
237/**
238 * @brief USBD_RegisterClassComposite
239 * Link class driver to Device Core.
240 * @param pdev : Device Handle
241 * @param pclass: Class handle
242 * @param classtype: Class type
243 * @param EpAddr: Endpoint Address handle
244 * @retval USBD Status
245 */
246USBD_StatusTypeDef USBD_RegisterClassComposite(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass,
247 USBD_CompositeClassTypeDef classtype, uint8_t *EpAddr)
248{
250 uint16_t len = 0U;
251
253 {
254 if ((uint32_t)pclass != 0U)
255 {
256 /* Link the class to the USB Device handle */
257 pdev->pClass[pdev->classId] = pclass;
258 ret = USBD_OK;
259
260 pdev->tclasslist[pdev->classId].EpAdd = EpAddr;
261
262 /* Call the composite class builder */
263 (void)USBD_CMPSIT_AddClass(pdev, pclass, classtype, 0);
264
265 /* Increment the ClassId for the next occurrence */
266 pdev->classId ++;
267 pdev->NumClasses ++;
268 }
269 else
270 {
271#if (USBD_DEBUG_LEVEL > 1U)
272 USBD_ErrLog("Invalid Class handle");
273#endif /* (USBD_DEBUG_LEVEL > 1U) */
274 ret = USBD_FAIL;
275 }
276 }
277
278 if (ret == USBD_OK)
279 {
280 /* Get Device Configuration Descriptor */
281#ifdef USE_USB_HS
282 pdev->pConfDesc = USBD_CMPSIT.GetHSConfigDescriptor(&len);
283#else /* Default USE_USB_FS */
284 pdev->pConfDesc = USBD_CMPSIT.GetFSConfigDescriptor(&len);
285#endif /* USE_USB_FS */
286 }
287
288 return ret;
289}
290
291/**
292 * @brief USBD_UnRegisterClassComposite
293 * UnLink all composite class drivers from Device Core.
294 * @param pdev: Device Handle
295 * @retval USBD Status
296 */
297USBD_StatusTypeDef USBD_UnRegisterClassComposite(USBD_HandleTypeDef *pdev)
298{
300 uint8_t idx1;
301 uint8_t idx2;
302
303 /* Unroll all activated classes */
304 for (idx1 = 0; idx1 < pdev->NumClasses; idx1++)
305 {
306 /* Check if the class correspond to the requested type and if it is active */
307 if (pdev->tclasslist[idx1].Active == 1U)
308 {
309 /* Set the new class ID */
310 pdev->classId = idx1;
311
312 /* Free resources used by the selected class */
313 if (pdev->pClass[pdev->classId] != NULL)
314 {
315 /* Free Class Resources */
316 if (pdev->pClass[pdev->classId]->DeInit(pdev, (uint8_t)pdev->dev_config) != 0U)
317 {
318#if (USBD_DEBUG_LEVEL > 1U)
319 USBD_ErrLog("Class DeInit didn't succeed!, can't unregister selected class");
320#endif /* (USBD_DEBUG_LEVEL > 1U) */
321
322 ret = USBD_FAIL;
323 }
324 }
325
326 /* Free the class pointer */
327 pdev->pClass[pdev->classId] = NULL;
328
329 /* Free the class location in classes table and reset its parameters to zero */
330 pdev->tclasslist[pdev->classId].ClassType = CLASS_TYPE_NONE;
331 pdev->tclasslist[pdev->classId].ClassId = 0U;
332 pdev->tclasslist[pdev->classId].Active = 0U;
333 pdev->tclasslist[pdev->classId].NumEps = 0U;
334 pdev->tclasslist[pdev->classId].NumIf = 0U;
335 pdev->tclasslist[pdev->classId].CurrPcktSze = 0U;
336
337 for (idx2 = 0U; idx2 < USBD_MAX_CLASS_ENDPOINTS; idx2++)
338 {
339 pdev->tclasslist[pdev->classId].Eps[idx2].add = 0U;
340 pdev->tclasslist[pdev->classId].Eps[idx2].type = 0U;
341 pdev->tclasslist[pdev->classId].Eps[idx2].size = 0U;
342 pdev->tclasslist[pdev->classId].Eps[idx2].is_used = 0U;
343 }
344
345 for (idx2 = 0U; idx2 < USBD_MAX_CLASS_INTERFACES; idx2++)
346 {
347 pdev->tclasslist[pdev->classId].Ifs[idx2] = 0U;
348 }
349 }
350 }
351
352 /* Reset the configuration descriptor */
353 (void)USBD_CMPST_ClearConfDesc(pdev);
354
355 /* Reset the class ID and number of classes */
356 pdev->classId = 0U;
357 pdev->NumClasses = 0U;
358
359 return ret;
360}
361#endif /* USE_USBD_COMPOSITE */
362
363#if (USBD_USER_REGISTER_CALLBACK == 1U)
364/**
365 * @brief USBD_RegisterDevStateCallback
366 * @param pdev : Device Handle
367 * @param pUserCallback: User Callback
368 * @retval USBD Status
369 */
370USBD_StatusTypeDef USBD_RegisterDevStateCallback(USBD_HandleTypeDef *pdev, USBD_DevStateCallbackTypeDef pUserCallback)
371{
372 pdev->DevStateCallback = pUserCallback;
373
374 return USBD_OK;
375}
376#endif /* USBD_USER_REGISTER_CALLBACK */
377
378/**
379 * @brief USBD_Start
380 * Start the USB Device Core.
381 * @param pdev: Device Handle
382 * @retval USBD Status
383 */
385{
386#ifdef USE_USBD_COMPOSITE
387 pdev->classId = 0U;
388#endif /* USE_USBD_COMPOSITE */
389
390 /* Start the low level driver */
391 return USBD_LL_Start(pdev);
392}
393
394/**
395 * @brief USBD_Stop
396 * Stop the USB Device Core.
397 * @param pdev: Device Handle
398 * @retval USBD Status
399 */
401{
402 /* Disconnect USB Device */
403 (void)USBD_LL_Stop(pdev);
404
405 /* Free Class Resources */
406#ifdef USE_USBD_COMPOSITE
407 /* Parse the table of classes in use */
408 for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++)
409 {
410 /* Check if current class is in use */
411 if ((pdev->tclasslist[i].Active) == 1U)
412 {
413 if (pdev->pClass[i] != NULL)
414 {
415 pdev->classId = i;
416 /* Free Class Resources */
417 (void)pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config);
418 }
419 }
420 }
421
422 /* Reset the class ID */
423 pdev->classId = 0U;
424#else
425 if (pdev->pClass[0] != NULL)
426 {
427 (void)pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config);
428 }
429#endif /* USE_USBD_COMPOSITE */
430
431 return USBD_OK;
432}
433
434/**
435 * @brief USBD_RunTestMode
436 * Launch test mode process
437 * @param pdev: device instance
438 * @retval status
439 */
441{
442#ifdef USBD_HS_TESTMODE_ENABLE
444
445 /* Run USB HS test mode */
446 ret = USBD_LL_SetTestMode(pdev, pdev->dev_test_mode);
447
448 return ret;
449#else
450 /* Prevent unused argument compilation warning */
451 UNUSED(pdev);
452
453 return USBD_OK;
454#endif /* USBD_HS_TESTMODE_ENABLE */
455}
456
457/**
458 * @brief USBD_SetClassConfig
459 * Configure device and start the interface
460 * @param pdev: device instance
461 * @param cfgidx: configuration index
462 * @retval status
463 */
464
466{
468
469#ifdef USE_USBD_COMPOSITE
470 /* Parse the table of classes in use */
471 for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++)
472 {
473 /* Check if current class is in use */
474 if ((pdev->tclasslist[i].Active) == 1U)
475 {
476 if (pdev->pClass[i] != NULL)
477 {
478 pdev->classId = i;
479 /* Set configuration and Start the Class*/
480 if (pdev->pClass[i]->Init(pdev, cfgidx) != 0U)
481 {
482 ret = USBD_FAIL;
483 }
484 }
485 }
486 }
487#else
488 if (pdev->pClass[0] != NULL)
489 {
490 /* Set configuration and Start the Class */
491 ret = (USBD_StatusTypeDef)pdev->pClass[0]->Init(pdev, cfgidx);
492 }
493#endif /* USE_USBD_COMPOSITE */
494
495 return ret;
496}
497
498/**
499 * @brief USBD_ClrClassConfig
500 * Clear current configuration
501 * @param pdev: device instance
502 * @param cfgidx: configuration index
503 * @retval status
504 */
506{
508
509#ifdef USE_USBD_COMPOSITE
510 /* Parse the table of classes in use */
511 for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++)
512 {
513 /* Check if current class is in use */
514 if ((pdev->tclasslist[i].Active) == 1U)
515 {
516 if (pdev->pClass[i] != NULL)
517 {
518 pdev->classId = i;
519 /* Clear configuration and De-initialize the Class process */
520 if (pdev->pClass[i]->DeInit(pdev, cfgidx) != 0U)
521 {
522 ret = USBD_FAIL;
523 }
524 }
525 }
526 }
527#else
528 /* Clear configuration and De-initialize the Class process */
529 if (pdev->pClass[0]->DeInit(pdev, cfgidx) != 0U)
530 {
531 ret = USBD_FAIL;
532 }
533#endif /* USE_USBD_COMPOSITE */
534
535 return ret;
536}
537
538
539/**
540 * @brief USBD_LL_SetupStage
541 * Handle the setup stage
542 * @param pdev: device instance
543 * @param psetup: setup packet buffer pointer
544 * @retval status
545 */
547{
549
550 USBD_ParseSetupRequest(&pdev->request, psetup);
551
553
554 pdev->ep0_data_len = pdev->request.wLength;
555
556 switch (pdev->request.bmRequest & 0x1FU)
557 {
559 ret = USBD_StdDevReq(pdev, &pdev->request);
560 break;
561
563 ret = USBD_StdItfReq(pdev, &pdev->request);
564 break;
565
567 ret = USBD_StdEPReq(pdev, &pdev->request);
568 break;
569
570 default:
571 ret = USBD_LL_StallEP(pdev, (pdev->request.bmRequest & 0x80U));
572 break;
573 }
574
575 return ret;
576}
577
578/**
579 * @brief USBD_LL_DataOutStage
580 * Handle data OUT stage
581 * @param pdev: device instance
582 * @param epnum: endpoint index
583 * @param pdata: data pointer
584 * @retval status
585 */
587 uint8_t epnum, uint8_t *pdata)
588{
591 uint8_t idx;
592
593 UNUSED(pdata);
594
595 if (epnum == 0U)
596 {
597 pep = &pdev->ep_out[0];
598
599 if (pdev->ep0_state == USBD_EP0_DATA_OUT)
600 {
601 if (pep->rem_length > pep->maxpacket)
602 {
603 pep->rem_length -= pep->maxpacket;
604 pep->pbuffer += pep->maxpacket;
605
606 (void)USBD_CtlContinueRx(pdev, pep->pbuffer, MAX(pep->rem_length, pep->maxpacket));
607 }
608 else
609 {
610 /* Find the class ID relative to the current request */
611 switch (pdev->request.bmRequest & 0x1FU)
612 {
614 /* Device requests must be managed by the first instantiated class
615 (or duplicated by all classes for simplicity) */
616 idx = 0U;
617 break;
618
620 idx = USBD_CoreFindIF(pdev, LOBYTE(pdev->request.wIndex));
621 break;
622
624 idx = USBD_CoreFindEP(pdev, LOBYTE(pdev->request.wIndex));
625 break;
626
627 default:
628 /* Back to the first class in case of doubt */
629 idx = 0U;
630 break;
631 }
632
633 if (idx < USBD_MAX_SUPPORTED_CLASS)
634 {
635 /* Setup the class ID and route the request to the relative class function */
636 if (pdev->dev_state == USBD_STATE_CONFIGURED)
637 {
638 if (pdev->pClass[idx]->EP0_RxReady != NULL)
639 {
640 pdev->classId = idx;
641 pdev->pClass[idx]->EP0_RxReady(pdev);
642 }
643 }
644 }
645
646 (void)USBD_CtlSendStatus(pdev);
647 }
648 }
649 }
650 else
651 {
652 /* Get the class index relative to this interface */
653 idx = USBD_CoreFindEP(pdev, (epnum & 0x7FU));
654
655 if (((uint16_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS))
656 {
657 /* Call the class data out function to manage the request */
658 if (pdev->dev_state == USBD_STATE_CONFIGURED)
659 {
660 if (pdev->pClass[idx]->DataOut != NULL)
661 {
662 pdev->classId = idx;
663 ret = (USBD_StatusTypeDef)pdev->pClass[idx]->DataOut(pdev, epnum);
664 }
665 }
666 if (ret != USBD_OK)
667 {
668 return ret;
669 }
670 }
671 }
672
673 return USBD_OK;
674}
675
676/**
677 * @brief USBD_LL_DataInStage
678 * Handle data in stage
679 * @param pdev: device instance
680 * @param epnum: endpoint index
681 * @param pdata: data pointer
682 * @retval status
683 */
685 uint8_t epnum, uint8_t *pdata)
686{
689 uint8_t idx;
690
691 UNUSED(pdata);
692
693 if (epnum == 0U)
694 {
695 pep = &pdev->ep_in[0];
696
697 if (pdev->ep0_state == USBD_EP0_DATA_IN)
698 {
699 if (pep->rem_length > pep->maxpacket)
700 {
701 pep->rem_length -= pep->maxpacket;
702 pep->pbuffer += pep->maxpacket;
703
704 (void)USBD_CtlContinueSendData(pdev, pep->pbuffer, pep->rem_length);
705
706 /* Prepare endpoint for premature end of transfer */
707 (void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
708 }
709 else
710 {
711 /* last packet is MPS multiple, so send ZLP packet */
712 if ((pep->maxpacket == pep->rem_length) &&
713 (pep->total_length >= pep->maxpacket) &&
714 (pep->total_length < pdev->ep0_data_len))
715 {
716 (void)USBD_CtlContinueSendData(pdev, NULL, 0U);
717 pdev->ep0_data_len = 0U;
718
719 /* Prepare endpoint for premature end of transfer */
720 (void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
721 }
722 else
723 {
724 if (pdev->dev_state == USBD_STATE_CONFIGURED)
725 {
726 if (pdev->pClass[0]->EP0_TxSent != NULL)
727 {
728 pdev->classId = 0U;
729 pdev->pClass[0]->EP0_TxSent(pdev);
730 }
731 }
732 (void)USBD_LL_StallEP(pdev, 0x80U);
733 (void)USBD_CtlReceiveStatus(pdev);
734 }
735 }
736 }
737
738 if (pdev->dev_test_mode != 0U)
739 {
740 (void)USBD_RunTestMode(pdev);
741 pdev->dev_test_mode = 0U;
742 }
743 }
744 else
745 {
746 /* Get the class index relative to this interface */
747 idx = USBD_CoreFindEP(pdev, ((uint8_t)epnum | 0x80U));
748
749 if (((uint16_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS))
750 {
751 /* Call the class data out function to manage the request */
752 if (pdev->dev_state == USBD_STATE_CONFIGURED)
753 {
754 if (pdev->pClass[idx]->DataIn != NULL)
755 {
756 pdev->classId = idx;
757 ret = (USBD_StatusTypeDef)pdev->pClass[idx]->DataIn(pdev, epnum);
758
759 if (ret != USBD_OK)
760 {
761 return ret;
762 }
763 }
764 }
765 }
766 }
767
768 return USBD_OK;
769}
770
771/**
772 * @brief USBD_LL_Reset
773 * Handle Reset event
774 * @param pdev: device instance
775 * @retval status
776 */
778{
780
781 /* Upon Reset call user call back */
783 pdev->ep0_state = USBD_EP0_IDLE;
784 pdev->dev_config = 0U;
785 pdev->dev_remote_wakeup = 0U;
786 pdev->dev_test_mode = 0U;
787
788#ifdef USE_USBD_COMPOSITE
789 /* Parse the table of classes in use */
790 for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++)
791 {
792 /* Check if current class is in use */
793 if ((pdev->tclasslist[i].Active) == 1U)
794 {
795 if (pdev->pClass[i] != NULL)
796 {
797 pdev->classId = i;
798 /* Clear configuration and De-initialize the Class process*/
799
800 if (pdev->pClass[i]->DeInit != NULL)
801 {
802 if (pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config) != USBD_OK)
803 {
804 ret = USBD_FAIL;
805 }
806 }
807 }
808 }
809 }
810#else
811
812 if (pdev->pClass[0] != NULL)
813 {
814 if (pdev->pClass[0]->DeInit != NULL)
815 {
816 if (pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config) != USBD_OK)
817 {
818 ret = USBD_FAIL;
819 }
820 }
821 }
822#endif /* USE_USBD_COMPOSITE */
823
824 /* Open EP0 OUT */
826 pdev->ep_out[0x00U & 0xFU].is_used = 1U;
827
829
830 /* Open EP0 IN */
832 pdev->ep_in[0x80U & 0xFU].is_used = 1U;
833
835
836 return ret;
837}
838
839/**
840 * @brief USBD_LL_SetSpeed
841 * Handle Reset event
842 * @param pdev: device instance
843 * @retval status
844 */
846 USBD_SpeedTypeDef speed)
847{
848 pdev->dev_speed = speed;
849
850 return USBD_OK;
851}
852
853/**
854 * @brief USBD_LL_Suspend
855 * Handle Suspend event
856 * @param pdev: device instance
857 * @retval status
858 */
860{
861 if (pdev->dev_state != USBD_STATE_SUSPENDED)
862 {
863 pdev->dev_old_state = pdev->dev_state;
864 }
865
867
868 return USBD_OK;
869}
870
871/**
872 * @brief USBD_LL_Resume
873 * Handle Resume event
874 * @param pdev: device instance
875 * @retval status
876 */
878{
879 if (pdev->dev_state == USBD_STATE_SUSPENDED)
880 {
881 pdev->dev_state = pdev->dev_old_state;
882 }
883
884 return USBD_OK;
885}
886
887/**
888 * @brief USBD_LL_SOF
889 * Handle SOF event
890 * @param pdev: device instance
891 * @retval status
892 */
894{
895 /* The SOF event can be distributed for all classes that support it */
896 if (pdev->dev_state == USBD_STATE_CONFIGURED)
897 {
898#ifdef USE_USBD_COMPOSITE
899 /* Parse the table of classes in use */
900 for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++)
901 {
902 /* Check if current class is in use */
903 if ((pdev->tclasslist[i].Active) == 1U)
904 {
905 if (pdev->pClass[i] != NULL)
906 {
907 if (pdev->pClass[i]->SOF != NULL)
908 {
909 pdev->classId = i;
910 (void)pdev->pClass[i]->SOF(pdev);
911 }
912 }
913 }
914 }
915#else
916 if (pdev->pClass[0] != NULL)
917 {
918 if (pdev->pClass[0]->SOF != NULL)
919 {
920 (void)pdev->pClass[0]->SOF(pdev);
921 }
922 }
923#endif /* USE_USBD_COMPOSITE */
924 }
925
926 return USBD_OK;
927}
928
929/**
930 * @brief USBD_LL_IsoINIncomplete
931 * Handle iso in incomplete event
932 * @param pdev: device instance
933 * @param epnum: Endpoint number
934 * @retval status
935 */
937 uint8_t epnum)
938{
939 if (pdev->pClass[pdev->classId] == NULL)
940 {
941 return USBD_FAIL;
942 }
943
944 if (pdev->dev_state == USBD_STATE_CONFIGURED)
945 {
946 if (pdev->pClass[pdev->classId]->IsoINIncomplete != NULL)
947 {
948 (void)pdev->pClass[pdev->classId]->IsoINIncomplete(pdev, epnum);
949 }
950 }
951
952 return USBD_OK;
953}
954
955/**
956 * @brief USBD_LL_IsoOUTIncomplete
957 * Handle iso out incomplete event
958 * @param pdev: device instance
959 * @param epnum: Endpoint number
960 * @retval status
961 */
963 uint8_t epnum)
964{
965 if (pdev->pClass[pdev->classId] == NULL)
966 {
967 return USBD_FAIL;
968 }
969
970 if (pdev->dev_state == USBD_STATE_CONFIGURED)
971 {
972 if (pdev->pClass[pdev->classId]->IsoOUTIncomplete != NULL)
973 {
974 (void)pdev->pClass[pdev->classId]->IsoOUTIncomplete(pdev, epnum);
975 }
976 }
977
978 return USBD_OK;
979}
980
981/**
982 * @brief USBD_LL_DevConnected
983 * Handle device connection event
984 * @param pdev: device instance
985 * @retval status
986 */
988{
989 /* Prevent unused argument compilation warning */
990 UNUSED(pdev);
991
992 return USBD_OK;
993}
994
995/**
996 * @brief USBD_LL_DevDisconnected
997 * Handle device disconnection event
998 * @param pdev: device instance
999 * @retval status
1000 */
1002{
1004
1005 /* Free Class Resources */
1007
1008#ifdef USE_USBD_COMPOSITE
1009 /* Parse the table of classes in use */
1010 for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++)
1011 {
1012 /* Check if current class is in use */
1013 if ((pdev->tclasslist[i].Active) == 1U)
1014 {
1015 if (pdev->pClass[i] != NULL)
1016 {
1017 pdev->classId = i;
1018 /* Clear configuration and De-initialize the Class process*/
1019 if (pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config) != 0U)
1020 {
1021 ret = USBD_FAIL;
1022 }
1023 }
1024 }
1025 }
1026#else
1027 if (pdev->pClass[0] != NULL)
1028 {
1029 if (pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config) != 0U)
1030 {
1031 ret = USBD_FAIL;
1032 }
1033 }
1034#endif /* USE_USBD_COMPOSITE */
1035
1036 return ret;
1037}
1038
1039/**
1040 * @brief USBD_CoreFindIF
1041 * return the class index relative to the selected interface
1042 * @param pdev: device instance
1043 * @param index : selected interface number
1044 * @retval index of the class using the selected interface number. OxFF if no class found.
1045 */
1046uint8_t USBD_CoreFindIF(USBD_HandleTypeDef *pdev, uint8_t index)
1047{
1048#ifdef USE_USBD_COMPOSITE
1049 /* Parse the table of classes in use */
1050 for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++)
1051 {
1052 /* Check if current class is in use */
1053 if ((pdev->tclasslist[i].Active) == 1U)
1054 {
1055 /* Parse all interfaces listed in the current class */
1056 for (uint32_t j = 0U; j < pdev->tclasslist[i].NumIf; j++)
1057 {
1058 /* Check if requested Interface matches the current class interface */
1059 if (pdev->tclasslist[i].Ifs[j] == index)
1060 {
1061 if (pdev->pClass[i]->Setup != NULL)
1062 {
1063 return (uint8_t)i;
1064 }
1065 }
1066 }
1067 }
1068 }
1069
1070 return 0xFFU;
1071#else
1072 UNUSED(pdev);
1073 UNUSED(index);
1074
1075 return 0x00U;
1076#endif /* USE_USBD_COMPOSITE */
1077}
1078
1079/**
1080 * @brief USBD_CoreFindEP
1081 * return the class index relative to the selected endpoint
1082 * @param pdev: device instance
1083 * @param index : selected endpoint number
1084 * @retval index of the class using the selected endpoint number. 0xFF if no class found.
1085 */
1086uint8_t USBD_CoreFindEP(USBD_HandleTypeDef *pdev, uint8_t index)
1087{
1088#ifdef USE_USBD_COMPOSITE
1089 /* Parse the table of classes in use */
1090 for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++)
1091 {
1092 /* Check if current class is in use */
1093 if ((pdev->tclasslist[i].Active) == 1U)
1094 {
1095 /* Parse all endpoints listed in the current class */
1096 for (uint32_t j = 0U; j < pdev->tclasslist[i].NumEps; j++)
1097 {
1098 /* Check if requested endpoint matches the current class endpoint */
1099 if (pdev->tclasslist[i].Eps[j].add == index)
1100 {
1101 if (pdev->pClass[i]->Setup != NULL)
1102 {
1103 return (uint8_t)i;
1104 }
1105 }
1106 }
1107 }
1108 }
1109
1110 return 0xFFU;
1111#else
1112 UNUSED(pdev);
1113 UNUSED(index);
1114
1115 return 0x00U;
1116#endif /* USE_USBD_COMPOSITE */
1117}
1118
1119#ifdef USE_USBD_COMPOSITE
1120/**
1121 * @brief USBD_CoreGetEPAdd
1122 * Get the endpoint address relative to a selected class
1123 * @param pdev: device instance
1124 * @param ep_dir: USBD_EP_IN or USBD_EP_OUT
1125 * @param ep_type: USBD_EP_TYPE_CTRL, USBD_EP_TYPE_ISOC, USBD_EP_TYPE_BULK or USBD_EP_TYPE_INTR
1126 * @param ClassId: The Class ID
1127 * @retval Address of the selected endpoint or 0xFFU if no endpoint found.
1128 */
1129uint8_t USBD_CoreGetEPAdd(USBD_HandleTypeDef *pdev, uint8_t ep_dir, uint8_t ep_type, uint8_t ClassId)
1130{
1131 uint8_t idx;
1132
1133 /* Find the EP address in the selected class table */
1134 for (idx = 0; idx < pdev->tclasslist[ClassId].NumEps; idx++)
1135 {
1136 if (((pdev->tclasslist[ClassId].Eps[idx].add & USBD_EP_IN) == ep_dir) && \
1137 (pdev->tclasslist[ClassId].Eps[idx].type == ep_type) && \
1138 (pdev->tclasslist[ClassId].Eps[idx].is_used != 0U))
1139 {
1140 return (pdev->tclasslist[ClassId].Eps[idx].add);
1141 }
1142 }
1143
1144 /* If reaching this point, then no endpoint was found */
1145 return 0xFFU;
1146}
1147#endif /* USE_USBD_COMPOSITE */
1148
1149/**
1150 * @brief USBD_GetEpDesc
1151 * This function return the Endpoint descriptor
1152 * @param pdev: device instance
1153 * @param pConfDesc: pointer to Bos descriptor
1154 * @param EpAddr: endpoint address
1155 * @retval pointer to video endpoint descriptor
1156 */
1157void *USBD_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr)
1158{
1159 USBD_DescHeaderTypeDef *pdesc = (USBD_DescHeaderTypeDef *)(void *)pConfDesc;
1160 USBD_ConfigDescTypeDef *desc = (USBD_ConfigDescTypeDef *)(void *)pConfDesc;
1161 USBD_EpDescTypeDef *pEpDesc = NULL;
1162 uint16_t ptr;
1163
1164 if (desc->wTotalLength > desc->bLength)
1165 {
1166 ptr = desc->bLength;
1167
1168 while (ptr < desc->wTotalLength)
1169 {
1170 pdesc = USBD_GetNextDesc((uint8_t *)pdesc, &ptr);
1171
1172 if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT)
1173 {
1174 pEpDesc = (USBD_EpDescTypeDef *)(void *)pdesc;
1175
1176 if (pEpDesc->bEndpointAddress == EpAddr)
1177 {
1178 break;
1179 }
1180 else
1181 {
1182 pEpDesc = NULL;
1183 }
1184 }
1185 }
1186 }
1187
1188 return (void *)pEpDesc;
1189}
1190
1191/**
1192 * @brief USBD_GetNextDesc
1193 * This function return the next descriptor header
1194 * @param buf: Buffer where the descriptor is available
1195 * @param ptr: data pointer inside the descriptor
1196 * @retval next header
1197 */
1199{
1200 USBD_DescHeaderTypeDef *pnext = (USBD_DescHeaderTypeDef *)(void *)pbuf;
1201
1202 *ptr += pnext->bLength;
1203 pnext = (USBD_DescHeaderTypeDef *)(void *)(pbuf + pnext->bLength);
1204
1205 return (pnext);
1206}
1207
1208/**
1209 * @}
1210 */
1211
1212
1213/**
1214 * @}
1215 */
1216
1217
1218/**
1219 * @}
1220 */
1221
#define USBD_ErrLog(...)
Definition usbd_conf.h:123
USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
Initializes the low level portion of the device driver.
Definition usbd_conf.c:323
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev)
Starts the low level portion of the device driver.
Definition usbd_conf.c:393
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size)
Prepares an endpoint for reception.
Definition usbd_conf.c:580
USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev)
De-Initializes the low level portion of the device driver.
Definition usbd_conf.c:376
USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
Sets a Stall condition on an endpoint of the Low Level Driver.
Definition usbd_conf.c:484
USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev)
Stops the low level portion of the device driver.
Definition usbd_conf.c:410
USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps)
Opens an endpoint of the low level driver.
Definition usbd_conf.c:430
USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev)
USBD_LL_DevDisconnected Handle device disconnection event.
Definition usbd_core.c:1001
USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata)
USBD_LL_DataInStage Handle data in stage.
Definition usbd_core.c:684
USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
USBD_ClrClassConfig Clear current configuration.
Definition usbd_core.c:505
USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
USBD_SetClassConfig Configure device and start the interface.
Definition usbd_core.c:465
USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata)
USBD_LL_DataOutStage Handle data OUT stage.
Definition usbd_core.c:586
USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum)
USBD_LL_IsoOUTIncomplete Handle iso out incomplete event.
Definition usbd_core.c:962
USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev)
USBD_RunTestMode Launch test mode process.
Definition usbd_core.c:440
USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass)
USBD_RegisterClass Link class driver to Device Core.
Definition usbd_core.c:202
USBD_DescHeaderTypeDef * USBD_GetNextDesc(uint8_t *pbuf, uint16_t *ptr)
USBD_GetNextDesc This function return the next descriptor header.
Definition usbd_core.c:1198
USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev)
USBD_Start Start the USB Device Core.
Definition usbd_core.c:384
uint8_t USBD_CoreFindEP(USBD_HandleTypeDef *pdev, uint8_t index)
USBD_CoreFindEP return the class index relative to the selected endpoint.
Definition usbd_core.c:1086
USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev)
USBD_Stop Stop the USB Device Core.
Definition usbd_core.c:400
uint8_t USBD_CoreFindIF(USBD_HandleTypeDef *pdev, uint8_t index)
USBD_CoreFindIF return the class index relative to the selected interface.
Definition usbd_core.c:1046
USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum)
USBD_LL_IsoINIncomplete Handle iso in incomplete event.
Definition usbd_core.c:936
USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev)
USBD_LL_Suspend Handle Suspend event.
Definition usbd_core.c:859
USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev)
USBD_LL_Reset Handle Reset event.
Definition usbd_core.c:777
USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev)
USBD_DeInit De-Initialize the device library.
Definition usbd_core.c:149
USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed)
USBD_LL_SetSpeed Handle Reset event.
Definition usbd_core.c:845
USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev)
USBD_LL_DevConnected Handle device connection event.
Definition usbd_core.c:987
USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup)
USBD_LL_SetupStage Handle the setup stage.
Definition usbd_core.c:546
USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev)
USBD_LL_SOF Handle SOF event.
Definition usbd_core.c:893
USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev)
USBD_LL_Resume Handle Resume event.
Definition usbd_core.c:877
USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id)
USBD_Init Initialize the device stack and load the class driver.
Definition usbd_core.c:92
void * USBD_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr)
USBD_GetEpDesc This function return the Endpoint descriptor.
Definition usbd_core.c:1157
#define LOBYTE(x)
Definition usbd_def.h:442
#define MAX(a, b)
Definition usbd_def.h:454
struct _USBD_HandleTypeDef USBD_HandleTypeDef
USBD_SpeedTypeDef
Definition usbd_def.h:272
struct _Device_cb USBD_ClassTypeDef
USBD_StatusTypeDef
Definition usbd_def.h:280
@ USBD_FAIL
Definition usbd_def.h:284
@ USBD_OK
Definition usbd_def.h:281
USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev)
USBD_CtlSendStatus send zero lzngth packet on the ctl pipe.
Definition usbd_ioreq.c:173
USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len)
USBD_CtlContinueSendData continue sending data on the ctl pipe.
Definition usbd_ioreq.c:114
USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len)
USBD_CtlContinueRx continue receive data on the ctl pipe.
Definition usbd_ioreq.c:159
USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev)
USBD_CtlReceiveStatus receive zero lzngth packet on the ctl pipe.
Definition usbd_ioreq.c:190
USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
USBD_StdEPReq Handle standard usb endpoint requests.
void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata)
USBD_ParseSetupRequest Copy buffer into setup structure.
USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
USBD_StdItfReq Handle standard usb interface requests.
USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
USBD_StdDevReq Handle standard usb device requests.
#define USBD_EP0_IDLE
Definition usbd_def.h:167
#define NULL
Definition usbd_def.h:44
#define USBD_EP0_DATA_IN
Definition usbd_def.h:169
#define USB_MAX_EP0_SIZE
Definition usbd_def.h:157
#define USBD_STATE_DEFAULT
Definition usbd_def.h:160
#define USBD_EP_TYPE_CTRL
Definition usbd_def.h:175
#define USBD_STATE_CONFIGURED
Definition usbd_def.h:162
#define USBD_EP0_DATA_OUT
Definition usbd_def.h:170
#define USB_REQ_RECIPIENT_DEVICE
Definition usbd_def.h:114
#define USBD_EP0_SETUP
Definition usbd_def.h:168
#define USB_DESC_TYPE_ENDPOINT
Definition usbd_def.h:135
#define USBD_MAX_SUPPORTED_CLASS
Definition usbd_def.h:61
#define USBD_MAX_CLASS_ENDPOINTS
Definition usbd_def.h:66
#define USBD_STATE_SUSPENDED
Definition usbd_def.h:163
#define USB_REQ_RECIPIENT_ENDPOINT
Definition usbd_def.h:116
#define USBD_MAX_CLASS_INTERFACES
Definition usbd_def.h:70
#define USB_REQ_RECIPIENT_INTERFACE
Definition usbd_def.h:115
*brief write string representation of the JSON pointer to stream *sa const json_pointer & ptr
Definition json.hpp:13895
#define UNUSED(x)
uint32_t total_length
Definition usbd_def.h:308
uint8_t(* IsoINIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum)
Definition usbd_def.h:257
uint8_t *(* GetFSConfigDescriptor)(uint16_t *length)
Definition usbd_def.h:261
uint8_t(* EP0_RxReady)(struct _USBD_HandleTypeDef *pdev)
Definition usbd_def.h:252
uint8_t *(* GetHSConfigDescriptor)(uint16_t *length)
Definition usbd_def.h:260
uint8_t(* DataIn)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum)
Definition usbd_def.h:254
uint8_t(* Init)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx)
Definition usbd_def.h:247
uint8_t(* IsoOUTIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum)
Definition usbd_def.h:258
uint8_t(* DeInit)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx)
Definition usbd_def.h:248
uint8_t(* Setup)(struct _USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
Definition usbd_def.h:250
uint8_t(* DataOut)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum)
Definition usbd_def.h:255
uint8_t(* EP0_TxSent)(struct _USBD_HandleTypeDef *pdev)
Definition usbd_def.h:251
uint8_t(* SOF)(struct _USBD_HandleTypeDef *pdev)
Definition usbd_def.h:256
__IO uint8_t dev_old_state
Definition usbd_def.h:373
USBD_EndpointTypeDef ep_in[16]
Definition usbd_def.h:368
USBD_EndpointTypeDef ep_out[16]
Definition usbd_def.h:369
uint32_t dev_remote_wakeup
Definition usbd_def.h:377
uint32_t dev_config
Definition usbd_def.h:364
USBD_DescriptorsTypeDef * pDesc
Definition usbd_def.h:381
uint32_t NumClasses
Definition usbd_def.h:390
uint8_t dev_test_mode
Definition usbd_def.h:376
__IO uint32_t ep0_state
Definition usbd_def.h:370
USBD_SpeedTypeDef dev_speed
Definition usbd_def.h:367
USBD_ClassTypeDef * pClass[USBD_MAX_SUPPORTED_CLASS]
Definition usbd_def.h:382
USBD_SetupReqTypedef request
Definition usbd_def.h:380
__IO uint8_t dev_state
Definition usbd_def.h:372
uint32_t ep0_data_len
Definition usbd_def.h:371
void * pUserData[USBD_MAX_SUPPORTED_CLASS]
Definition usbd_def.h:385
uint16_t wIndex
Definition usbd_def.h:202
uint8_t bmRequest
Definition usbd_def.h:199
uint16_t wLength
Definition usbd_def.h:203
Header file for usbd_core.c file.