2 ******************************************************************************
\r
3 * @file stm32l4xx_hal_pcd.c
\r
4 * @author MCD Application Team
\r
5 * @brief PCD HAL module driver.
\r
6 * This file provides firmware functions to manage the following
\r
7 * functionalities of the USB Peripheral Controller:
\r
8 * + Initialization and de-initialization functions
\r
9 * + IO operation functions
\r
10 * + Peripheral Control functions
\r
11 * + Peripheral State functions
\r
14 ==============================================================================
\r
15 ##### How to use this driver #####
\r
16 ==============================================================================
\r
18 The PCD HAL driver can be used as follows:
\r
20 (#) Declare a PCD_HandleTypeDef handle structure, for example:
\r
21 PCD_HandleTypeDef hpcd;
\r
23 (#) Fill parameters of Init structure in HCD handle
\r
25 (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...)
\r
27 (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
\r
28 (##) Enable the PCD/USB Low Level interface clock using
\r
29 (+++) __HAL_RCC_USB_CLK_ENABLE(); For USB Device only FS peripheral
\r
31 (##) Initialize the related GPIO clocks
\r
32 (##) Configure PCD pin-out
\r
33 (##) Configure PCD NVIC interrupt
\r
35 (#)Associate the Upper USB device stack to the HAL PCD Driver:
\r
36 (##) hpcd.pData = pdev;
\r
38 (#)Enable PCD transmission and reception:
\r
39 (##) HAL_PCD_Start();
\r
42 ******************************************************************************
\r
45 * <h2><center>© Copyright (c) 2017 STMicroelectronics.
\r
46 * All rights reserved.</center></h2>
\r
48 * This software component is licensed by ST under BSD 3-Clause license,
\r
49 * the "License"; You may not use this file except in compliance with the
\r
50 * License. You may obtain a copy of the License at:
\r
51 * opensource.org/licenses/BSD-3-Clause
\r
53 ******************************************************************************
\r
56 /* Includes ------------------------------------------------------------------*/
\r
57 #include "stm32l4xx_hal.h"
\r
59 /** @addtogroup STM32L4xx_HAL_Driver
\r
63 /** @defgroup PCD PCD
\r
64 * @brief PCD HAL module driver
\r
68 #ifdef HAL_PCD_MODULE_ENABLED
\r
70 #if defined (USB) || defined (USB_OTG_FS)
\r
72 /* Private types -------------------------------------------------------------*/
\r
73 /* Private variables ---------------------------------------------------------*/
\r
74 /* Private constants ---------------------------------------------------------*/
\r
75 /* Private macros ------------------------------------------------------------*/
\r
76 /** @defgroup PCD_Private_Macros PCD Private Macros
\r
79 #define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b))
\r
80 #define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b))
\r
85 /* Private functions prototypes ----------------------------------------------*/
\r
86 /** @defgroup PCD_Private_Functions PCD Private Functions
\r
89 #if defined (USB_OTG_FS)
\r
90 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
\r
91 static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
\r
92 static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
\r
93 #endif /* defined (USB_OTG_FS) */
\r
96 static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
\r
97 #endif /* defined (USB) */
\r
102 /* Exported functions --------------------------------------------------------*/
\r
103 /** @defgroup PCD_Exported_Functions PCD Exported Functions
\r
107 /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
\r
108 * @brief Initialization and Configuration functions
\r
111 ===============================================================================
\r
112 ##### Initialization and de-initialization functions #####
\r
113 ===============================================================================
\r
114 [..] This section provides functions allowing to:
\r
121 * @brief Initializes the PCD according to the specified
\r
122 * parameters in the PCD_InitTypeDef and initialize the associated handle.
\r
123 * @param hpcd PCD handle
\r
124 * @retval HAL status
\r
126 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
\r
128 #if defined (USB_OTG_FS)
\r
129 USB_OTG_GlobalTypeDef *USBx;
\r
130 #endif /* defined (USB_OTG_FS) */
\r
133 /* Check the PCD handle allocation */
\r
139 /* Check the parameters */
\r
140 assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
\r
142 #if defined (USB_OTG_FS)
\r
143 USBx = hpcd->Instance;
\r
144 #endif /* defined (USB_OTG_FS) */
\r
146 if (hpcd->State == HAL_PCD_STATE_RESET)
\r
148 /* Allocate lock resource and initialize it */
\r
149 hpcd->Lock = HAL_UNLOCKED;
\r
151 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
152 hpcd->SOFCallback = HAL_PCD_SOFCallback;
\r
153 hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
\r
154 hpcd->ResetCallback = HAL_PCD_ResetCallback;
\r
155 hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
\r
156 hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
\r
157 hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
\r
158 hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
\r
159 hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback;
\r
160 hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback;
\r
161 hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback;
\r
162 hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback;
\r
163 hpcd->LPMCallback = HAL_PCDEx_LPM_Callback;
\r
164 hpcd->BCDCallback = HAL_PCDEx_BCD_Callback;
\r
166 if (hpcd->MspInitCallback == NULL)
\r
168 hpcd->MspInitCallback = HAL_PCD_MspInit;
\r
171 /* Init the low level hardware */
\r
172 hpcd->MspInitCallback(hpcd);
\r
174 /* Init the low level hardware : GPIO, CLOCK, NVIC... */
\r
175 HAL_PCD_MspInit(hpcd);
\r
176 #endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */
\r
179 hpcd->State = HAL_PCD_STATE_BUSY;
\r
181 #if defined (USB_OTG_FS)
\r
182 /* Disable DMA mode for FS instance */
\r
183 if ((USBx->CID & (0x1U << 8)) == 0U)
\r
185 hpcd->Init.dma_enable = 0U;
\r
187 #endif /* defined (USB_OTG_FS) */
\r
189 /* Disable the Interrupts */
\r
190 __HAL_PCD_DISABLE(hpcd);
\r
192 /*Init the Core (common init.) */
\r
193 if (USB_CoreInit(hpcd->Instance, hpcd->Init) != HAL_OK)
\r
195 hpcd->State = HAL_PCD_STATE_ERROR;
\r
199 /* Force Device Mode*/
\r
200 (void)USB_SetCurrentMode(hpcd->Instance, USB_DEVICE_MODE);
\r
202 /* Init endpoints structures */
\r
203 for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
\r
205 /* Init ep structure */
\r
206 hpcd->IN_ep[i].is_in = 1U;
\r
207 hpcd->IN_ep[i].num = i;
\r
208 hpcd->IN_ep[i].tx_fifo_num = i;
\r
209 /* Control until ep is activated */
\r
210 hpcd->IN_ep[i].type = EP_TYPE_CTRL;
\r
211 hpcd->IN_ep[i].maxpacket = 0U;
\r
212 hpcd->IN_ep[i].xfer_buff = 0U;
\r
213 hpcd->IN_ep[i].xfer_len = 0U;
\r
216 for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
\r
218 hpcd->OUT_ep[i].is_in = 0U;
\r
219 hpcd->OUT_ep[i].num = i;
\r
220 /* Control until ep is activated */
\r
221 hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
\r
222 hpcd->OUT_ep[i].maxpacket = 0U;
\r
223 hpcd->OUT_ep[i].xfer_buff = 0U;
\r
224 hpcd->OUT_ep[i].xfer_len = 0U;
\r
228 if (USB_DevInit(hpcd->Instance, hpcd->Init) != HAL_OK)
\r
230 hpcd->State = HAL_PCD_STATE_ERROR;
\r
234 hpcd->USB_Address = 0U;
\r
235 hpcd->State = HAL_PCD_STATE_READY;
\r
238 if (hpcd->Init.lpm_enable == 1U)
\r
240 (void)HAL_PCDEx_ActivateLPM(hpcd);
\r
243 (void)USB_DevDisconnect(hpcd->Instance);
\r
249 * @brief DeInitializes the PCD peripheral.
\r
250 * @param hpcd PCD handle
\r
251 * @retval HAL status
\r
253 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
\r
255 /* Check the PCD handle allocation */
\r
261 hpcd->State = HAL_PCD_STATE_BUSY;
\r
264 (void)HAL_PCD_Stop(hpcd);
\r
266 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
267 if (hpcd->MspDeInitCallback == NULL)
\r
269 hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit */
\r
272 /* DeInit the low level hardware */
\r
273 hpcd->MspDeInitCallback(hpcd);
\r
275 /* DeInit the low level hardware: CLOCK, NVIC.*/
\r
276 HAL_PCD_MspDeInit(hpcd);
\r
277 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
279 hpcd->State = HAL_PCD_STATE_RESET;
\r
285 * @brief Initializes the PCD MSP.
\r
286 * @param hpcd PCD handle
\r
289 __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
\r
291 /* Prevent unused argument(s) compilation warning */
\r
294 /* NOTE : This function should not be modified, when the callback is needed,
\r
295 the HAL_PCD_MspInit could be implemented in the user file
\r
300 * @brief DeInitializes PCD MSP.
\r
301 * @param hpcd PCD handle
\r
304 __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
\r
306 /* Prevent unused argument(s) compilation warning */
\r
309 /* NOTE : This function should not be modified, when the callback is needed,
\r
310 the HAL_PCD_MspDeInit could be implemented in the user file
\r
314 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
316 * @brief Register a User USB PCD Callback
\r
317 * To be used instead of the weak predefined callback
\r
318 * @param hpcd USB PCD handle
\r
319 * @param CallbackID ID of the callback to be registered
\r
320 * This parameter can be one of the following values:
\r
321 * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
\r
322 * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
\r
323 * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
\r
324 * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
\r
325 * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
\r
326 * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
\r
327 * @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
\r
328 * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
\r
329 * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
\r
330 * @param pCallback pointer to the Callback function
\r
331 * @retval HAL status
\r
333 HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID, pPCD_CallbackTypeDef pCallback)
\r
335 HAL_StatusTypeDef status = HAL_OK;
\r
337 if (pCallback == NULL)
\r
339 /* Update the error code */
\r
340 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
343 /* Process locked */
\r
346 if (hpcd->State == HAL_PCD_STATE_READY)
\r
348 switch (CallbackID)
\r
350 case HAL_PCD_SOF_CB_ID :
\r
351 hpcd->SOFCallback = pCallback;
\r
354 case HAL_PCD_SETUPSTAGE_CB_ID :
\r
355 hpcd->SetupStageCallback = pCallback;
\r
358 case HAL_PCD_RESET_CB_ID :
\r
359 hpcd->ResetCallback = pCallback;
\r
362 case HAL_PCD_SUSPEND_CB_ID :
\r
363 hpcd->SuspendCallback = pCallback;
\r
366 case HAL_PCD_RESUME_CB_ID :
\r
367 hpcd->ResumeCallback = pCallback;
\r
370 case HAL_PCD_CONNECT_CB_ID :
\r
371 hpcd->ConnectCallback = pCallback;
\r
374 case HAL_PCD_DISCONNECT_CB_ID :
\r
375 hpcd->DisconnectCallback = pCallback;
\r
378 case HAL_PCD_MSPINIT_CB_ID :
\r
379 hpcd->MspInitCallback = pCallback;
\r
382 case HAL_PCD_MSPDEINIT_CB_ID :
\r
383 hpcd->MspDeInitCallback = pCallback;
\r
387 /* Update the error code */
\r
388 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
389 /* Return error status */
\r
390 status = HAL_ERROR;
\r
394 else if (hpcd->State == HAL_PCD_STATE_RESET)
\r
396 switch (CallbackID)
\r
398 case HAL_PCD_MSPINIT_CB_ID :
\r
399 hpcd->MspInitCallback = pCallback;
\r
402 case HAL_PCD_MSPDEINIT_CB_ID :
\r
403 hpcd->MspDeInitCallback = pCallback;
\r
407 /* Update the error code */
\r
408 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
409 /* Return error status */
\r
410 status = HAL_ERROR;
\r
416 /* Update the error code */
\r
417 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
418 /* Return error status */
\r
419 status = HAL_ERROR;
\r
423 __HAL_UNLOCK(hpcd);
\r
428 * @brief Unregister an USB PCD Callback
\r
429 * USB PCD callabck is redirected to the weak predefined callback
\r
430 * @param hpcd USB PCD handle
\r
431 * @param CallbackID ID of the callback to be unregistered
\r
432 * This parameter can be one of the following values:
\r
433 * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
\r
434 * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
\r
435 * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
\r
436 * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
\r
437 * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
\r
438 * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
\r
439 * @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
\r
440 * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
\r
441 * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
\r
442 * @retval HAL status
\r
444 HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID)
\r
446 HAL_StatusTypeDef status = HAL_OK;
\r
448 /* Process locked */
\r
451 /* Setup Legacy weak Callbacks */
\r
452 if (hpcd->State == HAL_PCD_STATE_READY)
\r
454 switch (CallbackID)
\r
456 case HAL_PCD_SOF_CB_ID :
\r
457 hpcd->SOFCallback = HAL_PCD_SOFCallback;
\r
460 case HAL_PCD_SETUPSTAGE_CB_ID :
\r
461 hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
\r
464 case HAL_PCD_RESET_CB_ID :
\r
465 hpcd->ResetCallback = HAL_PCD_ResetCallback;
\r
468 case HAL_PCD_SUSPEND_CB_ID :
\r
469 hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
\r
472 case HAL_PCD_RESUME_CB_ID :
\r
473 hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
\r
476 case HAL_PCD_CONNECT_CB_ID :
\r
477 hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
\r
480 case HAL_PCD_DISCONNECT_CB_ID :
\r
481 hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
\r
484 case HAL_PCD_MSPINIT_CB_ID :
\r
485 hpcd->MspInitCallback = HAL_PCD_MspInit;
\r
488 case HAL_PCD_MSPDEINIT_CB_ID :
\r
489 hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
\r
493 /* Update the error code */
\r
494 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
496 /* Return error status */
\r
497 status = HAL_ERROR;
\r
501 else if (hpcd->State == HAL_PCD_STATE_RESET)
\r
503 switch (CallbackID)
\r
505 case HAL_PCD_MSPINIT_CB_ID :
\r
506 hpcd->MspInitCallback = HAL_PCD_MspInit;
\r
509 case HAL_PCD_MSPDEINIT_CB_ID :
\r
510 hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
\r
514 /* Update the error code */
\r
515 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
517 /* Return error status */
\r
518 status = HAL_ERROR;
\r
524 /* Update the error code */
\r
525 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
527 /* Return error status */
\r
528 status = HAL_ERROR;
\r
532 __HAL_UNLOCK(hpcd);
\r
537 * @brief Register USB PCD Data OUT Stage Callback
\r
538 * To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback
\r
539 * @param hpcd PCD handle
\r
540 * @param pCallback pointer to the USB PCD Data OUT Stage Callback function
\r
541 * @retval HAL status
\r
543 HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataOutStageCallbackTypeDef pCallback)
\r
545 HAL_StatusTypeDef status = HAL_OK;
\r
547 if (pCallback == NULL)
\r
549 /* Update the error code */
\r
550 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
555 /* Process locked */
\r
558 if (hpcd->State == HAL_PCD_STATE_READY)
\r
560 hpcd->DataOutStageCallback = pCallback;
\r
564 /* Update the error code */
\r
565 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
567 /* Return error status */
\r
568 status = HAL_ERROR;
\r
572 __HAL_UNLOCK(hpcd);
\r
578 * @brief UnRegister the USB PCD Data OUT Stage Callback
\r
579 * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback
\r
580 * @param hpcd PCD handle
\r
581 * @retval HAL status
\r
583 HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd)
\r
585 HAL_StatusTypeDef status = HAL_OK;
\r
587 /* Process locked */
\r
590 if (hpcd->State == HAL_PCD_STATE_READY)
\r
592 hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback */
\r
596 /* Update the error code */
\r
597 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
599 /* Return error status */
\r
600 status = HAL_ERROR;
\r
604 __HAL_UNLOCK(hpcd);
\r
610 * @brief Register USB PCD Data IN Stage Callback
\r
611 * To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback
\r
612 * @param hpcd PCD handle
\r
613 * @param pCallback pointer to the USB PCD Data IN Stage Callback function
\r
614 * @retval HAL status
\r
616 HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataInStageCallbackTypeDef pCallback)
\r
618 HAL_StatusTypeDef status = HAL_OK;
\r
620 if (pCallback == NULL)
\r
622 /* Update the error code */
\r
623 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
628 /* Process locked */
\r
631 if (hpcd->State == HAL_PCD_STATE_READY)
\r
633 hpcd->DataInStageCallback = pCallback;
\r
637 /* Update the error code */
\r
638 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
640 /* Return error status */
\r
641 status = HAL_ERROR;
\r
645 __HAL_UNLOCK(hpcd);
\r
651 * @brief UnRegister the USB PCD Data IN Stage Callback
\r
652 * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback
\r
653 * @param hpcd PCD handle
\r
654 * @retval HAL status
\r
656 HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd)
\r
658 HAL_StatusTypeDef status = HAL_OK;
\r
660 /* Process locked */
\r
663 if (hpcd->State == HAL_PCD_STATE_READY)
\r
665 hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback */
\r
669 /* Update the error code */
\r
670 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
672 /* Return error status */
\r
673 status = HAL_ERROR;
\r
677 __HAL_UNLOCK(hpcd);
\r
683 * @brief Register USB PCD Iso OUT incomplete Callback
\r
684 * To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
\r
685 * @param hpcd PCD handle
\r
686 * @param pCallback pointer to the USB PCD Iso OUT incomplete Callback function
\r
687 * @retval HAL status
\r
689 HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoOutIncpltCallbackTypeDef pCallback)
\r
691 HAL_StatusTypeDef status = HAL_OK;
\r
693 if (pCallback == NULL)
\r
695 /* Update the error code */
\r
696 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
701 /* Process locked */
\r
704 if (hpcd->State == HAL_PCD_STATE_READY)
\r
706 hpcd->ISOOUTIncompleteCallback = pCallback;
\r
710 /* Update the error code */
\r
711 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
713 /* Return error status */
\r
714 status = HAL_ERROR;
\r
718 __HAL_UNLOCK(hpcd);
\r
724 * @brief UnRegister the USB PCD Iso OUT incomplete Callback
\r
725 * USB PCD Iso OUT incomplete Callback is redirected to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
\r
726 * @param hpcd PCD handle
\r
727 * @retval HAL status
\r
729 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
\r
731 HAL_StatusTypeDef status = HAL_OK;
\r
733 /* Process locked */
\r
736 if (hpcd->State == HAL_PCD_STATE_READY)
\r
738 hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback */
\r
742 /* Update the error code */
\r
743 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
745 /* Return error status */
\r
746 status = HAL_ERROR;
\r
750 __HAL_UNLOCK(hpcd);
\r
756 * @brief Register USB PCD Iso IN incomplete Callback
\r
757 * To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
\r
758 * @param hpcd PCD handle
\r
759 * @param pCallback pointer to the USB PCD Iso IN incomplete Callback function
\r
760 * @retval HAL status
\r
762 HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoInIncpltCallbackTypeDef pCallback)
\r
764 HAL_StatusTypeDef status = HAL_OK;
\r
766 if (pCallback == NULL)
\r
768 /* Update the error code */
\r
769 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
774 /* Process locked */
\r
777 if (hpcd->State == HAL_PCD_STATE_READY)
\r
779 hpcd->ISOINIncompleteCallback = pCallback;
\r
783 /* Update the error code */
\r
784 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
786 /* Return error status */
\r
787 status = HAL_ERROR;
\r
791 __HAL_UNLOCK(hpcd);
\r
797 * @brief UnRegister the USB PCD Iso IN incomplete Callback
\r
798 * USB PCD Iso IN incomplete Callback is redirected to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
\r
799 * @param hpcd PCD handle
\r
800 * @retval HAL status
\r
802 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
\r
804 HAL_StatusTypeDef status = HAL_OK;
\r
806 /* Process locked */
\r
809 if (hpcd->State == HAL_PCD_STATE_READY)
\r
811 hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback */
\r
815 /* Update the error code */
\r
816 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
818 /* Return error status */
\r
819 status = HAL_ERROR;
\r
823 __HAL_UNLOCK(hpcd);
\r
829 * @brief Register USB PCD BCD Callback
\r
830 * To be used instead of the weak HAL_PCDEx_BCD_Callback() predefined callback
\r
831 * @param hpcd PCD handle
\r
832 * @param pCallback pointer to the USB PCD BCD Callback function
\r
833 * @retval HAL status
\r
835 HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback)
\r
837 HAL_StatusTypeDef status = HAL_OK;
\r
839 if (pCallback == NULL)
\r
841 /* Update the error code */
\r
842 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
847 /* Process locked */
\r
850 if (hpcd->State == HAL_PCD_STATE_READY)
\r
852 hpcd->BCDCallback = pCallback;
\r
856 /* Update the error code */
\r
857 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
859 /* Return error status */
\r
860 status = HAL_ERROR;
\r
864 __HAL_UNLOCK(hpcd);
\r
870 * @brief UnRegister the USB PCD BCD Callback
\r
871 * USB BCD Callback is redirected to the weak HAL_PCDEx_BCD_Callback() predefined callback
\r
872 * @param hpcd PCD handle
\r
873 * @retval HAL status
\r
875 HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd)
\r
877 HAL_StatusTypeDef status = HAL_OK;
\r
879 /* Process locked */
\r
882 if (hpcd->State == HAL_PCD_STATE_READY)
\r
884 hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; /* Legacy weak HAL_PCDEx_BCD_Callback */
\r
888 /* Update the error code */
\r
889 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
891 /* Return error status */
\r
892 status = HAL_ERROR;
\r
896 __HAL_UNLOCK(hpcd);
\r
902 * @brief Register USB PCD LPM Callback
\r
903 * To be used instead of the weak HAL_PCDEx_LPM_Callback() predefined callback
\r
904 * @param hpcd PCD handle
\r
905 * @param pCallback pointer to the USB PCD LPM Callback function
\r
906 * @retval HAL status
\r
908 HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback)
\r
910 HAL_StatusTypeDef status = HAL_OK;
\r
912 if (pCallback == NULL)
\r
914 /* Update the error code */
\r
915 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
920 /* Process locked */
\r
923 if (hpcd->State == HAL_PCD_STATE_READY)
\r
925 hpcd->LPMCallback = pCallback;
\r
929 /* Update the error code */
\r
930 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
932 /* Return error status */
\r
933 status = HAL_ERROR;
\r
937 __HAL_UNLOCK(hpcd);
\r
943 * @brief UnRegister the USB PCD LPM Callback
\r
944 * USB LPM Callback is redirected to the weak HAL_PCDEx_LPM_Callback() predefined callback
\r
945 * @param hpcd PCD handle
\r
946 * @retval HAL status
\r
948 HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd)
\r
950 HAL_StatusTypeDef status = HAL_OK;
\r
952 /* Process locked */
\r
955 if (hpcd->State == HAL_PCD_STATE_READY)
\r
957 hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; /* Legacy weak HAL_PCDEx_LPM_Callback */
\r
961 /* Update the error code */
\r
962 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
\r
964 /* Return error status */
\r
965 status = HAL_ERROR;
\r
969 __HAL_UNLOCK(hpcd);
\r
973 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
979 /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
\r
980 * @brief Data transfers functions
\r
983 ===============================================================================
\r
984 ##### IO operation functions #####
\r
985 ===============================================================================
\r
987 This subsection provides a set of functions allowing to manage the PCD data
\r
995 * @brief Start the USB device
\r
996 * @param hpcd PCD handle
\r
997 * @retval HAL status
\r
999 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
\r
1001 #if defined (USB_OTG_FS)
\r
1002 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
\r
1003 #endif /* defined (USB_OTG_FS) */
\r
1006 #if defined (USB_OTG_FS)
\r
1007 if (hpcd->Init.battery_charging_enable == 1U)
\r
1009 /* Enable USB Transceiver */
\r
1010 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
\r
1012 #endif /* defined (USB_OTG_FS) */
\r
1013 (void)USB_DevConnect(hpcd->Instance);
\r
1014 __HAL_PCD_ENABLE(hpcd);
\r
1015 __HAL_UNLOCK(hpcd);
\r
1020 * @brief Stop the USB device.
\r
1021 * @param hpcd PCD handle
\r
1022 * @retval HAL status
\r
1024 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
\r
1027 __HAL_PCD_DISABLE(hpcd);
\r
1029 if (USB_StopDevice(hpcd->Instance) != HAL_OK)
\r
1031 __HAL_UNLOCK(hpcd);
\r
1035 (void)USB_DevDisconnect(hpcd->Instance);
\r
1036 __HAL_UNLOCK(hpcd);
\r
1040 #if defined (USB_OTG_FS)
\r
1042 * @brief Handles PCD interrupt request.
\r
1043 * @param hpcd PCD handle
\r
1044 * @retval HAL status
\r
1046 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
\r
1048 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
\r
1049 uint32_t USBx_BASE = (uint32_t)USBx;
\r
1050 uint32_t i, ep_intr, epint, epnum = 0U;
\r
1051 uint32_t fifoemptymsk, temp;
\r
1052 USB_OTG_EPTypeDef *ep;
\r
1054 /* ensure that we are in device mode */
\r
1055 if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
\r
1057 /* avoid spurious interrupt */
\r
1058 if (__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
\r
1063 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
\r
1065 /* incorrect mode, acknowledge the interrupt */
\r
1066 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
\r
1069 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
\r
1073 /* Read in the device interrupt bits */
\r
1074 ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
\r
1076 while (ep_intr != 0U)
\r
1078 if ((ep_intr & 0x1U) != 0U)
\r
1080 epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum);
\r
1082 if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
\r
1084 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
\r
1085 (void)PCD_EP_OutXfrComplete_int(hpcd, epnum);
\r
1088 if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
\r
1090 /* Class B setup phase done for previous decoded setup */
\r
1091 (void)PCD_EP_OutSetupPacket_int(hpcd, epnum);
\r
1092 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
\r
1095 if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
\r
1097 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
\r
1100 /* Clear Status Phase Received interrupt */
\r
1101 if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
\r
1103 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
\r
1106 /* Clear OUT NAK interrupt */
\r
1107 if ((epint & USB_OTG_DOEPINT_NAK) == USB_OTG_DOEPINT_NAK)
\r
1109 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_NAK);
\r
1117 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
\r
1119 /* Read in the device interrupt bits */
\r
1120 ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
\r
1124 while (ep_intr != 0U)
\r
1126 if ((ep_intr & 0x1U) != 0U) /* In ITR */
\r
1128 epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum);
\r
1130 if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
\r
1132 fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
\r
1133 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
\r
1135 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
\r
1137 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1138 hpcd->DataInStageCallback(hpcd, (uint8_t)epnum);
\r
1140 HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum);
\r
1141 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1143 if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
\r
1145 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
\r
1147 if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
\r
1149 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
\r
1151 if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
\r
1153 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
\r
1155 if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
\r
1157 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
\r
1159 if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
\r
1161 (void)PCD_WriteEmptyTxFifo(hpcd, epnum);
\r
1169 /* Handle Resume Interrupt */
\r
1170 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
\r
1172 /* Clear the Remote Wake-up Signaling */
\r
1173 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
\r
1175 if (hpcd->LPM_State == LPM_L1)
\r
1177 hpcd->LPM_State = LPM_L0;
\r
1179 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1180 hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE);
\r
1182 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
\r
1183 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1187 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1188 hpcd->ResumeCallback(hpcd);
\r
1190 HAL_PCD_ResumeCallback(hpcd);
\r
1191 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1194 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
\r
1197 /* Handle Suspend Interrupt */
\r
1198 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
\r
1200 if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
\r
1202 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1203 hpcd->SuspendCallback(hpcd);
\r
1205 HAL_PCD_SuspendCallback(hpcd);
\r
1206 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1208 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
\r
1211 /* Handle LPM Interrupt */
\r
1212 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT))
\r
1214 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT);
\r
1216 if (hpcd->LPM_State == LPM_L0)
\r
1218 hpcd->LPM_State = LPM_L1;
\r
1219 hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >> 2U;
\r
1221 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1222 hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE);
\r
1224 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
\r
1225 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1229 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1230 hpcd->SuspendCallback(hpcd);
\r
1232 HAL_PCD_SuspendCallback(hpcd);
\r
1233 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1237 /* Handle Reset Interrupt */
\r
1238 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
\r
1240 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
\r
1241 (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
\r
1243 for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
\r
1245 USBx_INEP(i)->DIEPINT = 0xFB7FU;
\r
1246 USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
\r
1247 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
\r
1248 USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
\r
1250 USBx_DEVICE->DAINTMSK |= 0x10001U;
\r
1252 if (hpcd->Init.use_dedicated_ep1 != 0U)
\r
1254 USBx_DEVICE->DOUTEP1MSK |= USB_OTG_DOEPMSK_STUPM |
\r
1255 USB_OTG_DOEPMSK_XFRCM |
\r
1256 USB_OTG_DOEPMSK_EPDM;
\r
1258 USBx_DEVICE->DINEP1MSK |= USB_OTG_DIEPMSK_TOM |
\r
1259 USB_OTG_DIEPMSK_XFRCM |
\r
1260 USB_OTG_DIEPMSK_EPDM;
\r
1264 USBx_DEVICE->DOEPMSK |= USB_OTG_DOEPMSK_STUPM |
\r
1265 USB_OTG_DOEPMSK_XFRCM |
\r
1266 USB_OTG_DOEPMSK_EPDM |
\r
1267 USB_OTG_DOEPMSK_OTEPSPRM |
\r
1268 USB_OTG_DOEPMSK_NAKM;
\r
1270 USBx_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_TOM |
\r
1271 USB_OTG_DIEPMSK_XFRCM |
\r
1272 USB_OTG_DIEPMSK_EPDM;
\r
1275 /* Set Default Address to 0 */
\r
1276 USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
\r
1278 /* setup EP0 to receive SETUP packets */
\r
1279 (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
\r
1281 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
\r
1284 /* Handle Enumeration done Interrupt */
\r
1285 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
\r
1287 (void)USB_ActivateSetup(hpcd->Instance);
\r
1288 hpcd->Init.speed = USB_GetDevSpeed(hpcd->Instance);
\r
1290 /* Set USB Turnaround time */
\r
1291 (void)USB_SetTurnaroundTime(hpcd->Instance,
\r
1292 HAL_RCC_GetHCLKFreq(),
\r
1293 (uint8_t)hpcd->Init.speed);
\r
1295 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1296 hpcd->ResetCallback(hpcd);
\r
1298 HAL_PCD_ResetCallback(hpcd);
\r
1299 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1301 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
\r
1304 /* Handle RxQLevel Interrupt */
\r
1305 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
\r
1307 USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
\r
1309 temp = USBx->GRXSTSP;
\r
1311 ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
\r
1313 if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT)
\r
1315 if ((temp & USB_OTG_GRXSTSP_BCNT) != 0U)
\r
1317 (void)USB_ReadPacket(USBx, ep->xfer_buff,
\r
1318 (uint16_t)((temp & USB_OTG_GRXSTSP_BCNT) >> 4));
\r
1320 ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
\r
1321 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
\r
1324 else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT)
\r
1326 (void)USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
\r
1327 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
\r
1333 USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
\r
1336 /* Handle SOF Interrupt */
\r
1337 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
\r
1339 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1340 hpcd->SOFCallback(hpcd);
\r
1342 HAL_PCD_SOFCallback(hpcd);
\r
1343 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1345 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
\r
1348 /* Handle Incomplete ISO IN Interrupt */
\r
1349 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
\r
1351 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1352 hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
\r
1354 HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
\r
1355 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1357 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
\r
1360 /* Handle Incomplete ISO OUT Interrupt */
\r
1361 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
\r
1363 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1364 hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
\r
1366 HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
\r
1367 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1369 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
\r
1372 /* Handle Connection event Interrupt */
\r
1373 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
\r
1375 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1376 hpcd->ConnectCallback(hpcd);
\r
1378 HAL_PCD_ConnectCallback(hpcd);
\r
1379 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1381 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
\r
1384 /* Handle Disconnection event Interrupt */
\r
1385 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
\r
1387 temp = hpcd->Instance->GOTGINT;
\r
1389 if ((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
\r
1391 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1392 hpcd->DisconnectCallback(hpcd);
\r
1394 HAL_PCD_DisconnectCallback(hpcd);
\r
1395 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1397 hpcd->Instance->GOTGINT |= temp;
\r
1401 #endif /* defined (USB_OTG_FS) */
\r
1405 * @brief This function handles PCD interrupt request.
\r
1406 * @param hpcd PCD handle
\r
1407 * @retval HAL status
\r
1409 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
\r
1411 if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_CTR))
\r
1413 /* servicing of the endpoint correct transfer interrupt */
\r
1414 /* clear of the CTR flag into the sub */
\r
1415 (void)PCD_EP_ISR_Handler(hpcd);
\r
1418 if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_RESET))
\r
1420 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
\r
1422 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1423 hpcd->ResetCallback(hpcd);
\r
1425 HAL_PCD_ResetCallback(hpcd);
\r
1426 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1428 (void)HAL_PCD_SetAddress(hpcd, 0U);
\r
1431 if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_PMAOVR))
\r
1433 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
\r
1436 if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ERR))
\r
1438 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
\r
1441 if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP))
\r
1443 hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LPMODE);
\r
1444 hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP);
\r
1446 if (hpcd->LPM_State == LPM_L1)
\r
1448 hpcd->LPM_State = LPM_L0;
\r
1449 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1450 hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE);
\r
1452 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
\r
1453 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1456 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1457 hpcd->ResumeCallback(hpcd);
\r
1459 HAL_PCD_ResumeCallback(hpcd);
\r
1460 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1462 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
\r
1465 if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SUSP))
\r
1467 /* Force low-power mode in the macrocell */
\r
1468 hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
\r
1470 /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
\r
1471 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
\r
1473 hpcd->Instance->CNTR |= USB_CNTR_LPMODE;
\r
1475 if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP) == 0U)
\r
1477 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1478 hpcd->SuspendCallback(hpcd);
\r
1480 HAL_PCD_SuspendCallback(hpcd);
\r
1481 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1485 /* Handle LPM Interrupt */
\r
1486 if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_L1REQ))
\r
1488 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_L1REQ);
\r
1489 if (hpcd->LPM_State == LPM_L0)
\r
1491 /* Force suspend and low-power mode before going to L1 state*/
\r
1492 hpcd->Instance->CNTR |= USB_CNTR_LPMODE;
\r
1493 hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
\r
1495 hpcd->LPM_State = LPM_L1;
\r
1496 hpcd->BESL = ((uint32_t)hpcd->Instance->LPMCSR & USB_LPMCSR_BESL) >> 2;
\r
1497 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1498 hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE);
\r
1500 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
\r
1501 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1505 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1506 hpcd->SuspendCallback(hpcd);
\r
1508 HAL_PCD_SuspendCallback(hpcd);
\r
1509 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1513 if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SOF))
\r
1515 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
\r
1517 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
1518 hpcd->SOFCallback(hpcd);
\r
1520 HAL_PCD_SOFCallback(hpcd);
\r
1521 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
1524 if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ESOF))
\r
1526 /* clear ESOF flag in ISTR */
\r
1527 __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
\r
1530 #endif /* defined (USB) */
\r
1533 * @brief Data OUT stage callback.
\r
1534 * @param hpcd PCD handle
\r
1535 * @param epnum endpoint number
\r
1538 __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
\r
1540 /* Prevent unused argument(s) compilation warning */
\r
1544 /* NOTE : This function should not be modified, when the callback is needed,
\r
1545 the HAL_PCD_DataOutStageCallback could be implemented in the user file
\r
1550 * @brief Data IN stage callback
\r
1551 * @param hpcd PCD handle
\r
1552 * @param epnum endpoint number
\r
1555 __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
\r
1557 /* Prevent unused argument(s) compilation warning */
\r
1561 /* NOTE : This function should not be modified, when the callback is needed,
\r
1562 the HAL_PCD_DataInStageCallback could be implemented in the user file
\r
1566 * @brief Setup stage callback
\r
1567 * @param hpcd PCD handle
\r
1570 __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
\r
1572 /* Prevent unused argument(s) compilation warning */
\r
1575 /* NOTE : This function should not be modified, when the callback is needed,
\r
1576 the HAL_PCD_SetupStageCallback could be implemented in the user file
\r
1581 * @brief USB Start Of Frame callback.
\r
1582 * @param hpcd PCD handle
\r
1585 __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
\r
1587 /* Prevent unused argument(s) compilation warning */
\r
1590 /* NOTE : This function should not be modified, when the callback is needed,
\r
1591 the HAL_PCD_SOFCallback could be implemented in the user file
\r
1596 * @brief USB Reset callback.
\r
1597 * @param hpcd PCD handle
\r
1600 __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
\r
1602 /* Prevent unused argument(s) compilation warning */
\r
1605 /* NOTE : This function should not be modified, when the callback is needed,
\r
1606 the HAL_PCD_ResetCallback could be implemented in the user file
\r
1611 * @brief Suspend event callback.
\r
1612 * @param hpcd PCD handle
\r
1615 __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
\r
1617 /* Prevent unused argument(s) compilation warning */
\r
1620 /* NOTE : This function should not be modified, when the callback is needed,
\r
1621 the HAL_PCD_SuspendCallback could be implemented in the user file
\r
1626 * @brief Resume event callback.
\r
1627 * @param hpcd PCD handle
\r
1630 __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
\r
1632 /* Prevent unused argument(s) compilation warning */
\r
1635 /* NOTE : This function should not be modified, when the callback is needed,
\r
1636 the HAL_PCD_ResumeCallback could be implemented in the user file
\r
1641 * @brief Incomplete ISO OUT callback.
\r
1642 * @param hpcd PCD handle
\r
1643 * @param epnum endpoint number
\r
1646 __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
\r
1648 /* Prevent unused argument(s) compilation warning */
\r
1652 /* NOTE : This function should not be modified, when the callback is needed,
\r
1653 the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
\r
1658 * @brief Incomplete ISO IN callback.
\r
1659 * @param hpcd PCD handle
\r
1660 * @param epnum endpoint number
\r
1663 __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
\r
1665 /* Prevent unused argument(s) compilation warning */
\r
1669 /* NOTE : This function should not be modified, when the callback is needed,
\r
1670 the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
\r
1675 * @brief Connection event callback.
\r
1676 * @param hpcd PCD handle
\r
1679 __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
\r
1681 /* Prevent unused argument(s) compilation warning */
\r
1684 /* NOTE : This function should not be modified, when the callback is needed,
\r
1685 the HAL_PCD_ConnectCallback could be implemented in the user file
\r
1690 * @brief Disconnection event callback.
\r
1691 * @param hpcd PCD handle
\r
1694 __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
\r
1696 /* Prevent unused argument(s) compilation warning */
\r
1699 /* NOTE : This function should not be modified, when the callback is needed,
\r
1700 the HAL_PCD_DisconnectCallback could be implemented in the user file
\r
1708 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
\r
1709 * @brief management functions
\r
1712 ===============================================================================
\r
1713 ##### Peripheral Control functions #####
\r
1714 ===============================================================================
\r
1716 This subsection provides a set of functions allowing to control the PCD data
\r
1724 * @brief Connect the USB device
\r
1725 * @param hpcd PCD handle
\r
1726 * @retval HAL status
\r
1728 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
\r
1730 #if defined (USB_OTG_FS)
\r
1731 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
\r
1732 #endif /* defined (USB_OTG_FS) */
\r
1735 #if defined (USB_OTG_FS)
\r
1736 if (hpcd->Init.battery_charging_enable == 1U)
\r
1738 /* Enable USB Transceiver */
\r
1739 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
\r
1741 #endif /* defined (USB_OTG_FS) */
\r
1742 (void)USB_DevConnect(hpcd->Instance);
\r
1743 __HAL_UNLOCK(hpcd);
\r
1748 * @brief Disconnect the USB device.
\r
1749 * @param hpcd PCD handle
\r
1750 * @retval HAL status
\r
1752 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
\r
1754 #if defined (USB_OTG_FS)
\r
1755 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
\r
1757 #endif /* defined (USB_OTG_FS) */
\r
1759 (void)USB_DevDisconnect(hpcd->Instance);
\r
1760 #if defined (USB_OTG_FS)
\r
1761 if (hpcd->Init.battery_charging_enable == 1U)
\r
1763 /* Disable USB Transceiver */
\r
1764 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
\r
1766 #endif /* defined (USB_OTG_FS) */
\r
1767 __HAL_UNLOCK(hpcd);
\r
1772 * @brief Set the USB Device address.
\r
1773 * @param hpcd PCD handle
\r
1774 * @param address new device address
\r
1775 * @retval HAL status
\r
1777 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
\r
1780 hpcd->USB_Address = address;
\r
1781 (void)USB_SetDevAddress(hpcd->Instance, address);
\r
1782 __HAL_UNLOCK(hpcd);
\r
1786 * @brief Open and configure an endpoint.
\r
1787 * @param hpcd PCD handle
\r
1788 * @param ep_addr endpoint address
\r
1789 * @param ep_mps endpoint max packet size
\r
1790 * @param ep_type endpoint type
\r
1791 * @retval HAL status
\r
1793 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
\r
1795 HAL_StatusTypeDef ret = HAL_OK;
\r
1796 PCD_EPTypeDef *ep;
\r
1798 if ((ep_addr & 0x80U) == 0x80U)
\r
1800 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
\r
1805 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
\r
1809 ep->num = ep_addr & EP_ADDR_MSK;
\r
1810 ep->maxpacket = ep_mps;
\r
1811 ep->type = ep_type;
\r
1813 if (ep->is_in != 0U)
\r
1815 /* Assign a Tx FIFO */
\r
1816 ep->tx_fifo_num = ep->num;
\r
1818 /* Set initial data PID. */
\r
1819 if (ep_type == EP_TYPE_BULK)
\r
1821 ep->data_pid_start = 0U;
\r
1825 (void)USB_ActivateEndpoint(hpcd->Instance, ep);
\r
1826 __HAL_UNLOCK(hpcd);
\r
1832 * @brief Deactivate an endpoint.
\r
1833 * @param hpcd PCD handle
\r
1834 * @param ep_addr endpoint address
\r
1835 * @retval HAL status
\r
1837 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
\r
1839 PCD_EPTypeDef *ep;
\r
1841 if ((ep_addr & 0x80U) == 0x80U)
\r
1843 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
\r
1848 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
\r
1851 ep->num = ep_addr & EP_ADDR_MSK;
\r
1854 (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
\r
1855 __HAL_UNLOCK(hpcd);
\r
1861 * @brief Receive an amount of data.
\r
1862 * @param hpcd PCD handle
\r
1863 * @param ep_addr endpoint address
\r
1864 * @param pBuf pointer to the reception buffer
\r
1865 * @param len amount of data to be received
\r
1866 * @retval HAL status
\r
1868 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
\r
1870 PCD_EPTypeDef *ep;
\r
1872 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
\r
1874 /*setup and start the Xfer */
\r
1875 ep->xfer_buff = pBuf;
\r
1876 ep->xfer_len = len;
\r
1877 ep->xfer_count = 0U;
\r
1879 ep->num = ep_addr & EP_ADDR_MSK;
\r
1881 if ((ep_addr & EP_ADDR_MSK) == 0U)
\r
1883 (void)USB_EP0StartXfer(hpcd->Instance, ep);
\r
1887 (void)USB_EPStartXfer(hpcd->Instance, ep);
\r
1894 * @brief Get Received Data Size
\r
1895 * @param hpcd PCD handle
\r
1896 * @param ep_addr endpoint address
\r
1897 * @retval Data Size
\r
1899 uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
\r
1901 return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count;
\r
1904 * @brief Send an amount of data
\r
1905 * @param hpcd PCD handle
\r
1906 * @param ep_addr endpoint address
\r
1907 * @param pBuf pointer to the transmission buffer
\r
1908 * @param len amount of data to be sent
\r
1909 * @retval HAL status
\r
1911 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
\r
1913 PCD_EPTypeDef *ep;
\r
1915 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
\r
1917 /*setup and start the Xfer */
\r
1918 ep->xfer_buff = pBuf;
\r
1919 ep->xfer_len = len;
\r
1920 ep->xfer_count = 0U;
\r
1922 ep->num = ep_addr & EP_ADDR_MSK;
\r
1924 if ((ep_addr & EP_ADDR_MSK) == 0U)
\r
1926 (void)USB_EP0StartXfer(hpcd->Instance, ep);
\r
1930 (void)USB_EPStartXfer(hpcd->Instance, ep);
\r
1937 * @brief Set a STALL condition over an endpoint
\r
1938 * @param hpcd PCD handle
\r
1939 * @param ep_addr endpoint address
\r
1940 * @retval HAL status
\r
1942 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
\r
1944 PCD_EPTypeDef *ep;
\r
1946 if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints)
\r
1951 if ((0x80U & ep_addr) == 0x80U)
\r
1953 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
\r
1958 ep = &hpcd->OUT_ep[ep_addr];
\r
1962 ep->is_stall = 1U;
\r
1963 ep->num = ep_addr & EP_ADDR_MSK;
\r
1967 (void)USB_EPSetStall(hpcd->Instance, ep);
\r
1968 if ((ep_addr & EP_ADDR_MSK) == 0U)
\r
1970 (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
\r
1972 __HAL_UNLOCK(hpcd);
\r
1978 * @brief Clear a STALL condition over in an endpoint
\r
1979 * @param hpcd PCD handle
\r
1980 * @param ep_addr endpoint address
\r
1981 * @retval HAL status
\r
1983 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
\r
1985 PCD_EPTypeDef *ep;
\r
1987 if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
\r
1992 if ((0x80U & ep_addr) == 0x80U)
\r
1994 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
\r
1999 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
\r
2003 ep->is_stall = 0U;
\r
2004 ep->num = ep_addr & EP_ADDR_MSK;
\r
2007 (void)USB_EPClearStall(hpcd->Instance, ep);
\r
2008 __HAL_UNLOCK(hpcd);
\r
2014 * @brief Flush an endpoint
\r
2015 * @param hpcd PCD handle
\r
2016 * @param ep_addr endpoint address
\r
2017 * @retval HAL status
\r
2019 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
\r
2023 if ((ep_addr & 0x80U) == 0x80U)
\r
2025 (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & EP_ADDR_MSK);
\r
2029 (void)USB_FlushRxFifo(hpcd->Instance);
\r
2032 __HAL_UNLOCK(hpcd);
\r
2038 * @brief Activate remote wakeup signalling
\r
2039 * @param hpcd PCD handle
\r
2040 * @retval HAL status
\r
2042 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
\r
2044 return (USB_ActivateRemoteWakeup(hpcd->Instance));
\r
2048 * @brief De-activate remote wakeup signalling.
\r
2049 * @param hpcd PCD handle
\r
2050 * @retval HAL status
\r
2052 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
\r
2054 return (USB_DeActivateRemoteWakeup(hpcd->Instance));
\r
2061 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
\r
2062 * @brief Peripheral State functions
\r
2065 ===============================================================================
\r
2066 ##### Peripheral State functions #####
\r
2067 ===============================================================================
\r
2069 This subsection permits to get in run-time the status of the peripheral
\r
2070 and the data flow.
\r
2077 * @brief Return the PCD handle state.
\r
2078 * @param hpcd PCD handle
\r
2079 * @retval HAL state
\r
2081 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
\r
2083 return hpcd->State;
\r
2094 /* Private functions ---------------------------------------------------------*/
\r
2095 /** @addtogroup PCD_Private_Functions
\r
2098 #if defined (USB_OTG_FS)
\r
2100 * @brief Check FIFO for the next packet to be loaded.
\r
2101 * @param hpcd PCD handle
\r
2102 * @param epnum endpoint number
\r
2103 * @retval HAL status
\r
2105 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
\r
2107 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
\r
2108 uint32_t USBx_BASE = (uint32_t)USBx;
\r
2109 USB_OTG_EPTypeDef *ep;
\r
2112 uint32_t fifoemptymsk;
\r
2114 ep = &hpcd->IN_ep[epnum];
\r
2116 if (ep->xfer_count > ep->xfer_len)
\r
2121 len = ep->xfer_len - ep->xfer_count;
\r
2123 if (len > ep->maxpacket)
\r
2125 len = ep->maxpacket;
\r
2128 len32b = (len + 3U) / 4U;
\r
2130 while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) &&
\r
2131 (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U))
\r
2133 /* Write the FIFO */
\r
2134 len = ep->xfer_len - ep->xfer_count;
\r
2136 if (len > ep->maxpacket)
\r
2138 len = ep->maxpacket;
\r
2140 len32b = (len + 3U) / 4U;
\r
2142 (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len);
\r
2144 ep->xfer_buff += len;
\r
2145 ep->xfer_count += len;
\r
2148 if (ep->xfer_len <= ep->xfer_count)
\r
2150 fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
\r
2151 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
\r
2159 * @brief process EP OUT transfer complete interrupt.
\r
2160 * @param hpcd PCD handle
\r
2161 * @param epnum endpoint number
\r
2162 * @retval HAL status
\r
2164 static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
\r
2166 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
\r
2167 uint32_t USBx_BASE = (uint32_t)USBx;
\r
2168 uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
\r
2169 uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
\r
2171 if (gSNPSiD == USB_OTG_CORE_ID_310A)
\r
2173 /* StupPktRcvd = 1 this is a setup packet */
\r
2174 if ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)
\r
2176 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
\r
2180 if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
\r
2182 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
\r
2185 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
2186 hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
\r
2188 HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
\r
2189 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
2194 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
2195 hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
\r
2197 HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
\r
2198 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
2206 * @brief process EP OUT setup packet received interrupt.
\r
2207 * @param hpcd PCD handle
\r
2208 * @param epnum endpoint number
\r
2209 * @retval HAL status
\r
2211 static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
\r
2213 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
\r
2214 uint32_t USBx_BASE = (uint32_t)USBx;
\r
2215 uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
\r
2216 uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
\r
2219 if ((gSNPSiD == USB_OTG_CORE_ID_310A) &&
\r
2220 ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
\r
2222 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
\r
2225 /* Inform the upper layer that a setup packet is available */
\r
2226 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
2227 hpcd->SetupStageCallback(hpcd);
\r
2229 HAL_PCD_SetupStageCallback(hpcd);
\r
2230 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
2234 #endif /* defined (USB_OTG_FS) */
\r
2238 * @brief This function handles PCD Endpoint interrupt request.
\r
2239 * @param hpcd PCD handle
\r
2240 * @retval HAL status
\r
2242 static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
\r
2244 PCD_EPTypeDef *ep;
\r
2250 /* stay in loop while pending interrupts */
\r
2251 while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U)
\r
2253 wIstr = hpcd->Instance->ISTR;
\r
2254 /* extract highest priority endpoint number */
\r
2255 epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
\r
2257 if (epindex == 0U)
\r
2259 /* Decode and service control endpoint interrupt */
\r
2261 /* DIR bit = origin of the interrupt */
\r
2262 if ((wIstr & USB_ISTR_DIR) == 0U)
\r
2266 /* DIR = 0 => IN int */
\r
2267 /* DIR = 0 implies that (EP_CTR_TX = 1) always */
\r
2268 PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
\r
2269 ep = &hpcd->IN_ep[0];
\r
2271 ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
\r
2272 ep->xfer_buff += ep->xfer_count;
\r
2275 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
2276 hpcd->DataInStageCallback(hpcd, 0U);
\r
2278 HAL_PCD_DataInStageCallback(hpcd, 0U);
\r
2279 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
2281 if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U))
\r
2283 hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF);
\r
2284 hpcd->USB_Address = 0U;
\r
2291 /* DIR = 1 & CTR_RX => SETUP or OUT int */
\r
2292 /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
\r
2293 ep = &hpcd->OUT_ep[0];
\r
2294 wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
\r
2296 if ((wEPVal & USB_EP_SETUP) != 0U)
\r
2298 /* Get SETUP Packet*/
\r
2299 ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
\r
2301 USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup,
\r
2302 ep->pmaadress, (uint16_t)ep->xfer_count);
\r
2304 /* SETUP bit kept frozen while CTR_RX = 1*/
\r
2305 PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
\r
2307 /* Process SETUP Packet*/
\r
2308 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
2309 hpcd->SetupStageCallback(hpcd);
\r
2311 HAL_PCD_SetupStageCallback(hpcd);
\r
2312 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
2315 else if ((wEPVal & USB_EP_CTR_RX) != 0U)
\r
2317 PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
\r
2319 /* Get Control Data OUT Packet*/
\r
2320 ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
\r
2322 if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U))
\r
2324 USB_ReadPMA(hpcd->Instance, ep->xfer_buff,
\r
2325 ep->pmaadress, (uint16_t)ep->xfer_count);
\r
2327 ep->xfer_buff += ep->xfer_count;
\r
2329 /* Process Control Data OUT Packet*/
\r
2330 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
2331 hpcd->DataOutStageCallback(hpcd, 0U);
\r
2333 HAL_PCD_DataOutStageCallback(hpcd, 0U);
\r
2334 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
2337 PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
\r
2338 PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
\r
2344 /* Decode and service non control endpoints interrupt */
\r
2346 /* process related endpoint register */
\r
2347 wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
\r
2348 if ((wEPVal & USB_EP_CTR_RX) != 0U)
\r
2350 /* clear int flag */
\r
2351 PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
\r
2352 ep = &hpcd->OUT_ep[epindex];
\r
2354 /* OUT double Buffering*/
\r
2355 if (ep->doublebuffer == 0U)
\r
2357 count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
\r
2360 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
\r
2365 if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U)
\r
2367 /*read from endpoint BUF0Addr buffer*/
\r
2368 count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
\r
2371 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
\r
2376 /*read from endpoint BUF1Addr buffer*/
\r
2377 count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
\r
2380 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
\r
2383 /* free EP OUT Buffer */
\r
2384 PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U);
\r
2386 /*multi-packet on the NON control OUT endpoint*/
\r
2387 ep->xfer_count += count;
\r
2388 ep->xfer_buff += count;
\r
2390 if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
\r
2393 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
2394 hpcd->DataOutStageCallback(hpcd, ep->num);
\r
2396 HAL_PCD_DataOutStageCallback(hpcd, ep->num);
\r
2397 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
2401 (void)HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
\r
2404 } /* if((wEPVal & EP_CTR_RX) */
\r
2406 if ((wEPVal & USB_EP_CTR_TX) != 0U)
\r
2408 ep = &hpcd->IN_ep[epindex];
\r
2410 /* clear int flag */
\r
2411 PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
\r
2413 /*multi-packet on the NON control IN endpoint*/
\r
2414 ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
\r
2415 ep->xfer_buff += ep->xfer_count;
\r
2417 /* Zero Length Packet? */
\r
2418 if (ep->xfer_len == 0U)
\r
2421 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
\r
2422 hpcd->DataInStageCallback(hpcd, ep->num);
\r
2424 HAL_PCD_DataInStageCallback(hpcd, ep->num);
\r
2425 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
\r
2429 (void)HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
\r
2436 #endif /* defined (USB) */
\r
2441 #endif /* defined (USB) || defined (USB_OTG_FS) */
\r
2442 #endif /* HAL_PCD_MODULE_ENABLED */
\r
2452 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\r