stm32h7xx_hal_hcd.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199
  1. /**
  2. ******************************************************************************
  3. * @file stm32h7xx_hal_hcd.c
  4. * @author MCD Application Team
  5. * @version V1.0.0
  6. * @date 21-April-2017
  7. * @brief HCD HAL module driver.
  8. * This file provides firmware functions to manage the following
  9. * functionalities of the USB Peripheral Controller:
  10. * + Initialization and de-initialization functions
  11. * + IO operation functions
  12. * + Peripheral Control functions
  13. * + Peripheral State functions
  14. *
  15. @verbatim
  16. ==============================================================================
  17. ##### How to use this driver #####
  18. ==============================================================================
  19. [..]
  20. (#)Declare a HCD_HandleTypeDef handle structure, for example:
  21. HCD_HandleTypeDef hhcd;
  22. (#)Fill parameters of Init structure in HCD handle
  23. (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...)
  24. (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API:
  25. (##) Enable the HCD/USB Low Level interface clock using the following macros
  26. (+++) __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) 2017 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 "stm32h7xx_hal.h"
  67. /** @addtogroup STM32H7xx_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_HCD_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_HCD_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 management 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. hhcd->hc[chnum].state = HC_NAK;
  794. __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  795. if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
  796. (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
  797. {
  798. /* re-activate the channel */
  799. USBx_HC(chnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHDIS;
  800. USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
  801. }
  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****/