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