You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1982 lines
50 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32l1xx_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. (#) Declare a PCD_HandleTypeDef handle structure, for example:
  20. PCD_HandleTypeDef hpcd;
  21. (#) Fill parameters of Init structure in HCD handle
  22. (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...)
  23. (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
  24. (##) Enable the PCD/USB Low Level interface clock using
  25. (+++) __HAL_RCC_USB_CLK_ENABLE(); For USB Device only FS peripheral
  26. (##) Initialize the related GPIO clocks
  27. (##) Configure PCD pin-out
  28. (##) Configure PCD NVIC interrupt
  29. (#)Associate the Upper USB device stack to the HAL PCD Driver:
  30. (##) hpcd.pData = pdev;
  31. (#)Enable PCD transmission and reception:
  32. (##) HAL_PCD_Start();
  33. @endverbatim
  34. ******************************************************************************
  35. * @attention
  36. *
  37. * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
  38. * All rights reserved.</center></h2>
  39. *
  40. * This software component is licensed by ST under BSD 3-Clause license,
  41. * the "License"; You may not use this file except in compliance with the
  42. * License. You may obtain a copy of the License at:
  43. * opensource.org/licenses/BSD-3-Clause
  44. *
  45. ******************************************************************************
  46. */
  47. /* Includes ------------------------------------------------------------------*/
  48. #include "stm32l1xx_hal.h"
  49. /** @addtogroup STM32L1xx_HAL_Driver
  50. * @{
  51. */
  52. /** @defgroup PCD PCD
  53. * @brief PCD HAL module driver
  54. * @{
  55. */
  56. #ifdef HAL_PCD_MODULE_ENABLED
  57. #if defined (USB)
  58. /* Private types -------------------------------------------------------------*/
  59. /* Private variables ---------------------------------------------------------*/
  60. /* Private constants ---------------------------------------------------------*/
  61. /* Private macros ------------------------------------------------------------*/
  62. /** @defgroup PCD_Private_Macros PCD Private Macros
  63. * @{
  64. */
  65. #define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b))
  66. #define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b))
  67. /**
  68. * @}
  69. */
  70. /* Private functions prototypes ----------------------------------------------*/
  71. /** @defgroup PCD_Private_Functions PCD Private Functions
  72. * @{
  73. */
  74. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
  75. static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef *ep, uint16_t wEPVal);
  76. static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef *ep, uint16_t wEPVal);
  77. /**
  78. * @}
  79. */
  80. /* Exported functions --------------------------------------------------------*/
  81. /** @defgroup PCD_Exported_Functions PCD Exported Functions
  82. * @{
  83. */
  84. /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
  85. * @brief Initialization and Configuration functions
  86. *
  87. @verbatim
  88. ===============================================================================
  89. ##### Initialization and de-initialization functions #####
  90. ===============================================================================
  91. [..] This section provides functions allowing to:
  92. @endverbatim
  93. * @{
  94. */
  95. /**
  96. * @brief Initializes the PCD according to the specified
  97. * parameters in the PCD_InitTypeDef and initialize the associated handle.
  98. * @param hpcd PCD handle
  99. * @retval HAL status
  100. */
  101. HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
  102. {
  103. uint8_t i;
  104. /* Check the PCD handle allocation */
  105. if (hpcd == NULL)
  106. {
  107. return HAL_ERROR;
  108. }
  109. /* Check the parameters */
  110. assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
  111. if (hpcd->State == HAL_PCD_STATE_RESET)
  112. {
  113. /* Allocate lock resource and initialize it */
  114. hpcd->Lock = HAL_UNLOCKED;
  115. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  116. hpcd->SOFCallback = HAL_PCD_SOFCallback;
  117. hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
  118. hpcd->ResetCallback = HAL_PCD_ResetCallback;
  119. hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
  120. hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
  121. hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
  122. hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
  123. hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback;
  124. hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback;
  125. hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback;
  126. hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback;
  127. if (hpcd->MspInitCallback == NULL)
  128. {
  129. hpcd->MspInitCallback = HAL_PCD_MspInit;
  130. }
  131. /* Init the low level hardware */
  132. hpcd->MspInitCallback(hpcd);
  133. #else
  134. /* Init the low level hardware : GPIO, CLOCK, NVIC... */
  135. HAL_PCD_MspInit(hpcd);
  136. #endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */
  137. }
  138. hpcd->State = HAL_PCD_STATE_BUSY;
  139. /* Disable the Interrupts */
  140. __HAL_PCD_DISABLE(hpcd);
  141. /* Init endpoints structures */
  142. for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  143. {
  144. /* Init ep structure */
  145. hpcd->IN_ep[i].is_in = 1U;
  146. hpcd->IN_ep[i].num = i;
  147. hpcd->IN_ep[i].tx_fifo_num = i;
  148. /* Control until ep is activated */
  149. hpcd->IN_ep[i].type = EP_TYPE_CTRL;
  150. hpcd->IN_ep[i].maxpacket = 0U;
  151. hpcd->IN_ep[i].xfer_buff = 0U;
  152. hpcd->IN_ep[i].xfer_len = 0U;
  153. }
  154. for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  155. {
  156. hpcd->OUT_ep[i].is_in = 0U;
  157. hpcd->OUT_ep[i].num = i;
  158. /* Control until ep is activated */
  159. hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
  160. hpcd->OUT_ep[i].maxpacket = 0U;
  161. hpcd->OUT_ep[i].xfer_buff = 0U;
  162. hpcd->OUT_ep[i].xfer_len = 0U;
  163. }
  164. /* Init Device */
  165. (void)USB_DevInit(hpcd->Instance, hpcd->Init);
  166. hpcd->USB_Address = 0U;
  167. hpcd->State = HAL_PCD_STATE_READY;
  168. return HAL_OK;
  169. }
  170. /**
  171. * @brief DeInitializes the PCD peripheral.
  172. * @param hpcd PCD handle
  173. * @retval HAL status
  174. */
  175. HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
  176. {
  177. /* Check the PCD handle allocation */
  178. if (hpcd == NULL)
  179. {
  180. return HAL_ERROR;
  181. }
  182. hpcd->State = HAL_PCD_STATE_BUSY;
  183. /* Stop Device */
  184. if (USB_StopDevice(hpcd->Instance) != HAL_OK)
  185. {
  186. return HAL_ERROR;
  187. }
  188. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  189. if (hpcd->MspDeInitCallback == NULL)
  190. {
  191. hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit */
  192. }
  193. /* DeInit the low level hardware */
  194. hpcd->MspDeInitCallback(hpcd);
  195. #else
  196. /* DeInit the low level hardware: CLOCK, NVIC.*/
  197. HAL_PCD_MspDeInit(hpcd);
  198. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  199. hpcd->State = HAL_PCD_STATE_RESET;
  200. return HAL_OK;
  201. }
  202. /**
  203. * @brief Initializes the PCD MSP.
  204. * @param hpcd PCD handle
  205. * @retval None
  206. */
  207. __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
  208. {
  209. /* Prevent unused argument(s) compilation warning */
  210. UNUSED(hpcd);
  211. /* NOTE : This function should not be modified, when the callback is needed,
  212. the HAL_PCD_MspInit could be implemented in the user file
  213. */
  214. }
  215. /**
  216. * @brief DeInitializes PCD MSP.
  217. * @param hpcd PCD handle
  218. * @retval None
  219. */
  220. __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
  221. {
  222. /* Prevent unused argument(s) compilation warning */
  223. UNUSED(hpcd);
  224. /* NOTE : This function should not be modified, when the callback is needed,
  225. the HAL_PCD_MspDeInit could be implemented in the user file
  226. */
  227. }
  228. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  229. /**
  230. * @brief Register a User USB PCD Callback
  231. * To be used instead of the weak predefined callback
  232. * @param hpcd USB PCD handle
  233. * @param CallbackID ID of the callback to be registered
  234. * This parameter can be one of the following values:
  235. * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
  236. * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
  237. * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
  238. * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
  239. * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
  240. * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
  241. * @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
  242. * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
  243. * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
  244. * @param pCallback pointer to the Callback function
  245. * @retval HAL status
  246. */
  247. HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID, pPCD_CallbackTypeDef pCallback)
  248. {
  249. HAL_StatusTypeDef status = HAL_OK;
  250. if (pCallback == NULL)
  251. {
  252. /* Update the error code */
  253. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  254. return HAL_ERROR;
  255. }
  256. /* Process locked */
  257. __HAL_LOCK(hpcd);
  258. if (hpcd->State == HAL_PCD_STATE_READY)
  259. {
  260. switch (CallbackID)
  261. {
  262. case HAL_PCD_SOF_CB_ID :
  263. hpcd->SOFCallback = pCallback;
  264. break;
  265. case HAL_PCD_SETUPSTAGE_CB_ID :
  266. hpcd->SetupStageCallback = pCallback;
  267. break;
  268. case HAL_PCD_RESET_CB_ID :
  269. hpcd->ResetCallback = pCallback;
  270. break;
  271. case HAL_PCD_SUSPEND_CB_ID :
  272. hpcd->SuspendCallback = pCallback;
  273. break;
  274. case HAL_PCD_RESUME_CB_ID :
  275. hpcd->ResumeCallback = pCallback;
  276. break;
  277. case HAL_PCD_CONNECT_CB_ID :
  278. hpcd->ConnectCallback = pCallback;
  279. break;
  280. case HAL_PCD_DISCONNECT_CB_ID :
  281. hpcd->DisconnectCallback = pCallback;
  282. break;
  283. case HAL_PCD_MSPINIT_CB_ID :
  284. hpcd->MspInitCallback = pCallback;
  285. break;
  286. case HAL_PCD_MSPDEINIT_CB_ID :
  287. hpcd->MspDeInitCallback = pCallback;
  288. break;
  289. default :
  290. /* Update the error code */
  291. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  292. /* Return error status */
  293. status = HAL_ERROR;
  294. break;
  295. }
  296. }
  297. else if (hpcd->State == HAL_PCD_STATE_RESET)
  298. {
  299. switch (CallbackID)
  300. {
  301. case HAL_PCD_MSPINIT_CB_ID :
  302. hpcd->MspInitCallback = pCallback;
  303. break;
  304. case HAL_PCD_MSPDEINIT_CB_ID :
  305. hpcd->MspDeInitCallback = pCallback;
  306. break;
  307. default :
  308. /* Update the error code */
  309. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  310. /* Return error status */
  311. status = HAL_ERROR;
  312. break;
  313. }
  314. }
  315. else
  316. {
  317. /* Update the error code */
  318. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  319. /* Return error status */
  320. status = HAL_ERROR;
  321. }
  322. /* Release Lock */
  323. __HAL_UNLOCK(hpcd);
  324. return status;
  325. }
  326. /**
  327. * @brief Unregister an USB PCD Callback
  328. * USB PCD callabck is redirected to the weak predefined callback
  329. * @param hpcd USB PCD handle
  330. * @param CallbackID ID of the callback to be unregistered
  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 OTG 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. * @retval HAL status
  342. */
  343. HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID)
  344. {
  345. HAL_StatusTypeDef status = HAL_OK;
  346. /* Process locked */
  347. __HAL_LOCK(hpcd);
  348. /* Setup Legacy weak Callbacks */
  349. if (hpcd->State == HAL_PCD_STATE_READY)
  350. {
  351. switch (CallbackID)
  352. {
  353. case HAL_PCD_SOF_CB_ID :
  354. hpcd->SOFCallback = HAL_PCD_SOFCallback;
  355. break;
  356. case HAL_PCD_SETUPSTAGE_CB_ID :
  357. hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
  358. break;
  359. case HAL_PCD_RESET_CB_ID :
  360. hpcd->ResetCallback = HAL_PCD_ResetCallback;
  361. break;
  362. case HAL_PCD_SUSPEND_CB_ID :
  363. hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
  364. break;
  365. case HAL_PCD_RESUME_CB_ID :
  366. hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
  367. break;
  368. case HAL_PCD_CONNECT_CB_ID :
  369. hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
  370. break;
  371. case HAL_PCD_DISCONNECT_CB_ID :
  372. hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
  373. break;
  374. case HAL_PCD_MSPINIT_CB_ID :
  375. hpcd->MspInitCallback = HAL_PCD_MspInit;
  376. break;
  377. case HAL_PCD_MSPDEINIT_CB_ID :
  378. hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
  379. break;
  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 = HAL_PCD_MspInit;
  394. break;
  395. case HAL_PCD_MSPDEINIT_CB_ID :
  396. hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
  397. break;
  398. default :
  399. /* Update the error code */
  400. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  401. /* Return error status */
  402. status = HAL_ERROR;
  403. break;
  404. }
  405. }
  406. else
  407. {
  408. /* Update the error code */
  409. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  410. /* Return error status */
  411. status = HAL_ERROR;
  412. }
  413. /* Release Lock */
  414. __HAL_UNLOCK(hpcd);
  415. return status;
  416. }
  417. /**
  418. * @brief Register USB PCD Data OUT Stage Callback
  419. * To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback
  420. * @param hpcd PCD handle
  421. * @param pCallback pointer to the USB PCD Data OUT Stage Callback function
  422. * @retval HAL status
  423. */
  424. HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataOutStageCallbackTypeDef pCallback)
  425. {
  426. HAL_StatusTypeDef status = HAL_OK;
  427. if (pCallback == NULL)
  428. {
  429. /* Update the error code */
  430. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  431. return HAL_ERROR;
  432. }
  433. /* Process locked */
  434. __HAL_LOCK(hpcd);
  435. if (hpcd->State == HAL_PCD_STATE_READY)
  436. {
  437. hpcd->DataOutStageCallback = pCallback;
  438. }
  439. else
  440. {
  441. /* Update the error code */
  442. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  443. /* Return error status */
  444. status = HAL_ERROR;
  445. }
  446. /* Release Lock */
  447. __HAL_UNLOCK(hpcd);
  448. return status;
  449. }
  450. /**
  451. * @brief Unregister the USB PCD Data OUT Stage Callback
  452. * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback
  453. * @param hpcd PCD handle
  454. * @retval HAL status
  455. */
  456. HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd)
  457. {
  458. HAL_StatusTypeDef status = HAL_OK;
  459. /* Process locked */
  460. __HAL_LOCK(hpcd);
  461. if (hpcd->State == HAL_PCD_STATE_READY)
  462. {
  463. hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback */
  464. }
  465. else
  466. {
  467. /* Update the error code */
  468. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  469. /* Return error status */
  470. status = HAL_ERROR;
  471. }
  472. /* Release Lock */
  473. __HAL_UNLOCK(hpcd);
  474. return status;
  475. }
  476. /**
  477. * @brief Register USB PCD Data IN Stage Callback
  478. * To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback
  479. * @param hpcd PCD handle
  480. * @param pCallback pointer to the USB PCD Data IN Stage Callback function
  481. * @retval HAL status
  482. */
  483. HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataInStageCallbackTypeDef pCallback)
  484. {
  485. HAL_StatusTypeDef status = HAL_OK;
  486. if (pCallback == NULL)
  487. {
  488. /* Update the error code */
  489. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  490. return HAL_ERROR;
  491. }
  492. /* Process locked */
  493. __HAL_LOCK(hpcd);
  494. if (hpcd->State == HAL_PCD_STATE_READY)
  495. {
  496. hpcd->DataInStageCallback = pCallback;
  497. }
  498. else
  499. {
  500. /* Update the error code */
  501. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  502. /* Return error status */
  503. status = HAL_ERROR;
  504. }
  505. /* Release Lock */
  506. __HAL_UNLOCK(hpcd);
  507. return status;
  508. }
  509. /**
  510. * @brief Unregister the USB PCD Data IN Stage Callback
  511. * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback
  512. * @param hpcd PCD handle
  513. * @retval HAL status
  514. */
  515. HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd)
  516. {
  517. HAL_StatusTypeDef status = HAL_OK;
  518. /* Process locked */
  519. __HAL_LOCK(hpcd);
  520. if (hpcd->State == HAL_PCD_STATE_READY)
  521. {
  522. hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback */
  523. }
  524. else
  525. {
  526. /* Update the error code */
  527. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  528. /* Return error status */
  529. status = HAL_ERROR;
  530. }
  531. /* Release Lock */
  532. __HAL_UNLOCK(hpcd);
  533. return status;
  534. }
  535. /**
  536. * @brief Register USB PCD Iso OUT incomplete Callback
  537. * To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
  538. * @param hpcd PCD handle
  539. * @param pCallback pointer to the USB PCD Iso OUT incomplete Callback function
  540. * @retval HAL status
  541. */
  542. HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoOutIncpltCallbackTypeDef pCallback)
  543. {
  544. HAL_StatusTypeDef status = HAL_OK;
  545. if (pCallback == NULL)
  546. {
  547. /* Update the error code */
  548. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  549. return HAL_ERROR;
  550. }
  551. /* Process locked */
  552. __HAL_LOCK(hpcd);
  553. if (hpcd->State == HAL_PCD_STATE_READY)
  554. {
  555. hpcd->ISOOUTIncompleteCallback = pCallback;
  556. }
  557. else
  558. {
  559. /* Update the error code */
  560. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  561. /* Return error status */
  562. status = HAL_ERROR;
  563. }
  564. /* Release Lock */
  565. __HAL_UNLOCK(hpcd);
  566. return status;
  567. }
  568. /**
  569. * @brief Unregister the USB PCD Iso OUT incomplete Callback
  570. * USB PCD Iso OUT incomplete Callback is redirected to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
  571. * @param hpcd PCD handle
  572. * @retval HAL status
  573. */
  574. HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
  575. {
  576. HAL_StatusTypeDef status = HAL_OK;
  577. /* Process locked */
  578. __HAL_LOCK(hpcd);
  579. if (hpcd->State == HAL_PCD_STATE_READY)
  580. {
  581. hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback */
  582. }
  583. else
  584. {
  585. /* Update the error code */
  586. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  587. /* Return error status */
  588. status = HAL_ERROR;
  589. }
  590. /* Release Lock */
  591. __HAL_UNLOCK(hpcd);
  592. return status;
  593. }
  594. /**
  595. * @brief Register USB PCD Iso IN incomplete Callback
  596. * To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
  597. * @param hpcd PCD handle
  598. * @param pCallback pointer to the USB PCD Iso IN incomplete Callback function
  599. * @retval HAL status
  600. */
  601. HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoInIncpltCallbackTypeDef pCallback)
  602. {
  603. HAL_StatusTypeDef status = HAL_OK;
  604. if (pCallback == NULL)
  605. {
  606. /* Update the error code */
  607. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  608. return HAL_ERROR;
  609. }
  610. /* Process locked */
  611. __HAL_LOCK(hpcd);
  612. if (hpcd->State == HAL_PCD_STATE_READY)
  613. {
  614. hpcd->ISOINIncompleteCallback = pCallback;
  615. }
  616. else
  617. {
  618. /* Update the error code */
  619. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  620. /* Return error status */
  621. status = HAL_ERROR;
  622. }
  623. /* Release Lock */
  624. __HAL_UNLOCK(hpcd);
  625. return status;
  626. }
  627. /**
  628. * @brief Unregister the USB PCD Iso IN incomplete Callback
  629. * USB PCD Iso IN incomplete Callback is redirected to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
  630. * @param hpcd PCD handle
  631. * @retval HAL status
  632. */
  633. HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
  634. {
  635. HAL_StatusTypeDef status = HAL_OK;
  636. /* Process locked */
  637. __HAL_LOCK(hpcd);
  638. if (hpcd->State == HAL_PCD_STATE_READY)
  639. {
  640. hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback */
  641. }
  642. else
  643. {
  644. /* Update the error code */
  645. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  646. /* Return error status */
  647. status = HAL_ERROR;
  648. }
  649. /* Release Lock */
  650. __HAL_UNLOCK(hpcd);
  651. return status;
  652. }
  653. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  654. /**
  655. * @}
  656. */
  657. /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
  658. * @brief Data transfers functions
  659. *
  660. @verbatim
  661. ===============================================================================
  662. ##### IO operation functions #####
  663. ===============================================================================
  664. [..]
  665. This subsection provides a set of functions allowing to manage the PCD data
  666. transfers.
  667. @endverbatim
  668. * @{
  669. */
  670. /**
  671. * @brief Start the USB device
  672. * @param hpcd PCD handle
  673. * @retval HAL status
  674. */
  675. HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
  676. {
  677. __HAL_LOCK(hpcd);
  678. __HAL_PCD_ENABLE(hpcd);
  679. HAL_PCDEx_SetConnectionState(hpcd, 1U);
  680. (void)USB_DevConnect(hpcd->Instance);
  681. __HAL_UNLOCK(hpcd);
  682. return HAL_OK;
  683. }
  684. /**
  685. * @brief Stop the USB device.
  686. * @param hpcd PCD handle
  687. * @retval HAL status
  688. */
  689. HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
  690. {
  691. __HAL_LOCK(hpcd);
  692. __HAL_PCD_DISABLE(hpcd);
  693. HAL_PCDEx_SetConnectionState(hpcd, 0U);
  694. (void)USB_DevDisconnect(hpcd->Instance);
  695. __HAL_UNLOCK(hpcd);
  696. return HAL_OK;
  697. }
  698. /**
  699. * @brief This function handles PCD interrupt request.
  700. * @param hpcd PCD handle
  701. * @retval HAL status
  702. */
  703. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  704. {
  705. if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_CTR))
  706. {
  707. /* servicing of the endpoint correct transfer interrupt */
  708. /* clear of the CTR flag into the sub */
  709. (void)PCD_EP_ISR_Handler(hpcd);
  710. }
  711. if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_RESET))
  712. {
  713. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
  714. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  715. hpcd->ResetCallback(hpcd);
  716. #else
  717. HAL_PCD_ResetCallback(hpcd);
  718. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  719. (void)HAL_PCD_SetAddress(hpcd, 0U);
  720. }
  721. if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_PMAOVR))
  722. {
  723. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
  724. }
  725. if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ERR))
  726. {
  727. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
  728. }
  729. if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP))
  730. {
  731. hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LPMODE);
  732. hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP);
  733. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  734. hpcd->ResumeCallback(hpcd);
  735. #else
  736. HAL_PCD_ResumeCallback(hpcd);
  737. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  738. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
  739. }
  740. if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SUSP))
  741. {
  742. /* Force low-power mode in the macrocell */
  743. hpcd->Instance->CNTR |= (uint16_t)USB_CNTR_FSUSP;
  744. /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
  745. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
  746. hpcd->Instance->CNTR |= (uint16_t)USB_CNTR_LPMODE;
  747. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  748. hpcd->SuspendCallback(hpcd);
  749. #else
  750. HAL_PCD_SuspendCallback(hpcd);
  751. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  752. }
  753. if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SOF))
  754. {
  755. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
  756. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  757. hpcd->SOFCallback(hpcd);
  758. #else
  759. HAL_PCD_SOFCallback(hpcd);
  760. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  761. }
  762. if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ESOF))
  763. {
  764. /* clear ESOF flag in ISTR */
  765. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
  766. }
  767. }
  768. /**
  769. * @brief Handles PCD Wakeup interrupt request.
  770. * @param hpcd PCD handle
  771. * @retval HAL status
  772. */
  773. void HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef *hpcd)
  774. {
  775. /* Clear EXTI pending Bit */
  776. __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG();
  777. }
  778. /**
  779. * @brief Data OUT stage callback.
  780. * @param hpcd PCD handle
  781. * @param epnum endpoint number
  782. * @retval None
  783. */
  784. __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  785. {
  786. /* Prevent unused argument(s) compilation warning */
  787. UNUSED(hpcd);
  788. UNUSED(epnum);
  789. /* NOTE : This function should not be modified, when the callback is needed,
  790. the HAL_PCD_DataOutStageCallback could be implemented in the user file
  791. */
  792. }
  793. /**
  794. * @brief Data IN stage callback
  795. * @param hpcd PCD handle
  796. * @param epnum endpoint number
  797. * @retval None
  798. */
  799. __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  800. {
  801. /* Prevent unused argument(s) compilation warning */
  802. UNUSED(hpcd);
  803. UNUSED(epnum);
  804. /* NOTE : This function should not be modified, when the callback is needed,
  805. the HAL_PCD_DataInStageCallback could be implemented in the user file
  806. */
  807. }
  808. /**
  809. * @brief Setup stage callback
  810. * @param hpcd PCD handle
  811. * @retval None
  812. */
  813. __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
  814. {
  815. /* Prevent unused argument(s) compilation warning */
  816. UNUSED(hpcd);
  817. /* NOTE : This function should not be modified, when the callback is needed,
  818. the HAL_PCD_SetupStageCallback could be implemented in the user file
  819. */
  820. }
  821. /**
  822. * @brief USB Start Of Frame callback.
  823. * @param hpcd PCD handle
  824. * @retval None
  825. */
  826. __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
  827. {
  828. /* Prevent unused argument(s) compilation warning */
  829. UNUSED(hpcd);
  830. /* NOTE : This function should not be modified, when the callback is needed,
  831. the HAL_PCD_SOFCallback could be implemented in the user file
  832. */
  833. }
  834. /**
  835. * @brief USB Reset callback.
  836. * @param hpcd PCD handle
  837. * @retval None
  838. */
  839. __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
  840. {
  841. /* Prevent unused argument(s) compilation warning */
  842. UNUSED(hpcd);
  843. /* NOTE : This function should not be modified, when the callback is needed,
  844. the HAL_PCD_ResetCallback could be implemented in the user file
  845. */
  846. }
  847. /**
  848. * @brief Suspend event callback.
  849. * @param hpcd PCD handle
  850. * @retval None
  851. */
  852. __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
  853. {
  854. /* Prevent unused argument(s) compilation warning */
  855. UNUSED(hpcd);
  856. /* NOTE : This function should not be modified, when the callback is needed,
  857. the HAL_PCD_SuspendCallback could be implemented in the user file
  858. */
  859. }
  860. /**
  861. * @brief Resume event callback.
  862. * @param hpcd PCD handle
  863. * @retval None
  864. */
  865. __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
  866. {
  867. /* Prevent unused argument(s) compilation warning */
  868. UNUSED(hpcd);
  869. /* NOTE : This function should not be modified, when the callback is needed,
  870. the HAL_PCD_ResumeCallback could be implemented in the user file
  871. */
  872. }
  873. /**
  874. * @brief Incomplete ISO OUT callback.
  875. * @param hpcd PCD handle
  876. * @param epnum endpoint number
  877. * @retval None
  878. */
  879. __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  880. {
  881. /* Prevent unused argument(s) compilation warning */
  882. UNUSED(hpcd);
  883. UNUSED(epnum);
  884. /* NOTE : This function should not be modified, when the callback is needed,
  885. the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
  886. */
  887. }
  888. /**
  889. * @brief Incomplete ISO IN callback.
  890. * @param hpcd PCD handle
  891. * @param epnum endpoint number
  892. * @retval None
  893. */
  894. __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  895. {
  896. /* Prevent unused argument(s) compilation warning */
  897. UNUSED(hpcd);
  898. UNUSED(epnum);
  899. /* NOTE : This function should not be modified, when the callback is needed,
  900. the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
  901. */
  902. }
  903. /**
  904. * @brief Connection event callback.
  905. * @param hpcd PCD handle
  906. * @retval None
  907. */
  908. __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
  909. {
  910. /* Prevent unused argument(s) compilation warning */
  911. UNUSED(hpcd);
  912. /* NOTE : This function should not be modified, when the callback is needed,
  913. the HAL_PCD_ConnectCallback could be implemented in the user file
  914. */
  915. }
  916. /**
  917. * @brief Disconnection event callback.
  918. * @param hpcd PCD handle
  919. * @retval None
  920. */
  921. __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
  922. {
  923. /* Prevent unused argument(s) compilation warning */
  924. UNUSED(hpcd);
  925. /* NOTE : This function should not be modified, when the callback is needed,
  926. the HAL_PCD_DisconnectCallback could be implemented in the user file
  927. */
  928. }
  929. /**
  930. * @}
  931. */
  932. /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
  933. * @brief management functions
  934. *
  935. @verbatim
  936. ===============================================================================
  937. ##### Peripheral Control functions #####
  938. ===============================================================================
  939. [..]
  940. This subsection provides a set of functions allowing to control the PCD data
  941. transfers.
  942. @endverbatim
  943. * @{
  944. */
  945. /**
  946. * @brief Connect the USB device
  947. * @param hpcd PCD handle
  948. * @retval HAL status
  949. */
  950. HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
  951. {
  952. __HAL_LOCK(hpcd);
  953. HAL_PCDEx_SetConnectionState(hpcd, 1U);
  954. (void)USB_DevConnect(hpcd->Instance);
  955. __HAL_UNLOCK(hpcd);
  956. return HAL_OK;
  957. }
  958. /**
  959. * @brief Disconnect the USB device.
  960. * @param hpcd PCD handle
  961. * @retval HAL status
  962. */
  963. HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
  964. {
  965. __HAL_LOCK(hpcd);
  966. HAL_PCDEx_SetConnectionState(hpcd, 0U);
  967. (void)USB_DevDisconnect(hpcd->Instance);
  968. __HAL_UNLOCK(hpcd);
  969. return HAL_OK;
  970. }
  971. /**
  972. * @brief Set the USB Device address.
  973. * @param hpcd PCD handle
  974. * @param address new device address
  975. * @retval HAL status
  976. */
  977. HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
  978. {
  979. __HAL_LOCK(hpcd);
  980. hpcd->USB_Address = address;
  981. (void)USB_SetDevAddress(hpcd->Instance, address);
  982. __HAL_UNLOCK(hpcd);
  983. return HAL_OK;
  984. }
  985. /**
  986. * @brief Open and configure an endpoint.
  987. * @param hpcd PCD handle
  988. * @param ep_addr endpoint address
  989. * @param ep_mps endpoint max packet size
  990. * @param ep_type endpoint type
  991. * @retval HAL status
  992. */
  993. HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
  994. {
  995. HAL_StatusTypeDef ret = HAL_OK;
  996. PCD_EPTypeDef *ep;
  997. if ((ep_addr & 0x80U) == 0x80U)
  998. {
  999. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1000. ep->is_in = 1U;
  1001. }
  1002. else
  1003. {
  1004. ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1005. ep->is_in = 0U;
  1006. }
  1007. ep->num = ep_addr & EP_ADDR_MSK;
  1008. ep->maxpacket = ep_mps;
  1009. ep->type = ep_type;
  1010. if (ep->is_in != 0U)
  1011. {
  1012. /* Assign a Tx FIFO */
  1013. ep->tx_fifo_num = ep->num;
  1014. }
  1015. /* Set initial data PID. */
  1016. if (ep_type == EP_TYPE_BULK)
  1017. {
  1018. ep->data_pid_start = 0U;
  1019. }
  1020. __HAL_LOCK(hpcd);
  1021. (void)USB_ActivateEndpoint(hpcd->Instance, ep);
  1022. __HAL_UNLOCK(hpcd);
  1023. return ret;
  1024. }
  1025. /**
  1026. * @brief Deactivate an endpoint.
  1027. * @param hpcd PCD handle
  1028. * @param ep_addr endpoint address
  1029. * @retval HAL status
  1030. */
  1031. HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1032. {
  1033. PCD_EPTypeDef *ep;
  1034. if ((ep_addr & 0x80U) == 0x80U)
  1035. {
  1036. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1037. ep->is_in = 1U;
  1038. }
  1039. else
  1040. {
  1041. ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1042. ep->is_in = 0U;
  1043. }
  1044. ep->num = ep_addr & EP_ADDR_MSK;
  1045. __HAL_LOCK(hpcd);
  1046. (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
  1047. __HAL_UNLOCK(hpcd);
  1048. return HAL_OK;
  1049. }
  1050. /**
  1051. * @brief Receive an amount of data.
  1052. * @param hpcd PCD handle
  1053. * @param ep_addr endpoint address
  1054. * @param pBuf pointer to the reception buffer
  1055. * @param len amount of data to be received
  1056. * @retval HAL status
  1057. */
  1058. HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  1059. {
  1060. PCD_EPTypeDef *ep;
  1061. ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1062. /*setup and start the Xfer */
  1063. ep->xfer_buff = pBuf;
  1064. ep->xfer_len = len;
  1065. ep->xfer_count = 0U;
  1066. ep->is_in = 0U;
  1067. ep->num = ep_addr & EP_ADDR_MSK;
  1068. if ((ep_addr & EP_ADDR_MSK) == 0U)
  1069. {
  1070. (void)USB_EP0StartXfer(hpcd->Instance, ep);
  1071. }
  1072. else
  1073. {
  1074. (void)USB_EPStartXfer(hpcd->Instance, ep);
  1075. }
  1076. return HAL_OK;
  1077. }
  1078. /**
  1079. * @brief Get Received Data Size
  1080. * @param hpcd PCD handle
  1081. * @param ep_addr endpoint address
  1082. * @retval Data Size
  1083. */
  1084. uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1085. {
  1086. return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count;
  1087. }
  1088. /**
  1089. * @brief Send an amount of data
  1090. * @param hpcd PCD handle
  1091. * @param ep_addr endpoint address
  1092. * @param pBuf pointer to the transmission buffer
  1093. * @param len amount of data to be sent
  1094. * @retval HAL status
  1095. */
  1096. HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  1097. {
  1098. PCD_EPTypeDef *ep;
  1099. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1100. /*setup and start the Xfer */
  1101. ep->xfer_buff = pBuf;
  1102. ep->xfer_len = len;
  1103. ep->xfer_fill_db = 1U;
  1104. ep->xfer_len_db = len;
  1105. ep->xfer_count = 0U;
  1106. ep->is_in = 1U;
  1107. ep->num = ep_addr & EP_ADDR_MSK;
  1108. if ((ep_addr & EP_ADDR_MSK) == 0U)
  1109. {
  1110. (void)USB_EP0StartXfer(hpcd->Instance, ep);
  1111. }
  1112. else
  1113. {
  1114. (void)USB_EPStartXfer(hpcd->Instance, ep);
  1115. }
  1116. return HAL_OK;
  1117. }
  1118. /**
  1119. * @brief Set a STALL condition over an endpoint
  1120. * @param hpcd PCD handle
  1121. * @param ep_addr endpoint address
  1122. * @retval HAL status
  1123. */
  1124. HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1125. {
  1126. PCD_EPTypeDef *ep;
  1127. if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints)
  1128. {
  1129. return HAL_ERROR;
  1130. }
  1131. if ((0x80U & ep_addr) == 0x80U)
  1132. {
  1133. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1134. ep->is_in = 1U;
  1135. }
  1136. else
  1137. {
  1138. ep = &hpcd->OUT_ep[ep_addr];
  1139. ep->is_in = 0U;
  1140. }
  1141. ep->is_stall = 1U;
  1142. ep->num = ep_addr & EP_ADDR_MSK;
  1143. __HAL_LOCK(hpcd);
  1144. (void)USB_EPSetStall(hpcd->Instance, ep);
  1145. if ((ep_addr & EP_ADDR_MSK) == 0U)
  1146. {
  1147. (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
  1148. }
  1149. __HAL_UNLOCK(hpcd);
  1150. return HAL_OK;
  1151. }
  1152. /**
  1153. * @brief Clear a STALL condition over in an endpoint
  1154. * @param hpcd PCD handle
  1155. * @param ep_addr endpoint address
  1156. * @retval HAL status
  1157. */
  1158. HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1159. {
  1160. PCD_EPTypeDef *ep;
  1161. if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
  1162. {
  1163. return HAL_ERROR;
  1164. }
  1165. if ((0x80U & ep_addr) == 0x80U)
  1166. {
  1167. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1168. ep->is_in = 1U;
  1169. }
  1170. else
  1171. {
  1172. ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1173. ep->is_in = 0U;
  1174. }
  1175. ep->is_stall = 0U;
  1176. ep->num = ep_addr & EP_ADDR_MSK;
  1177. __HAL_LOCK(hpcd);
  1178. (void)USB_EPClearStall(hpcd->Instance, ep);
  1179. __HAL_UNLOCK(hpcd);
  1180. return HAL_OK;
  1181. }
  1182. /**
  1183. * @brief Flush an endpoint
  1184. * @param hpcd PCD handle
  1185. * @param ep_addr endpoint address
  1186. * @retval HAL status
  1187. */
  1188. HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1189. {
  1190. /* Prevent unused argument(s) compilation warning */
  1191. UNUSED(hpcd);
  1192. UNUSED(ep_addr);
  1193. return HAL_OK;
  1194. }
  1195. /**
  1196. * @brief Activate remote wakeup signalling
  1197. * @param hpcd PCD handle
  1198. * @retval HAL status
  1199. */
  1200. HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1201. {
  1202. return (USB_ActivateRemoteWakeup(hpcd->Instance));
  1203. }
  1204. /**
  1205. * @brief De-activate remote wakeup signalling.
  1206. * @param hpcd PCD handle
  1207. * @retval HAL status
  1208. */
  1209. HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1210. {
  1211. return (USB_DeActivateRemoteWakeup(hpcd->Instance));
  1212. }
  1213. /**
  1214. * @}
  1215. */
  1216. /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
  1217. * @brief Peripheral State functions
  1218. *
  1219. @verbatim
  1220. ===============================================================================
  1221. ##### Peripheral State functions #####
  1222. ===============================================================================
  1223. [..]
  1224. This subsection permits to get in run-time the status of the peripheral
  1225. and the data flow.
  1226. @endverbatim
  1227. * @{
  1228. */
  1229. /**
  1230. * @brief Return the PCD handle state.
  1231. * @param hpcd PCD handle
  1232. * @retval HAL state
  1233. */
  1234. PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
  1235. {
  1236. return hpcd->State;
  1237. }
  1238. /**
  1239. * @}
  1240. */
  1241. /**
  1242. * @}
  1243. */
  1244. /* Private functions ---------------------------------------------------------*/
  1245. /** @addtogroup PCD_Private_Functions
  1246. * @{
  1247. */
  1248. /**
  1249. * @brief This function handles PCD Endpoint interrupt request.
  1250. * @param hpcd PCD handle
  1251. * @retval HAL status
  1252. */
  1253. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
  1254. {
  1255. PCD_EPTypeDef *ep;
  1256. uint16_t count, wIstr, wEPVal, TxByteNbre;
  1257. uint8_t epindex;
  1258. /* stay in loop while pending interrupts */
  1259. while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U)
  1260. {
  1261. wIstr = hpcd->Instance->ISTR;
  1262. /* extract highest priority endpoint number */
  1263. epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
  1264. if (epindex == 0U)
  1265. {
  1266. /* Decode and service control endpoint interrupt */
  1267. /* DIR bit = origin of the interrupt */
  1268. if ((wIstr & USB_ISTR_DIR) == 0U)
  1269. {
  1270. /* DIR = 0 */
  1271. /* DIR = 0 => IN int */
  1272. /* DIR = 0 implies that (EP_CTR_TX = 1) always */
  1273. PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1274. ep = &hpcd->IN_ep[0];
  1275. ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  1276. ep->xfer_buff += ep->xfer_count;
  1277. /* TX COMPLETE */
  1278. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1279. hpcd->DataInStageCallback(hpcd, 0U);
  1280. #else
  1281. HAL_PCD_DataInStageCallback(hpcd, 0U);
  1282. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1283. if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U))
  1284. {
  1285. hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF);
  1286. hpcd->USB_Address = 0U;
  1287. }
  1288. }
  1289. else
  1290. {
  1291. /* DIR = 1 */
  1292. /* DIR = 1 & CTR_RX => SETUP or OUT int */
  1293. /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
  1294. ep = &hpcd->OUT_ep[0];
  1295. wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
  1296. if ((wEPVal & USB_EP_SETUP) != 0U)
  1297. {
  1298. /* Get SETUP Packet */
  1299. ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1300. USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup,
  1301. ep->pmaadress, (uint16_t)ep->xfer_count);
  1302. /* SETUP bit kept frozen while CTR_RX = 1 */
  1303. PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1304. /* Process SETUP Packet*/
  1305. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1306. hpcd->SetupStageCallback(hpcd);
  1307. #else
  1308. HAL_PCD_SetupStageCallback(hpcd);
  1309. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1310. }
  1311. else if ((wEPVal & USB_EP_CTR_RX) != 0U)
  1312. {
  1313. PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1314. /* Get Control Data OUT Packet */
  1315. ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1316. if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U))
  1317. {
  1318. USB_ReadPMA(hpcd->Instance, ep->xfer_buff,
  1319. ep->pmaadress, (uint16_t)ep->xfer_count);
  1320. ep->xfer_buff += ep->xfer_count;
  1321. /* Process Control Data OUT Packet */
  1322. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1323. hpcd->DataOutStageCallback(hpcd, 0U);
  1324. #else
  1325. HAL_PCD_DataOutStageCallback(hpcd, 0U);
  1326. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1327. }
  1328. PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
  1329. PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
  1330. }
  1331. }
  1332. }
  1333. else
  1334. {
  1335. /* Decode and service non control endpoints interrupt */
  1336. /* process related endpoint register */
  1337. wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
  1338. if ((wEPVal & USB_EP_CTR_RX) != 0U)
  1339. {
  1340. /* clear int flag */
  1341. PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
  1342. ep = &hpcd->OUT_ep[epindex];
  1343. /* OUT Single Buffering */
  1344. if (ep->doublebuffer == 0U)
  1345. {
  1346. count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1347. if (count != 0U)
  1348. {
  1349. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
  1350. }
  1351. }
  1352. else
  1353. {
  1354. /* manage double buffer bulk out */
  1355. if (ep->type == EP_TYPE_BULK)
  1356. {
  1357. count = HAL_PCD_EP_DB_Receive(hpcd, ep, wEPVal);
  1358. }
  1359. else /* manage double buffer iso out */
  1360. {
  1361. /* free EP OUT Buffer */
  1362. PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U);
  1363. if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U)
  1364. {
  1365. /* read from endpoint BUF0Addr buffer */
  1366. count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  1367. if (count != 0U)
  1368. {
  1369. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
  1370. }
  1371. }
  1372. else
  1373. {
  1374. /* read from endpoint BUF1Addr buffer */
  1375. count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  1376. if (count != 0U)
  1377. {
  1378. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
  1379. }
  1380. }
  1381. }
  1382. }
  1383. /* multi-packet on the NON control OUT endpoint */
  1384. ep->xfer_count += count;
  1385. ep->xfer_buff += count;
  1386. if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
  1387. {
  1388. /* RX COMPLETE */
  1389. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1390. hpcd->DataOutStageCallback(hpcd, ep->num);
  1391. #else
  1392. HAL_PCD_DataOutStageCallback(hpcd, ep->num);
  1393. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1394. }
  1395. else
  1396. {
  1397. (void) USB_EPStartXfer(hpcd->Instance, ep);
  1398. }
  1399. }
  1400. if ((wEPVal & USB_EP_CTR_TX) != 0U)
  1401. {
  1402. ep = &hpcd->IN_ep[epindex];
  1403. /* clear int flag */
  1404. PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
  1405. /* Manage all non bulk transaction or Bulk Single Buffer Transaction */
  1406. if ((ep->type != EP_TYPE_BULK) ||
  1407. ((ep->type == EP_TYPE_BULK) && ((wEPVal & USB_EP_KIND) == 0U)))
  1408. {
  1409. /* multi-packet on the NON control IN endpoint */
  1410. TxByteNbre = (uint16_t)PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  1411. if (ep->xfer_len > TxByteNbre)
  1412. {
  1413. ep->xfer_len -= TxByteNbre;
  1414. }
  1415. else
  1416. {
  1417. ep->xfer_len = 0U;
  1418. }
  1419. /* Zero Length Packet? */
  1420. if (ep->xfer_len == 0U)
  1421. {
  1422. /* TX COMPLETE */
  1423. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1424. hpcd->DataInStageCallback(hpcd, ep->num);
  1425. #else
  1426. HAL_PCD_DataInStageCallback(hpcd, ep->num);
  1427. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1428. }
  1429. else
  1430. {
  1431. /* Transfer is not yet Done */
  1432. ep->xfer_buff += TxByteNbre;
  1433. ep->xfer_count += TxByteNbre;
  1434. (void)USB_EPStartXfer(hpcd->Instance, ep);
  1435. }
  1436. }
  1437. /* bulk in double buffer enable in case of transferLen> Ep_Mps */
  1438. else
  1439. {
  1440. (void)HAL_PCD_EP_DB_Transmit(hpcd, ep, wEPVal);
  1441. }
  1442. }
  1443. }
  1444. }
  1445. return HAL_OK;
  1446. }
  1447. /**
  1448. * @brief Manage double buffer bulk out transaction from ISR
  1449. * @param hpcd PCD handle
  1450. * @param ep current endpoint handle
  1451. * @param wEPVal Last snapshot of EPRx register value taken in ISR
  1452. * @retval HAL status
  1453. */
  1454. static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd,
  1455. PCD_EPTypeDef *ep, uint16_t wEPVal)
  1456. {
  1457. uint16_t count;
  1458. /* Manage Buffer0 OUT */
  1459. if ((wEPVal & USB_EP_DTOG_RX) != 0U)
  1460. {
  1461. /* Get count of received Data on buffer0 */
  1462. count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  1463. if (ep->xfer_len >= count)
  1464. {
  1465. ep->xfer_len -= count;
  1466. }
  1467. else
  1468. {
  1469. ep->xfer_len = 0U;
  1470. }
  1471. if (ep->xfer_len == 0U)
  1472. {
  1473. /* set NAK to OUT endpoint since double buffer is enabled */
  1474. PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK);
  1475. }
  1476. /* Check if Buffer1 is in blocked sate which requires to toggle */
  1477. if ((wEPVal & USB_EP_DTOG_TX) != 0U)
  1478. {
  1479. PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U);
  1480. }
  1481. if (count != 0U)
  1482. {
  1483. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
  1484. }
  1485. }
  1486. /* Manage Buffer 1 DTOG_RX=0 */
  1487. else
  1488. {
  1489. /* Get count of received data */
  1490. count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  1491. if (ep->xfer_len >= count)
  1492. {
  1493. ep->xfer_len -= count;
  1494. }
  1495. else
  1496. {
  1497. ep->xfer_len = 0U;
  1498. }
  1499. if (ep->xfer_len == 0U)
  1500. {
  1501. /* set NAK on the current endpoint */
  1502. PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK);
  1503. }
  1504. /*Need to FreeUser Buffer*/
  1505. if ((wEPVal & USB_EP_DTOG_TX) == 0U)
  1506. {
  1507. PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U);
  1508. }
  1509. if (count != 0U)
  1510. {
  1511. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
  1512. }
  1513. }
  1514. return count;
  1515. }
  1516. /**
  1517. * @brief Manage double buffer bulk IN transaction from ISR
  1518. * @param hpcd PCD handle
  1519. * @param ep current endpoint handle
  1520. * @param wEPVal Last snapshot of EPRx register value taken in ISR
  1521. * @retval HAL status
  1522. */
  1523. static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd,
  1524. PCD_EPTypeDef *ep, uint16_t wEPVal)
  1525. {
  1526. uint32_t len;
  1527. uint16_t TxByteNbre;
  1528. /* Data Buffer0 ACK received */
  1529. if ((wEPVal & USB_EP_DTOG_TX) != 0U)
  1530. {
  1531. /* multi-packet on the NON control IN endpoint */
  1532. TxByteNbre = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  1533. if (ep->xfer_len > TxByteNbre)
  1534. {
  1535. ep->xfer_len -= TxByteNbre;
  1536. }
  1537. else
  1538. {
  1539. ep->xfer_len = 0U;
  1540. }
  1541. /* Transfer is completed */
  1542. if (ep->xfer_len == 0U)
  1543. {
  1544. /* TX COMPLETE */
  1545. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1546. hpcd->DataInStageCallback(hpcd, ep->num);
  1547. #else
  1548. HAL_PCD_DataInStageCallback(hpcd, ep->num);
  1549. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1550. if ((wEPVal & USB_EP_DTOG_RX) != 0U)
  1551. {
  1552. PCD_FreeUserBuffer(hpcd->Instance, ep->num, 1U);
  1553. }
  1554. }
  1555. else /* Transfer is not yet Done */
  1556. {
  1557. /* need to Free USB Buff */
  1558. if ((wEPVal & USB_EP_DTOG_RX) != 0U)
  1559. {
  1560. PCD_FreeUserBuffer(hpcd->Instance, ep->num, 1U);
  1561. }
  1562. /* Still there is data to Fill in the next Buffer */
  1563. if (ep->xfer_fill_db == 1U)
  1564. {
  1565. ep->xfer_buff += TxByteNbre;
  1566. ep->xfer_count += TxByteNbre;
  1567. /* Calculate the len of the new buffer to fill */
  1568. if (ep->xfer_len_db >= ep->maxpacket)
  1569. {
  1570. len = ep->maxpacket;
  1571. ep->xfer_len_db -= len;
  1572. }
  1573. else if (ep->xfer_len_db == 0U)
  1574. {
  1575. len = TxByteNbre;
  1576. ep->xfer_fill_db = 0U;
  1577. }
  1578. else
  1579. {
  1580. ep->xfer_fill_db = 0U;
  1581. len = ep->xfer_len_db;
  1582. ep->xfer_len_db = 0U;
  1583. }
  1584. /* Write remaining Data to Buffer */
  1585. /* Set the Double buffer counter for pma buffer1 */
  1586. PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, len);
  1587. /* Copy user buffer to USB PMA */
  1588. USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, (uint16_t)len);
  1589. }
  1590. }
  1591. }
  1592. else /* Data Buffer1 ACK received */
  1593. {
  1594. /* multi-packet on the NON control IN endpoint */
  1595. TxByteNbre = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  1596. if (ep->xfer_len >= TxByteNbre)
  1597. {
  1598. ep->xfer_len -= TxByteNbre;
  1599. }
  1600. else
  1601. {
  1602. ep->xfer_len = 0U;
  1603. }
  1604. /* Transfer is completed */
  1605. if (ep->xfer_len == 0U)
  1606. {
  1607. /* TX COMPLETE */
  1608. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1609. hpcd->DataInStageCallback(hpcd, ep->num);
  1610. #else
  1611. HAL_PCD_DataInStageCallback(hpcd, ep->num);
  1612. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1613. /*need to Free USB Buff*/
  1614. if ((wEPVal & USB_EP_DTOG_RX) == 0U)
  1615. {
  1616. PCD_FreeUserBuffer(hpcd->Instance, ep->num, 1U);
  1617. }
  1618. }
  1619. else /* Transfer is not yet Done */
  1620. {
  1621. /* need to Free USB Buff */
  1622. if ((wEPVal & USB_EP_DTOG_RX) == 0U)
  1623. {
  1624. PCD_FreeUserBuffer(hpcd->Instance, ep->num, 1U);
  1625. }
  1626. /* Still there is data to Fill in the next Buffer */
  1627. if (ep->xfer_fill_db == 1U)
  1628. {
  1629. ep->xfer_buff += TxByteNbre;
  1630. ep->xfer_count += TxByteNbre;
  1631. /* Calculate the len of the new buffer to fill */
  1632. if (ep->xfer_len_db >= ep->maxpacket)
  1633. {
  1634. len = ep->maxpacket;
  1635. ep->xfer_len_db -= len;
  1636. }
  1637. else if (ep->xfer_len_db == 0U)
  1638. {
  1639. len = TxByteNbre;
  1640. ep->xfer_fill_db = 0U;
  1641. }
  1642. else
  1643. {
  1644. len = ep->xfer_len_db;
  1645. ep->xfer_len_db = 0U;
  1646. ep->xfer_fill_db = 0;
  1647. }
  1648. /* Set the Double buffer counter for pmabuffer1 */
  1649. PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, len);
  1650. /* Copy the user buffer to USB PMA */
  1651. USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, (uint16_t)len);
  1652. }
  1653. }
  1654. }
  1655. /*enable endpoint IN*/
  1656. PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_VALID);
  1657. return HAL_OK;
  1658. }
  1659. /**
  1660. * @}
  1661. */
  1662. #endif /* defined (USB) */
  1663. #endif /* HAL_PCD_MODULE_ENABLED */
  1664. /**
  1665. * @}
  1666. */
  1667. /**
  1668. * @}
  1669. */
  1670. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/