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