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