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