STM32F4xx HAL Documentation
Hardware Abstraction Layer for STM32F4 familiy
Loading...
Searching...
No Matches
stm32f4xx_hal_hcd.c
Go to the documentation of this file.
1
56/* Includes ------------------------------------------------------------------*/
57#include "stm32f4xx_hal.h"
58
63#ifdef HAL_HCD_MODULE_ENABLED
64#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
65
71/* Private typedef -----------------------------------------------------------*/
72/* Private define ------------------------------------------------------------*/
73/* Private macro -------------------------------------------------------------*/
74/* Private variables ---------------------------------------------------------*/
75/* Private function prototypes -----------------------------------------------*/
79static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
80static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
82static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
87/* Exported functions --------------------------------------------------------*/
111{
112#if defined (USB_OTG_FS)
113 const USB_OTG_GlobalTypeDef *USBx;
114#endif /* defined (USB_OTG_FS) */
115
116 /* Check the HCD handle allocation */
117 if (hhcd == NULL)
118 {
119 return HAL_ERROR;
120 }
121
122 /* Check the parameters */
123 assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
124
125#if defined (USB_OTG_FS)
126 USBx = hhcd->Instance;
127#endif /* defined (USB_OTG_FS) */
128
129 if (hhcd->State == HAL_HCD_STATE_RESET)
130 {
131 /* Allocate lock resource and initialize it */
132 hhcd->Lock = HAL_UNLOCKED;
133
134#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
135 hhcd->SOFCallback = HAL_HCD_SOF_Callback;
136 hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
137 hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
138 hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
139 hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
140 hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback;
141
142 if (hhcd->MspInitCallback == NULL)
143 {
144 hhcd->MspInitCallback = HAL_HCD_MspInit;
145 }
146
147 /* Init the low level hardware */
148 hhcd->MspInitCallback(hhcd);
149#else
150 /* Init the low level hardware : GPIO, CLOCK, NVIC... */
151 HAL_HCD_MspInit(hhcd);
152#endif /* (USE_HAL_HCD_REGISTER_CALLBACKS) */
153 }
154
156
157#if defined (USB_OTG_FS)
158 /* Disable DMA mode for FS instance */
159 if (USBx == USB_OTG_FS)
160 {
161 hhcd->Init.dma_enable = 0U;
162 }
163#endif /* defined (USB_OTG_FS) */
164
165 /* Disable the Interrupts */
166 __HAL_HCD_DISABLE(hhcd);
167
168 /* Init the Core (common init.) */
169 if (USB_CoreInit(hhcd->Instance, hhcd->Init) != HAL_OK)
170 {
172 return HAL_ERROR;
173 }
174
175 /* Force Host Mode */
176 if (USB_SetCurrentMode(hhcd->Instance, USB_HOST_MODE) != HAL_OK)
177 {
179 return HAL_ERROR;
180 }
181
182 /* Init Host */
183 if (USB_HostInit(hhcd->Instance, hhcd->Init) != HAL_OK)
184 {
186 return HAL_ERROR;
187 }
188
190
191 return HAL_OK;
192}
193
218HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, uint8_t ch_num, uint8_t epnum,
219 uint8_t dev_address, uint8_t speed, uint8_t ep_type, uint16_t mps)
220{
221 HAL_StatusTypeDef status;
222 uint32_t HostCoreSpeed;
223 uint32_t HCcharMps = mps;
224
225 __HAL_LOCK(hhcd);
226 hhcd->hc[ch_num].do_ping = 0U;
227 hhcd->hc[ch_num].dev_addr = dev_address;
228 hhcd->hc[ch_num].ch_num = ch_num;
229 hhcd->hc[ch_num].ep_type = ep_type;
230 hhcd->hc[ch_num].ep_num = epnum & 0x7FU;
231
232 (void)HAL_HCD_HC_ClearHubInfo(hhcd, ch_num);
233
234 if ((epnum & 0x80U) == 0x80U)
235 {
236 hhcd->hc[ch_num].ep_is_in = 1U;
237 }
238 else
239 {
240 hhcd->hc[ch_num].ep_is_in = 0U;
241 }
242
243 HostCoreSpeed = USB_GetHostSpeed(hhcd->Instance);
244
245 if (ep_type == EP_TYPE_ISOC)
246 {
247 /* FS device plugged to HS HUB */
248 if ((speed == HCD_DEVICE_SPEED_FULL) && (HostCoreSpeed == HPRT0_PRTSPD_HIGH_SPEED))
249 {
250 if (HCcharMps > ISO_SPLT_MPS)
251 {
252 /* ISO Max Packet Size for Split mode */
253 HCcharMps = ISO_SPLT_MPS;
254 }
255 }
256 }
257
258 hhcd->hc[ch_num].speed = speed;
259 hhcd->hc[ch_num].max_packet = (uint16_t)HCcharMps;
260
261 status = USB_HC_Init(hhcd->Instance, ch_num, epnum,
262 dev_address, speed, ep_type, (uint16_t)HCcharMps);
263
264 __HAL_UNLOCK(hhcd);
265
266 return status;
267}
268
277{
278 HAL_StatusTypeDef status = HAL_OK;
279
280 __HAL_LOCK(hhcd);
281 (void)USB_HC_Halt(hhcd->Instance, ch_num);
282 __HAL_UNLOCK(hhcd);
283
284 return status;
285}
286
293{
294 /* Check the HCD handle allocation */
295 if (hhcd == NULL)
296 {
297 return HAL_ERROR;
298 }
299
301
302#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
303 if (hhcd->MspDeInitCallback == NULL)
304 {
305 hhcd->MspDeInitCallback = HAL_HCD_MspDeInit; /* Legacy weak MspDeInit */
306 }
307
308 /* DeInit the low level hardware */
309 hhcd->MspDeInitCallback(hhcd);
310#else
311 /* DeInit the low level hardware: CLOCK, NVIC.*/
312 HAL_HCD_MspDeInit(hhcd);
313#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
314
315 __HAL_HCD_DISABLE(hhcd);
316
318
319 return HAL_OK;
320}
321
328{
329 /* Prevent unused argument(s) compilation warning */
330 UNUSED(hhcd);
331
332 /* NOTE : This function should not be modified, when the callback is needed,
333 the HAL_HCD_MspInit could be implemented in the user file
334 */
335}
336
343{
344 /* Prevent unused argument(s) compilation warning */
345 UNUSED(hhcd);
346
347 /* NOTE : This function should not be modified, when the callback is needed,
348 the HAL_HCD_MspDeInit could be implemented in the user file
349 */
350}
351
395 uint8_t ch_num,
396 uint8_t direction,
397 uint8_t ep_type,
398 uint8_t token,
399 uint8_t *pbuff,
400 uint16_t length,
401 uint8_t do_ping)
402{
403 hhcd->hc[ch_num].ep_is_in = direction;
404 hhcd->hc[ch_num].ep_type = ep_type;
405
406 if (token == 0U)
407 {
408 hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
409 hhcd->hc[ch_num].do_ping = do_ping;
410 }
411 else
412 {
413 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
414 }
415
416 /* Manage Data Toggle */
417 switch (ep_type)
418 {
419 case EP_TYPE_CTRL:
420 if (token == 1U) /* send data */
421 {
422 if (direction == 0U)
423 {
424 if (length == 0U)
425 {
426 /* For Status OUT stage, Length == 0U, Status Out PID = 1 */
427 hhcd->hc[ch_num].toggle_out = 1U;
428 }
429
430 /* Set the Data Toggle bit as per the Flag */
431 if (hhcd->hc[ch_num].toggle_out == 0U)
432 {
433 /* Put the PID 0 */
434 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
435 }
436 else
437 {
438 /* Put the PID 1 */
439 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
440 }
441 }
442 else
443 {
444 if (hhcd->hc[ch_num].do_ssplit == 1U)
445 {
446 if (hhcd->hc[ch_num].toggle_in == 0U)
447 {
448 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
449 }
450 else
451 {
452 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
453 }
454 }
455 }
456 }
457 break;
458
459 case EP_TYPE_BULK:
460 if (direction == 0U)
461 {
462 /* Set the Data Toggle bit as per the Flag */
463 if (hhcd->hc[ch_num].toggle_out == 0U)
464 {
465 /* Put the PID 0 */
466 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
467 }
468 else
469 {
470 /* Put the PID 1 */
471 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
472 }
473 }
474 else
475 {
476 if (hhcd->hc[ch_num].toggle_in == 0U)
477 {
478 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
479 }
480 else
481 {
482 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
483 }
484 }
485
486 break;
487 case EP_TYPE_INTR:
488 if (direction == 0U)
489 {
490 /* Set the Data Toggle bit as per the Flag */
491 if (hhcd->hc[ch_num].toggle_out == 0U)
492 {
493 /* Put the PID 0 */
494 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
495 }
496 else
497 {
498 /* Put the PID 1 */
499 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
500 }
501 }
502 else
503 {
504 if (hhcd->hc[ch_num].toggle_in == 0U)
505 {
506 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
507 }
508 else
509 {
510 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
511 }
512 }
513 break;
514
515 case EP_TYPE_ISOC:
516 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
517 break;
518
519 default:
520 break;
521 }
522
523 hhcd->hc[ch_num].xfer_buff = pbuff;
524 hhcd->hc[ch_num].xfer_len = length;
525 hhcd->hc[ch_num].urb_state = URB_IDLE;
526 hhcd->hc[ch_num].xfer_count = 0U;
527 hhcd->hc[ch_num].ch_num = ch_num;
528 hhcd->hc[ch_num].state = HC_IDLE;
529
530 return USB_HC_StartXfer(hhcd->Instance, &hhcd->hc[ch_num], (uint8_t)hhcd->Init.dma_enable);
531}
532
539{
540 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
541 uint32_t USBx_BASE = (uint32_t)USBx;
542 uint32_t i;
543 uint32_t interrupt;
544
545 /* Ensure that we are in device mode */
546 if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
547 {
548 /* Avoid spurious interrupt */
550 {
551 return;
552 }
553
554 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
555 {
556 /* Incorrect mode, acknowledge the interrupt */
557 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
558 }
559
560 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
561 {
562 /* Incorrect mode, acknowledge the interrupt */
563 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
564 }
565
566 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
567 {
568 /* Incorrect mode, acknowledge the interrupt */
569 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
570 }
571
572 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
573 {
574 /* Incorrect mode, acknowledge the interrupt */
575 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
576 }
577
578 /* Handle Host Disconnect Interrupts */
579 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
580 {
581 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
582
583 if ((USBx_HPRT0 & USB_OTG_HPRT_PCSTS) == 0U)
584 {
585 /* Flush USB Fifo */
586 (void)USB_FlushTxFifo(USBx, 0x10U);
587 (void)USB_FlushRxFifo(USBx);
588
589 if (hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
590 {
591 /* Restore FS Clock */
592 (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
593 }
594
595 /* Handle Host Port Disconnect Interrupt */
596#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
597 hhcd->DisconnectCallback(hhcd);
598#else
600#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
601 }
602 }
603
604 /* Handle Host Port Interrupts */
605 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
606 {
608 }
609
610 /* Handle Host SOF Interrupt */
611 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
612 {
613#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
614 hhcd->SOFCallback(hhcd);
615#else
617#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
618
619 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
620 }
621
622 /* Handle Host channel Interrupt */
623 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
624 {
625 interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
626 for (i = 0U; i < hhcd->Init.Host_channels; i++)
627 {
628 if ((interrupt & (1UL << (i & 0xFU))) != 0U)
629 {
630 if ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_EPDIR) == USB_OTG_HCCHAR_EPDIR)
631 {
632 HCD_HC_IN_IRQHandler(hhcd, (uint8_t)i);
633 }
634 else
635 {
636 HCD_HC_OUT_IRQHandler(hhcd, (uint8_t)i);
637 }
638 }
639 }
640 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
641 }
642
643 /* Handle Rx Queue Level Interrupts */
644 if ((__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL)) != 0U)
645 {
646 USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
647
649
650 USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
651 }
652 }
653}
654
655
662{
663 UNUSED(hhcd);
664}
665
666
673{
674 /* Prevent unused argument(s) compilation warning */
675 UNUSED(hhcd);
676
677 /* NOTE : This function should not be modified, when the callback is needed,
678 the HAL_HCD_SOF_Callback could be implemented in the user file
679 */
680}
681
688{
689 /* Prevent unused argument(s) compilation warning */
690 UNUSED(hhcd);
691
692 /* NOTE : This function should not be modified, when the callback is needed,
693 the HAL_HCD_Connect_Callback could be implemented in the user file
694 */
695}
696
703{
704 /* Prevent unused argument(s) compilation warning */
705 UNUSED(hhcd);
706
707 /* NOTE : This function should not be modified, when the callback is needed,
708 the HAL_HCD_Disconnect_Callback could be implemented in the user file
709 */
710}
711
718{
719 /* Prevent unused argument(s) compilation warning */
720 UNUSED(hhcd);
721
722 /* NOTE : This function should not be modified, when the callback is needed,
723 the HAL_HCD_Disconnect_Callback could be implemented in the user file
724 */
725}
726
733{
734 /* Prevent unused argument(s) compilation warning */
735 UNUSED(hhcd);
736
737 /* NOTE : This function should not be modified, when the callback is needed,
738 the HAL_HCD_Disconnect_Callback could be implemented in the user file
739 */
740}
741
758{
759 /* Prevent unused argument(s) compilation warning */
760 UNUSED(hhcd);
761 UNUSED(chnum);
762 UNUSED(urb_state);
763
764 /* NOTE : This function should not be modified, when the callback is needed,
765 the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
766 */
767}
768
769#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
786HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd,
787 HAL_HCD_CallbackIDTypeDef CallbackID,
788 pHCD_CallbackTypeDef pCallback)
789{
790 HAL_StatusTypeDef status = HAL_OK;
791
792 if (pCallback == NULL)
793 {
794 /* Update the error code */
795 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
796 return HAL_ERROR;
797 }
798 /* Process locked */
799 __HAL_LOCK(hhcd);
800
801 if (hhcd->State == HAL_HCD_STATE_READY)
802 {
803 switch (CallbackID)
804 {
805 case HAL_HCD_SOF_CB_ID :
806 hhcd->SOFCallback = pCallback;
807 break;
808
809 case HAL_HCD_CONNECT_CB_ID :
810 hhcd->ConnectCallback = pCallback;
811 break;
812
813 case HAL_HCD_DISCONNECT_CB_ID :
814 hhcd->DisconnectCallback = pCallback;
815 break;
816
817 case HAL_HCD_PORT_ENABLED_CB_ID :
818 hhcd->PortEnabledCallback = pCallback;
819 break;
820
821 case HAL_HCD_PORT_DISABLED_CB_ID :
822 hhcd->PortDisabledCallback = pCallback;
823 break;
824
825 case HAL_HCD_MSPINIT_CB_ID :
826 hhcd->MspInitCallback = pCallback;
827 break;
828
829 case HAL_HCD_MSPDEINIT_CB_ID :
830 hhcd->MspDeInitCallback = pCallback;
831 break;
832
833 default :
834 /* Update the error code */
835 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
836 /* Return error status */
837 status = HAL_ERROR;
838 break;
839 }
840 }
841 else if (hhcd->State == HAL_HCD_STATE_RESET)
842 {
843 switch (CallbackID)
844 {
845 case HAL_HCD_MSPINIT_CB_ID :
846 hhcd->MspInitCallback = pCallback;
847 break;
848
849 case HAL_HCD_MSPDEINIT_CB_ID :
850 hhcd->MspDeInitCallback = pCallback;
851 break;
852
853 default :
854 /* Update the error code */
855 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
856 /* Return error status */
857 status = HAL_ERROR;
858 break;
859 }
860 }
861 else
862 {
863 /* Update the error code */
864 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
865 /* Return error status */
866 status = HAL_ERROR;
867 }
868
869 /* Release Lock */
870 __HAL_UNLOCK(hhcd);
871 return status;
872}
873
889HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID)
890{
891 HAL_StatusTypeDef status = HAL_OK;
892
893 /* Process locked */
894 __HAL_LOCK(hhcd);
895
896 /* Setup Legacy weak Callbacks */
897 if (hhcd->State == HAL_HCD_STATE_READY)
898 {
899 switch (CallbackID)
900 {
901 case HAL_HCD_SOF_CB_ID :
902 hhcd->SOFCallback = HAL_HCD_SOF_Callback;
903 break;
904
905 case HAL_HCD_CONNECT_CB_ID :
906 hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
907 break;
908
909 case HAL_HCD_DISCONNECT_CB_ID :
910 hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
911 break;
912
913 case HAL_HCD_PORT_ENABLED_CB_ID :
914 hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
915 break;
916
917 case HAL_HCD_PORT_DISABLED_CB_ID :
918 hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
919 break;
920
921 case HAL_HCD_MSPINIT_CB_ID :
922 hhcd->MspInitCallback = HAL_HCD_MspInit;
923 break;
924
925 case HAL_HCD_MSPDEINIT_CB_ID :
926 hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
927 break;
928
929 default :
930 /* Update the error code */
931 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
932
933 /* Return error status */
934 status = HAL_ERROR;
935 break;
936 }
937 }
938 else if (hhcd->State == HAL_HCD_STATE_RESET)
939 {
940 switch (CallbackID)
941 {
942 case HAL_HCD_MSPINIT_CB_ID :
943 hhcd->MspInitCallback = HAL_HCD_MspInit;
944 break;
945
946 case HAL_HCD_MSPDEINIT_CB_ID :
947 hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
948 break;
949
950 default :
951 /* Update the error code */
952 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
953
954 /* Return error status */
955 status = HAL_ERROR;
956 break;
957 }
958 }
959 else
960 {
961 /* Update the error code */
962 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
963
964 /* Return error status */
965 status = HAL_ERROR;
966 }
967
968 /* Release Lock */
969 __HAL_UNLOCK(hhcd);
970 return status;
971}
972
980HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd,
981 pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback)
982{
983 HAL_StatusTypeDef status = HAL_OK;
984
985 if (pCallback == NULL)
986 {
987 /* Update the error code */
988 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
989
990 return HAL_ERROR;
991 }
992
993 /* Process locked */
994 __HAL_LOCK(hhcd);
995
996 if (hhcd->State == HAL_HCD_STATE_READY)
997 {
998 hhcd->HC_NotifyURBChangeCallback = pCallback;
999 }
1000 else
1001 {
1002 /* Update the error code */
1003 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
1004
1005 /* Return error status */
1006 status = HAL_ERROR;
1007 }
1008
1009 /* Release Lock */
1010 __HAL_UNLOCK(hhcd);
1011
1012 return status;
1013}
1014
1022HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd)
1023{
1024 HAL_StatusTypeDef status = HAL_OK;
1025
1026 /* Process locked */
1027 __HAL_LOCK(hhcd);
1028
1029 if (hhcd->State == HAL_HCD_STATE_READY)
1030 {
1031 hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback; /* Legacy weak DataOutStageCallback */
1032 }
1033 else
1034 {
1035 /* Update the error code */
1036 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
1037
1038 /* Return error status */
1039 status = HAL_ERROR;
1040 }
1041
1042 /* Release Lock */
1043 __HAL_UNLOCK(hhcd);
1044
1045 return status;
1046}
1047#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1048
1074{
1075 __HAL_LOCK(hhcd);
1076 /* Enable port power */
1077 (void)USB_DriveVbus(hhcd->Instance, 1U);
1078
1079 /* Enable global interrupt */
1080 __HAL_HCD_ENABLE(hhcd);
1081 __HAL_UNLOCK(hhcd);
1082
1083 return HAL_OK;
1084}
1085
1093{
1094 __HAL_LOCK(hhcd);
1095 (void)USB_StopHost(hhcd->Instance);
1096 __HAL_UNLOCK(hhcd);
1097
1098 return HAL_OK;
1099}
1100
1107{
1108 return (USB_ResetPort(hhcd->Instance));
1109}
1110
1136{
1137 return hhcd->State;
1138}
1139
1155{
1156 return hhcd->hc[chnum].urb_state;
1157}
1158
1159
1167uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
1168{
1169 return hhcd->hc[chnum].xfer_count;
1170}
1171
1190{
1191 return hhcd->hc[chnum].state;
1192}
1193
1200{
1201 return (USB_GetCurrentFrame(hhcd->Instance));
1202}
1203
1210{
1211 return (USB_GetHostSpeed(hhcd->Instance));
1212}
1213
1224 uint8_t addr, uint8_t PortNbr)
1225{
1226 uint32_t HostCoreSpeed = USB_GetHostSpeed(hhcd->Instance);
1227
1228 /* LS/FS device plugged to HS HUB */
1229 if ((hhcd->hc[ch_num].speed != HCD_DEVICE_SPEED_HIGH) && (HostCoreSpeed == HPRT0_PRTSPD_HIGH_SPEED))
1230 {
1231 hhcd->hc[ch_num].do_ssplit = 1U;
1232
1233 if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) && (hhcd->hc[ch_num].ep_is_in != 0U))
1234 {
1235 hhcd->hc[ch_num].toggle_in = 1U;
1236 }
1237 }
1238
1239 hhcd->hc[ch_num].hub_addr = addr;
1240 hhcd->hc[ch_num].hub_port_nbr = PortNbr;
1241
1242 return HAL_OK;
1243}
1244
1245
1254{
1255 hhcd->hc[ch_num].do_ssplit = 0U;
1256 hhcd->hc[ch_num].do_csplit = 0U;
1257 hhcd->hc[ch_num].hub_addr = 0U;
1258 hhcd->hc[ch_num].hub_port_nbr = 0U;
1259
1260 return HAL_OK;
1261}
1280static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
1281{
1282 const USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1283 uint32_t USBx_BASE = (uint32_t)USBx;
1284 uint32_t tmpreg;
1285
1286 if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_AHBERR))
1287 {
1288 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
1289 hhcd->hc[chnum].state = HC_XACTERR;
1290 (void)USB_HC_Halt(hhcd->Instance, chnum);
1291 }
1292 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_BBERR))
1293 {
1294 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_BBERR);
1295 hhcd->hc[chnum].state = HC_BBLERR;
1296 (void)USB_HC_Halt(hhcd->Instance, chnum);
1297 }
1298 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_STALL))
1299 {
1300 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
1301 hhcd->hc[chnum].state = HC_STALL;
1302 (void)USB_HC_Halt(hhcd->Instance, chnum);
1303 }
1304 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_DTERR))
1305 {
1306 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
1307 hhcd->hc[chnum].state = HC_DATATGLERR;
1308 (void)USB_HC_Halt(hhcd->Instance, chnum);
1309 }
1310 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_TXERR))
1311 {
1312 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
1313 hhcd->hc[chnum].state = HC_XACTERR;
1314 (void)USB_HC_Halt(hhcd->Instance, chnum);
1315 }
1316 else
1317 {
1318 /* ... */
1319 }
1320
1321 if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_FRMOR))
1322 {
1323 (void)USB_HC_Halt(hhcd->Instance, chnum);
1324 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
1325 }
1326 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_XFRC))
1327 {
1328 /* Clear any pending ACK IT */
1329 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
1330
1331 if (hhcd->hc[chnum].do_csplit == 1U)
1332 {
1333 hhcd->hc[chnum].do_csplit = 0U;
1335 }
1336
1337 if (hhcd->Init.dma_enable != 0U)
1338 {
1339 hhcd->hc[chnum].xfer_count = hhcd->hc[chnum].XferSize - (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ);
1340 }
1341
1342 hhcd->hc[chnum].state = HC_XFRC;
1343 hhcd->hc[chnum].ErrCnt = 0U;
1344 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
1345
1346 if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1347 (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1348 {
1349 (void)USB_HC_Halt(hhcd->Instance, chnum);
1350 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
1351 }
1352 else if ((hhcd->hc[chnum].ep_type == EP_TYPE_INTR) ||
1353 (hhcd->hc[chnum].ep_type == EP_TYPE_ISOC))
1354 {
1355 USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
1356 hhcd->hc[chnum].urb_state = URB_DONE;
1357
1358#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1359 hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1360#else
1361 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1362#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1363 }
1364 else
1365 {
1366 /* ... */
1367 }
1368
1369 if (hhcd->Init.dma_enable == 1U)
1370 {
1371 if ((((hhcd->hc[chnum].xfer_count + hhcd->hc[chnum].max_packet - 1U) / hhcd->hc[chnum].max_packet) & 1U) != 0U)
1372 {
1373 hhcd->hc[chnum].toggle_in ^= 1U;
1374 }
1375 }
1376 else
1377 {
1378 hhcd->hc[chnum].toggle_in ^= 1U;
1379 }
1380 }
1381 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_ACK))
1382 {
1383 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
1384
1385 if (hhcd->hc[chnum].do_ssplit == 1U)
1386 {
1387 hhcd->hc[chnum].do_csplit = 1U;
1388 hhcd->hc[chnum].state = HC_ACK;
1389
1390 (void)USB_HC_Halt(hhcd->Instance, chnum);
1391 }
1392 }
1393 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_CHH))
1394 {
1395 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
1396
1397 if (hhcd->hc[chnum].state == HC_XFRC)
1398 {
1399 hhcd->hc[chnum].state = HC_HALTED;
1400 hhcd->hc[chnum].urb_state = URB_DONE;
1401 }
1402 else if (hhcd->hc[chnum].state == HC_STALL)
1403 {
1404 hhcd->hc[chnum].state = HC_HALTED;
1405 hhcd->hc[chnum].urb_state = URB_STALL;
1406 }
1407 else if ((hhcd->hc[chnum].state == HC_XACTERR) ||
1408 (hhcd->hc[chnum].state == HC_DATATGLERR))
1409 {
1410 hhcd->hc[chnum].state = HC_HALTED;
1411 hhcd->hc[chnum].ErrCnt++;
1412 if (hhcd->hc[chnum].ErrCnt > 2U)
1413 {
1414 hhcd->hc[chnum].ErrCnt = 0U;
1415
1416 if (hhcd->hc[chnum].do_ssplit == 1U)
1417 {
1418 hhcd->hc[chnum].do_csplit = 0U;
1419 hhcd->hc[chnum].ep_ss_schedule = 0U;
1421 }
1422
1423 hhcd->hc[chnum].urb_state = URB_ERROR;
1424 }
1425 else
1426 {
1427 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1428
1429 if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1430 (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1431 {
1432 /* re-activate the channel */
1433 tmpreg = USBx_HC(chnum)->HCCHAR;
1434 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1435 tmpreg |= USB_OTG_HCCHAR_CHENA;
1436 USBx_HC(chnum)->HCCHAR = tmpreg;
1437 }
1438 }
1439 }
1440 else if (hhcd->hc[chnum].state == HC_NYET)
1441 {
1442 hhcd->hc[chnum].state = HC_HALTED;
1443
1444 if (hhcd->hc[chnum].do_csplit == 1U)
1445 {
1446 if (hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
1447 {
1448 hhcd->hc[chnum].NyetErrCnt++;
1449 if (hhcd->hc[chnum].NyetErrCnt > 2U)
1450 {
1451 hhcd->hc[chnum].NyetErrCnt = 0U;
1452 hhcd->hc[chnum].do_csplit = 0U;
1453
1454 if (hhcd->hc[chnum].ErrCnt < 3U)
1455 {
1456 hhcd->hc[chnum].ep_ss_schedule = 1U;
1457 }
1459 hhcd->hc[chnum].urb_state = URB_ERROR;
1460 }
1461 else
1462 {
1463 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1464 }
1465 }
1466 else
1467 {
1468 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1469 }
1470
1471 if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1472 (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1473 {
1474 /* re-activate the channel */
1475 tmpreg = USBx_HC(chnum)->HCCHAR;
1476 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1477 tmpreg |= USB_OTG_HCCHAR_CHENA;
1478 USBx_HC(chnum)->HCCHAR = tmpreg;
1479 }
1480 }
1481 }
1482 else if (hhcd->hc[chnum].state == HC_ACK)
1483 {
1484 hhcd->hc[chnum].state = HC_HALTED;
1485
1486 if (hhcd->hc[chnum].do_csplit == 1U)
1487 {
1488 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1489
1490 /* Set Complete split and re-activate the channel */
1491 USBx_HC(chnum)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
1492 USBx_HC(chnum)->HCINTMSK |= USB_OTG_HCINTMSK_NYET;
1493 USBx_HC(chnum)->HCINTMSK &= ~USB_OTG_HCINT_ACK;
1494
1495 if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1496 (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1497 {
1498 /* re-activate the channel */
1499 tmpreg = USBx_HC(chnum)->HCCHAR;
1500 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1501 tmpreg |= USB_OTG_HCCHAR_CHENA;
1502 USBx_HC(chnum)->HCCHAR = tmpreg;
1503 }
1504 }
1505 }
1506 else if (hhcd->hc[chnum].state == HC_NAK)
1507 {
1508 hhcd->hc[chnum].state = HC_HALTED;
1509 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1510
1511 if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1512 (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1513 {
1514 /* re-activate the channel */
1515 tmpreg = USBx_HC(chnum)->HCCHAR;
1516 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1517 tmpreg |= USB_OTG_HCCHAR_CHENA;
1518 USBx_HC(chnum)->HCCHAR = tmpreg;
1519 }
1520 }
1521 else if (hhcd->hc[chnum].state == HC_BBLERR)
1522 {
1523 hhcd->hc[chnum].state = HC_HALTED;
1524 hhcd->hc[chnum].ErrCnt++;
1525 hhcd->hc[chnum].urb_state = URB_ERROR;
1526 }
1527 else
1528 {
1529 if (hhcd->hc[chnum].state == HC_HALTED)
1530 {
1531 return;
1532 }
1533 }
1534
1535#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1536 hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1537#else
1538 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1539#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1540 }
1541 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NYET))
1542 {
1543 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
1544 hhcd->hc[chnum].state = HC_NYET;
1545
1546 if (hhcd->hc[chnum].do_ssplit == 0U)
1547 {
1548 hhcd->hc[chnum].ErrCnt = 0U;
1549 }
1550
1551 (void)USB_HC_Halt(hhcd->Instance, chnum);
1552 }
1553 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NAK))
1554 {
1555 if (hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
1556 {
1557 hhcd->hc[chnum].ErrCnt = 0U;
1558 hhcd->hc[chnum].state = HC_NAK;
1559 (void)USB_HC_Halt(hhcd->Instance, chnum);
1560 }
1561 else if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1562 (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1563 {
1564 hhcd->hc[chnum].ErrCnt = 0U;
1565
1566 if ((hhcd->Init.dma_enable == 0U) || (hhcd->hc[chnum].do_csplit == 1U))
1567 {
1568 hhcd->hc[chnum].state = HC_NAK;
1569 (void)USB_HC_Halt(hhcd->Instance, chnum);
1570 }
1571 }
1572 else
1573 {
1574 /* ... */
1575 }
1576
1577 if (hhcd->hc[chnum].do_csplit == 1U)
1578 {
1579 hhcd->hc[chnum].do_csplit = 0U;
1582 }
1583
1584 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
1585 }
1586 else
1587 {
1588 /* ... */
1589 }
1590}
1591
1599static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
1600{
1601 const USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1602 uint32_t USBx_BASE = (uint32_t)USBx;
1603 uint32_t tmpreg;
1604 uint32_t num_packets;
1605
1606 if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_AHBERR))
1607 {
1608 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
1609 hhcd->hc[chnum].state = HC_XACTERR;
1610 (void)USB_HC_Halt(hhcd->Instance, chnum);
1611 }
1612 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_ACK))
1613 {
1614 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
1615
1616 if (hhcd->hc[chnum].do_ping == 1U)
1617 {
1618 hhcd->hc[chnum].do_ping = 0U;
1619 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1620 hhcd->hc[chnum].state = HC_ACK;
1621 (void)USB_HC_Halt(hhcd->Instance, chnum);
1622 }
1623
1624 if ((hhcd->hc[chnum].do_ssplit == 1U) && (hhcd->hc[chnum].do_csplit == 0U))
1625 {
1626 if (hhcd->hc[chnum].ep_type != EP_TYPE_ISOC)
1627 {
1628 hhcd->hc[chnum].do_csplit = 1U;
1629 }
1630
1631 hhcd->hc[chnum].state = HC_ACK;
1632 (void)USB_HC_Halt(hhcd->Instance, chnum);
1633
1634 /* reset error_count */
1635 hhcd->hc[chnum].ErrCnt = 0U;
1636 }
1637 }
1638 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_FRMOR))
1639 {
1640 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
1641 (void)USB_HC_Halt(hhcd->Instance, chnum);
1642 }
1643 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_XFRC))
1644 {
1645 hhcd->hc[chnum].ErrCnt = 0U;
1646
1647 /* transaction completed with NYET state, update do ping state */
1648 if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NYET))
1649 {
1650 hhcd->hc[chnum].do_ping = 1U;
1651 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
1652 }
1653
1654 if (hhcd->hc[chnum].do_csplit != 0U)
1655 {
1656 hhcd->hc[chnum].do_csplit = 0U;
1658 }
1659
1660 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
1661 hhcd->hc[chnum].state = HC_XFRC;
1662 (void)USB_HC_Halt(hhcd->Instance, chnum);
1663 }
1664 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NYET))
1665 {
1666 hhcd->hc[chnum].state = HC_NYET;
1667
1668 if (hhcd->hc[chnum].do_ssplit == 0U)
1669 {
1670 hhcd->hc[chnum].do_ping = 1U;
1671 }
1672
1673 hhcd->hc[chnum].ErrCnt = 0U;
1674 (void)USB_HC_Halt(hhcd->Instance, chnum);
1675 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
1676 }
1677 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_STALL))
1678 {
1679 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
1680 hhcd->hc[chnum].state = HC_STALL;
1681 (void)USB_HC_Halt(hhcd->Instance, chnum);
1682 }
1683 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NAK))
1684 {
1685 hhcd->hc[chnum].ErrCnt = 0U;
1686 hhcd->hc[chnum].state = HC_NAK;
1687
1688 if (hhcd->hc[chnum].do_ping == 0U)
1689 {
1690 if (hhcd->hc[chnum].speed == HCD_DEVICE_SPEED_HIGH)
1691 {
1692 hhcd->hc[chnum].do_ping = 1U;
1693 }
1694 }
1695
1696 (void)USB_HC_Halt(hhcd->Instance, chnum);
1697 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
1698 }
1699 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_TXERR))
1700 {
1701 if (hhcd->Init.dma_enable == 0U)
1702 {
1703 hhcd->hc[chnum].state = HC_XACTERR;
1704 (void)USB_HC_Halt(hhcd->Instance, chnum);
1705 }
1706 else
1707 {
1708 hhcd->hc[chnum].ErrCnt++;
1709 if (hhcd->hc[chnum].ErrCnt > 2U)
1710 {
1711 hhcd->hc[chnum].ErrCnt = 0U;
1712 hhcd->hc[chnum].urb_state = URB_ERROR;
1713
1714#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1715 hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1716#else
1717 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1718#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1719 }
1720 else
1721 {
1722 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1723
1724 /* Re-activate the channel */
1725 tmpreg = USBx_HC(chnum)->HCCHAR;
1726 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1727 tmpreg |= USB_OTG_HCCHAR_CHENA;
1728 USBx_HC(chnum)->HCCHAR = tmpreg;
1729 }
1730 }
1731 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
1732 }
1733 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_DTERR))
1734 {
1735 hhcd->hc[chnum].state = HC_DATATGLERR;
1736 (void)USB_HC_Halt(hhcd->Instance, chnum);
1737 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
1738 }
1739 else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_CHH))
1740 {
1741 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
1742
1743 if (hhcd->hc[chnum].state == HC_XFRC)
1744 {
1745 hhcd->hc[chnum].state = HC_HALTED;
1746 hhcd->hc[chnum].urb_state = URB_DONE;
1747
1748 if ((hhcd->hc[chnum].ep_type == EP_TYPE_BULK) ||
1749 (hhcd->hc[chnum].ep_type == EP_TYPE_INTR))
1750 {
1751 if (hhcd->Init.dma_enable == 0U)
1752 {
1753 hhcd->hc[chnum].toggle_out ^= 1U;
1754 }
1755
1756 if ((hhcd->Init.dma_enable == 1U) && (hhcd->hc[chnum].xfer_len > 0U))
1757 {
1758 num_packets = (hhcd->hc[chnum].xfer_len + hhcd->hc[chnum].max_packet - 1U) / hhcd->hc[chnum].max_packet;
1759
1760 if ((num_packets & 1U) != 0U)
1761 {
1762 hhcd->hc[chnum].toggle_out ^= 1U;
1763 }
1764 }
1765 }
1766 }
1767 else if (hhcd->hc[chnum].state == HC_ACK)
1768 {
1769 hhcd->hc[chnum].state = HC_HALTED;
1770
1771 if (hhcd->hc[chnum].do_csplit == 1U)
1772 {
1773 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1774 }
1775 }
1776 else if (hhcd->hc[chnum].state == HC_NAK)
1777 {
1778 hhcd->hc[chnum].state = HC_HALTED;
1779 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1780
1781 if (hhcd->hc[chnum].do_csplit == 1U)
1782 {
1783 hhcd->hc[chnum].do_csplit = 0U;
1785 }
1786 }
1787 else if (hhcd->hc[chnum].state == HC_NYET)
1788 {
1789 hhcd->hc[chnum].state = HC_HALTED;
1790 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1791 }
1792 else if (hhcd->hc[chnum].state == HC_STALL)
1793 {
1794 hhcd->hc[chnum].state = HC_HALTED;
1795 hhcd->hc[chnum].urb_state = URB_STALL;
1796 }
1797 else if ((hhcd->hc[chnum].state == HC_XACTERR) ||
1798 (hhcd->hc[chnum].state == HC_DATATGLERR))
1799 {
1800 hhcd->hc[chnum].state = HC_HALTED;
1801 hhcd->hc[chnum].ErrCnt++;
1802 if (hhcd->hc[chnum].ErrCnt > 2U)
1803 {
1804 hhcd->hc[chnum].ErrCnt = 0U;
1805 hhcd->hc[chnum].urb_state = URB_ERROR;
1806 }
1807 else
1808 {
1809 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1810
1811 /* re-activate the channel */
1812 tmpreg = USBx_HC(chnum)->HCCHAR;
1813 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1814 tmpreg |= USB_OTG_HCCHAR_CHENA;
1815 USBx_HC(chnum)->HCCHAR = tmpreg;
1816 }
1817 }
1818 else
1819 {
1820 return;
1821 }
1822
1823#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1824 hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1825#else
1826 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1827#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1828 }
1829 else
1830 {
1831 return;
1832 }
1833}
1834
1841{
1842 const USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1843 uint32_t USBx_BASE = (uint32_t)USBx;
1844 uint32_t pktsts;
1845 uint32_t pktcnt;
1846 uint32_t GrxstspReg;
1847 uint32_t xferSizePktCnt;
1848 uint32_t tmpreg;
1849 uint32_t chnum;
1850
1851 GrxstspReg = hhcd->Instance->GRXSTSP;
1852 chnum = GrxstspReg & USB_OTG_GRXSTSP_EPNUM;
1853 pktsts = (GrxstspReg & USB_OTG_GRXSTSP_PKTSTS) >> 17;
1854 pktcnt = (GrxstspReg & USB_OTG_GRXSTSP_BCNT) >> 4;
1855
1856 switch (pktsts)
1857 {
1858 case GRXSTS_PKTSTS_IN:
1859 /* Read the data into the host buffer. */
1860 if ((pktcnt > 0U) && (hhcd->hc[chnum].xfer_buff != (void *)0))
1861 {
1862 if ((hhcd->hc[chnum].xfer_count + pktcnt) <= hhcd->hc[chnum].xfer_len)
1863 {
1864 (void)USB_ReadPacket(hhcd->Instance,
1865 hhcd->hc[chnum].xfer_buff, (uint16_t)pktcnt);
1866
1867 /* manage multiple Xfer */
1868 hhcd->hc[chnum].xfer_buff += pktcnt;
1869 hhcd->hc[chnum].xfer_count += pktcnt;
1870
1871 /* get transfer size packet count */
1872 xferSizePktCnt = (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19;
1873
1874 if ((hhcd->hc[chnum].max_packet == pktcnt) && (xferSizePktCnt > 0U))
1875 {
1876 /* re-activate the channel when more packets are expected */
1877 tmpreg = USBx_HC(chnum)->HCCHAR;
1878 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1879 tmpreg |= USB_OTG_HCCHAR_CHENA;
1880 USBx_HC(chnum)->HCCHAR = tmpreg;
1881 hhcd->hc[chnum].toggle_in ^= 1U;
1882 }
1883 }
1884 else
1885 {
1886 hhcd->hc[chnum].urb_state = URB_ERROR;
1887 }
1888 }
1889 break;
1890
1891 case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
1892 break;
1893
1894 case GRXSTS_PKTSTS_IN_XFER_COMP:
1895 case GRXSTS_PKTSTS_CH_HALTED:
1896 default:
1897 break;
1898 }
1899}
1900
1907{
1908 const USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1909 uint32_t USBx_BASE = (uint32_t)USBx;
1910 __IO uint32_t hprt0;
1911 __IO uint32_t hprt0_dup;
1912
1913 /* Handle Host Port Interrupts */
1914 hprt0 = USBx_HPRT0;
1915 hprt0_dup = USBx_HPRT0;
1916
1917 hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | \
1918 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1919
1920 /* Check whether Port Connect detected */
1921 if ((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
1922 {
1923 if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
1924 {
1925#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1926 hhcd->ConnectCallback(hhcd);
1927#else
1929#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1930 }
1931 hprt0_dup |= USB_OTG_HPRT_PCDET;
1932 }
1933
1934 /* Check whether Port Enable Changed */
1935 if ((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
1936 {
1937 hprt0_dup |= USB_OTG_HPRT_PENCHNG;
1938
1939 if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
1940 {
1941 if (hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
1942 {
1943 if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17))
1944 {
1945 (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_6_MHZ);
1946 }
1947 else
1948 {
1949 (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
1950 }
1951 }
1952 else
1953 {
1954 if (hhcd->Init.speed == HCD_SPEED_FULL)
1955 {
1956 USBx_HOST->HFIR = HFIR_60_MHZ;
1957 }
1958 }
1959#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1960 hhcd->PortEnabledCallback(hhcd);
1961#else
1963#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1964
1965 }
1966 else
1967 {
1968#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1969 hhcd->PortDisabledCallback(hhcd);
1970#else
1972#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1973 }
1974 }
1975
1976 /* Check for an overcurrent */
1977 if ((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
1978 {
1979 hprt0_dup |= USB_OTG_HPRT_POCCHNG;
1980 }
1981
1982 /* Clear Port Interrupts */
1983 USBx_HPRT0 = hprt0_dup;
1984}
1985
1994#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
1995#endif /* HAL_HCD_MODULE_ENABLED */
1996
#define HCD_DEVICE_SPEED_HIGH
#define HCD_DEVICE_SPEED_FULL
void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
DeInitialize the HCD MSP.
HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
Halt a host channel.
void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
Initialize the HCD MSP.
HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, uint8_t ch_num, uint8_t epnum, uint8_t dev_address, uint8_t speed, uint8_t ep_type, uint16_t mps)
Initialize a host channel.
HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
DeInitialize the host driver.
HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
Initialize the host driver.
void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd)
Port Disabled Event callback.
void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
Connection Event callback.
void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd)
Port Enabled Event callback.
void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
Notify URB state change callback.
void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
SOF callback.
HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, uint8_t ch_num, uint8_t direction, uint8_t ep_type, uint8_t token, uint8_t *pbuff, uint16_t length, uint8_t do_ping)
Submit a new URB for processing.
void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
Handle HCD interrupt request.
void HAL_HCD_WKUP_IRQHandler(HCD_HandleTypeDef *hhcd)
Handles HCD Wakeup interrupt request.
void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
Disconnection Event callback.
HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
Stop the host driver.
HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
Reset the host port.
HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
Start the host driver.
HAL_StatusTypeDef HAL_HCD_HC_SetHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num, uint8_t addr, uint8_t PortNbr)
Set host channel Hub information.
HAL_StatusTypeDef HAL_HCD_HC_ClearHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
Clear host channel hub information.
HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
Return URB state for a channel.
HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
Return the Host Channel state.
uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
Return the current Host frame number.
uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
Return the Host enumeration speed.
HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef const *hhcd)
Return the HCD handle state.
uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
Return the last host transfer size.
#define __HAL_HCD_GET_CH_FLAG(__HANDLE__, __chnum__, __INTERRUPT__)
#define __HAL_HCD_DISABLE(__HANDLE__)
#define __HAL_HCD_CLEAR_HC_CSPLT(chnum)
#define __HAL_HCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__)
#define __HAL_HCD_CLEAR_HC_INT(chnum, __INTERRUPT__)
#define __HAL_HCD_UNMASK_ACK_HC_INT(chnum)
#define __HAL_HCD_IS_INVALID_INTERRUPT(__HANDLE__)
#define __HAL_HCD_ENABLE(__HANDLE__)
#define __HAL_HCD_GET_FLAG(__HANDLE__, __INTERRUPT__)
HCD_StateTypeDef
USB_OTG_URBStateTypeDef HCD_URBStateTypeDef
USB_OTG_HCStateTypeDef HCD_HCStateTypeDef
@ HAL_HCD_STATE_ERROR
@ HAL_HCD_STATE_RESET
@ HAL_HCD_STATE_READY
@ HAL_HCD_STATE_BUSY
static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd)
Handle Rx Queue Level interrupt requests.
static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd)
Handle Host Port interrupt requests.
static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
Handle Host Channel IN interrupt requests.
static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
Handle Host Channel OUT interrupt requests.
#define HCD_SPEED_FULL
#define assert_param(expr)
This file contains all the functions prototypes for the HAL module driver.
HAL_StatusTypeDef
HAL Status structures definition
@ HAL_ERROR
@ HAL_OK
#define UNUSED(X)
#define __HAL_UNLOCK(__HANDLE__)
@ HAL_UNLOCKED
#define __HAL_LOCK(__HANDLE__)
__IO uint32_t ErrorCode
__IO HCD_StateTypeDef State
HAL_LockTypeDef Lock
HCD_HCTypeDef hc[16]
HCD_TypeDef * Instance
HCD_InitTypeDef Init