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.

1997 lines
54 KiB

9 months ago
  1. /**
  2. ******************************************************************************
  3. * @file stm32f4xx_hal_hcd.c
  4. * @author MCD Application Team
  5. * @brief HCD HAL module driver.
  6. * This file provides firmware functions to manage the following
  7. * functionalities of the USB Peripheral Controller:
  8. * + Initialization and de-initialization functions
  9. * + IO operation functions
  10. * + Peripheral Control functions
  11. * + Peripheral State functions
  12. *
  13. ******************************************************************************
  14. * @attention
  15. *
  16. * Copyright (c) 2016 STMicroelectronics.
  17. * All rights reserved.
  18. *
  19. * This software is licensed under terms that can be found in the LICENSE file
  20. * in the root directory of this software component.
  21. * If no LICENSE file comes with this software, it is provided AS-IS.
  22. *
  23. ******************************************************************************
  24. @verbatim
  25. ==============================================================================
  26. ##### How to use this driver #####
  27. ==============================================================================
  28. [..]
  29. (#)Declare a HCD_HandleTypeDef handle structure, for example:
  30. HCD_HandleTypeDef hhcd;
  31. (#)Fill parameters of Init structure in HCD handle
  32. (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...)
  33. (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API:
  34. (##) Enable the HCD/USB Low Level interface clock using the following macros
  35. (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
  36. (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode)
  37. (+++) __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); (For High Speed Mode)
  38. (##) Initialize the related GPIO clocks
  39. (##) Configure HCD pin-out
  40. (##) Configure HCD NVIC interrupt
  41. (#)Associate the Upper USB Host stack to the HAL HCD Driver:
  42. (##) hhcd.pData = phost;
  43. (#)Enable HCD transmission and reception:
  44. (##) HAL_HCD_Start();
  45. @endverbatim
  46. ******************************************************************************
  47. */
  48. /* Includes ------------------------------------------------------------------*/
  49. #include "stm32f4xx_hal.h"
  50. /** @addtogroup STM32F4xx_HAL_Driver
  51. * @{
  52. */
  53. #ifdef HAL_HCD_MODULE_ENABLED
  54. #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
  55. /** @defgroup HCD HCD
  56. * @brief HCD HAL module driver
  57. * @{
  58. */
  59. /* Private typedef -----------------------------------------------------------*/
  60. /* Private define ------------------------------------------------------------*/
  61. /* Private macro -------------------------------------------------------------*/
  62. /* Private variables ---------------------------------------------------------*/
  63. /* Private function prototypes -----------------------------------------------*/
  64. /** @defgroup HCD_Private_Functions HCD Private Functions
  65. * @{
  66. */
  67. static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
  68. static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
  69. static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd);
  70. static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
  71. /**
  72. * @}
  73. */
  74. /* Exported functions --------------------------------------------------------*/
  75. /** @defgroup HCD_Exported_Functions HCD Exported Functions
  76. * @{
  77. */
  78. /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
  79. * @brief Initialization and Configuration functions
  80. *
  81. @verbatim
  82. ===============================================================================
  83. ##### Initialization and de-initialization functions #####
  84. ===============================================================================
  85. [..] This section provides functions allowing to:
  86. @endverbatim
  87. * @{
  88. */
  89. /**
  90. * @brief Initialize the host driver.
  91. * @param hhcd HCD handle
  92. * @retval HAL status
  93. */
  94. HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
  95. {
  96. #if defined (USB_OTG_FS)
  97. const USB_OTG_GlobalTypeDef *USBx;
  98. #endif /* defined (USB_OTG_FS) */
  99. /* Check the HCD handle allocation */
  100. if (hhcd == NULL)
  101. {
  102. return HAL_ERROR;
  103. }
  104. /* Check the parameters */
  105. assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
  106. #if defined (USB_OTG_FS)
  107. USBx = hhcd->Instance;
  108. #endif /* defined (USB_OTG_FS) */
  109. if (hhcd->State == HAL_HCD_STATE_RESET)
  110. {
  111. /* Allocate lock resource and initialize it */
  112. hhcd->Lock = HAL_UNLOCKED;
  113. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  114. hhcd->SOFCallback = HAL_HCD_SOF_Callback;
  115. hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
  116. hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
  117. hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
  118. hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
  119. hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback;
  120. if (hhcd->MspInitCallback == NULL)
  121. {
  122. hhcd->MspInitCallback = HAL_HCD_MspInit;
  123. }
  124. /* Init the low level hardware */
  125. hhcd->MspInitCallback(hhcd);
  126. #else
  127. /* Init the low level hardware : GPIO, CLOCK, NVIC... */
  128. HAL_HCD_MspInit(hhcd);
  129. #endif /* (USE_HAL_HCD_REGISTER_CALLBACKS) */
  130. }
  131. hhcd->State = HAL_HCD_STATE_BUSY;
  132. #if defined (USB_OTG_FS)
  133. /* Disable DMA mode for FS instance */
  134. if (USBx == USB_OTG_FS)
  135. {
  136. hhcd->Init.dma_enable = 0U;
  137. }
  138. #endif /* defined (USB_OTG_FS) */
  139. /* Disable the Interrupts */
  140. __HAL_HCD_DISABLE(hhcd);
  141. /* Init the Core (common init.) */
  142. if (USB_CoreInit(hhcd->Instance, hhcd->Init) != HAL_OK)
  143. {
  144. hhcd->State = HAL_HCD_STATE_ERROR;
  145. return HAL_ERROR;
  146. }
  147. /* Force Host Mode */
  148. if (USB_SetCurrentMode(hhcd->Instance, USB_HOST_MODE) != HAL_OK)
  149. {
  150. hhcd->State = HAL_HCD_STATE_ERROR;
  151. return HAL_ERROR;
  152. }
  153. /* Init Host */
  154. if (USB_HostInit(hhcd->Instance, hhcd->Init) != HAL_OK)
  155. {
  156. hhcd->State = HAL_HCD_STATE_ERROR;
  157. return HAL_ERROR;
  158. }
  159. hhcd->State = HAL_HCD_STATE_READY;
  160. return HAL_OK;
  161. }
  162. /**
  163. * @brief Initialize a host channel.
  164. * @param hhcd HCD handle
  165. * @param ch_num Channel number.
  166. * This parameter can be a value from 1 to 15
  167. * @param epnum Endpoint number.
  168. * This parameter can be a value from 1 to 15
  169. * @param dev_address Current device address
  170. * This parameter can be a value from 0 to 255
  171. * @param speed Current device speed.
  172. * This parameter can be one of these values:
  173. * HCD_DEVICE_SPEED_HIGH: High speed mode,
  174. * HCD_DEVICE_SPEED_FULL: Full speed mode,
  175. * HCD_DEVICE_SPEED_LOW: Low speed mode
  176. * @param ep_type Endpoint Type.
  177. * This parameter can be one of these values:
  178. * EP_TYPE_CTRL: Control type,
  179. * EP_TYPE_ISOC: Isochronous type,
  180. * EP_TYPE_BULK: Bulk type,
  181. * EP_TYPE_INTR: Interrupt type
  182. * @param mps Max Packet Size.
  183. * This parameter can be a value from 0 to32K
  184. * @retval HAL status
  185. */
  186. HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, uint8_t ch_num, uint8_t epnum,
  187. uint8_t dev_address, uint8_t speed, uint8_t ep_type, uint16_t mps)
  188. {
  189. HAL_StatusTypeDef status;
  190. uint32_t HostCoreSpeed;
  191. uint32_t HCcharMps = mps;
  192. __HAL_LOCK(hhcd);
  193. hhcd->hc[ch_num].do_ping = 0U;
  194. hhcd->hc[ch_num].dev_addr = dev_address;
  195. hhcd->hc[ch_num].ch_num = ch_num;
  196. hhcd->hc[ch_num].ep_type = ep_type;
  197. hhcd->hc[ch_num].ep_num = epnum & 0x7FU;
  198. (void)HAL_HCD_HC_ClearHubInfo(hhcd, ch_num);
  199. if ((epnum & 0x80U) == 0x80U)
  200. {
  201. hhcd->hc[ch_num].ep_is_in = 1U;
  202. }
  203. else
  204. {
  205. hhcd->hc[ch_num].ep_is_in = 0U;
  206. }
  207. HostCoreSpeed = USB_GetHostSpeed(hhcd->Instance);
  208. if (ep_type == EP_TYPE_ISOC)
  209. {
  210. /* FS device plugged to HS HUB */
  211. if ((speed == HCD_DEVICE_SPEED_FULL) && (HostCoreSpeed == HPRT0_PRTSPD_HIGH_SPEED))
  212. {
  213. if (HCcharMps > ISO_SPLT_MPS)
  214. {
  215. /* ISO Max Packet Size for Split mode */
  216. HCcharMps = ISO_SPLT_MPS;
  217. }
  218. }
  219. }
  220. hhcd->hc[ch_num].speed = speed;
  221. hhcd->hc[ch_num].max_packet = (uint16_t)HCcharMps;
  222. status = USB_HC_Init(hhcd->Instance, ch_num, epnum,
  223. dev_address, speed, ep_type, (uint16_t)HCcharMps);
  224. __HAL_UNLOCK(hhcd);
  225. return status;
  226. }
  227. /**
  228. * @brief Halt a host channel.
  229. * @param hhcd HCD handle
  230. * @param ch_num Channel number.
  231. * This parameter can be a value from 1 to 15
  232. * @retval HAL status
  233. */
  234. HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
  235. {
  236. HAL_StatusTypeDef status = HAL_OK;
  237. __HAL_LOCK(hhcd);
  238. (void)USB_HC_Halt(hhcd->Instance, ch_num);
  239. __HAL_UNLOCK(hhcd);
  240. return status;
  241. }
  242. /**
  243. * @brief DeInitialize the host driver.
  244. * @param hhcd HCD handle
  245. * @retval HAL status
  246. */
  247. HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
  248. {
  249. /* Check the HCD handle allocation */
  250. if (hhcd == NULL)
  251. {
  252. return HAL_ERROR;
  253. }
  254. hhcd->State = HAL_HCD_STATE_BUSY;
  255. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  256. if (hhcd->MspDeInitCallback == NULL)
  257. {
  258. hhcd->MspDeInitCallback = HAL_HCD_MspDeInit; /* Legacy weak MspDeInit */
  259. }
  260. /* DeInit the low level hardware */
  261. hhcd->MspDeInitCallback(hhcd);
  262. #else
  263. /* DeInit the low level hardware: CLOCK, NVIC.*/
  264. HAL_HCD_MspDeInit(hhcd);
  265. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  266. __HAL_HCD_DISABLE(hhcd);
  267. hhcd->State = HAL_HCD_STATE_RESET;
  268. return HAL_OK;
  269. }
  270. /**
  271. * @brief Initialize the HCD MSP.
  272. * @param hhcd HCD handle
  273. * @retval None
  274. */
  275. __weak void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
  276. {
  277. /* Prevent unused argument(s) compilation warning */
  278. UNUSED(hhcd);
  279. /* NOTE : This function should not be modified, when the callback is needed,
  280. the HAL_HCD_MspInit could be implemented in the user file
  281. */
  282. }
  283. /**
  284. * @brief DeInitialize the HCD MSP.
  285. * @param hhcd HCD handle
  286. * @retval None
  287. */
  288. __weak void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
  289. {
  290. /* Prevent unused argument(s) compilation warning */
  291. UNUSED(hhcd);
  292. /* NOTE : This function should not be modified, when the callback is needed,
  293. the HAL_HCD_MspDeInit could be implemented in the user file
  294. */
  295. }
  296. /**
  297. * @}
  298. */
  299. /** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions
  300. * @brief HCD IO operation functions
  301. *
  302. @verbatim
  303. ===============================================================================
  304. ##### IO operation functions #####
  305. ===============================================================================
  306. [..] This subsection provides a set of functions allowing to manage the USB Host Data
  307. Transfer
  308. @endverbatim
  309. * @{
  310. */
  311. /**
  312. * @brief Submit a new URB for processing.
  313. * @param hhcd HCD handle
  314. * @param ch_num Channel number.
  315. * This parameter can be a value from 1 to 15
  316. * @param direction Channel number.
  317. * This parameter can be one of these values:
  318. * 0 : Output / 1 : Input
  319. * @param ep_type Endpoint Type.
  320. * This parameter can be one of these values:
  321. * EP_TYPE_CTRL: Control type/
  322. * EP_TYPE_ISOC: Isochronous type/
  323. * EP_TYPE_BULK: Bulk type/
  324. * EP_TYPE_INTR: Interrupt type/
  325. * @param token Endpoint Type.
  326. * This parameter can be one of these values:
  327. * 0: HC_PID_SETUP / 1: HC_PID_DATA1
  328. * @param pbuff pointer to URB data
  329. * @param length Length of URB data
  330. * @param do_ping activate do ping protocol (for high speed only).
  331. * This parameter can be one of these values:
  332. * 0 : do ping inactive / 1 : do ping active
  333. * @retval HAL status
  334. */
  335. HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
  336. uint8_t ch_num,
  337. uint8_t direction,
  338. uint8_t ep_type,
  339. uint8_t token,
  340. uint8_t *pbuff,
  341. uint16_t length,
  342. uint8_t do_ping)
  343. {
  344. hhcd->hc[ch_num].ep_is_in = direction;
  345. hhcd->hc[ch_num].ep_type = ep_type;
  346. if (token == 0U)
  347. {
  348. hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
  349. hhcd->hc[ch_num].do_ping = do_ping;
  350. }
  351. else
  352. {
  353. hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  354. }
  355. /* Manage Data Toggle */
  356. switch (ep_type)
  357. {
  358. case EP_TYPE_CTRL:
  359. if (token == 1U) /* send data */
  360. {
  361. if (direction == 0U)
  362. {
  363. if (length == 0U)
  364. {
  365. /* For Status OUT stage, Length == 0U, Status Out PID = 1 */
  366. hhcd->hc[ch_num].toggle_out = 1U;
  367. }
  368. /* Set the Data Toggle bit as per the Flag */
  369. if (hhcd->hc[ch_num].toggle_out == 0U)
  370. {
  371. /* Put the PID 0 */
  372. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  373. }
  374. else
  375. {
  376. /* Put the PID 1 */
  377. hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  378. }
  379. }
  380. else
  381. {
  382. if (hhcd->hc[ch_num].do_ssplit == 1U)
  383. {
  384. if (hhcd->hc[ch_num].toggle_in == 0U)
  385. {
  386. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  387. }
  388. else
  389. {
  390. hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  391. }
  392. }
  393. }
  394. }
  395. break;
  396. case EP_TYPE_BULK:
  397. if (direction == 0U)
  398. {
  399. /* Set the Data Toggle bit as per the Flag */
  400. if (hhcd->hc[ch_num].toggle_out == 0U)
  401. {
  402. /* Put the PID 0 */
  403. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  404. }
  405. else
  406. {
  407. /* Put the PID 1 */
  408. hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  409. }
  410. }
  411. else
  412. {
  413. if (hhcd->hc[ch_num].toggle_in == 0U)
  414. {
  415. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  416. }
  417. else
  418. {
  419. hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  420. }
  421. }
  422. break;
  423. case EP_TYPE_INTR:
  424. if (direction == 0U)
  425. {
  426. /* Set the Data Toggle bit as per the Flag */
  427. if (hhcd->hc[ch_num].toggle_out == 0U)
  428. {
  429. /* Put the PID 0 */
  430. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  431. }
  432. else
  433. {
  434. /* Put the PID 1 */
  435. hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  436. }
  437. }
  438. else
  439. {
  440. if (hhcd->hc[ch_num].toggle_in == 0U)
  441. {
  442. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  443. }
  444. else
  445. {
  446. hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  447. }
  448. }
  449. break;
  450. case EP_TYPE_ISOC:
  451. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  452. break;
  453. default:
  454. break;
  455. }
  456. hhcd->hc[ch_num].xfer_buff = pbuff;
  457. hhcd->hc[ch_num].xfer_len = length;
  458. hhcd->hc[ch_num].urb_state = URB_IDLE;
  459. hhcd->hc[ch_num].xfer_count = 0U;
  460. hhcd->hc[ch_num].ch_num = ch_num;
  461. hhcd->hc[ch_num].state = HC_IDLE;
  462. return USB_HC_StartXfer(hhcd->Instance, &hhcd->hc[ch_num], (uint8_t)hhcd->Init.dma_enable);
  463. }
  464. /**
  465. * @brief Handle HCD interrupt request.
  466. * @param hhcd HCD handle
  467. * @retval None
  468. */
  469. void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
  470. {
  471. USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  472. uint32_t USBx_BASE = (uint32_t)USBx;
  473. uint32_t i;
  474. uint32_t interrupt;
  475. /* Ensure that we are in device mode */
  476. if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
  477. {
  478. /* Avoid spurious interrupt */
  479. if (__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
  480. {
  481. return;
  482. }
  483. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
  484. {
  485. /* Incorrect mode, acknowledge the interrupt */
  486. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
  487. }
  488. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
  489. {
  490. /* Incorrect mode, acknowledge the interrupt */
  491. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
  492. }
  493. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
  494. {
  495. /* Incorrect mode, acknowledge the interrupt */
  496. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
  497. }
  498. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
  499. {
  500. /* Incorrect mode, acknowledge the interrupt */
  501. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
  502. }
  503. /* Handle Host Disconnect Interrupts */
  504. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
  505. {
  506. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
  507. if ((USBx_HPRT0 & USB_OTG_HPRT_PCSTS) == 0U)
  508. {
  509. /* Flush USB Fifo */
  510. (void)USB_FlushTxFifo(USBx, 0x10U);
  511. (void)USB_FlushRxFifo(USBx);
  512. if (hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
  513. {
  514. /* Restore FS Clock */
  515. (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
  516. }
  517. /* Handle Host Port Disconnect Interrupt */
  518. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  519. hhcd->DisconnectCallback(hhcd);
  520. #else
  521. HAL_HCD_Disconnect_Callback(hhcd);
  522. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  523. }
  524. }
  525. /* Handle Host Port Interrupts */
  526. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
  527. {
  528. HCD_Port_IRQHandler(hhcd);
  529. }
  530. /* Handle Host SOF Interrupt */
  531. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
  532. {
  533. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  534. hhcd->SOFCallback(hhcd);
  535. #else
  536. HAL_HCD_SOF_Callback(hhcd);
  537. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  538. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
  539. }
  540. /* Handle Host channel Interrupt */
  541. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
  542. {
  543. interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
  544. for (i = 0U; i < hhcd->Init.Host_channels; i++)
  545. {
  546. if ((interrupt & (1UL << (i & 0xFU))) != 0U)
  547. {
  548. if ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_EPDIR) == USB_OTG_HCCHAR_EPDIR)
  549. {
  550. HCD_HC_IN_IRQHandler(hhcd, (uint8_t)i);
  551. }
  552. else
  553. {
  554. HCD_HC_OUT_IRQHandler(hhcd, (uint8_t)i);
  555. }
  556. }
  557. }
  558. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
  559. }
  560. /* Handle Rx Queue Level Interrupts */
  561. if ((__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL)) != 0U)
  562. {
  563. USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  564. HCD_RXQLVL_IRQHandler(hhcd);
  565. USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  566. }
  567. }
  568. }
  569. /**
  570. * @brief Handles HCD Wakeup interrupt request.
  571. * @param hhcd HCD handle
  572. * @retval HAL status
  573. */
  574. void HAL_HCD_WKUP_IRQHandler(HCD_HandleTypeDef *hhcd)
  575. {
  576. UNUSED(hhcd);
  577. }
  578. /**
  579. * @brief SOF callback.
  580. * @param hhcd HCD handle
  581. * @retval None
  582. */
  583. __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
  584. {
  585. /* Prevent unused argument(s) compilation warning */
  586. UNUSED(hhcd);
  587. /* NOTE : This function should not be modified, when the callback is needed,
  588. the HAL_HCD_SOF_Callback could be implemented in the user file
  589. */
  590. }
  591. /**
  592. * @brief Connection Event callback.
  593. * @param hhcd HCD handle
  594. * @retval None
  595. */
  596. __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
  597. {
  598. /* Prevent unused argument(s) compilation warning */
  599. UNUSED(hhcd);
  600. /* NOTE : This function should not be modified, when the callback is needed,
  601. the HAL_HCD_Connect_Callback could be implemented in the user file
  602. */
  603. }
  604. /**
  605. * @brief Disconnection Event callback.
  606. * @param hhcd HCD handle
  607. * @retval None
  608. */
  609. __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
  610. {
  611. /* Prevent unused argument(s) compilation warning */
  612. UNUSED(hhcd);
  613. /* NOTE : This function should not be modified, when the callback is needed,
  614. the HAL_HCD_Disconnect_Callback could be implemented in the user file
  615. */
  616. }
  617. /**
  618. * @brief Port Enabled Event callback.
  619. * @param hhcd HCD handle
  620. * @retval None
  621. */
  622. __weak void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd)
  623. {
  624. /* Prevent unused argument(s) compilation warning */
  625. UNUSED(hhcd);
  626. /* NOTE : This function should not be modified, when the callback is needed,
  627. the HAL_HCD_Disconnect_Callback could be implemented in the user file
  628. */
  629. }
  630. /**
  631. * @brief Port Disabled Event callback.
  632. * @param hhcd HCD handle
  633. * @retval None
  634. */
  635. __weak void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd)
  636. {
  637. /* Prevent unused argument(s) compilation warning */
  638. UNUSED(hhcd);
  639. /* NOTE : This function should not be modified, when the callback is needed,
  640. the HAL_HCD_Disconnect_Callback could be implemented in the user file
  641. */
  642. }
  643. /**
  644. * @brief Notify URB state change callback.
  645. * @param hhcd HCD handle
  646. * @param chnum Channel number.
  647. * This parameter can be a value from 1 to 15
  648. * @param urb_state:
  649. * This parameter can be one of these values:
  650. * URB_IDLE/
  651. * URB_DONE/
  652. * URB_NOTREADY/
  653. * URB_NYET/
  654. * URB_ERROR/
  655. * URB_STALL/
  656. * @retval None
  657. */
  658. __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
  659. {
  660. /* Prevent unused argument(s) compilation warning */
  661. UNUSED(hhcd);
  662. UNUSED(chnum);
  663. UNUSED(urb_state);
  664. /* NOTE : This function should not be modified, when the callback is needed,
  665. the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
  666. */
  667. }
  668. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  669. /**
  670. * @brief Register a User USB HCD Callback
  671. * To be used instead of the weak predefined callback
  672. * @param hhcd USB HCD handle
  673. * @param CallbackID ID of the callback to be registered
  674. * This parameter can be one of the following values:
  675. * @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
  676. * @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
  677. * @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
  678. * @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enable callback ID
  679. * @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disable callback ID
  680. * @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
  681. * @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
  682. * @param pCallback pointer to the Callback function
  683. * @retval HAL status
  684. */
  685. HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd,
  686. HAL_HCD_CallbackIDTypeDef CallbackID,
  687. pHCD_CallbackTypeDef pCallback)
  688. {
  689. HAL_StatusTypeDef status = HAL_OK;
  690. if (pCallback == NULL)
  691. {
  692. /* Update the error code */
  693. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  694. return HAL_ERROR;
  695. }
  696. /* Process locked */
  697. __HAL_LOCK(hhcd);
  698. if (hhcd->State == HAL_HCD_STATE_READY)
  699. {
  700. switch (CallbackID)
  701. {
  702. case HAL_HCD_SOF_CB_ID :
  703. hhcd->SOFCallback = pCallback;
  704. break;
  705. case HAL_HCD_CONNECT_CB_ID :
  706. hhcd->ConnectCallback = pCallback;
  707. break;
  708. case HAL_HCD_DISCONNECT_CB_ID :
  709. hhcd->DisconnectCallback = pCallback;
  710. break;
  711. case HAL_HCD_PORT_ENABLED_CB_ID :
  712. hhcd->PortEnabledCallback = pCallback;
  713. break;
  714. case HAL_HCD_PORT_DISABLED_CB_ID :
  715. hhcd->PortDisabledCallback = pCallback;
  716. break;
  717. case HAL_HCD_MSPINIT_CB_ID :
  718. hhcd->MspInitCallback = pCallback;
  719. break;
  720. case HAL_HCD_MSPDEINIT_CB_ID :
  721. hhcd->MspDeInitCallback = pCallback;
  722. break;
  723. default :
  724. /* Update the error code */
  725. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  726. /* Return error status */
  727. status = HAL_ERROR;
  728. break;
  729. }
  730. }
  731. else if (hhcd->State == HAL_HCD_STATE_RESET)
  732. {
  733. switch (CallbackID)
  734. {
  735. case HAL_HCD_MSPINIT_CB_ID :
  736. hhcd->MspInitCallback = pCallback;
  737. break;
  738. case HAL_HCD_MSPDEINIT_CB_ID :
  739. hhcd->MspDeInitCallback = pCallback;
  740. break;
  741. default :
  742. /* Update the error code */
  743. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  744. /* Return error status */
  745. status = HAL_ERROR;
  746. break;
  747. }
  748. }
  749. else
  750. {
  751. /* Update the error code */
  752. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  753. /* Return error status */
  754. status = HAL_ERROR;
  755. }
  756. /* Release Lock */
  757. __HAL_UNLOCK(hhcd);
  758. return status;
  759. }
  760. /**
  761. * @brief Unregister an USB HCD Callback
  762. * USB HCD callback is redirected to the weak predefined callback
  763. * @param hhcd USB HCD handle
  764. * @param CallbackID ID of the callback to be unregistered
  765. * This parameter can be one of the following values:
  766. * @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
  767. * @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
  768. * @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
  769. * @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enabled callback ID
  770. * @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disabled callback ID
  771. * @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
  772. * @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
  773. * @retval HAL status
  774. */
  775. HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID)
  776. {
  777. HAL_StatusTypeDef status = HAL_OK;
  778. /* Process locked */
  779. __HAL_LOCK(hhcd);
  780. /* Setup Legacy weak Callbacks */
  781. if (hhcd->State == HAL_HCD_STATE_READY)
  782. {
  783. switch (CallbackID)
  784. {
  785. case HAL_HCD_SOF_CB_ID :
  786. hhcd->SOFCallback = HAL_HCD_SOF_Callback;
  787. break;
  788. case HAL_HCD_CONNECT_CB_ID :
  789. hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
  790. break;
  791. case HAL_HCD_DISCONNECT_CB_ID :
  792. hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
  793. break;
  794. case HAL_HCD_PORT_ENABLED_CB_ID :
  795. hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
  796. break;
  797. case HAL_HCD_PORT_DISABLED_CB_ID :
  798. hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
  799. break;
  800. case HAL_HCD_MSPINIT_CB_ID :
  801. hhcd->MspInitCallback = HAL_HCD_MspInit;
  802. break;
  803. case HAL_HCD_MSPDEINIT_CB_ID :
  804. hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
  805. break;
  806. default :
  807. /* Update the error code */
  808. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  809. /* Return error status */
  810. status = HAL_ERROR;
  811. break;
  812. }
  813. }
  814. else if (hhcd->State == HAL_HCD_STATE_RESET)
  815. {
  816. switch (CallbackID)
  817. {
  818. case HAL_HCD_MSPINIT_CB_ID :
  819. hhcd->MspInitCallback = HAL_HCD_MspInit;
  820. break;
  821. case HAL_HCD_MSPDEINIT_CB_ID :
  822. hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
  823. break;
  824. default :
  825. /* Update the error code */
  826. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  827. /* Return error status */
  828. status = HAL_ERROR;
  829. break;
  830. }
  831. }
  832. else
  833. {
  834. /* Update the error code */
  835. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  836. /* Return error status */
  837. status = HAL_ERROR;
  838. }
  839. /* Release Lock */
  840. __HAL_UNLOCK(hhcd);
  841. return status;
  842. }
  843. /**
  844. * @brief Register USB HCD Host Channel Notify URB Change Callback
  845. * To be used instead of the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
  846. * @param hhcd HCD handle
  847. * @param pCallback pointer to the USB HCD Host Channel Notify URB Change Callback function
  848. * @retval HAL status
  849. */
  850. HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd,
  851. pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback)
  852. {
  853. HAL_StatusTypeDef status = HAL_OK;
  854. if (pCallback == NULL)
  855. {
  856. /* Update the error code */
  857. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  858. return HAL_ERROR;
  859. }
  860. /* Process locked */
  861. __HAL_LOCK(hhcd);
  862. if (hhcd->State == HAL_HCD_STATE_READY)
  863. {
  864. hhcd->HC_NotifyURBChangeCallback = pCallback;
  865. }
  866. else
  867. {
  868. /* Update the error code */
  869. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  870. /* Return error status */
  871. status = HAL_ERROR;
  872. }
  873. /* Release Lock */
  874. __HAL_UNLOCK(hhcd);
  875. return status;
  876. }
  877. /**
  878. * @brief Unregister the USB HCD Host Channel Notify URB Change Callback
  879. * USB HCD Host Channel Notify URB Change Callback is redirected
  880. * to the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
  881. * @param hhcd HCD handle
  882. * @retval HAL status
  883. */
  884. HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd)
  885. {
  886. HAL_StatusTypeDef status = HAL_OK;
  887. /* Process locked */
  888. __HAL_LOCK(hhcd);
  889. if (hhcd->State == HAL_HCD_STATE_READY)
  890. {
  891. hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback; /* Legacy weak DataOutStageCallback */
  892. }
  893. else
  894. {
  895. /* Update the error code */
  896. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  897. /* Return error status */
  898. status = HAL_ERROR;
  899. }
  900. /* Release Lock */
  901. __HAL_UNLOCK(hhcd);
  902. return status;
  903. }
  904. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  905. /**
  906. * @}
  907. */
  908. /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
  909. * @brief Management functions
  910. *
  911. @verbatim
  912. ===============================================================================
  913. ##### Peripheral Control functions #####
  914. ===============================================================================
  915. [..]
  916. This subsection provides a set of functions allowing to control the HCD data
  917. transfers.
  918. @endverbatim
  919. * @{
  920. */
  921. /**
  922. * @brief Start the host driver.
  923. * @param hhcd HCD handle
  924. * @retval HAL status
  925. */
  926. HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
  927. {
  928. __HAL_LOCK(hhcd);
  929. /* Enable port power */
  930. (void)USB_DriveVbus(hhcd->Instance, 1U);
  931. /* Enable global interrupt */
  932. __HAL_HCD_ENABLE(hhcd);
  933. __HAL_UNLOCK(hhcd);
  934. return HAL_OK;
  935. }
  936. /**
  937. * @brief Stop the host driver.
  938. * @param hhcd HCD handle
  939. * @retval HAL status
  940. */
  941. HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
  942. {
  943. __HAL_LOCK(hhcd);
  944. (void)USB_StopHost(hhcd->Instance);
  945. __HAL_UNLOCK(hhcd);
  946. return HAL_OK;
  947. }
  948. /**
  949. * @brief Reset the host port.
  950. * @param hhcd HCD handle
  951. * @retval HAL status
  952. */
  953. HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
  954. {
  955. return (USB_ResetPort(hhcd->Instance));
  956. }
  957. /**
  958. * @}
  959. */
  960. /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
  961. * @brief Peripheral State functions
  962. *
  963. @verbatim
  964. ===============================================================================
  965. ##### Peripheral State functions #####
  966. ===============================================================================
  967. [..]
  968. This subsection permits to get in run-time the status of the peripheral
  969. and the data flow.
  970. @endverbatim
  971. * @{
  972. */
  973. /**
  974. * @brief Return the HCD handle state.
  975. * @param hhcd HCD handle
  976. * @retval HAL state
  977. */
  978. HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef const *hhcd)
  979. {
  980. return hhcd->State;
  981. }
  982. /**
  983. * @brief Return URB state for a channel.
  984. * @param hhcd HCD handle
  985. * @param chnum Channel number.
  986. * This parameter can be a value from 1 to 15
  987. * @retval URB state.
  988. * This parameter can be one of these values:
  989. * URB_IDLE/
  990. * URB_DONE/
  991. * URB_NOTREADY/
  992. * URB_NYET/
  993. * URB_ERROR/
  994. * URB_STALL
  995. */
  996. HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
  997. {
  998. return hhcd->hc[chnum].urb_state;
  999. }
  1000. /**
  1001. * @brief Return the last host transfer size.
  1002. * @param hhcd HCD handle
  1003. * @param chnum Channel number.
  1004. * This parameter can be a value from 1 to 15
  1005. * @retval last transfer size in byte
  1006. */
  1007. uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
  1008. {
  1009. return hhcd->hc[chnum].xfer_count;
  1010. }
  1011. /**
  1012. * @brief Return the Host Channel state.
  1013. * @param hhcd HCD handle
  1014. * @param chnum Channel number.
  1015. * This parameter can be a value from 1 to 15
  1016. * @retval Host channel state
  1017. * This parameter can be one of these values:
  1018. * HC_IDLE/
  1019. * HC_XFRC/
  1020. * HC_HALTED/
  1021. * HC_NYET/
  1022. * HC_NAK/
  1023. * HC_STALL/
  1024. * HC_XACTERR/
  1025. * HC_BBLERR/
  1026. * HC_DATATGLERR
  1027. */
  1028. HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
  1029. {
  1030. return hhcd->hc[chnum].state;
  1031. }
  1032. /**
  1033. * @brief Return the current Host frame number.
  1034. * @param hhcd HCD handle
  1035. * @retval Current Host frame number
  1036. */
  1037. uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
  1038. {
  1039. return (USB_GetCurrentFrame(hhcd->Instance));
  1040. }
  1041. /**
  1042. * @brief Return the Host enumeration speed.
  1043. * @param hhcd HCD handle
  1044. * @retval Enumeration speed
  1045. */
  1046. uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
  1047. {
  1048. return (USB_GetHostSpeed(hhcd->Instance));
  1049. }
  1050. /**
  1051. * @brief Set host channel Hub information.
  1052. * @param hhcd HCD handle
  1053. * @param ch_num Channel number.
  1054. * This parameter can be a value from 1 to 15
  1055. * @param addr Hub address
  1056. * @param PortNbr Hub port number
  1057. * @retval HAL status
  1058. */
  1059. HAL_StatusTypeDef HAL_HCD_HC_SetHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num,
  1060. uint8_t addr, uint8_t PortNbr)
  1061. {
  1062. uint32_t HostCoreSpeed = USB_GetHostSpeed(hhcd->Instance);
  1063. /* LS/FS device plugged to HS HUB */
  1064. if ((hhcd->hc[ch_num].speed != HCD_DEVICE_SPEED_HIGH) && (HostCoreSpeed == HPRT0_PRTSPD_HIGH_SPEED))
  1065. {
  1066. hhcd->hc[ch_num].do_ssplit = 1U;
  1067. if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) && (hhcd->hc[ch_num].ep_is_in != 0U))
  1068. {
  1069. hhcd->hc[ch_num].toggle_in = 1U;
  1070. }
  1071. }
  1072. hhcd->hc[ch_num].hub_addr = addr;
  1073. hhcd->hc[ch_num].hub_port_nbr = PortNbr;
  1074. return HAL_OK;
  1075. }
  1076. /**
  1077. * @brief Clear host channel hub information.
  1078. * @param hhcd HCD handle
  1079. * @param ch_num Channel number.
  1080. * This parameter can be a value from 1 to 15
  1081. * @retval HAL status
  1082. */
  1083. HAL_StatusTypeDef HAL_HCD_HC_ClearHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
  1084. {
  1085. hhcd->hc[ch_num].do_ssplit = 0U;
  1086. hhcd->hc[ch_num].do_csplit = 0U;
  1087. hhcd->hc[ch_num].hub_addr = 0U;
  1088. hhcd->hc[ch_num].hub_port_nbr = 0U;
  1089. return HAL_OK;
  1090. }
  1091. /**
  1092. * @}
  1093. */
  1094. /**
  1095. * @}
  1096. */
  1097. /** @addtogroup HCD_Private_Functions
  1098. * @{
  1099. */
  1100. /**
  1101. * @brief Handle Host Channel IN interrupt requests.
  1102. * @param hhcd HCD handle
  1103. * @param chnum Channel number.
  1104. * This parameter can be a value from 1 to 15
  1105. * @retval none
  1106. */
  1107. static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  1108. {
  1109. const USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1110. uint32_t USBx_BASE = (uint32_t)USBx;
  1111. uint32_t tmpreg;
  1112. if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_AHBERR))
  1113. {
  1114. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
  1115. hhcd->hc[chnum].state = HC_XACTERR;
  1116. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1117. }
  1118. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_BBERR))
  1119. {
  1120. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_BBERR);
  1121. hhcd->hc[chnum].state = HC_BBLERR;
  1122. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1123. }
  1124. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_STALL))
  1125. {
  1126. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
  1127. hhcd->hc[chnum].state = HC_STALL;
  1128. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1129. }
  1130. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_DTERR))
  1131. {
  1132. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
  1133. hhcd->hc[chnum].state = HC_DATATGLERR;
  1134. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1135. }
  1136. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_TXERR))
  1137. {
  1138. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
  1139. hhcd->hc[chnum].state = HC_XACTERR;
  1140. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1141. }
  1142. else
  1143. {
  1144. /* ... */
  1145. }
  1146. if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_FRMOR))
  1147. {
  1148. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1149. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
  1150. }
  1151. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_XFRC))
  1152. {
  1153. /* Clear any pending ACK IT */
  1154. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
  1155. if (hhcd->hc[chnum].do_csplit == 1U)
  1156. {
  1157. hhcd->hc[chnum].do_csplit = 0U;
  1158. __HAL_HCD_CLEAR_HC_CSPLT(chnum);
  1159. }
  1160. if (hhcd->Init.dma_enable != 0U)
  1161. {
  1162. hhcd->hc[chnum].xfer_count = hhcd->hc[chnum].XferSize - (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ);
  1163. }
  1164. hhcd->hc[chnum].state = HC_XFRC;
  1165. hhcd->hc[chnum].ErrCnt = 0U;
  1166. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
  1167. if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
  1168. (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
  1169. {
  1170. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1171. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  1172. }
  1173. else if ((hhcd->hc[chnum].ep_type == EP_TYPE_INTR) ||
  1174. (hhcd->hc[chnum].ep_type == EP_TYPE_ISOC))
  1175. {
  1176. USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
  1177. hhcd->hc[chnum].urb_state = URB_DONE;
  1178. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1179. hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  1180. #else
  1181. HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  1182. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1183. }
  1184. else
  1185. {
  1186. /* ... */
  1187. }
  1188. if (hhcd->Init.dma_enable == 1U)
  1189. {
  1190. if ((((hhcd->hc[chnum].xfer_count + hhcd->hc[chnum].max_packet - 1U) / hhcd->hc[chnum].max_packet) & 1U) != 0U)
  1191. {
  1192. hhcd->hc[chnum].toggle_in ^= 1U;
  1193. }
  1194. }
  1195. else
  1196. {
  1197. hhcd->hc[chnum].toggle_in ^= 1U;
  1198. }
  1199. }
  1200. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_ACK))
  1201. {
  1202. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
  1203. if (hhcd->hc[chnum].do_ssplit == 1U)
  1204. {
  1205. hhcd->hc[chnum].do_csplit = 1U;
  1206. hhcd->hc[chnum].state = HC_ACK;
  1207. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1208. }
  1209. }
  1210. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_CHH))
  1211. {
  1212. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
  1213. if (hhcd->hc[chnum].state == HC_XFRC)
  1214. {
  1215. hhcd->hc[chnum].state = HC_HALTED;
  1216. hhcd->hc[chnum].urb_state = URB_DONE;
  1217. }
  1218. else if (hhcd->hc[chnum].state == HC_STALL)
  1219. {
  1220. hhcd->hc[chnum].state = HC_HALTED;
  1221. hhcd->hc[chnum].urb_state = URB_STALL;
  1222. }
  1223. else if ((hhcd->hc[chnum].state == HC_XACTERR) ||
  1224. (hhcd->hc[chnum].state == HC_DATATGLERR))
  1225. {
  1226. hhcd->hc[chnum].state = HC_HALTED;
  1227. hhcd->hc[chnum].ErrCnt++;
  1228. if (hhcd->hc[chnum].ErrCnt > 2U)
  1229. {
  1230. hhcd->hc[chnum].ErrCnt = 0U;
  1231. if (hhcd->hc[chnum].do_ssplit == 1U)
  1232. {
  1233. hhcd->hc[chnum].do_csplit = 0U;
  1234. hhcd->hc[chnum].ep_ss_schedule = 0U;
  1235. __HAL_HCD_CLEAR_HC_CSPLT(chnum);
  1236. }
  1237. hhcd->hc[chnum].urb_state = URB_ERROR;
  1238. }
  1239. else
  1240. {
  1241. hhcd->hc[chnum].urb_state = URB_NOTREADY;
  1242. if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
  1243. (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
  1244. {
  1245. /* re-activate the channel */
  1246. tmpreg = USBx_HC(chnum)->HCCHAR;
  1247. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1248. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1249. USBx_HC(chnum)->HCCHAR = tmpreg;
  1250. }
  1251. }
  1252. }
  1253. else if (hhcd->hc[chnum].state == HC_NYET)
  1254. {
  1255. hhcd->hc[chnum].state = HC_HALTED;
  1256. if (hhcd->hc[chnum].do_csplit == 1U)
  1257. {
  1258. if (hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
  1259. {
  1260. hhcd->hc[chnum].NyetErrCnt++;
  1261. if (hhcd->hc[chnum].NyetErrCnt > 2U)
  1262. {
  1263. hhcd->hc[chnum].NyetErrCnt = 0U;
  1264. hhcd->hc[chnum].do_csplit = 0U;
  1265. if (hhcd->hc[chnum].ErrCnt < 3U)
  1266. {
  1267. hhcd->hc[chnum].ep_ss_schedule = 1U;
  1268. }
  1269. __HAL_HCD_CLEAR_HC_CSPLT(chnum);
  1270. hhcd->hc[chnum].urb_state = URB_ERROR;
  1271. }
  1272. else
  1273. {
  1274. hhcd->hc[chnum].urb_state = URB_NOTREADY;
  1275. }
  1276. }
  1277. else
  1278. {
  1279. hhcd->hc[chnum].urb_state = URB_NOTREADY;
  1280. }
  1281. if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
  1282. (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
  1283. {
  1284. /* re-activate the channel */
  1285. tmpreg = USBx_HC(chnum)->HCCHAR;
  1286. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1287. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1288. USBx_HC(chnum)->HCCHAR = tmpreg;
  1289. }
  1290. }
  1291. }
  1292. else if (hhcd->hc[chnum].state == HC_ACK)
  1293. {
  1294. hhcd->hc[chnum].state = HC_HALTED;
  1295. if (hhcd->hc[chnum].do_csplit == 1U)
  1296. {
  1297. hhcd->hc[chnum].urb_state = URB_NOTREADY;
  1298. /* Set Complete split and re-activate the channel */
  1299. USBx_HC(chnum)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
  1300. USBx_HC(chnum)->HCINTMSK |= USB_OTG_HCINTMSK_NYET;
  1301. USBx_HC(chnum)->HCINTMSK &= ~USB_OTG_HCINT_ACK;
  1302. if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
  1303. (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
  1304. {
  1305. /* re-activate the channel */
  1306. tmpreg = USBx_HC(chnum)->HCCHAR;
  1307. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1308. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1309. USBx_HC(chnum)->HCCHAR = tmpreg;
  1310. }
  1311. }
  1312. }
  1313. else if (hhcd->hc[chnum].state == HC_NAK)
  1314. {
  1315. hhcd->hc[chnum].state = HC_HALTED;
  1316. hhcd->hc[chnum].urb_state = URB_NOTREADY;
  1317. if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
  1318. (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
  1319. {
  1320. /* re-activate the channel */
  1321. tmpreg = USBx_HC(chnum)->HCCHAR;
  1322. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1323. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1324. USBx_HC(chnum)->HCCHAR = tmpreg;
  1325. }
  1326. }
  1327. else if (hhcd->hc[chnum].state == HC_BBLERR)
  1328. {
  1329. hhcd->hc[chnum].state = HC_HALTED;
  1330. hhcd->hc[chnum].ErrCnt++;
  1331. hhcd->hc[chnum].urb_state = URB_ERROR;
  1332. }
  1333. else
  1334. {
  1335. if (hhcd->hc[chnum].state == HC_HALTED)
  1336. {
  1337. return;
  1338. }
  1339. }
  1340. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1341. hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  1342. #else
  1343. HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  1344. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1345. }
  1346. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NYET))
  1347. {
  1348. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
  1349. hhcd->hc[chnum].state = HC_NYET;
  1350. if (hhcd->hc[chnum].do_ssplit == 0U)
  1351. {
  1352. hhcd->hc[chnum].ErrCnt = 0U;
  1353. }
  1354. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1355. }
  1356. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NAK))
  1357. {
  1358. if (hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
  1359. {
  1360. hhcd->hc[chnum].ErrCnt = 0U;
  1361. hhcd->hc[chnum].state = HC_NAK;
  1362. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1363. }
  1364. else if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
  1365. (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
  1366. {
  1367. hhcd->hc[chnum].ErrCnt = 0U;
  1368. if ((hhcd->Init.dma_enable == 0U) || (hhcd->hc[chnum].do_csplit == 1U))
  1369. {
  1370. hhcd->hc[chnum].state = HC_NAK;
  1371. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1372. }
  1373. }
  1374. else
  1375. {
  1376. /* ... */
  1377. }
  1378. if (hhcd->hc[chnum].do_csplit == 1U)
  1379. {
  1380. hhcd->hc[chnum].do_csplit = 0U;
  1381. __HAL_HCD_CLEAR_HC_CSPLT(chnum);
  1382. __HAL_HCD_UNMASK_ACK_HC_INT(chnum);
  1383. }
  1384. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  1385. }
  1386. else
  1387. {
  1388. /* ... */
  1389. }
  1390. }
  1391. /**
  1392. * @brief Handle Host Channel OUT interrupt requests.
  1393. * @param hhcd HCD handle
  1394. * @param chnum Channel number.
  1395. * This parameter can be a value from 1 to 15
  1396. * @retval none
  1397. */
  1398. static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  1399. {
  1400. const USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1401. uint32_t USBx_BASE = (uint32_t)USBx;
  1402. uint32_t tmpreg;
  1403. uint32_t num_packets;
  1404. if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_AHBERR))
  1405. {
  1406. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
  1407. hhcd->hc[chnum].state = HC_XACTERR;
  1408. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1409. }
  1410. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_ACK))
  1411. {
  1412. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
  1413. if (hhcd->hc[chnum].do_ping == 1U)
  1414. {
  1415. hhcd->hc[chnum].do_ping = 0U;
  1416. hhcd->hc[chnum].urb_state = URB_NOTREADY;
  1417. hhcd->hc[chnum].state = HC_ACK;
  1418. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1419. }
  1420. if ((hhcd->hc[chnum].do_ssplit == 1U) && (hhcd->hc[chnum].do_csplit == 0U))
  1421. {
  1422. if (hhcd->hc[chnum].ep_type != EP_TYPE_ISOC)
  1423. {
  1424. hhcd->hc[chnum].do_csplit = 1U;
  1425. }
  1426. hhcd->hc[chnum].state = HC_ACK;
  1427. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1428. /* reset error_count */
  1429. hhcd->hc[chnum].ErrCnt = 0U;
  1430. }
  1431. }
  1432. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_FRMOR))
  1433. {
  1434. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
  1435. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1436. }
  1437. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_XFRC))
  1438. {
  1439. hhcd->hc[chnum].ErrCnt = 0U;
  1440. /* transaction completed with NYET state, update do ping state */
  1441. if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NYET))
  1442. {
  1443. hhcd->hc[chnum].do_ping = 1U;
  1444. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
  1445. }
  1446. if (hhcd->hc[chnum].do_csplit != 0U)
  1447. {
  1448. hhcd->hc[chnum].do_csplit = 0U;
  1449. __HAL_HCD_CLEAR_HC_CSPLT(chnum);
  1450. }
  1451. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
  1452. hhcd->hc[chnum].state = HC_XFRC;
  1453. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1454. }
  1455. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NYET))
  1456. {
  1457. hhcd->hc[chnum].state = HC_NYET;
  1458. if (hhcd->hc[chnum].do_ssplit == 0U)
  1459. {
  1460. hhcd->hc[chnum].do_ping = 1U;
  1461. }
  1462. hhcd->hc[chnum].ErrCnt = 0U;
  1463. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1464. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
  1465. }
  1466. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_STALL))
  1467. {
  1468. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
  1469. hhcd->hc[chnum].state = HC_STALL;
  1470. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1471. }
  1472. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NAK))
  1473. {
  1474. hhcd->hc[chnum].ErrCnt = 0U;
  1475. hhcd->hc[chnum].state = HC_NAK;
  1476. if (hhcd->hc[chnum].do_ping == 0U)
  1477. {
  1478. if (hhcd->hc[chnum].speed == HCD_DEVICE_SPEED_HIGH)
  1479. {
  1480. hhcd->hc[chnum].do_ping = 1U;
  1481. }
  1482. }
  1483. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1484. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  1485. }
  1486. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_TXERR))
  1487. {
  1488. if (hhcd->Init.dma_enable == 0U)
  1489. {
  1490. hhcd->hc[chnum].state = HC_XACTERR;
  1491. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1492. }
  1493. else
  1494. {
  1495. hhcd->hc[chnum].ErrCnt++;
  1496. if (hhcd->hc[chnum].ErrCnt > 2U)
  1497. {
  1498. hhcd->hc[chnum].ErrCnt = 0U;
  1499. hhcd->hc[chnum].urb_state = URB_ERROR;
  1500. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1501. hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  1502. #else
  1503. HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  1504. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1505. }
  1506. else
  1507. {
  1508. hhcd->hc[chnum].urb_state = URB_NOTREADY;
  1509. }
  1510. }
  1511. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
  1512. }
  1513. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_DTERR))
  1514. {
  1515. hhcd->hc[chnum].state = HC_DATATGLERR;
  1516. (void)USB_HC_Halt(hhcd->Instance, chnum);
  1517. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
  1518. }
  1519. else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_CHH))
  1520. {
  1521. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
  1522. if (hhcd->hc[chnum].state == HC_XFRC)
  1523. {
  1524. hhcd->hc[chnum].state = HC_HALTED;
  1525. hhcd->hc[chnum].urb_state = URB_DONE;
  1526. if ((hhcd->hc[chnum].ep_type == EP_TYPE_BULK) ||
  1527. (hhcd->hc[chnum].ep_type == EP_TYPE_INTR))
  1528. {
  1529. if (hhcd->Init.dma_enable == 0U)
  1530. {
  1531. hhcd->hc[chnum].toggle_out ^= 1U;
  1532. }
  1533. if ((hhcd->Init.dma_enable == 1U) && (hhcd->hc[chnum].xfer_len > 0U))
  1534. {
  1535. num_packets = (hhcd->hc[chnum].xfer_len + hhcd->hc[chnum].max_packet - 1U) / hhcd->hc[chnum].max_packet;
  1536. if ((num_packets & 1U) != 0U)
  1537. {
  1538. hhcd->hc[chnum].toggle_out ^= 1U;
  1539. }
  1540. }
  1541. }
  1542. }
  1543. else if (hhcd->hc[chnum].state == HC_ACK)
  1544. {
  1545. hhcd->hc[chnum].state = HC_HALTED;
  1546. if (hhcd->hc[chnum].do_csplit == 1U)
  1547. {
  1548. hhcd->hc[chnum].urb_state = URB_NOTREADY;
  1549. }
  1550. }
  1551. else if (hhcd->hc[chnum].state == HC_NAK)
  1552. {
  1553. hhcd->hc[chnum].state = HC_HALTED;
  1554. hhcd->hc[chnum].urb_state = URB_NOTREADY;
  1555. if (hhcd->hc[chnum].do_csplit == 1U)
  1556. {
  1557. hhcd->hc[chnum].do_csplit = 0U;
  1558. __HAL_HCD_CLEAR_HC_CSPLT(chnum);
  1559. }
  1560. }
  1561. else if (hhcd->hc[chnum].state == HC_NYET)
  1562. {
  1563. hhcd->hc[chnum].state = HC_HALTED;
  1564. hhcd->hc[chnum].urb_state = URB_NOTREADY;
  1565. }
  1566. else if (hhcd->hc[chnum].state == HC_STALL)
  1567. {
  1568. hhcd->hc[chnum].state = HC_HALTED;
  1569. hhcd->hc[chnum].urb_state = URB_STALL;
  1570. }
  1571. else if ((hhcd->hc[chnum].state == HC_XACTERR) ||
  1572. (hhcd->hc[chnum].state == HC_DATATGLERR))
  1573. {
  1574. hhcd->hc[chnum].state = HC_HALTED;
  1575. hhcd->hc[chnum].ErrCnt++;
  1576. if (hhcd->hc[chnum].ErrCnt > 2U)
  1577. {
  1578. hhcd->hc[chnum].ErrCnt = 0U;
  1579. hhcd->hc[chnum].urb_state = URB_ERROR;
  1580. }
  1581. else
  1582. {
  1583. hhcd->hc[chnum].urb_state = URB_NOTREADY;
  1584. /* re-activate the channel */
  1585. tmpreg = USBx_HC(chnum)->HCCHAR;
  1586. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1587. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1588. USBx_HC(chnum)->HCCHAR = tmpreg;
  1589. }
  1590. }
  1591. else
  1592. {
  1593. return;
  1594. }
  1595. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1596. hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  1597. #else
  1598. HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  1599. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1600. }
  1601. else
  1602. {
  1603. return;
  1604. }
  1605. }
  1606. /**
  1607. * @brief Handle Rx Queue Level interrupt requests.
  1608. * @param hhcd HCD handle
  1609. * @retval none
  1610. */
  1611. static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd)
  1612. {
  1613. const USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1614. uint32_t USBx_BASE = (uint32_t)USBx;
  1615. uint32_t pktsts;
  1616. uint32_t pktcnt;
  1617. uint32_t GrxstspReg;
  1618. uint32_t xferSizePktCnt;
  1619. uint32_t tmpreg;
  1620. uint32_t chnum;
  1621. GrxstspReg = hhcd->Instance->GRXSTSP;
  1622. chnum = GrxstspReg & USB_OTG_GRXSTSP_EPNUM;
  1623. pktsts = (GrxstspReg & USB_OTG_GRXSTSP_PKTSTS) >> 17;
  1624. pktcnt = (GrxstspReg & USB_OTG_GRXSTSP_BCNT) >> 4;
  1625. switch (pktsts)
  1626. {
  1627. case GRXSTS_PKTSTS_IN:
  1628. /* Read the data into the host buffer. */
  1629. if ((pktcnt > 0U) && (hhcd->hc[chnum].xfer_buff != (void *)0))
  1630. {
  1631. if ((hhcd->hc[chnum].xfer_count + pktcnt) <= hhcd->hc[chnum].xfer_len)
  1632. {
  1633. (void)USB_ReadPacket(hhcd->Instance,
  1634. hhcd->hc[chnum].xfer_buff, (uint16_t)pktcnt);
  1635. /* manage multiple Xfer */
  1636. hhcd->hc[chnum].xfer_buff += pktcnt;
  1637. hhcd->hc[chnum].xfer_count += pktcnt;
  1638. /* get transfer size packet count */
  1639. xferSizePktCnt = (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19;
  1640. if ((hhcd->hc[chnum].max_packet == pktcnt) && (xferSizePktCnt > 0U))
  1641. {
  1642. /* re-activate the channel when more packets are expected */
  1643. tmpreg = USBx_HC(chnum)->HCCHAR;
  1644. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1645. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1646. USBx_HC(chnum)->HCCHAR = tmpreg;
  1647. hhcd->hc[chnum].toggle_in ^= 1U;
  1648. }
  1649. }
  1650. else
  1651. {
  1652. hhcd->hc[chnum].urb_state = URB_ERROR;
  1653. }
  1654. }
  1655. break;
  1656. case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
  1657. break;
  1658. case GRXSTS_PKTSTS_IN_XFER_COMP:
  1659. case GRXSTS_PKTSTS_CH_HALTED:
  1660. default:
  1661. break;
  1662. }
  1663. }
  1664. /**
  1665. * @brief Handle Host Port interrupt requests.
  1666. * @param hhcd HCD handle
  1667. * @retval None
  1668. */
  1669. static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd)
  1670. {
  1671. const USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1672. uint32_t USBx_BASE = (uint32_t)USBx;
  1673. __IO uint32_t hprt0;
  1674. __IO uint32_t hprt0_dup;
  1675. /* Handle Host Port Interrupts */
  1676. hprt0 = USBx_HPRT0;
  1677. hprt0_dup = USBx_HPRT0;
  1678. hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | \
  1679. USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
  1680. /* Check whether Port Connect detected */
  1681. if ((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
  1682. {
  1683. if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
  1684. {
  1685. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1686. hhcd->ConnectCallback(hhcd);
  1687. #else
  1688. HAL_HCD_Connect_Callback(hhcd);
  1689. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1690. }
  1691. hprt0_dup |= USB_OTG_HPRT_PCDET;
  1692. }
  1693. /* Check whether Port Enable Changed */
  1694. if ((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
  1695. {
  1696. hprt0_dup |= USB_OTG_HPRT_PENCHNG;
  1697. if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
  1698. {
  1699. if (hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
  1700. {
  1701. if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17))
  1702. {
  1703. (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_6_MHZ);
  1704. }
  1705. else
  1706. {
  1707. (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
  1708. }
  1709. }
  1710. else
  1711. {
  1712. if (hhcd->Init.speed == HCD_SPEED_FULL)
  1713. {
  1714. USBx_HOST->HFIR = HFIR_60_MHZ;
  1715. }
  1716. }
  1717. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1718. hhcd->PortEnabledCallback(hhcd);
  1719. #else
  1720. HAL_HCD_PortEnabled_Callback(hhcd);
  1721. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1722. }
  1723. else
  1724. {
  1725. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1726. hhcd->PortDisabledCallback(hhcd);
  1727. #else
  1728. HAL_HCD_PortDisabled_Callback(hhcd);
  1729. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1730. }
  1731. }
  1732. /* Check for an overcurrent */
  1733. if ((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
  1734. {
  1735. hprt0_dup |= USB_OTG_HPRT_POCCHNG;
  1736. }
  1737. /* Clear Port Interrupts */
  1738. USBx_HPRT0 = hprt0_dup;
  1739. }
  1740. /**
  1741. * @}
  1742. */
  1743. /**
  1744. * @}
  1745. */
  1746. #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
  1747. #endif /* HAL_HCD_MODULE_ENABLED */
  1748. /**
  1749. * @}
  1750. */
  1751. /**
  1752. * @}
  1753. */