STM32F4xx_HAL_Driver  1.8.3
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 -----------------------------------------------*/
79 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
80 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
81 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd);
82 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
87 /* Exported functions --------------------------------------------------------*/
110 HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
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 
155  hhcd->State = HAL_HCD_STATE_BUSY;
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  {
171  hhcd->State = HAL_HCD_STATE_ERROR;
172  return HAL_ERROR;
173  }
174 
175  /* Force Host Mode */
176  if (USB_SetCurrentMode(hhcd->Instance, USB_HOST_MODE) != HAL_OK)
177  {
178  hhcd->State = HAL_HCD_STATE_ERROR;
179  return HAL_ERROR;
180  }
181 
182  /* Init Host */
183  if (USB_HostInit(hhcd->Instance, hhcd->Init) != HAL_OK)
184  {
185  hhcd->State = HAL_HCD_STATE_ERROR;
186  return HAL_ERROR;
187  }
188 
189  hhcd->State = HAL_HCD_STATE_READY;
190 
191  return HAL_OK;
192 }
193 
218 HAL_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 
276 HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
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 
292 HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
293 {
294  /* Check the HCD handle allocation */
295  if (hhcd == NULL)
296  {
297  return HAL_ERROR;
298  }
299 
300  hhcd->State = HAL_HCD_STATE_BUSY;
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 
317  hhcd->State = HAL_HCD_STATE_RESET;
318 
319  return HAL_OK;
320 }
321 
327 __weak void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
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 
342 __weak void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
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 
394 HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
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 
538 void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
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 */
549  if (__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
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  {
607  HCD_Port_IRQHandler(hhcd);
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
616  HAL_HCD_SOF_Callback(hhcd);
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 
648  HCD_RXQLVL_IRQHandler(hhcd);
649 
650  USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
651  }
652  }
653 }
654 
655 
661 void HAL_HCD_WKUP_IRQHandler(HCD_HandleTypeDef *hhcd)
662 {
663  UNUSED(hhcd);
664 }
665 
666 
672 __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
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 
687 __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
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 
702 __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
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 
717 __weak void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd)
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 
732 __weak void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd)
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 
757 __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
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)
786 HAL_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 
814  hhcd->DisconnectCallback = pCallback;
815  break;
816 
818  hhcd->PortEnabledCallback = pCallback;
819  break;
820 
822  hhcd->PortDisabledCallback = pCallback;
823  break;
824 
825  case HAL_HCD_MSPINIT_CB_ID :
826  hhcd->MspInitCallback = pCallback;
827  break;
828 
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 
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 
889 HAL_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 
910  hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
911  break;
912 
914  hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
915  break;
916 
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 
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 
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 
980 HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd,
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 
1022 HAL_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 
1073 HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
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 
1092 HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
1093 {
1094  __HAL_LOCK(hhcd);
1095  (void)USB_StopHost(hhcd->Instance);
1096  __HAL_UNLOCK(hhcd);
1097 
1098  return HAL_OK;
1099 }
1100 
1106 HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
1107 {
1108  return (USB_ResetPort(hhcd->Instance));
1109 }
1110 
1135 HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef const *hhcd)
1136 {
1137  return hhcd->State;
1138 }
1139 
1154 HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
1155 {
1156  return hhcd->hc[chnum].urb_state;
1157 }
1158 
1159 
1167 uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
1168 {
1169  return hhcd->hc[chnum].xfer_count;
1170 }
1171 
1189 HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
1190 {
1191  return hhcd->hc[chnum].state;
1192 }
1193 
1199 uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
1200 {
1201  return (USB_GetCurrentFrame(hhcd->Instance));
1202 }
1203 
1209 uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
1210 {
1211  return (USB_GetHostSpeed(hhcd->Instance));
1212 }
1213 
1223 HAL_StatusTypeDef HAL_HCD_HC_SetHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num,
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 
1253 HAL_StatusTypeDef HAL_HCD_HC_ClearHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
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 }
1280 static 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;
1334  __HAL_HCD_CLEAR_HC_CSPLT(chnum);
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;
1420  __HAL_HCD_CLEAR_HC_CSPLT(chnum);
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  }
1458  __HAL_HCD_CLEAR_HC_CSPLT(chnum);
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;
1580  __HAL_HCD_CLEAR_HC_CSPLT(chnum);
1581  __HAL_HCD_UNMASK_ACK_HC_INT(chnum);
1582  }
1583 
1584  __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
1585  }
1586  else
1587  {
1588  /* ... */
1589  }
1590 }
1591 
1599 static 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;
1657  __HAL_HCD_CLEAR_HC_CSPLT(chnum);
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;
1784  __HAL_HCD_CLEAR_HC_CSPLT(chnum);
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 
1840 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd)
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 
1906 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd)
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 
HAL_HCD_CallbackIDTypeDef
@ HAL_HCD_MSPINIT_CB_ID
@ HAL_HCD_PORT_DISABLED_CB_ID
@ HAL_HCD_PORT_ENABLED_CB_ID
@ HAL_HCD_CONNECT_CB_ID
@ HAL_HCD_SOF_CB_ID
@ HAL_HCD_DISCONNECT_CB_ID
@ HAL_HCD_MSPDEINIT_CB_ID
void(* pHCD_HC_NotifyURBChangeCallbackTypeDef)(HCD_HandleTypeDef *hhcd, uint8_t epnum, HCD_URBStateTypeDef urb_state)
void(* pHCD_CallbackTypeDef)(HCD_HandleTypeDef *hhcd)
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.
HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID, pHCD_CallbackTypeDef pCallback)
Register a User USB HCD Callback To be used instead of the weak predefined callback.
void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd)
Port Disabled Event callback.
void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
Connection Event callback.
HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd, pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback)
Register USB HCD Host Channel Notify URB Change Callback To be used instead of the weak HAL_HCD_HC_No...
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.
HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd)
Unregister the USB HCD Host Channel Notify URB Change Callback USB HCD Host Channel Notify URB Change...
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.
HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID)
Unregister an USB HCD Callback USB HCD callback is redirected to the weak predefined callback.
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.
uint32_t USB_GetMode(const USB_OTG_GlobalTypeDef *USBx)
Returns USB core mode.
uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef const *USBx)
Return Host Core speed.
HAL_StatusTypeDef USB_ResetPort(const USB_OTG_GlobalTypeDef *USBx)
USB_OTG_ResetPort : Reset Host Port.
uint32_t USB_HC_ReadInterrupt(const USB_OTG_GlobalTypeDef *USBx)
Read all host channel interrupts status.
void * USB_ReadPacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
USB_ReadPacket : read a packet from the RX FIFO.
HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, 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 USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
Initializes the USB Core.
HAL_StatusTypeDef USB_HC_Halt(const USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num)
Halt a host channel.
HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
USB_HostInit : Initializes the USB OTG controller registers for Host mode.
HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma)
Start a transfer over a host channel.
HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_OTG_ModeTypeDef mode)
USB_SetCurrentMode Set functional mode.
HAL_StatusTypeDef USB_DriveVbus(const USB_OTG_GlobalTypeDef *USBx, uint8_t state)
USB_DriveVbus : activate or de-activate vbus.
HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
USB_FlushRxFifo Flush Rx FIFO.
HAL_StatusTypeDef USB_InitFSLSPClkSel(const USB_OTG_GlobalTypeDef *USBx, uint8_t freq)
USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the HCFG register on the PHY type and set ...
HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
Stop Host Core.
HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
USB_FlushTxFifo Flush a Tx FIFO.
uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef const *USBx)
Return Host Current Frame number.
USB_HCStateTypeDef
Host channel States definition.
USB_URBStateTypeDef
URB States definition.
This file contains all the functions prototypes for the HAL module driver.