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