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.
 
 
 

1230 lines
34 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32f7xx_hal_hcd.c
  4. * @author MCD Application Team
  5. * @version V1.2.2
  6. * @date 14-April-2017
  7. * @brief HCD HAL module driver.
  8. * This file provides firmware functions to manage the following
  9. * functionalities of the USB Peripheral Controller:
  10. * + Initialization and de-initialization functions
  11. * + IO operation functions
  12. * + Peripheral Control functions
  13. * + Peripheral State functions
  14. *
  15. @verbatim
  16. ==============================================================================
  17. ##### How to use this driver #####
  18. ==============================================================================
  19. [..]
  20. (#)Declare a HCD_HandleTypeDef handle structure, for example:
  21. HCD_HandleTypeDef hhcd;
  22. (#)Fill parameters of Init structure in HCD handle
  23. (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...)
  24. (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API:
  25. (##) Enable the HCD/USB Low Level interface clock using the following macros
  26. (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
  27. (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode)
  28. (+++) __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); (For High Speed Mode)
  29. (##) Initialize the related GPIO clocks
  30. (##) Configure HCD pin-out
  31. (##) Configure HCD NVIC interrupt
  32. (#)Associate the Upper USB Host stack to the HAL HCD Driver:
  33. (##) hhcd.pData = phost;
  34. (#)Enable HCD transmission and reception:
  35. (##) HAL_HCD_Start();
  36. @endverbatim
  37. ******************************************************************************
  38. * @attention
  39. *
  40. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  41. *
  42. * Redistribution and use in source and binary forms, with or without modification,
  43. * are permitted provided that the following conditions are met:
  44. * 1. Redistributions of source code must retain the above copyright notice,
  45. * this list of conditions and the following disclaimer.
  46. * 2. Redistributions in binary form must reproduce the above copyright notice,
  47. * this list of conditions and the following disclaimer in the documentation
  48. * and/or other materials provided with the distribution.
  49. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  50. * may be used to endorse or promote products derived from this software
  51. * without specific prior written permission.
  52. *
  53. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  54. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  55. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  56. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  57. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  58. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  59. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  60. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  61. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  62. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  63. *
  64. ******************************************************************************
  65. */
  66. /* Includes ------------------------------------------------------------------*/
  67. #include "stm32f7xx_hal.h"
  68. /** @addtogroup STM32F7xx_HAL_Driver
  69. * @{
  70. */
  71. /** @defgroup HCD HCD
  72. * @brief HCD HAL module driver
  73. * @{
  74. */
  75. #ifdef HAL_HCD_MODULE_ENABLED
  76. /* Private typedef -----------------------------------------------------------*/
  77. /* Private define ------------------------------------------------------------*/
  78. /* Private macro -------------------------------------------------------------*/
  79. /* Private variables ---------------------------------------------------------*/
  80. /* Private function ----------------------------------------------------------*/
  81. /** @defgroup HCD_Private_Functions HCD Private Functions
  82. * @{
  83. */
  84. static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
  85. static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
  86. static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd);
  87. static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
  88. /**
  89. * @}
  90. */
  91. /* Exported functions --------------------------------------------------------*/
  92. /** @defgroup HCD_Exported_Functions HCD Exported Functions
  93. * @{
  94. */
  95. /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
  96. * @brief Initialization and Configuration functions
  97. *
  98. @verbatim
  99. ===============================================================================
  100. ##### Initialization and de-initialization functions #####
  101. ===============================================================================
  102. [..] This section provides functions allowing to:
  103. @endverbatim
  104. * @{
  105. */
  106. /**
  107. * @brief Initialize the host driver.
  108. * @param hhcd: HCD handle
  109. * @retval HAL status
  110. */
  111. HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
  112. {
  113. /* Check the HCD handle allocation */
  114. if(hhcd == NULL)
  115. {
  116. return HAL_ERROR;
  117. }
  118. /* Check the parameters */
  119. assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
  120. hhcd->State = HAL_HCD_STATE_BUSY;
  121. /* Init the low level hardware : GPIO, CLOCK, NVIC... */
  122. HAL_HCD_MspInit(hhcd);
  123. /* Disable the Interrupts */
  124. __HAL_HCD_DISABLE(hhcd);
  125. /*Init the Core (common init.) */
  126. USB_CoreInit(hhcd->Instance, hhcd->Init);
  127. /* Force Host Mode*/
  128. USB_SetCurrentMode(hhcd->Instance , USB_OTG_HOST_MODE);
  129. /* Init Host */
  130. USB_HostInit(hhcd->Instance, hhcd->Init);
  131. hhcd->State= HAL_HCD_STATE_READY;
  132. return HAL_OK;
  133. }
  134. /**
  135. * @brief Initialize a host channel.
  136. * @param hhcd: HCD handle
  137. * @param ch_num: Channel number.
  138. * This parameter can be a value from 1 to 15
  139. * @param epnum: Endpoint number.
  140. * This parameter can be a value from 1 to 15
  141. * @param dev_address : Current device address
  142. * This parameter can be a value from 0 to 255
  143. * @param speed: Current device speed.
  144. * This parameter can be one of these values:
  145. * HCD_SPEED_HIGH: High speed mode,
  146. * HCD_SPEED_FULL: Full speed mode,
  147. * HCD_SPEED_LOW: Low speed mode
  148. * @param ep_type: Endpoint Type.
  149. * This parameter can be one of these values:
  150. * EP_TYPE_CTRL: Control type,
  151. * EP_TYPE_ISOC: Isochronous type,
  152. * EP_TYPE_BULK: Bulk type,
  153. * EP_TYPE_INTR: Interrupt type
  154. * @param mps: Max Packet Size.
  155. * This parameter can be a value from 0 to32K
  156. * @retval HAL status
  157. */
  158. HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd,
  159. uint8_t ch_num,
  160. uint8_t epnum,
  161. uint8_t dev_address,
  162. uint8_t speed,
  163. uint8_t ep_type,
  164. uint16_t mps)
  165. {
  166. HAL_StatusTypeDef status = HAL_OK;
  167. __HAL_LOCK(hhcd);
  168. hhcd->hc[ch_num].dev_addr = dev_address;
  169. hhcd->hc[ch_num].max_packet = mps;
  170. hhcd->hc[ch_num].ch_num = ch_num;
  171. hhcd->hc[ch_num].ep_type = ep_type;
  172. hhcd->hc[ch_num].ep_num = epnum & 0x7F;
  173. hhcd->hc[ch_num].ep_is_in = ((epnum & 0x80) == 0x80);
  174. hhcd->hc[ch_num].speed = speed;
  175. status = USB_HC_Init(hhcd->Instance,
  176. ch_num,
  177. epnum,
  178. dev_address,
  179. speed,
  180. ep_type,
  181. mps);
  182. __HAL_UNLOCK(hhcd);
  183. return status;
  184. }
  185. /**
  186. * @brief Halt a host channel.
  187. * @param hhcd: HCD handle
  188. * @param ch_num: Channel number.
  189. * This parameter can be a value from 1 to 15
  190. * @retval HAL status
  191. */
  192. HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
  193. {
  194. HAL_StatusTypeDef status = HAL_OK;
  195. __HAL_LOCK(hhcd);
  196. USB_HC_Halt(hhcd->Instance, ch_num);
  197. __HAL_UNLOCK(hhcd);
  198. return status;
  199. }
  200. /**
  201. * @brief DeInitialize the host driver.
  202. * @param hhcd: HCD handle
  203. * @retval HAL status
  204. */
  205. HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
  206. {
  207. /* Check the HCD handle allocation */
  208. if(hhcd == NULL)
  209. {
  210. return HAL_ERROR;
  211. }
  212. hhcd->State = HAL_HCD_STATE_BUSY;
  213. /* DeInit the low level hardware */
  214. HAL_HCD_MspDeInit(hhcd);
  215. __HAL_HCD_DISABLE(hhcd);
  216. hhcd->State = HAL_HCD_STATE_RESET;
  217. return HAL_OK;
  218. }
  219. /**
  220. * @brief Initialize the HCD MSP.
  221. * @param hhcd: HCD handle
  222. * @retval None
  223. */
  224. __weak void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
  225. {
  226. /* Prevent unused argument(s) compilation warning */
  227. UNUSED(hhcd);
  228. /* NOTE : This function Should not be modified, when the callback is needed,
  229. the HAL_HCD_MspInit could be implemented in the user file
  230. */
  231. }
  232. /**
  233. * @brief DeInitialize the HCD MSP.
  234. * @param hhcd: HCD handle
  235. * @retval None
  236. */
  237. __weak void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
  238. {
  239. /* Prevent unused argument(s) compilation warning */
  240. UNUSED(hhcd);
  241. /* NOTE : This function Should not be modified, when the callback is needed,
  242. the HAL_HCD_MspDeInit could be implemented in the user file
  243. */
  244. }
  245. /**
  246. * @}
  247. */
  248. /** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions
  249. * @brief HCD IO operation functions
  250. *
  251. @verbatim
  252. ===============================================================================
  253. ##### IO operation functions #####
  254. ===============================================================================
  255. [..] This subsection provides a set of functions allowing to manage the USB Host Data
  256. Transfer
  257. @endverbatim
  258. * @{
  259. */
  260. /**
  261. * @brief Submit a new URB for processing.
  262. * @param hhcd: HCD handle
  263. * @param ch_num: Channel number.
  264. * This parameter can be a value from 1 to 15
  265. * @param direction: Channel number.
  266. * This parameter can be one of these values:
  267. * 0 : Output / 1 : Input
  268. * @param ep_type: Endpoint Type.
  269. * This parameter can be one of these values:
  270. * EP_TYPE_CTRL: Control type/
  271. * EP_TYPE_ISOC: Isochronous type/
  272. * EP_TYPE_BULK: Bulk type/
  273. * EP_TYPE_INTR: Interrupt type/
  274. * @param token: Endpoint Type.
  275. * This parameter can be one of these values:
  276. * 0: HC_PID_SETUP / 1: HC_PID_DATA1
  277. * @param pbuff: pointer to URB data
  278. * @param length: Length of URB data
  279. * @param do_ping: activate do ping protocol (for high speed only).
  280. * This parameter can be one of these values:
  281. * 0 : do ping inactive / 1 : do ping active
  282. * @retval HAL status
  283. */
  284. HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
  285. uint8_t ch_num,
  286. uint8_t direction ,
  287. uint8_t ep_type,
  288. uint8_t token,
  289. uint8_t* pbuff,
  290. uint16_t length,
  291. uint8_t do_ping)
  292. {
  293. hhcd->hc[ch_num].ep_is_in = direction;
  294. hhcd->hc[ch_num].ep_type = ep_type;
  295. if(token == 0)
  296. {
  297. hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
  298. }
  299. else
  300. {
  301. hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  302. }
  303. /* Manage Data Toggle */
  304. switch(ep_type)
  305. {
  306. case EP_TYPE_CTRL:
  307. if((token == 1) && (direction == 0)) /*send data */
  308. {
  309. if ( length == 0 )
  310. { /* For Status OUT stage, Length==0, Status Out PID = 1 */
  311. hhcd->hc[ch_num].toggle_out = 1;
  312. }
  313. /* Set the Data Toggle bit as per the Flag */
  314. if ( hhcd->hc[ch_num].toggle_out == 0)
  315. { /* Put the PID 0 */
  316. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  317. }
  318. else
  319. { /* Put the PID 1 */
  320. hhcd->hc[ch_num].data_pid = HC_PID_DATA1 ;
  321. }
  322. if(hhcd->hc[ch_num].urb_state != URB_NOTREADY)
  323. {
  324. hhcd->hc[ch_num].do_ping = do_ping;
  325. }
  326. }
  327. break;
  328. case EP_TYPE_BULK:
  329. if(direction == 0)
  330. {
  331. /* Set the Data Toggle bit as per the Flag */
  332. if ( hhcd->hc[ch_num].toggle_out == 0)
  333. { /* Put the PID 0 */
  334. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  335. }
  336. else
  337. { /* Put the PID 1 */
  338. hhcd->hc[ch_num].data_pid = HC_PID_DATA1 ;
  339. }
  340. if(hhcd->hc[ch_num].urb_state != URB_NOTREADY)
  341. {
  342. hhcd->hc[ch_num].do_ping = do_ping;
  343. }
  344. }
  345. else
  346. {
  347. if( hhcd->hc[ch_num].toggle_in == 0)
  348. {
  349. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  350. }
  351. else
  352. {
  353. hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  354. }
  355. }
  356. break;
  357. case EP_TYPE_INTR:
  358. if(direction == 0)
  359. {
  360. /* Set the Data Toggle bit as per the Flag */
  361. if ( hhcd->hc[ch_num].toggle_out == 0)
  362. { /* Put the PID 0 */
  363. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  364. }
  365. else
  366. { /* Put the PID 1 */
  367. hhcd->hc[ch_num].data_pid = HC_PID_DATA1 ;
  368. }
  369. }
  370. else
  371. {
  372. if( hhcd->hc[ch_num].toggle_in == 0)
  373. {
  374. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  375. }
  376. else
  377. {
  378. hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  379. }
  380. }
  381. break;
  382. case EP_TYPE_ISOC:
  383. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  384. break;
  385. }
  386. hhcd->hc[ch_num].xfer_buff = pbuff;
  387. hhcd->hc[ch_num].xfer_len = length;
  388. hhcd->hc[ch_num].urb_state = URB_IDLE;
  389. hhcd->hc[ch_num].xfer_count = 0 ;
  390. hhcd->hc[ch_num].ch_num = ch_num;
  391. hhcd->hc[ch_num].state = HC_IDLE;
  392. return USB_HC_StartXfer(hhcd->Instance, &(hhcd->hc[ch_num]), hhcd->Init.dma_enable);
  393. }
  394. /**
  395. * @brief Handle HCD interrupt request.
  396. * @param hhcd: HCD handle
  397. * @retval None
  398. */
  399. void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
  400. {
  401. USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  402. uint32_t i = 0 , interrupt = 0;
  403. /* ensure that we are in device mode */
  404. if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
  405. {
  406. /* avoid spurious interrupt */
  407. if(__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
  408. {
  409. return;
  410. }
  411. if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
  412. {
  413. /* incorrect mode, acknowledge the interrupt */
  414. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
  415. }
  416. if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
  417. {
  418. /* incorrect mode, acknowledge the interrupt */
  419. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
  420. }
  421. if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
  422. {
  423. /* incorrect mode, acknowledge the interrupt */
  424. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
  425. }
  426. if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
  427. {
  428. /* incorrect mode, acknowledge the interrupt */
  429. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
  430. }
  431. /* Handle Host Disconnect Interrupts */
  432. if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
  433. {
  434. /* Cleanup HPRT */
  435. USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
  436. USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
  437. /* Handle Host Port Interrupts */
  438. HAL_HCD_Disconnect_Callback(hhcd);
  439. USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ );
  440. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
  441. }
  442. /* Handle Host Port Interrupts */
  443. if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
  444. {
  445. HCD_Port_IRQHandler (hhcd);
  446. }
  447. /* Handle Host SOF Interrupts */
  448. if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
  449. {
  450. HAL_HCD_SOF_Callback(hhcd);
  451. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
  452. }
  453. /* Handle Host channel Interrupts */
  454. if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
  455. {
  456. interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
  457. for (i = 0; i < hhcd->Init.Host_channels ; i++)
  458. {
  459. if (interrupt & (1 << i))
  460. {
  461. if ((USBx_HC(i)->HCCHAR) & USB_OTG_HCCHAR_EPDIR)
  462. {
  463. HCD_HC_IN_IRQHandler (hhcd, i);
  464. }
  465. else
  466. {
  467. HCD_HC_OUT_IRQHandler (hhcd, i);
  468. }
  469. }
  470. }
  471. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
  472. }
  473. /* Handle Rx Queue Level Interrupts */
  474. if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL))
  475. {
  476. USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  477. HCD_RXQLVL_IRQHandler (hhcd);
  478. USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  479. }
  480. }
  481. }
  482. /**
  483. * @brief SOF callback.
  484. * @param hhcd: HCD handle
  485. * @retval None
  486. */
  487. __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
  488. {
  489. /* Prevent unused argument(s) compilation warning */
  490. UNUSED(hhcd);
  491. /* NOTE : This function Should not be modified, when the callback is needed,
  492. the HAL_HCD_SOF_Callback could be implemented in the user file
  493. */
  494. }
  495. /**
  496. * @brief Connection Event callback.
  497. * @param hhcd: HCD handle
  498. * @retval None
  499. */
  500. __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
  501. {
  502. /* Prevent unused argument(s) compilation warning */
  503. UNUSED(hhcd);
  504. /* NOTE : This function Should not be modified, when the callback is needed,
  505. the HAL_HCD_Connect_Callback could be implemented in the user file
  506. */
  507. }
  508. /**
  509. * @brief Disconnection Event callback.
  510. * @param hhcd: HCD handle
  511. * @retval None
  512. */
  513. __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
  514. {
  515. /* Prevent unused argument(s) compilation warning */
  516. UNUSED(hhcd);
  517. /* NOTE : This function Should not be modified, when the callback is needed,
  518. the HAL_HCD_Disconnect_Callback could be implemented in the user file
  519. */
  520. }
  521. /**
  522. * @brief Notify URB state change callback.
  523. * @param hhcd: HCD handle
  524. * @param chnum: Channel number.
  525. * This parameter can be a value from 1 to 15
  526. * @param urb_state:
  527. * This parameter can be one of these values:
  528. * URB_IDLE/
  529. * URB_DONE/
  530. * URB_NOTREADY/
  531. * URB_NYET/
  532. * URB_ERROR/
  533. * URB_STALL/
  534. * @retval None
  535. */
  536. __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
  537. {
  538. /* Prevent unused argument(s) compilation warning */
  539. UNUSED(hhcd);
  540. /* NOTE : This function Should not be modified, when the callback is needed,
  541. the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
  542. */
  543. }
  544. /**
  545. * @}
  546. */
  547. /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
  548. * @brief Management functions
  549. *
  550. @verbatim
  551. ===============================================================================
  552. ##### Peripheral Control functions #####
  553. ===============================================================================
  554. [..]
  555. This subsection provides a set of functions allowing to control the HCD data
  556. transfers.
  557. @endverbatim
  558. * @{
  559. */
  560. /**
  561. * @brief Start the host driver.
  562. * @param hhcd: HCD handle
  563. * @retval HAL status
  564. */
  565. HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
  566. {
  567. __HAL_LOCK(hhcd);
  568. __HAL_HCD_ENABLE(hhcd);
  569. USB_DriveVbus(hhcd->Instance, 1);
  570. __HAL_UNLOCK(hhcd);
  571. return HAL_OK;
  572. }
  573. /**
  574. * @brief Stop the host driver.
  575. * @param hhcd: HCD handle
  576. * @retval HAL status
  577. */
  578. HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
  579. {
  580. __HAL_LOCK(hhcd);
  581. USB_StopHost(hhcd->Instance);
  582. __HAL_UNLOCK(hhcd);
  583. return HAL_OK;
  584. }
  585. /**
  586. * @brief Reset the host port.
  587. * @param hhcd: HCD handle
  588. * @retval HAL status
  589. */
  590. HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
  591. {
  592. return (USB_ResetPort(hhcd->Instance));
  593. }
  594. /**
  595. * @}
  596. */
  597. /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
  598. * @brief Peripheral State functions
  599. *
  600. @verbatim
  601. ===============================================================================
  602. ##### Peripheral State functions #####
  603. ===============================================================================
  604. [..]
  605. This subsection permits to get in run-time the status of the peripheral
  606. and the data flow.
  607. @endverbatim
  608. * @{
  609. */
  610. /**
  611. * @brief Return the HCD handle state.
  612. * @param hhcd: HCD handle
  613. * @retval HAL state
  614. */
  615. HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd)
  616. {
  617. return hhcd->State;
  618. }
  619. /**
  620. * @brief Return URB state for a channel.
  621. * @param hhcd: HCD handle
  622. * @param chnum: Channel number.
  623. * This parameter can be a value from 1 to 15
  624. * @retval URB state.
  625. * This parameter can be one of these values:
  626. * URB_IDLE/
  627. * URB_DONE/
  628. * URB_NOTREADY/
  629. * URB_NYET/
  630. * URB_ERROR/
  631. * URB_STALL
  632. */
  633. HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  634. {
  635. return hhcd->hc[chnum].urb_state;
  636. }
  637. /**
  638. * @brief Return the last host transfer size.
  639. * @param hhcd: HCD handle
  640. * @param chnum: Channel number.
  641. * This parameter can be a value from 1 to 15
  642. * @retval last transfer size in byte
  643. */
  644. uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  645. {
  646. return hhcd->hc[chnum].xfer_count;
  647. }
  648. /**
  649. * @brief Return the Host Channel state.
  650. * @param hhcd: HCD handle
  651. * @param chnum: Channel number.
  652. * This parameter can be a value from 1 to 15
  653. * @retval Host channel state
  654. * This parameter can be one of these values:
  655. * HC_IDLE/
  656. * HC_XFRC/
  657. * HC_HALTED/
  658. * HC_NYET/
  659. * HC_NAK/
  660. * HC_STALL/
  661. * HC_XACTERR/
  662. * HC_BBLERR/
  663. * HC_DATATGLERR
  664. */
  665. HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  666. {
  667. return hhcd->hc[chnum].state;
  668. }
  669. /**
  670. * @brief Return the current Host frame number.
  671. * @param hhcd: HCD handle
  672. * @retval Current Host frame number
  673. */
  674. uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
  675. {
  676. return (USB_GetCurrentFrame(hhcd->Instance));
  677. }
  678. /**
  679. * @brief Return the Host enumeration speed.
  680. * @param hhcd: HCD handle
  681. * @retval Enumeration speed
  682. */
  683. uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
  684. {
  685. return (USB_GetHostSpeed(hhcd->Instance));
  686. }
  687. /**
  688. * @}
  689. */
  690. /**
  691. * @}
  692. */
  693. /** @addtogroup HCD_Private_Functions
  694. * @{
  695. */
  696. /**
  697. * @brief Handle Host Channel IN interrupt requests.
  698. * @param hhcd: HCD handle
  699. * @param chnum: Channel number.
  700. * This parameter can be a value from 1 to 15
  701. * @retval none
  702. */
  703. static void HCD_HC_IN_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
  704. {
  705. USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  706. uint32_t tmpreg = 0;
  707. if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR)
  708. {
  709. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
  710. __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  711. }
  712. else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK)
  713. {
  714. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
  715. }
  716. else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL)
  717. {
  718. __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  719. hhcd->hc[chnum].state = HC_STALL;
  720. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  721. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
  722. USB_HC_Halt(hhcd->Instance, chnum);
  723. }
  724. else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR)
  725. {
  726. __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  727. USB_HC_Halt(hhcd->Instance, chnum);
  728. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  729. hhcd->hc[chnum].state = HC_DATATGLERR;
  730. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
  731. }
  732. if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR)
  733. {
  734. __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  735. USB_HC_Halt(hhcd->Instance, chnum);
  736. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
  737. }
  738. else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC)
  739. {
  740. if (hhcd->Init.dma_enable)
  741. {
  742. hhcd->hc[chnum].xfer_count = hhcd->hc[chnum].xfer_len - \
  743. (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ);
  744. }
  745. hhcd->hc[chnum].state = HC_XFRC;
  746. hhcd->hc[chnum].ErrCnt = 0;
  747. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
  748. if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
  749. (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
  750. {
  751. __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  752. USB_HC_Halt(hhcd->Instance, chnum);
  753. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  754. }
  755. else if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
  756. {
  757. USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
  758. hhcd->hc[chnum].urb_state = URB_DONE;
  759. HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  760. }
  761. hhcd->hc[chnum].toggle_in ^= 1;
  762. }
  763. else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH)
  764. {
  765. __HAL_HCD_MASK_HALT_HC_INT(chnum);
  766. if(hhcd->hc[chnum].state == HC_XFRC)
  767. {
  768. hhcd->hc[chnum].urb_state = URB_DONE;
  769. }
  770. else if (hhcd->hc[chnum].state == HC_STALL)
  771. {
  772. hhcd->hc[chnum].urb_state = URB_STALL;
  773. }
  774. else if((hhcd->hc[chnum].state == HC_XACTERR) ||
  775. (hhcd->hc[chnum].state == HC_DATATGLERR))
  776. {
  777. if(hhcd->hc[chnum].ErrCnt++ > 3)
  778. {
  779. hhcd->hc[chnum].ErrCnt = 0;
  780. hhcd->hc[chnum].urb_state = URB_ERROR;
  781. }
  782. else
  783. {
  784. hhcd->hc[chnum].urb_state = URB_NOTREADY;
  785. }
  786. /* re-activate the channel */
  787. tmpreg = USBx_HC(chnum)->HCCHAR;
  788. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  789. tmpreg |= USB_OTG_HCCHAR_CHENA;
  790. USBx_HC(chnum)->HCCHAR = tmpreg;
  791. }
  792. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
  793. HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  794. }
  795. else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR)
  796. {
  797. __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  798. hhcd->hc[chnum].ErrCnt++;
  799. hhcd->hc[chnum].state = HC_XACTERR;
  800. USB_HC_Halt(hhcd->Instance, chnum);
  801. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
  802. }
  803. else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK)
  804. {
  805. if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
  806. {
  807. __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  808. USB_HC_Halt(hhcd->Instance, chnum);
  809. }
  810. else if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
  811. (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
  812. {
  813. /* re-activate the channel */
  814. tmpreg = USBx_HC(chnum)->HCCHAR;
  815. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  816. tmpreg |= USB_OTG_HCCHAR_CHENA;
  817. USBx_HC(chnum)->HCCHAR = tmpreg;
  818. }
  819. hhcd->hc[chnum].state = HC_NAK;
  820. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  821. }
  822. }
  823. /**
  824. * @brief Handle Host Channel OUT interrupt requests.
  825. * @param hhcd: HCD handle
  826. * @param chnum: Channel number.
  827. * This parameter can be a value from 1 to 15
  828. * @retval none
  829. */
  830. static void HCD_HC_OUT_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
  831. {
  832. USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  833. uint32_t tmpreg = 0;
  834. if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR)
  835. {
  836. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
  837. __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  838. }
  839. else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK)
  840. {
  841. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
  842. if( hhcd->hc[chnum].do_ping == 1)
  843. {
  844. hhcd->hc[chnum].state = HC_NYET;
  845. __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  846. USB_HC_Halt(hhcd->Instance, chnum);
  847. hhcd->hc[chnum].urb_state = URB_NOTREADY;
  848. }
  849. }
  850. else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NYET)
  851. {
  852. hhcd->hc[chnum].state = HC_NYET;
  853. hhcd->hc[chnum].ErrCnt= 0;
  854. __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  855. USB_HC_Halt(hhcd->Instance, chnum);
  856. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
  857. }
  858. else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR)
  859. {
  860. __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  861. USB_HC_Halt(hhcd->Instance, chnum);
  862. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
  863. }
  864. else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC)
  865. {
  866. hhcd->hc[chnum].ErrCnt = 0;
  867. __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  868. USB_HC_Halt(hhcd->Instance, chnum);
  869. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
  870. hhcd->hc[chnum].state = HC_XFRC;
  871. }
  872. else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL)
  873. {
  874. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
  875. __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  876. USB_HC_Halt(hhcd->Instance, chnum);
  877. hhcd->hc[chnum].state = HC_STALL;
  878. }
  879. else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK)
  880. {
  881. hhcd->hc[chnum].ErrCnt = 0;
  882. __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  883. USB_HC_Halt(hhcd->Instance, chnum);
  884. hhcd->hc[chnum].state = HC_NAK;
  885. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  886. }
  887. else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR)
  888. {
  889. __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  890. USB_HC_Halt(hhcd->Instance, chnum);
  891. hhcd->hc[chnum].state = HC_XACTERR;
  892. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
  893. }
  894. else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR)
  895. {
  896. __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  897. USB_HC_Halt(hhcd->Instance, chnum);
  898. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  899. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
  900. hhcd->hc[chnum].state = HC_DATATGLERR;
  901. }
  902. else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH)
  903. {
  904. __HAL_HCD_MASK_HALT_HC_INT(chnum);
  905. if(hhcd->hc[chnum].state == HC_XFRC)
  906. {
  907. hhcd->hc[chnum].urb_state = URB_DONE;
  908. if (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)
  909. {
  910. hhcd->hc[chnum].toggle_out ^= 1;
  911. }
  912. }
  913. else if (hhcd->hc[chnum].state == HC_NAK)
  914. {
  915. hhcd->hc[chnum].urb_state = URB_NOTREADY;
  916. }
  917. else if (hhcd->hc[chnum].state == HC_NYET)
  918. {
  919. hhcd->hc[chnum].urb_state = URB_NOTREADY;
  920. hhcd->hc[chnum].do_ping = 0;
  921. }
  922. else if (hhcd->hc[chnum].state == HC_STALL)
  923. {
  924. hhcd->hc[chnum].urb_state = URB_STALL;
  925. }
  926. else if((hhcd->hc[chnum].state == HC_XACTERR) ||
  927. (hhcd->hc[chnum].state == HC_DATATGLERR))
  928. {
  929. if(hhcd->hc[chnum].ErrCnt++ > 3)
  930. {
  931. hhcd->hc[chnum].ErrCnt = 0;
  932. hhcd->hc[chnum].urb_state = URB_ERROR;
  933. }
  934. else
  935. {
  936. hhcd->hc[chnum].urb_state = URB_NOTREADY;
  937. }
  938. /* re-activate the channel */
  939. tmpreg = USBx_HC(chnum)->HCCHAR;
  940. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  941. tmpreg |= USB_OTG_HCCHAR_CHENA;
  942. USBx_HC(chnum)->HCCHAR = tmpreg;
  943. }
  944. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
  945. HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  946. }
  947. }
  948. /**
  949. * @brief Handle Rx Queue Level interrupt requests.
  950. * @param hhcd: HCD handle
  951. * @retval none
  952. */
  953. static void HCD_RXQLVL_IRQHandler (HCD_HandleTypeDef *hhcd)
  954. {
  955. USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  956. uint8_t channelnum =0;
  957. uint32_t pktsts;
  958. uint32_t pktcnt;
  959. uint32_t temp = 0;
  960. uint32_t tmpreg = 0;
  961. temp = hhcd->Instance->GRXSTSP ;
  962. channelnum = temp & USB_OTG_GRXSTSP_EPNUM;
  963. pktsts = (temp & USB_OTG_GRXSTSP_PKTSTS) >> 17;
  964. pktcnt = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  965. switch (pktsts)
  966. {
  967. case GRXSTS_PKTSTS_IN:
  968. /* Read the data into the host buffer. */
  969. if ((pktcnt > 0) && (hhcd->hc[channelnum].xfer_buff != (void *)0))
  970. {
  971. USB_ReadPacket(hhcd->Instance, hhcd->hc[channelnum].xfer_buff, pktcnt);
  972. /*manage multiple Xfer */
  973. hhcd->hc[channelnum].xfer_buff += pktcnt;
  974. hhcd->hc[channelnum].xfer_count += pktcnt;
  975. if((USBx_HC(channelnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) > 0)
  976. {
  977. /* re-activate the channel when more packets are expected */
  978. tmpreg = USBx_HC(channelnum)->HCCHAR;
  979. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  980. tmpreg |= USB_OTG_HCCHAR_CHENA;
  981. USBx_HC(channelnum)->HCCHAR = tmpreg;
  982. hhcd->hc[channelnum].toggle_in ^= 1;
  983. }
  984. }
  985. break;
  986. case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
  987. break;
  988. case GRXSTS_PKTSTS_IN_XFER_COMP:
  989. case GRXSTS_PKTSTS_CH_HALTED:
  990. default:
  991. break;
  992. }
  993. }
  994. /**
  995. * @brief Handle Host Port interrupt requests.
  996. * @param hhcd: HCD handle
  997. * @retval None
  998. */
  999. static void HCD_Port_IRQHandler (HCD_HandleTypeDef *hhcd)
  1000. {
  1001. USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1002. __IO uint32_t hprt0, hprt0_dup;
  1003. /* Handle Host Port Interrupts */
  1004. hprt0 = USBx_HPRT0;
  1005. hprt0_dup = USBx_HPRT0;
  1006. hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
  1007. USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
  1008. /* Check whether Port Connect detected */
  1009. if((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
  1010. {
  1011. if((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
  1012. {
  1013. USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
  1014. HAL_HCD_Connect_Callback(hhcd);
  1015. }
  1016. hprt0_dup |= USB_OTG_HPRT_PCDET;
  1017. }
  1018. /* Check whether Port Enable Changed */
  1019. if((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
  1020. {
  1021. hprt0_dup |= USB_OTG_HPRT_PENCHNG;
  1022. if((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
  1023. {
  1024. if(hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
  1025. {
  1026. if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17))
  1027. {
  1028. USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_6_MHZ );
  1029. }
  1030. else
  1031. {
  1032. USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ );
  1033. }
  1034. }
  1035. else
  1036. {
  1037. if(hhcd->Init.speed == HCD_SPEED_FULL)
  1038. {
  1039. USBx_HOST->HFIR = (uint32_t)60000;
  1040. }
  1041. }
  1042. HAL_HCD_Connect_Callback(hhcd);
  1043. }
  1044. else
  1045. {
  1046. /* Cleanup HPRT */
  1047. USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
  1048. USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
  1049. USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
  1050. }
  1051. }
  1052. /* Check For an overcurrent */
  1053. if((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
  1054. {
  1055. hprt0_dup |= USB_OTG_HPRT_POCCHNG;
  1056. }
  1057. /* Clear Port Interrupts */
  1058. USBx_HPRT0 = hprt0_dup;
  1059. }
  1060. /**
  1061. * @}
  1062. */
  1063. /**
  1064. * @}
  1065. */
  1066. #endif /* HAL_HCD_MODULE_ENABLED */
  1067. /**
  1068. * @}
  1069. */
  1070. /**
  1071. * @}
  1072. */
  1073. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/