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.
 
 
 

2202 lines
57 KiB

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