1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_pcd.c
4 * @author MCD Application Team
5 * @brief PCD HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the USB Peripheral Controller:
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 * + Peripheral Control functions
11 * + Peripheral State functions
12 *
13 ******************************************************************************
14 * @attention
15 *
16 * Copyright (c) 2016 STMicroelectronics.
17 * All rights reserved.
18 *
19 * This software is licensed under terms that can be found in the LICENSE file
20 * in the root directory of this software component.
21 * If no LICENSE file comes with this software, it is provided AS-IS.
22 *
23 ******************************************************************************
24 @verbatim
25 ==============================================================================
26 ##### How to use this driver #####
27 ==============================================================================
28 [..]
29 The PCD HAL driver can be used as follows:
30
31 (#) Declare a PCD_HandleTypeDef handle structure, for example:
32 PCD_HandleTypeDef hpcd;
33
34 (#) Fill parameters of Init structure in HCD handle
35
36 (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...)
37
38 (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
39 (##) Enable the PCD/USB Low Level interface clock using
40 (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
41 (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode)
42
43 (##) Initialize the related GPIO clocks
44 (##) Configure PCD pin-out
45 (##) Configure PCD NVIC interrupt
46
47 (#)Associate the Upper USB device stack to the HAL PCD Driver:
48 (##) hpcd.pData = pdev;
49
50 (#)Enable PCD transmission and reception:
51 (##) HAL_PCD_Start();
52
53 @endverbatim
54 ******************************************************************************
55 */
56
57 /* Includes ------------------------------------------------------------------*/
58 #include "stm32f4xx_hal.h"
59
60 /** @addtogroup STM32F4xx_HAL_Driver
61 * @{
62 */
63
64 /** @defgroup PCD PCD
65 * @brief PCD HAL module driver
66 * @{
67 */
68
69 #ifdef HAL_PCD_MODULE_ENABLED
70
71 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
72
73 /* Private types -------------------------------------------------------------*/
74 /* Private variables ---------------------------------------------------------*/
75 /* Private constants ---------------------------------------------------------*/
76 /* Private macros ------------------------------------------------------------*/
77 /** @defgroup PCD_Private_Macros PCD Private Macros
78 * @{
79 */
80 #define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b))
81 #define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b))
82 /**
83 * @}
84 */
85
86 /* Private functions prototypes ----------------------------------------------*/
87 /** @defgroup PCD_Private_Functions PCD Private Functions
88 * @{
89 */
90 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
91 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
92 static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
93 static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
94 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
95 /**
96 * @}
97 */
98
99 /* Exported functions --------------------------------------------------------*/
100 /** @defgroup PCD_Exported_Functions PCD Exported Functions
101 * @{
102 */
103
104 /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
105 * @brief Initialization and Configuration functions
106 *
107 @verbatim
108 ===============================================================================
109 ##### Initialization and de-initialization functions #####
110 ===============================================================================
111 [..] This section provides functions allowing to:
112
113 @endverbatim
114 * @{
115 */
116
117 /**
118 * @brief Initializes the PCD according to the specified
119 * parameters in the PCD_InitTypeDef and initialize the associated handle.
120 * @param hpcd PCD handle
121 * @retval HAL status
122 */
HAL_PCD_Init(PCD_HandleTypeDef * hpcd)123 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
124 {
125 #if defined (USB_OTG_FS)
126 const USB_OTG_GlobalTypeDef *USBx;
127 #endif /* defined (USB_OTG_FS) */
128 uint8_t i;
129
130 /* Check the PCD handle allocation */
131 if (hpcd == NULL)
132 {
133 return HAL_ERROR;
134 }
135
136 /* Check the parameters */
137 assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
138
139 #if defined (USB_OTG_FS)
140 USBx = hpcd->Instance;
141 #endif /* defined (USB_OTG_FS) */
142
143 if (hpcd->State == HAL_PCD_STATE_RESET)
144 {
145 /* Allocate lock resource and initialize it */
146 hpcd->Lock = HAL_UNLOCKED;
147
148 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
149 hpcd->SOFCallback = HAL_PCD_SOFCallback;
150 hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
151 hpcd->ResetCallback = HAL_PCD_ResetCallback;
152 hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
153 hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
154 hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
155 hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
156 hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback;
157 hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback;
158 hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback;
159 hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback;
160 hpcd->LPMCallback = HAL_PCDEx_LPM_Callback;
161 hpcd->BCDCallback = HAL_PCDEx_BCD_Callback;
162
163 if (hpcd->MspInitCallback == NULL)
164 {
165 hpcd->MspInitCallback = HAL_PCD_MspInit;
166 }
167
168 /* Init the low level hardware */
169 hpcd->MspInitCallback(hpcd);
170 #else
171 /* Init the low level hardware : GPIO, CLOCK, NVIC... */
172 HAL_PCD_MspInit(hpcd);
173 #endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */
174 }
175
176 hpcd->State = HAL_PCD_STATE_BUSY;
177
178 #if defined (USB_OTG_FS)
179 /* Disable DMA mode for FS instance */
180 if (USBx == USB_OTG_FS)
181 {
182 hpcd->Init.dma_enable = 0U;
183 }
184 #endif /* defined (USB_OTG_FS) */
185
186 /* Disable the Interrupts */
187 __HAL_PCD_DISABLE(hpcd);
188
189 /*Init the Core (common init.) */
190 if (USB_CoreInit(hpcd->Instance, hpcd->Init) != HAL_OK)
191 {
192 hpcd->State = HAL_PCD_STATE_ERROR;
193 return HAL_ERROR;
194 }
195
196 /* Force Device Mode */
197 if (USB_SetCurrentMode(hpcd->Instance, USB_DEVICE_MODE) != HAL_OK)
198 {
199 hpcd->State = HAL_PCD_STATE_ERROR;
200 return HAL_ERROR;
201 }
202
203 /* Init endpoints structures */
204 for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
205 {
206 /* Init ep structure */
207 hpcd->IN_ep[i].is_in = 1U;
208 hpcd->IN_ep[i].num = i;
209 hpcd->IN_ep[i].tx_fifo_num = i;
210 /* Control until ep is activated */
211 hpcd->IN_ep[i].type = EP_TYPE_CTRL;
212 hpcd->IN_ep[i].maxpacket = 0U;
213 hpcd->IN_ep[i].xfer_buff = 0U;
214 hpcd->IN_ep[i].xfer_len = 0U;
215 }
216
217 for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
218 {
219 hpcd->OUT_ep[i].is_in = 0U;
220 hpcd->OUT_ep[i].num = i;
221 /* Control until ep is activated */
222 hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
223 hpcd->OUT_ep[i].maxpacket = 0U;
224 hpcd->OUT_ep[i].xfer_buff = 0U;
225 hpcd->OUT_ep[i].xfer_len = 0U;
226 }
227
228 /* Init Device */
229 if (USB_DevInit(hpcd->Instance, hpcd->Init) != HAL_OK)
230 {
231 hpcd->State = HAL_PCD_STATE_ERROR;
232 return HAL_ERROR;
233 }
234
235 hpcd->USB_Address = 0U;
236 hpcd->State = HAL_PCD_STATE_READY;
237 #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) \
238 || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) \
239 || defined(STM32F423xx)
240 /* Activate LPM */
241 if (hpcd->Init.lpm_enable == 1U)
242 {
243 (void)HAL_PCDEx_ActivateLPM(hpcd);
244 }
245 #endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||
246 defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) ||
247 defined(STM32F423xx) */
248 (void)USB_DevDisconnect(hpcd->Instance);
249
250 return HAL_OK;
251 }
252
253 /**
254 * @brief DeInitializes the PCD peripheral.
255 * @param hpcd PCD handle
256 * @retval HAL status
257 */
HAL_PCD_DeInit(PCD_HandleTypeDef * hpcd)258 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
259 {
260 /* Check the PCD handle allocation */
261 if (hpcd == NULL)
262 {
263 return HAL_ERROR;
264 }
265
266 hpcd->State = HAL_PCD_STATE_BUSY;
267
268 /* Stop Device */
269 if (USB_StopDevice(hpcd->Instance) != HAL_OK)
270 {
271 return HAL_ERROR;
272 }
273
274 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
275 if (hpcd->MspDeInitCallback == NULL)
276 {
277 hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit */
278 }
279
280 /* DeInit the low level hardware */
281 hpcd->MspDeInitCallback(hpcd);
282 #else
283 /* DeInit the low level hardware: CLOCK, NVIC.*/
284 HAL_PCD_MspDeInit(hpcd);
285 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
286
287 hpcd->State = HAL_PCD_STATE_RESET;
288
289 return HAL_OK;
290 }
291
292 /**
293 * @brief Initializes the PCD MSP.
294 * @param hpcd PCD handle
295 * @retval None
296 */
HAL_PCD_MspInit(PCD_HandleTypeDef * hpcd)297 __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
298 {
299 /* Prevent unused argument(s) compilation warning */
300 UNUSED(hpcd);
301
302 /* NOTE : This function should not be modified, when the callback is needed,
303 the HAL_PCD_MspInit could be implemented in the user file
304 */
305 }
306
307 /**
308 * @brief DeInitializes PCD MSP.
309 * @param hpcd PCD handle
310 * @retval None
311 */
HAL_PCD_MspDeInit(PCD_HandleTypeDef * hpcd)312 __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
313 {
314 /* Prevent unused argument(s) compilation warning */
315 UNUSED(hpcd);
316
317 /* NOTE : This function should not be modified, when the callback is needed,
318 the HAL_PCD_MspDeInit could be implemented in the user file
319 */
320 }
321
322 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
323 /**
324 * @brief Register a User USB PCD Callback
325 * To be used instead of the weak predefined callback
326 * @param hpcd USB PCD handle
327 * @param CallbackID ID of the callback to be registered
328 * This parameter can be one of the following values:
329 * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
330 * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
331 * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
332 * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
333 * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
334 * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
335 * @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID
336 * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
337 * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
338 * @param pCallback pointer to the Callback function
339 * @retval HAL status
340 */
HAL_PCD_RegisterCallback(PCD_HandleTypeDef * hpcd,HAL_PCD_CallbackIDTypeDef CallbackID,pPCD_CallbackTypeDef pCallback)341 HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd,
342 HAL_PCD_CallbackIDTypeDef CallbackID,
343 pPCD_CallbackTypeDef pCallback)
344 {
345 HAL_StatusTypeDef status = HAL_OK;
346
347 if (pCallback == NULL)
348 {
349 /* Update the error code */
350 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
351 return HAL_ERROR;
352 }
353 /* Process locked */
354 __HAL_LOCK(hpcd);
355
356 if (hpcd->State == HAL_PCD_STATE_READY)
357 {
358 switch (CallbackID)
359 {
360 case HAL_PCD_SOF_CB_ID :
361 hpcd->SOFCallback = pCallback;
362 break;
363
364 case HAL_PCD_SETUPSTAGE_CB_ID :
365 hpcd->SetupStageCallback = pCallback;
366 break;
367
368 case HAL_PCD_RESET_CB_ID :
369 hpcd->ResetCallback = pCallback;
370 break;
371
372 case HAL_PCD_SUSPEND_CB_ID :
373 hpcd->SuspendCallback = pCallback;
374 break;
375
376 case HAL_PCD_RESUME_CB_ID :
377 hpcd->ResumeCallback = pCallback;
378 break;
379
380 case HAL_PCD_CONNECT_CB_ID :
381 hpcd->ConnectCallback = pCallback;
382 break;
383
384 case HAL_PCD_DISCONNECT_CB_ID :
385 hpcd->DisconnectCallback = pCallback;
386 break;
387
388 case HAL_PCD_MSPINIT_CB_ID :
389 hpcd->MspInitCallback = pCallback;
390 break;
391
392 case HAL_PCD_MSPDEINIT_CB_ID :
393 hpcd->MspDeInitCallback = pCallback;
394 break;
395
396 default :
397 /* Update the error code */
398 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
399 /* Return error status */
400 status = HAL_ERROR;
401 break;
402 }
403 }
404 else if (hpcd->State == HAL_PCD_STATE_RESET)
405 {
406 switch (CallbackID)
407 {
408 case HAL_PCD_MSPINIT_CB_ID :
409 hpcd->MspInitCallback = pCallback;
410 break;
411
412 case HAL_PCD_MSPDEINIT_CB_ID :
413 hpcd->MspDeInitCallback = pCallback;
414 break;
415
416 default :
417 /* Update the error code */
418 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
419 /* Return error status */
420 status = HAL_ERROR;
421 break;
422 }
423 }
424 else
425 {
426 /* Update the error code */
427 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
428 /* Return error status */
429 status = HAL_ERROR;
430 }
431
432 /* Release Lock */
433 __HAL_UNLOCK(hpcd);
434 return status;
435 }
436
437 /**
438 * @brief Unregister an USB PCD Callback
439 * USB PCD callback is redirected to the weak predefined callback
440 * @param hpcd USB PCD handle
441 * @param CallbackID ID of the callback to be unregistered
442 * This parameter can be one of the following values:
443 * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
444 * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
445 * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
446 * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
447 * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
448 * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
449 * @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID
450 * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
451 * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
452 * @retval HAL status
453 */
HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef * hpcd,HAL_PCD_CallbackIDTypeDef CallbackID)454 HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID)
455 {
456 HAL_StatusTypeDef status = HAL_OK;
457
458 /* Process locked */
459 __HAL_LOCK(hpcd);
460
461 /* Setup Legacy weak Callbacks */
462 if (hpcd->State == HAL_PCD_STATE_READY)
463 {
464 switch (CallbackID)
465 {
466 case HAL_PCD_SOF_CB_ID :
467 hpcd->SOFCallback = HAL_PCD_SOFCallback;
468 break;
469
470 case HAL_PCD_SETUPSTAGE_CB_ID :
471 hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
472 break;
473
474 case HAL_PCD_RESET_CB_ID :
475 hpcd->ResetCallback = HAL_PCD_ResetCallback;
476 break;
477
478 case HAL_PCD_SUSPEND_CB_ID :
479 hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
480 break;
481
482 case HAL_PCD_RESUME_CB_ID :
483 hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
484 break;
485
486 case HAL_PCD_CONNECT_CB_ID :
487 hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
488 break;
489
490 case HAL_PCD_DISCONNECT_CB_ID :
491 hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
492 break;
493
494 case HAL_PCD_MSPINIT_CB_ID :
495 hpcd->MspInitCallback = HAL_PCD_MspInit;
496 break;
497
498 case HAL_PCD_MSPDEINIT_CB_ID :
499 hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
500 break;
501
502 default :
503 /* Update the error code */
504 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
505
506 /* Return error status */
507 status = HAL_ERROR;
508 break;
509 }
510 }
511 else if (hpcd->State == HAL_PCD_STATE_RESET)
512 {
513 switch (CallbackID)
514 {
515 case HAL_PCD_MSPINIT_CB_ID :
516 hpcd->MspInitCallback = HAL_PCD_MspInit;
517 break;
518
519 case HAL_PCD_MSPDEINIT_CB_ID :
520 hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
521 break;
522
523 default :
524 /* Update the error code */
525 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
526
527 /* Return error status */
528 status = HAL_ERROR;
529 break;
530 }
531 }
532 else
533 {
534 /* Update the error code */
535 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
536
537 /* Return error status */
538 status = HAL_ERROR;
539 }
540
541 /* Release Lock */
542 __HAL_UNLOCK(hpcd);
543 return status;
544 }
545
546 /**
547 * @brief Register USB PCD Data OUT Stage Callback
548 * To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback
549 * @param hpcd PCD handle
550 * @param pCallback pointer to the USB PCD Data OUT Stage Callback function
551 * @retval HAL status
552 */
HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef * hpcd,pPCD_DataOutStageCallbackTypeDef pCallback)553 HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd,
554 pPCD_DataOutStageCallbackTypeDef pCallback)
555 {
556 HAL_StatusTypeDef status = HAL_OK;
557
558 if (pCallback == NULL)
559 {
560 /* Update the error code */
561 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
562
563 return HAL_ERROR;
564 }
565
566 /* Process locked */
567 __HAL_LOCK(hpcd);
568
569 if (hpcd->State == HAL_PCD_STATE_READY)
570 {
571 hpcd->DataOutStageCallback = pCallback;
572 }
573 else
574 {
575 /* Update the error code */
576 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
577
578 /* Return error status */
579 status = HAL_ERROR;
580 }
581
582 /* Release Lock */
583 __HAL_UNLOCK(hpcd);
584
585 return status;
586 }
587
588 /**
589 * @brief Unregister the USB PCD Data OUT Stage Callback
590 * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback
591 * @param hpcd PCD handle
592 * @retval HAL status
593 */
HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef * hpcd)594 HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd)
595 {
596 HAL_StatusTypeDef status = HAL_OK;
597
598 /* Process locked */
599 __HAL_LOCK(hpcd);
600
601 if (hpcd->State == HAL_PCD_STATE_READY)
602 {
603 hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback */
604 }
605 else
606 {
607 /* Update the error code */
608 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
609
610 /* Return error status */
611 status = HAL_ERROR;
612 }
613
614 /* Release Lock */
615 __HAL_UNLOCK(hpcd);
616
617 return status;
618 }
619
620 /**
621 * @brief Register USB PCD Data IN Stage Callback
622 * To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback
623 * @param hpcd PCD handle
624 * @param pCallback pointer to the USB PCD Data IN Stage Callback function
625 * @retval HAL status
626 */
HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef * hpcd,pPCD_DataInStageCallbackTypeDef pCallback)627 HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd,
628 pPCD_DataInStageCallbackTypeDef pCallback)
629 {
630 HAL_StatusTypeDef status = HAL_OK;
631
632 if (pCallback == NULL)
633 {
634 /* Update the error code */
635 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
636
637 return HAL_ERROR;
638 }
639
640 /* Process locked */
641 __HAL_LOCK(hpcd);
642
643 if (hpcd->State == HAL_PCD_STATE_READY)
644 {
645 hpcd->DataInStageCallback = pCallback;
646 }
647 else
648 {
649 /* Update the error code */
650 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
651
652 /* Return error status */
653 status = HAL_ERROR;
654 }
655
656 /* Release Lock */
657 __HAL_UNLOCK(hpcd);
658
659 return status;
660 }
661
662 /**
663 * @brief Unregister the USB PCD Data IN Stage Callback
664 * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback
665 * @param hpcd PCD handle
666 * @retval HAL status
667 */
HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef * hpcd)668 HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd)
669 {
670 HAL_StatusTypeDef status = HAL_OK;
671
672 /* Process locked */
673 __HAL_LOCK(hpcd);
674
675 if (hpcd->State == HAL_PCD_STATE_READY)
676 {
677 hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback */
678 }
679 else
680 {
681 /* Update the error code */
682 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
683
684 /* Return error status */
685 status = HAL_ERROR;
686 }
687
688 /* Release Lock */
689 __HAL_UNLOCK(hpcd);
690
691 return status;
692 }
693
694 /**
695 * @brief Register USB PCD Iso OUT incomplete Callback
696 * To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
697 * @param hpcd PCD handle
698 * @param pCallback pointer to the USB PCD Iso OUT incomplete Callback function
699 * @retval HAL status
700 */
HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef * hpcd,pPCD_IsoOutIncpltCallbackTypeDef pCallback)701 HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd,
702 pPCD_IsoOutIncpltCallbackTypeDef pCallback)
703 {
704 HAL_StatusTypeDef status = HAL_OK;
705
706 if (pCallback == NULL)
707 {
708 /* Update the error code */
709 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
710
711 return HAL_ERROR;
712 }
713
714 /* Process locked */
715 __HAL_LOCK(hpcd);
716
717 if (hpcd->State == HAL_PCD_STATE_READY)
718 {
719 hpcd->ISOOUTIncompleteCallback = pCallback;
720 }
721 else
722 {
723 /* Update the error code */
724 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
725
726 /* Return error status */
727 status = HAL_ERROR;
728 }
729
730 /* Release Lock */
731 __HAL_UNLOCK(hpcd);
732
733 return status;
734 }
735
736 /**
737 * @brief Unregister the USB PCD Iso OUT incomplete Callback
738 * USB PCD Iso OUT incomplete Callback is redirected
739 * to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
740 * @param hpcd PCD handle
741 * @retval HAL status
742 */
HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef * hpcd)743 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
744 {
745 HAL_StatusTypeDef status = HAL_OK;
746
747 /* Process locked */
748 __HAL_LOCK(hpcd);
749
750 if (hpcd->State == HAL_PCD_STATE_READY)
751 {
752 hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback */
753 }
754 else
755 {
756 /* Update the error code */
757 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
758
759 /* Return error status */
760 status = HAL_ERROR;
761 }
762
763 /* Release Lock */
764 __HAL_UNLOCK(hpcd);
765
766 return status;
767 }
768
769 /**
770 * @brief Register USB PCD Iso IN incomplete Callback
771 * To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
772 * @param hpcd PCD handle
773 * @param pCallback pointer to the USB PCD Iso IN incomplete Callback function
774 * @retval HAL status
775 */
HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef * hpcd,pPCD_IsoInIncpltCallbackTypeDef pCallback)776 HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd,
777 pPCD_IsoInIncpltCallbackTypeDef pCallback)
778 {
779 HAL_StatusTypeDef status = HAL_OK;
780
781 if (pCallback == NULL)
782 {
783 /* Update the error code */
784 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
785
786 return HAL_ERROR;
787 }
788
789 /* Process locked */
790 __HAL_LOCK(hpcd);
791
792 if (hpcd->State == HAL_PCD_STATE_READY)
793 {
794 hpcd->ISOINIncompleteCallback = pCallback;
795 }
796 else
797 {
798 /* Update the error code */
799 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
800
801 /* Return error status */
802 status = HAL_ERROR;
803 }
804
805 /* Release Lock */
806 __HAL_UNLOCK(hpcd);
807
808 return status;
809 }
810
811 /**
812 * @brief Unregister the USB PCD Iso IN incomplete Callback
813 * USB PCD Iso IN incomplete Callback is redirected
814 * to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
815 * @param hpcd PCD handle
816 * @retval HAL status
817 */
HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef * hpcd)818 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
819 {
820 HAL_StatusTypeDef status = HAL_OK;
821
822 /* Process locked */
823 __HAL_LOCK(hpcd);
824
825 if (hpcd->State == HAL_PCD_STATE_READY)
826 {
827 hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback */
828 }
829 else
830 {
831 /* Update the error code */
832 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
833
834 /* Return error status */
835 status = HAL_ERROR;
836 }
837
838 /* Release Lock */
839 __HAL_UNLOCK(hpcd);
840
841 return status;
842 }
843
844 /**
845 * @brief Register USB PCD BCD Callback
846 * To be used instead of the weak HAL_PCDEx_BCD_Callback() predefined callback
847 * @param hpcd PCD handle
848 * @param pCallback pointer to the USB PCD BCD Callback function
849 * @retval HAL status
850 */
HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef * hpcd,pPCD_BcdCallbackTypeDef pCallback)851 HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback)
852 {
853 HAL_StatusTypeDef status = HAL_OK;
854
855 if (pCallback == NULL)
856 {
857 /* Update the error code */
858 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
859
860 return HAL_ERROR;
861 }
862
863 /* Process locked */
864 __HAL_LOCK(hpcd);
865
866 if (hpcd->State == HAL_PCD_STATE_READY)
867 {
868 hpcd->BCDCallback = pCallback;
869 }
870 else
871 {
872 /* Update the error code */
873 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
874
875 /* Return error status */
876 status = HAL_ERROR;
877 }
878
879 /* Release Lock */
880 __HAL_UNLOCK(hpcd);
881
882 return status;
883 }
884
885 /**
886 * @brief Unregister the USB PCD BCD Callback
887 * USB BCD Callback is redirected to the weak HAL_PCDEx_BCD_Callback() predefined callback
888 * @param hpcd PCD handle
889 * @retval HAL status
890 */
HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef * hpcd)891 HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd)
892 {
893 HAL_StatusTypeDef status = HAL_OK;
894
895 /* Process locked */
896 __HAL_LOCK(hpcd);
897
898 if (hpcd->State == HAL_PCD_STATE_READY)
899 {
900 hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; /* Legacy weak HAL_PCDEx_BCD_Callback */
901 }
902 else
903 {
904 /* Update the error code */
905 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
906
907 /* Return error status */
908 status = HAL_ERROR;
909 }
910
911 /* Release Lock */
912 __HAL_UNLOCK(hpcd);
913
914 return status;
915 }
916
917 /**
918 * @brief Register USB PCD LPM Callback
919 * To be used instead of the weak HAL_PCDEx_LPM_Callback() predefined callback
920 * @param hpcd PCD handle
921 * @param pCallback pointer to the USB PCD LPM Callback function
922 * @retval HAL status
923 */
HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef * hpcd,pPCD_LpmCallbackTypeDef pCallback)924 HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback)
925 {
926 HAL_StatusTypeDef status = HAL_OK;
927
928 if (pCallback == NULL)
929 {
930 /* Update the error code */
931 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
932
933 return HAL_ERROR;
934 }
935
936 /* Process locked */
937 __HAL_LOCK(hpcd);
938
939 if (hpcd->State == HAL_PCD_STATE_READY)
940 {
941 hpcd->LPMCallback = pCallback;
942 }
943 else
944 {
945 /* Update the error code */
946 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
947
948 /* Return error status */
949 status = HAL_ERROR;
950 }
951
952 /* Release Lock */
953 __HAL_UNLOCK(hpcd);
954
955 return status;
956 }
957
958 /**
959 * @brief Unregister the USB PCD LPM Callback
960 * USB LPM Callback is redirected to the weak HAL_PCDEx_LPM_Callback() predefined callback
961 * @param hpcd PCD handle
962 * @retval HAL status
963 */
HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef * hpcd)964 HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd)
965 {
966 HAL_StatusTypeDef status = HAL_OK;
967
968 /* Process locked */
969 __HAL_LOCK(hpcd);
970
971 if (hpcd->State == HAL_PCD_STATE_READY)
972 {
973 hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; /* Legacy weak HAL_PCDEx_LPM_Callback */
974 }
975 else
976 {
977 /* Update the error code */
978 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
979
980 /* Return error status */
981 status = HAL_ERROR;
982 }
983
984 /* Release Lock */
985 __HAL_UNLOCK(hpcd);
986
987 return status;
988 }
989 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
990
991 /**
992 * @}
993 */
994
995 /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
996 * @brief Data transfers functions
997 *
998 @verbatim
999 ===============================================================================
1000 ##### IO operation functions #####
1001 ===============================================================================
1002 [..]
1003 This subsection provides a set of functions allowing to manage the PCD data
1004 transfers.
1005
1006 @endverbatim
1007 * @{
1008 */
1009
1010 /**
1011 * @brief Start the USB device
1012 * @param hpcd PCD handle
1013 * @retval HAL status
1014 */
HAL_PCD_Start(PCD_HandleTypeDef * hpcd)1015 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
1016 {
1017 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1018
1019 __HAL_LOCK(hpcd);
1020
1021 if (((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U) &&
1022 (hpcd->Init.battery_charging_enable == 1U))
1023 {
1024 /* Enable USB Transceiver */
1025 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
1026 }
1027
1028 __HAL_PCD_ENABLE(hpcd);
1029 (void)USB_DevConnect(hpcd->Instance);
1030 __HAL_UNLOCK(hpcd);
1031
1032 return HAL_OK;
1033 }
1034
1035 /**
1036 * @brief Stop the USB device.
1037 * @param hpcd PCD handle
1038 * @retval HAL status
1039 */
HAL_PCD_Stop(PCD_HandleTypeDef * hpcd)1040 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
1041 {
1042 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1043
1044 __HAL_LOCK(hpcd);
1045 __HAL_PCD_DISABLE(hpcd);
1046 (void)USB_DevDisconnect(hpcd->Instance);
1047
1048 (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
1049
1050 if (((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U) &&
1051 (hpcd->Init.battery_charging_enable == 1U))
1052 {
1053 /* Disable USB Transceiver */
1054 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
1055 }
1056
1057 __HAL_UNLOCK(hpcd);
1058
1059 return HAL_OK;
1060 }
1061
1062 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
1063 /**
1064 * @brief Handles PCD interrupt request.
1065 * @param hpcd PCD handle
1066 * @retval HAL status
1067 */
HAL_PCD_IRQHandler(PCD_HandleTypeDef * hpcd)1068 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
1069 {
1070 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1071 uint32_t USBx_BASE = (uint32_t)USBx;
1072 USB_OTG_EPTypeDef *ep;
1073 uint32_t i;
1074 uint32_t ep_intr;
1075 uint32_t epint;
1076 uint32_t epnum;
1077 uint32_t fifoemptymsk;
1078 uint32_t RegVal;
1079
1080 /* ensure that we are in device mode */
1081 if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
1082 {
1083 /* avoid spurious interrupt */
1084 if (__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
1085 {
1086 return;
1087 }
1088
1089 /* store current frame number */
1090 hpcd->FrameNumber = (USBx_DEVICE->DSTS & USB_OTG_DSTS_FNSOF_Msk) >> USB_OTG_DSTS_FNSOF_Pos;
1091
1092 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
1093 {
1094 /* incorrect mode, acknowledge the interrupt */
1095 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
1096 }
1097
1098 /* Handle RxQLevel Interrupt */
1099 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
1100 {
1101 USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
1102
1103 RegVal = USBx->GRXSTSP;
1104
1105 ep = &hpcd->OUT_ep[RegVal & USB_OTG_GRXSTSP_EPNUM];
1106
1107 if (((RegVal & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT)
1108 {
1109 if ((RegVal & USB_OTG_GRXSTSP_BCNT) != 0U)
1110 {
1111 (void)USB_ReadPacket(USBx, ep->xfer_buff,
1112 (uint16_t)((RegVal & USB_OTG_GRXSTSP_BCNT) >> 4));
1113
1114 ep->xfer_buff += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
1115 ep->xfer_count += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
1116 }
1117 }
1118 else if (((RegVal & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT)
1119 {
1120 (void)USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
1121 ep->xfer_count += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
1122 }
1123 else
1124 {
1125 /* ... */
1126 }
1127
1128 USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
1129 }
1130
1131 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
1132 {
1133 epnum = 0U;
1134
1135 /* Read in the device interrupt bits */
1136 ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
1137
1138 while (ep_intr != 0U)
1139 {
1140 if ((ep_intr & 0x1U) != 0U)
1141 {
1142 epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum);
1143
1144 if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
1145 {
1146 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
1147 (void)PCD_EP_OutXfrComplete_int(hpcd, epnum);
1148 }
1149
1150 if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
1151 {
1152 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
1153 /* Class B setup phase done for previous decoded setup */
1154 (void)PCD_EP_OutSetupPacket_int(hpcd, epnum);
1155 }
1156
1157 if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
1158 {
1159 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
1160 }
1161
1162 /* Clear OUT Endpoint disable interrupt */
1163 if ((epint & USB_OTG_DOEPINT_EPDISD) == USB_OTG_DOEPINT_EPDISD)
1164 {
1165 if ((USBx->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF) == USB_OTG_GINTSTS_BOUTNAKEFF)
1166 {
1167 USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK;
1168 }
1169
1170 ep = &hpcd->OUT_ep[epnum];
1171
1172 if (ep->is_iso_incomplete == 1U)
1173 {
1174 ep->is_iso_incomplete = 0U;
1175
1176 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1177 hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
1178 #else
1179 HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
1180 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1181 }
1182
1183 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_EPDISD);
1184 }
1185
1186 /* Clear Status Phase Received interrupt */
1187 if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
1188 {
1189 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
1190 }
1191
1192 /* Clear OUT NAK interrupt */
1193 if ((epint & USB_OTG_DOEPINT_NAK) == USB_OTG_DOEPINT_NAK)
1194 {
1195 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_NAK);
1196 }
1197 }
1198 epnum++;
1199 ep_intr >>= 1U;
1200 }
1201 }
1202
1203 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
1204 {
1205 /* Read in the device interrupt bits */
1206 ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
1207
1208 epnum = 0U;
1209
1210 while (ep_intr != 0U)
1211 {
1212 if ((ep_intr & 0x1U) != 0U) /* In ITR */
1213 {
1214 epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum);
1215
1216 if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
1217 {
1218 fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
1219 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
1220
1221 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
1222
1223 if (hpcd->Init.dma_enable == 1U)
1224 {
1225 hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket;
1226
1227 /* this is ZLP, so prepare EP0 for next setup */
1228 if ((epnum == 0U) && (hpcd->IN_ep[epnum].xfer_len == 0U))
1229 {
1230 /* prepare to rx more setup packets */
1231 (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
1232 }
1233 }
1234
1235 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1236 hpcd->DataInStageCallback(hpcd, (uint8_t)epnum);
1237 #else
1238 HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum);
1239 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1240 }
1241 if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
1242 {
1243 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
1244 }
1245 if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
1246 {
1247 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
1248 }
1249 if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
1250 {
1251 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
1252 }
1253 if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
1254 {
1255 (void)USB_FlushTxFifo(USBx, epnum);
1256
1257 ep = &hpcd->IN_ep[epnum];
1258
1259 if (ep->is_iso_incomplete == 1U)
1260 {
1261 ep->is_iso_incomplete = 0U;
1262
1263 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1264 hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
1265 #else
1266 HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
1267 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1268 }
1269
1270 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
1271 }
1272 if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
1273 {
1274 (void)PCD_WriteEmptyTxFifo(hpcd, epnum);
1275 }
1276 }
1277 epnum++;
1278 ep_intr >>= 1U;
1279 }
1280 }
1281
1282 /* Handle Resume Interrupt */
1283 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
1284 {
1285 /* Clear the Remote Wake-up Signaling */
1286 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
1287
1288 if (hpcd->LPM_State == LPM_L1)
1289 {
1290 hpcd->LPM_State = LPM_L0;
1291
1292 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1293 hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE);
1294 #else
1295 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
1296 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1297 }
1298 else
1299 {
1300 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1301 hpcd->ResumeCallback(hpcd);
1302 #else
1303 HAL_PCD_ResumeCallback(hpcd);
1304 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1305 }
1306
1307 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
1308 }
1309
1310 /* Handle Suspend Interrupt */
1311 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
1312 {
1313 if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
1314 {
1315 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1316 hpcd->SuspendCallback(hpcd);
1317 #else
1318 HAL_PCD_SuspendCallback(hpcd);
1319 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1320 }
1321 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
1322 }
1323 #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) \
1324 || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) \
1325 || defined(STM32F423xx)
1326 /* Handle LPM Interrupt */
1327 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT))
1328 {
1329 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT);
1330
1331 if (hpcd->LPM_State == LPM_L0)
1332 {
1333 hpcd->LPM_State = LPM_L1;
1334 hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >> 2U;
1335
1336 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1337 hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE);
1338 #else
1339 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
1340 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1341 }
1342 else
1343 {
1344 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1345 hpcd->SuspendCallback(hpcd);
1346 #else
1347 HAL_PCD_SuspendCallback(hpcd);
1348 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1349 }
1350 }
1351 #endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||
1352 defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) ||
1353 defined(STM32F423xx) */
1354 /* Handle Reset Interrupt */
1355 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
1356 {
1357 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
1358 (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
1359
1360 for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
1361 {
1362 USBx_INEP(i)->DIEPINT = 0xFB7FU;
1363 USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
1364 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1365 USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
1366 USBx_OUTEP(i)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
1367 }
1368 USBx_DEVICE->DAINTMSK |= 0x10001U;
1369
1370 if (hpcd->Init.use_dedicated_ep1 != 0U)
1371 {
1372 USBx_DEVICE->DOUTEP1MSK |= USB_OTG_DOEPMSK_STUPM |
1373 USB_OTG_DOEPMSK_XFRCM |
1374 USB_OTG_DOEPMSK_EPDM;
1375
1376 USBx_DEVICE->DINEP1MSK |= USB_OTG_DIEPMSK_TOM |
1377 USB_OTG_DIEPMSK_XFRCM |
1378 USB_OTG_DIEPMSK_EPDM;
1379 }
1380 else
1381 {
1382 USBx_DEVICE->DOEPMSK |= USB_OTG_DOEPMSK_STUPM |
1383 USB_OTG_DOEPMSK_XFRCM |
1384 USB_OTG_DOEPMSK_EPDM |
1385 USB_OTG_DOEPMSK_OTEPSPRM |
1386 USB_OTG_DOEPMSK_NAKM;
1387
1388 USBx_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_TOM |
1389 USB_OTG_DIEPMSK_XFRCM |
1390 USB_OTG_DIEPMSK_EPDM;
1391 }
1392
1393 /* Set Default Address to 0 */
1394 USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
1395
1396 /* setup EP0 to receive SETUP packets */
1397 (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable,
1398 (uint8_t *)hpcd->Setup);
1399
1400 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
1401 }
1402
1403 /* Handle Enumeration done Interrupt */
1404 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
1405 {
1406 (void)USB_ActivateSetup(hpcd->Instance);
1407 hpcd->Init.speed = USB_GetDevSpeed(hpcd->Instance);
1408
1409 /* Set USB Turnaround time */
1410 (void)USB_SetTurnaroundTime(hpcd->Instance,
1411 HAL_RCC_GetHCLKFreq(),
1412 (uint8_t)hpcd->Init.speed);
1413
1414 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1415 hpcd->ResetCallback(hpcd);
1416 #else
1417 HAL_PCD_ResetCallback(hpcd);
1418 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1419
1420 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
1421 }
1422
1423 /* Handle SOF Interrupt */
1424 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
1425 {
1426 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1427 hpcd->SOFCallback(hpcd);
1428 #else
1429 HAL_PCD_SOFCallback(hpcd);
1430 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1431
1432 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
1433 }
1434
1435 /* Handle Global OUT NAK effective Interrupt */
1436 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_BOUTNAKEFF))
1437 {
1438 USBx->GINTMSK &= ~USB_OTG_GINTMSK_GONAKEFFM;
1439
1440 for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
1441 {
1442 if (hpcd->OUT_ep[epnum].is_iso_incomplete == 1U)
1443 {
1444 /* Abort current transaction and disable the EP */
1445 (void)HAL_PCD_EP_Abort(hpcd, (uint8_t)epnum);
1446 }
1447 }
1448 }
1449
1450 /* Handle Incomplete ISO IN Interrupt */
1451 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
1452 {
1453 for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
1454 {
1455 RegVal = USBx_INEP(epnum)->DIEPCTL;
1456
1457 if ((hpcd->IN_ep[epnum].type == EP_TYPE_ISOC) &&
1458 ((RegVal & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA))
1459 {
1460 hpcd->IN_ep[epnum].is_iso_incomplete = 1U;
1461
1462 /* Abort current transaction and disable the EP */
1463 (void)HAL_PCD_EP_Abort(hpcd, (uint8_t)(epnum | 0x80U));
1464 }
1465 }
1466
1467 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
1468 }
1469
1470 /* Handle Incomplete ISO OUT Interrupt */
1471 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
1472 {
1473 for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
1474 {
1475 RegVal = USBx_OUTEP(epnum)->DOEPCTL;
1476
1477 if ((hpcd->OUT_ep[epnum].type == EP_TYPE_ISOC) &&
1478 ((RegVal & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) &&
1479 ((RegVal & (0x1U << 16)) == (hpcd->FrameNumber & 0x1U)))
1480 {
1481 hpcd->OUT_ep[epnum].is_iso_incomplete = 1U;
1482
1483 USBx->GINTMSK |= USB_OTG_GINTMSK_GONAKEFFM;
1484
1485 if ((USBx->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF) == 0U)
1486 {
1487 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SGONAK;
1488 break;
1489 }
1490 }
1491 }
1492
1493 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
1494 }
1495
1496 /* Handle Connection event Interrupt */
1497 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
1498 {
1499 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1500 hpcd->ConnectCallback(hpcd);
1501 #else
1502 HAL_PCD_ConnectCallback(hpcd);
1503 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1504
1505 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
1506 }
1507
1508 /* Handle Disconnection event Interrupt */
1509 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
1510 {
1511 RegVal = hpcd->Instance->GOTGINT;
1512
1513 if ((RegVal & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
1514 {
1515 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1516 hpcd->DisconnectCallback(hpcd);
1517 #else
1518 HAL_PCD_DisconnectCallback(hpcd);
1519 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1520 }
1521 hpcd->Instance->GOTGINT |= RegVal;
1522 }
1523 }
1524 }
1525
1526
1527 /**
1528 * @brief Handles PCD Wakeup interrupt request.
1529 * @param hpcd PCD handle
1530 * @retval HAL status
1531 */
HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef * hpcd)1532 void HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef *hpcd)
1533 {
1534 #if defined (USB_OTG_FS)
1535 USB_OTG_GlobalTypeDef *USBx;
1536 USBx = hpcd->Instance;
1537
1538 if (USBx == USB_OTG_FS)
1539 {
1540 /* Clear EXTI pending Bit */
1541 __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG();
1542 }
1543 else
1544 #endif /* defined (USB_OTG_FS) */
1545 {
1546 /* Clear EXTI pending Bit */
1547 __HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG();
1548 }
1549 }
1550 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
1551
1552
1553 /**
1554 * @brief Data OUT stage callback.
1555 * @param hpcd PCD handle
1556 * @param epnum endpoint number
1557 * @retval None
1558 */
HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef * hpcd,uint8_t epnum)1559 __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1560 {
1561 /* Prevent unused argument(s) compilation warning */
1562 UNUSED(hpcd);
1563 UNUSED(epnum);
1564
1565 /* NOTE : This function should not be modified, when the callback is needed,
1566 the HAL_PCD_DataOutStageCallback could be implemented in the user file
1567 */
1568 }
1569
1570 /**
1571 * @brief Data IN stage callback
1572 * @param hpcd PCD handle
1573 * @param epnum endpoint number
1574 * @retval None
1575 */
HAL_PCD_DataInStageCallback(PCD_HandleTypeDef * hpcd,uint8_t epnum)1576 __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1577 {
1578 /* Prevent unused argument(s) compilation warning */
1579 UNUSED(hpcd);
1580 UNUSED(epnum);
1581
1582 /* NOTE : This function should not be modified, when the callback is needed,
1583 the HAL_PCD_DataInStageCallback could be implemented in the user file
1584 */
1585 }
1586 /**
1587 * @brief Setup stage callback
1588 * @param hpcd PCD handle
1589 * @retval None
1590 */
HAL_PCD_SetupStageCallback(PCD_HandleTypeDef * hpcd)1591 __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
1592 {
1593 /* Prevent unused argument(s) compilation warning */
1594 UNUSED(hpcd);
1595
1596 /* NOTE : This function should not be modified, when the callback is needed,
1597 the HAL_PCD_SetupStageCallback could be implemented in the user file
1598 */
1599 }
1600
1601 /**
1602 * @brief USB Start Of Frame callback.
1603 * @param hpcd PCD handle
1604 * @retval None
1605 */
HAL_PCD_SOFCallback(PCD_HandleTypeDef * hpcd)1606 __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
1607 {
1608 /* Prevent unused argument(s) compilation warning */
1609 UNUSED(hpcd);
1610
1611 /* NOTE : This function should not be modified, when the callback is needed,
1612 the HAL_PCD_SOFCallback could be implemented in the user file
1613 */
1614 }
1615
1616 /**
1617 * @brief USB Reset callback.
1618 * @param hpcd PCD handle
1619 * @retval None
1620 */
HAL_PCD_ResetCallback(PCD_HandleTypeDef * hpcd)1621 __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
1622 {
1623 /* Prevent unused argument(s) compilation warning */
1624 UNUSED(hpcd);
1625
1626 /* NOTE : This function should not be modified, when the callback is needed,
1627 the HAL_PCD_ResetCallback could be implemented in the user file
1628 */
1629 }
1630
1631 /**
1632 * @brief Suspend event callback.
1633 * @param hpcd PCD handle
1634 * @retval None
1635 */
HAL_PCD_SuspendCallback(PCD_HandleTypeDef * hpcd)1636 __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
1637 {
1638 /* Prevent unused argument(s) compilation warning */
1639 UNUSED(hpcd);
1640
1641 /* NOTE : This function should not be modified, when the callback is needed,
1642 the HAL_PCD_SuspendCallback could be implemented in the user file
1643 */
1644 }
1645
1646 /**
1647 * @brief Resume event callback.
1648 * @param hpcd PCD handle
1649 * @retval None
1650 */
HAL_PCD_ResumeCallback(PCD_HandleTypeDef * hpcd)1651 __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
1652 {
1653 /* Prevent unused argument(s) compilation warning */
1654 UNUSED(hpcd);
1655
1656 /* NOTE : This function should not be modified, when the callback is needed,
1657 the HAL_PCD_ResumeCallback could be implemented in the user file
1658 */
1659 }
1660
1661 /**
1662 * @brief Incomplete ISO OUT callback.
1663 * @param hpcd PCD handle
1664 * @param epnum endpoint number
1665 * @retval None
1666 */
HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef * hpcd,uint8_t epnum)1667 __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1668 {
1669 /* Prevent unused argument(s) compilation warning */
1670 UNUSED(hpcd);
1671 UNUSED(epnum);
1672
1673 /* NOTE : This function should not be modified, when the callback is needed,
1674 the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
1675 */
1676 }
1677
1678 /**
1679 * @brief Incomplete ISO IN callback.
1680 * @param hpcd PCD handle
1681 * @param epnum endpoint number
1682 * @retval None
1683 */
HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef * hpcd,uint8_t epnum)1684 __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1685 {
1686 /* Prevent unused argument(s) compilation warning */
1687 UNUSED(hpcd);
1688 UNUSED(epnum);
1689
1690 /* NOTE : This function should not be modified, when the callback is needed,
1691 the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
1692 */
1693 }
1694
1695 /**
1696 * @brief Connection event callback.
1697 * @param hpcd PCD handle
1698 * @retval None
1699 */
HAL_PCD_ConnectCallback(PCD_HandleTypeDef * hpcd)1700 __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
1701 {
1702 /* Prevent unused argument(s) compilation warning */
1703 UNUSED(hpcd);
1704
1705 /* NOTE : This function should not be modified, when the callback is needed,
1706 the HAL_PCD_ConnectCallback could be implemented in the user file
1707 */
1708 }
1709
1710 /**
1711 * @brief Disconnection event callback.
1712 * @param hpcd PCD handle
1713 * @retval None
1714 */
HAL_PCD_DisconnectCallback(PCD_HandleTypeDef * hpcd)1715 __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
1716 {
1717 /* Prevent unused argument(s) compilation warning */
1718 UNUSED(hpcd);
1719
1720 /* NOTE : This function should not be modified, when the callback is needed,
1721 the HAL_PCD_DisconnectCallback could be implemented in the user file
1722 */
1723 }
1724
1725 /**
1726 * @}
1727 */
1728
1729 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
1730 * @brief management functions
1731 *
1732 @verbatim
1733 ===============================================================================
1734 ##### Peripheral Control functions #####
1735 ===============================================================================
1736 [..]
1737 This subsection provides a set of functions allowing to control the PCD data
1738 transfers.
1739
1740 @endverbatim
1741 * @{
1742 */
1743
1744 /**
1745 * @brief Connect the USB device
1746 * @param hpcd PCD handle
1747 * @retval HAL status
1748 */
HAL_PCD_DevConnect(PCD_HandleTypeDef * hpcd)1749 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
1750 {
1751 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1752
1753 __HAL_LOCK(hpcd);
1754
1755 if (((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U) &&
1756 (hpcd->Init.battery_charging_enable == 1U))
1757 {
1758 /* Enable USB Transceiver */
1759 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
1760 }
1761 (void)USB_DevConnect(hpcd->Instance);
1762 __HAL_UNLOCK(hpcd);
1763
1764 return HAL_OK;
1765 }
1766
1767 /**
1768 * @brief Disconnect the USB device.
1769 * @param hpcd PCD handle
1770 * @retval HAL status
1771 */
HAL_PCD_DevDisconnect(PCD_HandleTypeDef * hpcd)1772 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
1773 {
1774 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1775
1776 __HAL_LOCK(hpcd);
1777 (void)USB_DevDisconnect(hpcd->Instance);
1778
1779 if (((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U) &&
1780 (hpcd->Init.battery_charging_enable == 1U))
1781 {
1782 /* Disable USB Transceiver */
1783 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
1784 }
1785
1786 __HAL_UNLOCK(hpcd);
1787
1788 return HAL_OK;
1789 }
1790
1791 /**
1792 * @brief Set the USB Device address.
1793 * @param hpcd PCD handle
1794 * @param address new device address
1795 * @retval HAL status
1796 */
HAL_PCD_SetAddress(PCD_HandleTypeDef * hpcd,uint8_t address)1797 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
1798 {
1799 __HAL_LOCK(hpcd);
1800 hpcd->USB_Address = address;
1801 (void)USB_SetDevAddress(hpcd->Instance, address);
1802 __HAL_UNLOCK(hpcd);
1803
1804 return HAL_OK;
1805 }
1806 /**
1807 * @brief Open and configure an endpoint.
1808 * @param hpcd PCD handle
1809 * @param ep_addr endpoint address
1810 * @param ep_mps endpoint max packet size
1811 * @param ep_type endpoint type
1812 * @retval HAL status
1813 */
HAL_PCD_EP_Open(PCD_HandleTypeDef * hpcd,uint8_t ep_addr,uint16_t ep_mps,uint8_t ep_type)1814 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
1815 uint16_t ep_mps, uint8_t ep_type)
1816 {
1817 HAL_StatusTypeDef ret = HAL_OK;
1818 PCD_EPTypeDef *ep;
1819
1820 if ((ep_addr & 0x80U) == 0x80U)
1821 {
1822 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1823 ep->is_in = 1U;
1824 }
1825 else
1826 {
1827 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1828 ep->is_in = 0U;
1829 }
1830
1831 ep->num = ep_addr & EP_ADDR_MSK;
1832 ep->maxpacket = (uint32_t)ep_mps & 0x7FFU;
1833 ep->type = ep_type;
1834
1835 if (ep->is_in != 0U)
1836 {
1837 /* Assign a Tx FIFO */
1838 ep->tx_fifo_num = ep->num;
1839 }
1840
1841 /* Set initial data PID. */
1842 if (ep_type == EP_TYPE_BULK)
1843 {
1844 ep->data_pid_start = 0U;
1845 }
1846
1847 __HAL_LOCK(hpcd);
1848 (void)USB_ActivateEndpoint(hpcd->Instance, ep);
1849 __HAL_UNLOCK(hpcd);
1850
1851 return ret;
1852 }
1853
1854 /**
1855 * @brief Deactivate an endpoint.
1856 * @param hpcd PCD handle
1857 * @param ep_addr endpoint address
1858 * @retval HAL status
1859 */
HAL_PCD_EP_Close(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)1860 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1861 {
1862 PCD_EPTypeDef *ep;
1863
1864 if ((ep_addr & 0x80U) == 0x80U)
1865 {
1866 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1867 ep->is_in = 1U;
1868 }
1869 else
1870 {
1871 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1872 ep->is_in = 0U;
1873 }
1874 ep->num = ep_addr & EP_ADDR_MSK;
1875
1876 __HAL_LOCK(hpcd);
1877 (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
1878 __HAL_UNLOCK(hpcd);
1879 return HAL_OK;
1880 }
1881
1882
1883 /**
1884 * @brief Receive an amount of data.
1885 * @param hpcd PCD handle
1886 * @param ep_addr endpoint address
1887 * @param pBuf pointer to the reception buffer
1888 * @param len amount of data to be received
1889 * @retval HAL status
1890 */
HAL_PCD_EP_Receive(PCD_HandleTypeDef * hpcd,uint8_t ep_addr,uint8_t * pBuf,uint32_t len)1891 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
1892 {
1893 PCD_EPTypeDef *ep;
1894
1895 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1896
1897 /*setup and start the Xfer */
1898 ep->xfer_buff = pBuf;
1899 ep->xfer_len = len;
1900 ep->xfer_count = 0U;
1901 ep->is_in = 0U;
1902 ep->num = ep_addr & EP_ADDR_MSK;
1903
1904 if (hpcd->Init.dma_enable == 1U)
1905 {
1906 ep->dma_addr = (uint32_t)pBuf;
1907 }
1908
1909 (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable);
1910
1911 return HAL_OK;
1912 }
1913
1914 /**
1915 * @brief Get Received Data Size
1916 * @param hpcd PCD handle
1917 * @param ep_addr endpoint address
1918 * @retval Data Size
1919 */
HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef const * hpcd,uint8_t ep_addr)1920 uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef const *hpcd, uint8_t ep_addr)
1921 {
1922 return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count;
1923 }
1924 /**
1925 * @brief Send an amount of data
1926 * @param hpcd PCD handle
1927 * @param ep_addr endpoint address
1928 * @param pBuf pointer to the transmission buffer
1929 * @param len amount of data to be sent
1930 * @retval HAL status
1931 */
HAL_PCD_EP_Transmit(PCD_HandleTypeDef * hpcd,uint8_t ep_addr,uint8_t * pBuf,uint32_t len)1932 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
1933 {
1934 PCD_EPTypeDef *ep;
1935
1936 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1937
1938 /*setup and start the Xfer */
1939 ep->xfer_buff = pBuf;
1940 ep->xfer_len = len;
1941 ep->xfer_count = 0U;
1942 ep->is_in = 1U;
1943 ep->num = ep_addr & EP_ADDR_MSK;
1944
1945 if (hpcd->Init.dma_enable == 1U)
1946 {
1947 ep->dma_addr = (uint32_t)pBuf;
1948 }
1949
1950 (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable);
1951
1952 return HAL_OK;
1953 }
1954
1955 /**
1956 * @brief Set a STALL condition over an endpoint
1957 * @param hpcd PCD handle
1958 * @param ep_addr endpoint address
1959 * @retval HAL status
1960 */
HAL_PCD_EP_SetStall(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)1961 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1962 {
1963 PCD_EPTypeDef *ep;
1964
1965 if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints)
1966 {
1967 return HAL_ERROR;
1968 }
1969
1970 if ((0x80U & ep_addr) == 0x80U)
1971 {
1972 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1973 ep->is_in = 1U;
1974 }
1975 else
1976 {
1977 ep = &hpcd->OUT_ep[ep_addr];
1978 ep->is_in = 0U;
1979 }
1980
1981 ep->is_stall = 1U;
1982 ep->num = ep_addr & EP_ADDR_MSK;
1983
1984 __HAL_LOCK(hpcd);
1985
1986 (void)USB_EPSetStall(hpcd->Instance, ep);
1987
1988 if ((ep_addr & EP_ADDR_MSK) == 0U)
1989 {
1990 (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup);
1991 }
1992
1993 __HAL_UNLOCK(hpcd);
1994
1995 return HAL_OK;
1996 }
1997
1998 /**
1999 * @brief Clear a STALL condition over in an endpoint
2000 * @param hpcd PCD handle
2001 * @param ep_addr endpoint address
2002 * @retval HAL status
2003 */
HAL_PCD_EP_ClrStall(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)2004 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
2005 {
2006 PCD_EPTypeDef *ep;
2007
2008 if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
2009 {
2010 return HAL_ERROR;
2011 }
2012
2013 if ((0x80U & ep_addr) == 0x80U)
2014 {
2015 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
2016 ep->is_in = 1U;
2017 }
2018 else
2019 {
2020 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
2021 ep->is_in = 0U;
2022 }
2023
2024 ep->is_stall = 0U;
2025 ep->num = ep_addr & EP_ADDR_MSK;
2026
2027 __HAL_LOCK(hpcd);
2028 (void)USB_EPClearStall(hpcd->Instance, ep);
2029 __HAL_UNLOCK(hpcd);
2030
2031 return HAL_OK;
2032 }
2033
2034 /**
2035 * @brief Abort an USB EP transaction.
2036 * @param hpcd PCD handle
2037 * @param ep_addr endpoint address
2038 * @retval HAL status
2039 */
HAL_PCD_EP_Abort(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)2040 HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
2041 {
2042 HAL_StatusTypeDef ret;
2043 PCD_EPTypeDef *ep;
2044
2045 if ((0x80U & ep_addr) == 0x80U)
2046 {
2047 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
2048 }
2049 else
2050 {
2051 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
2052 }
2053
2054 /* Stop Xfer */
2055 ret = USB_EPStopXfer(hpcd->Instance, ep);
2056
2057 return ret;
2058 }
2059
2060 /**
2061 * @brief Flush an endpoint
2062 * @param hpcd PCD handle
2063 * @param ep_addr endpoint address
2064 * @retval HAL status
2065 */
HAL_PCD_EP_Flush(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)2066 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
2067 {
2068 __HAL_LOCK(hpcd);
2069
2070 if ((ep_addr & 0x80U) == 0x80U)
2071 {
2072 (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & EP_ADDR_MSK);
2073 }
2074 else
2075 {
2076 (void)USB_FlushRxFifo(hpcd->Instance);
2077 }
2078
2079 __HAL_UNLOCK(hpcd);
2080
2081 return HAL_OK;
2082 }
2083
2084 /**
2085 * @brief Activate remote wakeup signalling
2086 * @param hpcd PCD handle
2087 * @retval HAL status
2088 */
HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef * hpcd)2089 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
2090 {
2091 return (USB_ActivateRemoteWakeup(hpcd->Instance));
2092 }
2093
2094 /**
2095 * @brief De-activate remote wakeup signalling.
2096 * @param hpcd PCD handle
2097 * @retval HAL status
2098 */
HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef * hpcd)2099 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
2100 {
2101 return (USB_DeActivateRemoteWakeup(hpcd->Instance));
2102 }
2103
2104 /**
2105 * @}
2106 */
2107
2108 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
2109 * @brief Peripheral State functions
2110 *
2111 @verbatim
2112 ===============================================================================
2113 ##### Peripheral State functions #####
2114 ===============================================================================
2115 [..]
2116 This subsection permits to get in run-time the status of the peripheral
2117 and the data flow.
2118
2119 @endverbatim
2120 * @{
2121 */
2122
2123 /**
2124 * @brief Return the PCD handle state.
2125 * @param hpcd PCD handle
2126 * @retval HAL state
2127 */
HAL_PCD_GetState(PCD_HandleTypeDef const * hpcd)2128 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef const *hpcd)
2129 {
2130 return hpcd->State;
2131 }
2132
2133 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
2134 /**
2135 * @brief Set the USB Device high speed test mode.
2136 * @param hpcd PCD handle
2137 * @param testmode USB Device high speed test mode
2138 * @retval HAL status
2139 */
HAL_PCD_SetTestMode(const PCD_HandleTypeDef * hpcd,uint8_t testmode)2140 HAL_StatusTypeDef HAL_PCD_SetTestMode(const PCD_HandleTypeDef *hpcd, uint8_t testmode)
2141 {
2142 const USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2143 uint32_t USBx_BASE = (uint32_t)USBx;
2144
2145 switch (testmode)
2146 {
2147 case TEST_J:
2148 case TEST_K:
2149 case TEST_SE0_NAK:
2150 case TEST_PACKET:
2151 case TEST_FORCE_EN:
2152 USBx_DEVICE->DCTL |= (uint32_t)testmode << 4;
2153 break;
2154
2155 default:
2156 break;
2157 }
2158
2159 return HAL_OK;
2160 }
2161 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2162 /**
2163 * @}
2164 */
2165
2166 /**
2167 * @}
2168 */
2169
2170 /* Private functions ---------------------------------------------------------*/
2171 /** @addtogroup PCD_Private_Functions
2172 * @{
2173 */
2174 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
2175 /**
2176 * @brief Check FIFO for the next packet to be loaded.
2177 * @param hpcd PCD handle
2178 * @param epnum endpoint number
2179 * @retval HAL status
2180 */
PCD_WriteEmptyTxFifo(PCD_HandleTypeDef * hpcd,uint32_t epnum)2181 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
2182 {
2183 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2184 uint32_t USBx_BASE = (uint32_t)USBx;
2185 USB_OTG_EPTypeDef *ep;
2186 uint32_t len;
2187 uint32_t len32b;
2188 uint32_t fifoemptymsk;
2189
2190 ep = &hpcd->IN_ep[epnum];
2191
2192 if (ep->xfer_count > ep->xfer_len)
2193 {
2194 return HAL_ERROR;
2195 }
2196
2197 len = ep->xfer_len - ep->xfer_count;
2198
2199 if (len > ep->maxpacket)
2200 {
2201 len = ep->maxpacket;
2202 }
2203
2204 len32b = (len + 3U) / 4U;
2205
2206 while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) &&
2207 (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U))
2208 {
2209 /* Write the FIFO */
2210 len = ep->xfer_len - ep->xfer_count;
2211
2212 if (len > ep->maxpacket)
2213 {
2214 len = ep->maxpacket;
2215 }
2216 len32b = (len + 3U) / 4U;
2217
2218 (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len,
2219 (uint8_t)hpcd->Init.dma_enable);
2220
2221 ep->xfer_buff += len;
2222 ep->xfer_count += len;
2223 }
2224
2225 if (ep->xfer_len <= ep->xfer_count)
2226 {
2227 fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
2228 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
2229 }
2230
2231 return HAL_OK;
2232 }
2233
2234
2235 /**
2236 * @brief process EP OUT transfer complete interrupt.
2237 * @param hpcd PCD handle
2238 * @param epnum endpoint number
2239 * @retval HAL status
2240 */
PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef * hpcd,uint32_t epnum)2241 static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
2242 {
2243 USB_OTG_EPTypeDef *ep;
2244 const USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2245 uint32_t USBx_BASE = (uint32_t)USBx;
2246 uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U);
2247 uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
2248
2249 if (hpcd->Init.dma_enable == 1U)
2250 {
2251 if ((DoepintReg & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) /* Class C */
2252 {
2253 /* StupPktRcvd = 1 this is a setup packet */
2254 if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
2255 ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
2256 {
2257 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2258 }
2259 }
2260 else if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) /* Class E */
2261 {
2262 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
2263 }
2264 else if ((DoepintReg & (USB_OTG_DOEPINT_STUP | USB_OTG_DOEPINT_OTEPSPR)) == 0U)
2265 {
2266 /* StupPktRcvd = 1 this is a setup packet */
2267 if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
2268 ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
2269 {
2270 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2271 }
2272 else
2273 {
2274 ep = &hpcd->OUT_ep[epnum];
2275
2276 /* out data packet received over EP */
2277 ep->xfer_count = ep->xfer_size - (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ);
2278
2279 if (epnum == 0U)
2280 {
2281 if (ep->xfer_len == 0U)
2282 {
2283 /* this is ZLP, so prepare EP0 for next setup */
2284 (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
2285 }
2286 else
2287 {
2288 ep->xfer_buff += ep->xfer_count;
2289 }
2290 }
2291
2292 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2293 hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
2294 #else
2295 HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
2296 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2297 }
2298 }
2299 else
2300 {
2301 /* ... */
2302 }
2303 }
2304 else
2305 {
2306 if (gSNPSiD == USB_OTG_CORE_ID_310A)
2307 {
2308 /* StupPktRcvd = 1 this is a setup packet */
2309 if ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)
2310 {
2311 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2312 }
2313 else
2314 {
2315 if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
2316 {
2317 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
2318 }
2319
2320 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2321 hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
2322 #else
2323 HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
2324 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2325 }
2326 }
2327 else
2328 {
2329 if ((epnum == 0U) && (hpcd->OUT_ep[epnum].xfer_len == 0U))
2330 {
2331 /* this is ZLP, so prepare EP0 for next setup */
2332 (void)USB_EP0_OutStart(hpcd->Instance, 0U, (uint8_t *)hpcd->Setup);
2333 }
2334
2335 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2336 hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
2337 #else
2338 HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
2339 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2340 }
2341 }
2342
2343 return HAL_OK;
2344 }
2345
2346
2347 /**
2348 * @brief process EP OUT setup packet received interrupt.
2349 * @param hpcd PCD handle
2350 * @param epnum endpoint number
2351 * @retval HAL status
2352 */
PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef * hpcd,uint32_t epnum)2353 static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
2354 {
2355 const USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2356 uint32_t USBx_BASE = (uint32_t)USBx;
2357 uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U);
2358 uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
2359
2360 if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
2361 ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
2362 {
2363 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2364 }
2365
2366 /* Inform the upper layer that a setup packet is available */
2367 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2368 hpcd->SetupStageCallback(hpcd);
2369 #else
2370 HAL_PCD_SetupStageCallback(hpcd);
2371 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2372
2373 if ((gSNPSiD > USB_OTG_CORE_ID_300A) && (hpcd->Init.dma_enable == 1U))
2374 {
2375 (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
2376 }
2377
2378 return HAL_OK;
2379 }
2380 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2381
2382 /**
2383 * @}
2384 */
2385 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2386 #endif /* HAL_PCD_MODULE_ENABLED */
2387 /**
2388 * @}
2389 */
2390
2391 /**
2392 * @}
2393 */
2394