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