stm32f4xx_hal_hcd.c 34 KB

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