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.
 
 
 

1798 lines
50 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32f7xx_ll_usb.c
  4. * @author MCD Application Team
  5. * @version V1.2.2
  6. * @date 14-April-2017
  7. * @brief USB Low Layer HAL module driver.
  8. *
  9. * This file provides firmware functions to manage the following
  10. * functionalities of the USB Peripheral Controller:
  11. * + Initialization/de-initialization functions
  12. * + I/O operation functions
  13. * + Peripheral Control functions
  14. * + Peripheral State functions
  15. *
  16. @verbatim
  17. ==============================================================================
  18. ##### How to use this driver #####
  19. ==============================================================================
  20. [..]
  21. (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure.
  22. (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
  23. (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
  24. @endverbatim
  25. ******************************************************************************
  26. * @attention
  27. *
  28. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  29. *
  30. * Redistribution and use in source and binary forms, with or without modification,
  31. * are permitted provided that the following conditions are met:
  32. * 1. Redistributions of source code must retain the above copyright notice,
  33. * this list of conditions and the following disclaimer.
  34. * 2. Redistributions in binary form must reproduce the above copyright notice,
  35. * this list of conditions and the following disclaimer in the documentation
  36. * and/or other materials provided with the distribution.
  37. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  38. * may be used to endorse or promote products derived from this software
  39. * without specific prior written permission.
  40. *
  41. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  42. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  44. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  45. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  47. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  48. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  49. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  50. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  51. *
  52. ******************************************************************************
  53. */
  54. /* Includes ------------------------------------------------------------------*/
  55. #include "stm32f7xx_hal.h"
  56. /** @addtogroup STM32F7xx_LL_USB_DRIVER
  57. * @{
  58. */
  59. #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
  60. /* Private typedef -----------------------------------------------------------*/
  61. /* Private define ------------------------------------------------------------*/
  62. /* Private macro -------------------------------------------------------------*/
  63. /* Private variables ---------------------------------------------------------*/
  64. /* Private function prototypes -----------------------------------------------*/
  65. /* Private functions ---------------------------------------------------------*/
  66. static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
  67. #ifdef USB_HS_PHYC
  68. static HAL_StatusTypeDef USB_HS_PHYCInit(USB_OTG_GlobalTypeDef *USBx);
  69. #endif
  70. /* Exported functions --------------------------------------------------------*/
  71. /** @defgroup LL_USB_Exported_Functions USB Low Layer Exported Functions
  72. * @{
  73. */
  74. /** @defgroup LL_USB_Group1 Initialization/de-initialization functions
  75. * @brief Initialization and Configuration functions
  76. *
  77. @verbatim
  78. ===============================================================================
  79. ##### Initialization/de-initialization functions #####
  80. ===============================================================================
  81. [..] This section provides functions allowing to:
  82. @endverbatim
  83. * @{
  84. */
  85. /**
  86. * @brief Initializes the USB Core
  87. * @param USBx: USB Instance
  88. * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
  89. * the configuration information for the specified USBx peripheral.
  90. * @retval HAL status
  91. */
  92. HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
  93. {
  94. if (cfg.phy_itface == USB_OTG_ULPI_PHY)
  95. {
  96. USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
  97. /* Init The ULPI Interface */
  98. USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
  99. /* Select vbus source */
  100. USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
  101. if(cfg.use_external_vbus == 1)
  102. {
  103. USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
  104. }
  105. /* Reset after a PHY select */
  106. USB_CoreReset(USBx);
  107. }
  108. #ifdef USB_HS_PHYC
  109. else if (cfg.phy_itface == USB_OTG_HS_EMBEDDED_PHY)
  110. {
  111. USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
  112. /* Init The UTMI Interface */
  113. USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
  114. /* Select vbus source */
  115. USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
  116. /* Select UTMI Interace */
  117. USBx->GUSBCFG &= ~ USB_OTG_GUSBCFG_ULPI_UTMI_SEL;
  118. USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;
  119. /* Enables control of a High Speed USB PHY */
  120. USB_HS_PHYCInit(USBx);
  121. if(cfg.use_external_vbus == 1)
  122. {
  123. USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
  124. }
  125. /* Reset after a PHY select */
  126. USB_CoreReset(USBx);
  127. }
  128. #endif
  129. else /* FS interface (embedded Phy) */
  130. {
  131. /* Select FS Embedded PHY */
  132. USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
  133. /* Reset after a PHY select and set Host mode */
  134. USB_CoreReset(USBx);
  135. /* Deactivate the power down*/
  136. USBx->GCCFG = USB_OTG_GCCFG_PWRDWN;
  137. }
  138. if(cfg.dma_enable == ENABLE)
  139. {
  140. USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2;
  141. USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
  142. }
  143. return HAL_OK;
  144. }
  145. /**
  146. * @brief USB_EnableGlobalInt
  147. * Enables the controller's Global Int in the AHB Config reg
  148. * @param USBx : Selected device
  149. * @retval HAL status
  150. */
  151. HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
  152. {
  153. USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
  154. return HAL_OK;
  155. }
  156. /**
  157. * @brief USB_DisableGlobalInt
  158. * Disable the controller's Global Int in the AHB Config reg
  159. * @param USBx : Selected device
  160. * @retval HAL status
  161. */
  162. HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
  163. {
  164. USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
  165. return HAL_OK;
  166. }
  167. /**
  168. * @brief USB_SetCurrentMode : Set functional mode
  169. * @param USBx : Selected device
  170. * @param mode : current core mode
  171. * This parameter can be one of these values:
  172. * @arg USB_OTG_DEVICE_MODE: Peripheral mode
  173. * @arg USB_OTG_HOST_MODE: Host mode
  174. * @arg USB_OTG_DRD_MODE: Dual Role Device mode
  175. * @retval HAL status
  176. */
  177. HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx , USB_OTG_ModeTypeDef mode)
  178. {
  179. USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
  180. if ( mode == USB_OTG_HOST_MODE)
  181. {
  182. USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
  183. }
  184. else if ( mode == USB_OTG_DEVICE_MODE)
  185. {
  186. USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
  187. }
  188. HAL_Delay(50);
  189. return HAL_OK;
  190. }
  191. /**
  192. * @brief USB_DevInit : Initializes the USB_OTG controller registers
  193. * for device mode
  194. * @param USBx : Selected device
  195. * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
  196. * the configuration information for the specified USBx peripheral.
  197. * @retval HAL status
  198. */
  199. HAL_StatusTypeDef USB_DevInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
  200. {
  201. uint32_t i = 0;
  202. /*Activate VBUS Sensing B */
  203. USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
  204. if (cfg.vbus_sensing_enable == 0)
  205. {
  206. /* Deactivate VBUS Sensing B */
  207. USBx->GCCFG &= ~ USB_OTG_GCCFG_VBDEN;
  208. /* B-peripheral session valid override enable*/
  209. USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
  210. USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
  211. }
  212. /* Restart the Phy Clock */
  213. USBx_PCGCCTL = 0;
  214. /* Device mode configuration */
  215. USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80;
  216. if(cfg.phy_itface == USB_OTG_ULPI_PHY)
  217. {
  218. if(cfg.speed == USB_OTG_SPEED_HIGH)
  219. {
  220. /* Set High speed phy */
  221. USB_SetDevSpeed (USBx , USB_OTG_SPEED_HIGH);
  222. }
  223. else
  224. {
  225. /* set High speed phy in Full speed mode */
  226. USB_SetDevSpeed (USBx , USB_OTG_SPEED_HIGH_IN_FULL);
  227. }
  228. }
  229. else if(cfg.phy_itface == USB_OTG_HS_EMBEDDED_PHY)
  230. {
  231. if(cfg.speed == USB_OTG_SPEED_HIGH)
  232. {
  233. /* Set High speed phy */
  234. USB_SetDevSpeed (USBx , USB_OTG_SPEED_HIGH);
  235. }
  236. else
  237. {
  238. /* set High speed phy in Full speed mode */
  239. USB_SetDevSpeed (USBx , USB_OTG_SPEED_HIGH_IN_FULL);
  240. }
  241. }
  242. else
  243. {
  244. /* Set Full speed phy */
  245. USB_SetDevSpeed (USBx , USB_OTG_SPEED_FULL);
  246. }
  247. /* Flush the FIFOs */
  248. USB_FlushTxFifo(USBx , 0x10); /* all Tx FIFOs */
  249. USB_FlushRxFifo(USBx);
  250. /* Clear all pending Device Interrupts */
  251. USBx_DEVICE->DIEPMSK = 0;
  252. USBx_DEVICE->DOEPMSK = 0;
  253. USBx_DEVICE->DAINT = 0xFFFFFFFF;
  254. USBx_DEVICE->DAINTMSK = 0;
  255. for (i = 0; i < cfg.dev_endpoints; i++)
  256. {
  257. if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
  258. {
  259. USBx_INEP(i)->DIEPCTL = (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK);
  260. }
  261. else
  262. {
  263. USBx_INEP(i)->DIEPCTL = 0;
  264. }
  265. USBx_INEP(i)->DIEPTSIZ = 0;
  266. USBx_INEP(i)->DIEPINT = 0xFF;
  267. }
  268. for (i = 0; i < cfg.dev_endpoints; i++)
  269. {
  270. if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
  271. {
  272. USBx_OUTEP(i)->DOEPCTL = (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK);
  273. }
  274. else
  275. {
  276. USBx_OUTEP(i)->DOEPCTL = 0;
  277. }
  278. USBx_OUTEP(i)->DOEPTSIZ = 0;
  279. USBx_OUTEP(i)->DOEPINT = 0xFF;
  280. }
  281. USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
  282. if (cfg.dma_enable == 1)
  283. {
  284. /*Set threshold parameters */
  285. USBx_DEVICE->DTHRCTL = (USB_OTG_DTHRCTL_TXTHRLEN_6 | USB_OTG_DTHRCTL_RXTHRLEN_6);
  286. USBx_DEVICE->DTHRCTL |= (USB_OTG_DTHRCTL_RXTHREN | USB_OTG_DTHRCTL_ISOTHREN | USB_OTG_DTHRCTL_NONISOTHREN);
  287. i= USBx_DEVICE->DTHRCTL;
  288. }
  289. /* Disable all interrupts. */
  290. USBx->GINTMSK = 0;
  291. /* Clear any pending interrupts */
  292. USBx->GINTSTS = 0xBFFFFFFF;
  293. /* Enable the common interrupts */
  294. if (cfg.dma_enable == DISABLE)
  295. {
  296. USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
  297. }
  298. /* Enable interrupts matching to the Device mode ONLY */
  299. USBx->GINTMSK |= (USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |\
  300. USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |\
  301. USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM|\
  302. USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
  303. if(cfg.Sof_enable)
  304. {
  305. USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
  306. }
  307. if (cfg.vbus_sensing_enable == ENABLE)
  308. {
  309. USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
  310. }
  311. return HAL_OK;
  312. }
  313. /**
  314. * @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO
  315. * @param USBx : Selected device
  316. * @param num : FIFO number
  317. * This parameter can be a value from 1 to 15
  318. 15 means Flush all Tx FIFOs
  319. * @retval HAL status
  320. */
  321. HAL_StatusTypeDef USB_FlushTxFifo (USB_OTG_GlobalTypeDef *USBx, uint32_t num )
  322. {
  323. uint32_t count = 0;
  324. USBx->GRSTCTL = ( USB_OTG_GRSTCTL_TXFFLSH |(uint32_t)( num << 6));
  325. do
  326. {
  327. if (++count > 200000)
  328. {
  329. return HAL_TIMEOUT;
  330. }
  331. }
  332. while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
  333. return HAL_OK;
  334. }
  335. /**
  336. * @brief USB_FlushRxFifo : Flush Rx FIFO
  337. * @param USBx : Selected device
  338. * @retval HAL status
  339. */
  340. HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
  341. {
  342. uint32_t count = 0;
  343. USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
  344. do
  345. {
  346. if (++count > 200000)
  347. {
  348. return HAL_TIMEOUT;
  349. }
  350. }
  351. while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
  352. return HAL_OK;
  353. }
  354. /**
  355. * @brief USB_SetDevSpeed :Initializes the DevSpd field of DCFG register
  356. * depending the PHY type and the enumeration speed of the device.
  357. * @param USBx : Selected device
  358. * @param speed : device speed
  359. * This parameter can be one of these values:
  360. * @arg USB_OTG_SPEED_HIGH: High speed mode
  361. * @arg USB_OTG_SPEED_HIGH_IN_FULL: High speed core in Full Speed mode
  362. * @arg USB_OTG_SPEED_FULL: Full speed mode
  363. * @arg USB_OTG_SPEED_LOW: Low speed mode
  364. * @retval Hal status
  365. */
  366. HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx , uint8_t speed)
  367. {
  368. USBx_DEVICE->DCFG |= speed;
  369. return HAL_OK;
  370. }
  371. /**
  372. * @brief USB_GetDevSpeed :Return the Dev Speed
  373. * @param USBx : Selected device
  374. * @retval speed : device speed
  375. * This parameter can be one of these values:
  376. * @arg USB_OTG_SPEED_HIGH: High speed mode
  377. * @arg USB_OTG_SPEED_FULL: Full speed mode
  378. * @arg USB_OTG_SPEED_LOW: Low speed mode
  379. */
  380. uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx)
  381. {
  382. uint8_t speed = 0;
  383. if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ)
  384. {
  385. speed = USB_OTG_SPEED_HIGH;
  386. }
  387. else if (((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ)||
  388. ((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_48MHZ))
  389. {
  390. speed = USB_OTG_SPEED_FULL;
  391. }
  392. else if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ)
  393. {
  394. speed = USB_OTG_SPEED_LOW;
  395. }
  396. return speed;
  397. }
  398. /**
  399. * @brief Activate and configure an endpoint
  400. * @param USBx : Selected device
  401. * @param ep: pointer to endpoint structure
  402. * @retval HAL status
  403. */
  404. HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
  405. {
  406. if (ep->is_in == 1)
  407. {
  408. USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)));
  409. if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0)
  410. {
  411. USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\
  412. ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP));
  413. }
  414. }
  415. else
  416. {
  417. USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16);
  418. if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0)
  419. {
  420. USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\
  421. (USB_OTG_DIEPCTL_SD0PID_SEVNFRM)| (USB_OTG_DOEPCTL_USBAEP));
  422. }
  423. }
  424. return HAL_OK;
  425. }
  426. /**
  427. * @brief Activate and configure a dedicated endpoint
  428. * @param USBx : Selected device
  429. * @param ep: pointer to endpoint structure
  430. * @retval HAL status
  431. */
  432. HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
  433. {
  434. static __IO uint32_t debug = 0;
  435. /* Read DEPCTLn register */
  436. if (ep->is_in == 1)
  437. {
  438. if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0)
  439. {
  440. USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\
  441. ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP));
  442. }
  443. debug |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\
  444. ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP));
  445. USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)));
  446. }
  447. else
  448. {
  449. if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0)
  450. {
  451. USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\
  452. ((ep->num) << 22 ) | (USB_OTG_DOEPCTL_USBAEP));
  453. debug = (uint32_t)(((uint32_t )USBx) + USB_OTG_OUT_ENDPOINT_BASE + (0)*USB_OTG_EP_REG_SIZE);
  454. debug = (uint32_t )&USBx_OUTEP(ep->num)->DOEPCTL;
  455. debug |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\
  456. ((ep->num) << 22 ) | (USB_OTG_DOEPCTL_USBAEP));
  457. }
  458. USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16);
  459. }
  460. return HAL_OK;
  461. }
  462. /**
  463. * @brief De-activate and de-initialize an endpoint
  464. * @param USBx : Selected device
  465. * @param ep: pointer to endpoint structure
  466. * @retval HAL status
  467. */
  468. HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
  469. {
  470. /* Read DEPCTLn register */
  471. if (ep->is_in == 1)
  472. {
  473. USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))));
  474. USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))));
  475. USBx_INEP(ep->num)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
  476. }
  477. else
  478. {
  479. USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));
  480. USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));
  481. USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
  482. }
  483. return HAL_OK;
  484. }
  485. /**
  486. * @brief De-activate and de-initialize a dedicated endpoint
  487. * @param USBx : Selected device
  488. * @param ep: pointer to endpoint structure
  489. * @retval HAL status
  490. */
  491. HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
  492. {
  493. /* Read DEPCTLn register */
  494. if (ep->is_in == 1)
  495. {
  496. USBx_INEP(ep->num)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
  497. USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))));
  498. }
  499. else
  500. {
  501. USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
  502. USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));
  503. }
  504. return HAL_OK;
  505. }
  506. /**
  507. * @brief USB_EPStartXfer : setup and starts a transfer over an EP
  508. * @param USBx : Selected device
  509. * @param ep: pointer to endpoint structure
  510. * @param dma: USB dma enabled or disabled
  511. * This parameter can be one of these values:
  512. * 0 : DMA feature not used
  513. * 1 : DMA feature used
  514. * @retval HAL status
  515. */
  516. HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma)
  517. {
  518. uint16_t pktcnt = 0;
  519. /* IN endpoint */
  520. if (ep->is_in == 1)
  521. {
  522. /* Zero Length Packet? */
  523. if (ep->xfer_len == 0)
  524. {
  525. USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
  526. USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ;
  527. USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
  528. }
  529. else
  530. {
  531. /* Program the transfer size and packet count
  532. * as follows: xfersize = N * maxpacket +
  533. * short_packet pktcnt = N + (short_packet
  534. * exist ? 1 : 0)
  535. */
  536. USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
  537. USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
  538. USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket) << 19)) ;
  539. USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
  540. if (ep->type == EP_TYPE_ISOC)
  541. {
  542. USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
  543. USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1 << 29));
  544. }
  545. }
  546. if (dma == 1)
  547. {
  548. USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr);
  549. }
  550. else
  551. {
  552. if (ep->type != EP_TYPE_ISOC)
  553. {
  554. /* Enable the Tx FIFO Empty Interrupt for this EP */
  555. if (ep->xfer_len > 0)
  556. {
  557. USBx_DEVICE->DIEPEMPMSK |= 1 << ep->num;
  558. }
  559. }
  560. }
  561. if (ep->type == EP_TYPE_ISOC)
  562. {
  563. if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0)
  564. {
  565. USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
  566. }
  567. else
  568. {
  569. USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
  570. }
  571. }
  572. /* EP enable, IN data in FIFO */
  573. USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
  574. if (ep->type == EP_TYPE_ISOC)
  575. {
  576. USB_WritePacket(USBx, ep->xfer_buff, ep->num, ep->xfer_len, dma);
  577. }
  578. }
  579. else /* OUT endpoint */
  580. {
  581. /* Program the transfer size and packet count as follows:
  582. * pktcnt = N
  583. * xfersize = N * maxpacket
  584. */
  585. USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
  586. USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
  587. if (ep->xfer_len == 0)
  588. {
  589. USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
  590. USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) ;
  591. }
  592. else
  593. {
  594. pktcnt = (ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket;
  595. USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19));
  596. USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt));
  597. }
  598. if (dma == 1)
  599. {
  600. USBx_OUTEP(ep->num)->DOEPDMA = (uint32_t)ep->xfer_buff;
  601. }
  602. if (ep->type == EP_TYPE_ISOC)
  603. {
  604. if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0)
  605. {
  606. USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
  607. }
  608. else
  609. {
  610. USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
  611. }
  612. }
  613. /* EP enable */
  614. USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
  615. }
  616. return HAL_OK;
  617. }
  618. /**
  619. * @brief USB_EP0StartXfer : setup and starts a transfer over the EP 0
  620. * @param USBx : Selected device
  621. * @param ep: pointer to endpoint structure
  622. * @param dma: USB dma enabled or disabled
  623. * This parameter can be one of these values:
  624. * 0 : DMA feature not used
  625. * 1 : DMA feature used
  626. * @retval HAL status
  627. */
  628. HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma)
  629. {
  630. /* IN endpoint */
  631. if (ep->is_in == 1)
  632. {
  633. /* Zero Length Packet? */
  634. if (ep->xfer_len == 0)
  635. {
  636. USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
  637. USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ;
  638. USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
  639. }
  640. else
  641. {
  642. /* Program the transfer size and packet count
  643. * as follows: xfersize = N * maxpacket +
  644. * short_packet pktcnt = N + (short_packet
  645. * exist ? 1 : 0)
  646. */
  647. USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
  648. USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
  649. if(ep->xfer_len > ep->maxpacket)
  650. {
  651. ep->xfer_len = ep->maxpacket;
  652. }
  653. USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ;
  654. USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
  655. }
  656. /* EP enable, IN data in FIFO */
  657. USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
  658. if (dma == 1)
  659. {
  660. USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr);
  661. }
  662. else
  663. {
  664. /* Enable the Tx FIFO Empty Interrupt for this EP */
  665. if (ep->xfer_len > 0U)
  666. {
  667. USBx_DEVICE->DIEPEMPMSK |= 1U << (ep->num);
  668. }
  669. }
  670. }
  671. else /* OUT endpoint */
  672. {
  673. /* Program the transfer size and packet count as follows:
  674. * pktcnt = N
  675. * xfersize = N * maxpacket
  676. */
  677. USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
  678. USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
  679. if (ep->xfer_len > 0)
  680. {
  681. ep->xfer_len = ep->maxpacket;
  682. }
  683. USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));
  684. USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket));
  685. if (dma == 1)
  686. {
  687. USBx_OUTEP(ep->num)->DOEPDMA = (uint32_t)(ep->xfer_buff);
  688. }
  689. /* EP enable */
  690. USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
  691. }
  692. return HAL_OK;
  693. }
  694. /**
  695. * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
  696. * with the EP/channel
  697. * @param USBx : Selected device
  698. * @param src : pointer to source buffer
  699. * @param ch_ep_num : endpoint or host channel number
  700. * @param len : Number of bytes to write
  701. * @param dma: USB dma enabled or disabled
  702. * This parameter can be one of these values:
  703. * 0 : DMA feature not used
  704. * 1 : DMA feature used
  705. * @retval HAL status
  706. */
  707. HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len, uint8_t dma)
  708. {
  709. uint32_t count32b= 0 , i= 0;
  710. if (dma == 0)
  711. {
  712. count32b = (len + 3) / 4;
  713. for (i = 0; i < count32b; i++, src += 4)
  714. {
  715. USBx_DFIFO(ch_ep_num) = *((__packed uint32_t *)src);
  716. }
  717. }
  718. return HAL_OK;
  719. }
  720. /**
  721. * @brief USB_ReadPacket : read a packet from the Tx FIFO associated
  722. * with the EP/channel
  723. * @param USBx : Selected device
  724. * @param src : source pointer
  725. * @param ch_ep_num : endpoint or host channel number
  726. * @param len : Number of bytes to read
  727. * @param dma: USB dma enabled or disabled
  728. * This parameter can be one of these values:
  729. * 0 : DMA feature not used
  730. * 1 : DMA feature used
  731. * @retval pointer to destination buffer
  732. */
  733. void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
  734. {
  735. uint32_t i=0;
  736. uint32_t count32b = (len + 3) / 4;
  737. for ( i = 0; i < count32b; i++, dest += 4 )
  738. {
  739. *(__packed uint32_t *)dest = USBx_DFIFO(0);
  740. }
  741. return ((void *)dest);
  742. }
  743. /**
  744. * @brief USB_EPSetStall : set a stall condition over an EP
  745. * @param USBx : Selected device
  746. * @param ep: pointer to endpoint structure
  747. * @retval HAL status
  748. */
  749. HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep)
  750. {
  751. if (ep->is_in == 1)
  752. {
  753. if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == 0)
  754. {
  755. USBx_INEP(ep->num)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
  756. }
  757. USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
  758. }
  759. else
  760. {
  761. if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == 0)
  762. {
  763. USBx_OUTEP(ep->num)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
  764. }
  765. USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
  766. }
  767. return HAL_OK;
  768. }
  769. /**
  770. * @brief USB_EPClearStall : Clear a stall condition over an EP
  771. * @param USBx : Selected device
  772. * @param ep: pointer to endpoint structure
  773. * @retval HAL status
  774. */
  775. HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
  776. {
  777. if (ep->is_in == 1)
  778. {
  779. USBx_INEP(ep->num)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
  780. if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
  781. {
  782. USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
  783. }
  784. }
  785. else
  786. {
  787. USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
  788. if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
  789. {
  790. USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
  791. }
  792. }
  793. return HAL_OK;
  794. }
  795. /**
  796. * @brief USB_StopDevice : Stop the usb device mode
  797. * @param USBx : Selected device
  798. * @retval HAL status
  799. */
  800. HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
  801. {
  802. uint32_t i;
  803. /* Clear Pending interrupt */
  804. for (i = 0; i < 15 ; i++)
  805. {
  806. USBx_INEP(i)->DIEPINT = 0xFF;
  807. USBx_OUTEP(i)->DOEPINT = 0xFF;
  808. }
  809. USBx_DEVICE->DAINT = 0xFFFFFFFF;
  810. /* Clear interrupt masks */
  811. USBx_DEVICE->DIEPMSK = 0;
  812. USBx_DEVICE->DOEPMSK = 0;
  813. USBx_DEVICE->DAINTMSK = 0;
  814. /* Flush the FIFO */
  815. USB_FlushRxFifo(USBx);
  816. USB_FlushTxFifo(USBx , 0x10 );
  817. return HAL_OK;
  818. }
  819. /**
  820. * @brief USB_SetDevAddress : Stop the usb device mode
  821. * @param USBx : Selected device
  822. * @param address : new device address to be assigned
  823. * This parameter can be a value from 0 to 255
  824. * @retval HAL status
  825. */
  826. HAL_StatusTypeDef USB_SetDevAddress (USB_OTG_GlobalTypeDef *USBx, uint8_t address)
  827. {
  828. USBx_DEVICE->DCFG &= ~ (USB_OTG_DCFG_DAD);
  829. USBx_DEVICE->DCFG |= (address << 4) & USB_OTG_DCFG_DAD ;
  830. return HAL_OK;
  831. }
  832. /**
  833. * @brief USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down
  834. * @param USBx : Selected device
  835. * @retval HAL status
  836. */
  837. HAL_StatusTypeDef USB_DevConnect (USB_OTG_GlobalTypeDef *USBx)
  838. {
  839. USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS ;
  840. HAL_Delay(3);
  841. return HAL_OK;
  842. }
  843. /**
  844. * @brief USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down
  845. * @param USBx : Selected device
  846. * @retval HAL status
  847. */
  848. HAL_StatusTypeDef USB_DevDisconnect (USB_OTG_GlobalTypeDef *USBx)
  849. {
  850. USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS ;
  851. HAL_Delay(3);
  852. return HAL_OK;
  853. }
  854. /**
  855. * @brief USB_ReadInterrupts: return the global USB interrupt status
  856. * @param USBx : Selected device
  857. * @retval HAL status
  858. */
  859. uint32_t USB_ReadInterrupts (USB_OTG_GlobalTypeDef *USBx)
  860. {
  861. uint32_t v = 0;
  862. v = USBx->GINTSTS;
  863. v &= USBx->GINTMSK;
  864. return v;
  865. }
  866. /**
  867. * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
  868. * @param USBx : Selected device
  869. * @retval HAL status
  870. */
  871. uint32_t USB_ReadDevAllOutEpInterrupt (USB_OTG_GlobalTypeDef *USBx)
  872. {
  873. uint32_t v;
  874. v = USBx_DEVICE->DAINT;
  875. v &= USBx_DEVICE->DAINTMSK;
  876. return ((v & 0xffff0000) >> 16);
  877. }
  878. /**
  879. * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
  880. * @param USBx : Selected device
  881. * @retval HAL status
  882. */
  883. uint32_t USB_ReadDevAllInEpInterrupt (USB_OTG_GlobalTypeDef *USBx)
  884. {
  885. uint32_t v;
  886. v = USBx_DEVICE->DAINT;
  887. v &= USBx_DEVICE->DAINTMSK;
  888. return ((v & 0xFFFF));
  889. }
  890. /**
  891. * @brief Returns Device OUT EP Interrupt register
  892. * @param USBx : Selected device
  893. * @param epnum : endpoint number
  894. * This parameter can be a value from 0 to 15
  895. * @retval Device OUT EP Interrupt register
  896. */
  897. uint32_t USB_ReadDevOutEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)
  898. {
  899. uint32_t v;
  900. v = USBx_OUTEP(epnum)->DOEPINT;
  901. v &= USBx_DEVICE->DOEPMSK;
  902. return v;
  903. }
  904. /**
  905. * @brief Returns Device IN EP Interrupt register
  906. * @param USBx : Selected device
  907. * @param epnum : endpoint number
  908. * This parameter can be a value from 0 to 15
  909. * @retval Device IN EP Interrupt register
  910. */
  911. uint32_t USB_ReadDevInEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)
  912. {
  913. uint32_t v, msk, emp;
  914. msk = USBx_DEVICE->DIEPMSK;
  915. emp = USBx_DEVICE->DIEPEMPMSK;
  916. msk |= ((emp >> epnum) & 0x1) << 7;
  917. v = USBx_INEP(epnum)->DIEPINT & msk;
  918. return v;
  919. }
  920. /**
  921. * @brief USB_ClearInterrupts: clear a USB interrupt
  922. * @param USBx : Selected device
  923. * @param interrupt : interrupt flag
  924. * @retval None
  925. */
  926. void USB_ClearInterrupts (USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
  927. {
  928. USBx->GINTSTS |= interrupt;
  929. }
  930. /**
  931. * @brief Returns USB core mode
  932. * @param USBx : Selected device
  933. * @retval return core mode : Host or Device
  934. * This parameter can be one of these values:
  935. * 0 : Host
  936. * 1 : Device
  937. */
  938. uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx)
  939. {
  940. return ((USBx->GINTSTS ) & 0x1);
  941. }
  942. /**
  943. * @brief Activate EP0 for Setup transactions
  944. * @param USBx : Selected device
  945. * @retval HAL status
  946. */
  947. HAL_StatusTypeDef USB_ActivateSetup (USB_OTG_GlobalTypeDef *USBx)
  948. {
  949. /* Set the MPS of the IN EP based on the enumeration speed */
  950. USBx_INEP(0)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
  951. if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ)
  952. {
  953. USBx_INEP(0)->DIEPCTL |= 3;
  954. }
  955. USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
  956. return HAL_OK;
  957. }
  958. /**
  959. * @brief Prepare the EP0 to start the first control setup
  960. * @param USBx : Selected device
  961. * @param dma: USB dma enabled or disabled
  962. * This parameter can be one of these values:
  963. * 0 : DMA feature not used
  964. * 1 : DMA feature used
  965. * @param psetup : pointer to setup packet
  966. * @retval HAL status
  967. */
  968. HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t dma, uint8_t *psetup)
  969. {
  970. USBx_OUTEP(0)->DOEPTSIZ = 0;
  971. USBx_OUTEP(0)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) ;
  972. USBx_OUTEP(0)->DOEPTSIZ |= (3 * 8);
  973. USBx_OUTEP(0)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
  974. if (dma == 1)
  975. {
  976. USBx_OUTEP(0)->DOEPDMA = (uint32_t)psetup;
  977. /* EP enable */
  978. USBx_OUTEP(0)->DOEPCTL = 0x80008000;
  979. }
  980. return HAL_OK;
  981. }
  982. /**
  983. * @brief Reset the USB Core (needed after USB clock settings change)
  984. * @param USBx : Selected device
  985. * @retval HAL status
  986. */
  987. static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
  988. {
  989. uint32_t count = 0;
  990. /* Wait for AHB master IDLE state. */
  991. do
  992. {
  993. if (++count > 200000)
  994. {
  995. return HAL_TIMEOUT;
  996. }
  997. }
  998. while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0);
  999. /* Core Soft Reset */
  1000. count = 0;
  1001. USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
  1002. do
  1003. {
  1004. if (++count > 200000)
  1005. {
  1006. return HAL_TIMEOUT;
  1007. }
  1008. }
  1009. while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
  1010. return HAL_OK;
  1011. }
  1012. #ifdef USB_HS_PHYC
  1013. /**
  1014. * @brief Enables control of a High Speed USB PHY's
  1015. * Init the low level hardware : GPIO, CLOCK, NVIC...
  1016. * @param USBx : Selected device
  1017. * @retval HAL status
  1018. */
  1019. static HAL_StatusTypeDef USB_HS_PHYCInit(USB_OTG_GlobalTypeDef *USBx)
  1020. {
  1021. uint32_t count = 0;
  1022. /* Enable LDO */
  1023. USB_HS_PHYC->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE;
  1024. /* wait for LDO Ready */
  1025. while((USB_HS_PHYC->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) == RESET)
  1026. {
  1027. if (++count > 200000)
  1028. {
  1029. return HAL_TIMEOUT;
  1030. }
  1031. }
  1032. /* Controls PHY frequency operation selection */
  1033. if (HSE_VALUE == 12000000) /* HSE = 12MHz */
  1034. {
  1035. USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x0 << 1);
  1036. }
  1037. else if (HSE_VALUE == 12500000) /* HSE = 12.5MHz */
  1038. {
  1039. USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x2 << 1);
  1040. }
  1041. else if (HSE_VALUE == 16000000) /* HSE = 16MHz */
  1042. {
  1043. USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x3 << 1);
  1044. }
  1045. else if (HSE_VALUE == 24000000) /* HSE = 24MHz */
  1046. {
  1047. USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x4 << 1);
  1048. }
  1049. else if (HSE_VALUE == 25000000) /* HSE = 25MHz */
  1050. {
  1051. USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x5 << 1);
  1052. }
  1053. else if (HSE_VALUE == 32000000) /* HSE = 32MHz */
  1054. {
  1055. USB_HS_PHYC->USB_HS_PHYC_PLL = (uint32_t)(0x7 << 1);
  1056. }
  1057. /* Control the tuning interface of the High Speed PHY */
  1058. USB_HS_PHYC->USB_HS_PHYC_TUNE |= USB_HS_PHYC_TUNE_VALUE;
  1059. /* Enable PLL internal PHY */
  1060. USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN;
  1061. /* 2ms Delay required to get internal phy clock stable */
  1062. HAL_Delay(2);
  1063. return HAL_OK;
  1064. }
  1065. #endif /* USB_HS_PHYC */
  1066. /**
  1067. * @brief USB_HostInit : Initializes the USB OTG controller registers
  1068. * for Host mode
  1069. * @param USBx : Selected device
  1070. * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
  1071. * the configuration information for the specified USBx peripheral.
  1072. * @retval HAL status
  1073. */
  1074. HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
  1075. {
  1076. uint32_t i;
  1077. /* Restart the Phy Clock */
  1078. USBx_PCGCCTL = 0;
  1079. /*Activate VBUS Sensing B */
  1080. USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
  1081. /* Disable the FS/LS support mode only */
  1082. if((cfg.speed == USB_OTG_SPEED_FULL)&&
  1083. (USBx != USB_OTG_FS))
  1084. {
  1085. USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS;
  1086. }
  1087. else
  1088. {
  1089. USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
  1090. }
  1091. /* Make sure the FIFOs are flushed. */
  1092. USB_FlushTxFifo(USBx, 0x10 ); /* all Tx FIFOs */
  1093. USB_FlushRxFifo(USBx);
  1094. /* Clear all pending HC Interrupts */
  1095. for (i = 0; i < cfg.Host_channels; i++)
  1096. {
  1097. USBx_HC(i)->HCINT = 0xFFFFFFFF;
  1098. USBx_HC(i)->HCINTMSK = 0;
  1099. }
  1100. /* Enable VBUS driving */
  1101. USB_DriveVbus(USBx, 1);
  1102. HAL_Delay(200);
  1103. /* Disable all interrupts. */
  1104. USBx->GINTMSK = 0;
  1105. /* Clear any pending interrupts */
  1106. USBx->GINTSTS = 0xFFFFFFFF;
  1107. if(USBx == USB_OTG_FS)
  1108. {
  1109. /* set Rx FIFO size */
  1110. USBx->GRXFSIZ = (uint32_t )0x80;
  1111. USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x60 << 16)& USB_OTG_NPTXFD) | 0x80);
  1112. USBx->HPTXFSIZ = (uint32_t )(((0x40 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0);
  1113. }
  1114. else
  1115. {
  1116. /* set Rx FIFO size */
  1117. USBx->GRXFSIZ = (uint32_t )0x200;
  1118. USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x100 << 16)& USB_OTG_NPTXFD) | 0x200);
  1119. USBx->HPTXFSIZ = (uint32_t )(((0xE0 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0x300);
  1120. }
  1121. /* Enable the common interrupts */
  1122. if (cfg.dma_enable == DISABLE)
  1123. {
  1124. USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
  1125. }
  1126. /* Enable interrupts matching to the Host mode ONLY */
  1127. USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM |\
  1128. USB_OTG_GINTMSK_SOFM |USB_OTG_GINTSTS_DISCINT|\
  1129. USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
  1130. return HAL_OK;
  1131. }
  1132. /**
  1133. * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
  1134. * HCFG register on the PHY type and set the right frame interval
  1135. * @param USBx : Selected device
  1136. * @param freq : clock frequency
  1137. * This parameter can be one of these values:
  1138. * HCFG_48_MHZ : Full Speed 48 MHz Clock
  1139. * HCFG_6_MHZ : Low Speed 6 MHz Clock
  1140. * @retval HAL status
  1141. */
  1142. HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx , uint8_t freq)
  1143. {
  1144. USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
  1145. USBx_HOST->HCFG |= (freq & USB_OTG_HCFG_FSLSPCS);
  1146. if (freq == HCFG_48_MHZ)
  1147. {
  1148. USBx_HOST->HFIR = (uint32_t)48000;
  1149. }
  1150. else if (freq == HCFG_6_MHZ)
  1151. {
  1152. USBx_HOST->HFIR = (uint32_t)6000;
  1153. }
  1154. return HAL_OK;
  1155. }
  1156. /**
  1157. * @brief USB_OTG_ResetPort : Reset Host Port
  1158. * @param USBx : Selected device
  1159. * @retval HAL status
  1160. * @note : (1)The application must wait at least 10 ms
  1161. * before clearing the reset bit.
  1162. */
  1163. HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx)
  1164. {
  1165. __IO uint32_t hprt0;
  1166. hprt0 = USBx_HPRT0;
  1167. hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
  1168. USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
  1169. USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
  1170. HAL_Delay (100); /* See Note #1 */
  1171. USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
  1172. HAL_Delay (10);
  1173. return HAL_OK;
  1174. }
  1175. /**
  1176. * @brief USB_DriveVbus : activate or de-activate vbus
  1177. * @param state : VBUS state
  1178. * This parameter can be one of these values:
  1179. * 0 : VBUS Active
  1180. * 1 : VBUS Inactive
  1181. * @retval HAL status
  1182. */
  1183. HAL_StatusTypeDef USB_DriveVbus (USB_OTG_GlobalTypeDef *USBx, uint8_t state)
  1184. {
  1185. __IO uint32_t hprt0;
  1186. hprt0 = USBx_HPRT0;
  1187. hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
  1188. USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
  1189. if (((hprt0 & USB_OTG_HPRT_PPWR) == 0 ) && (state == 1 ))
  1190. {
  1191. USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
  1192. }
  1193. if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0 ))
  1194. {
  1195. USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
  1196. }
  1197. return HAL_OK;
  1198. }
  1199. /**
  1200. * @brief Return Host Core speed
  1201. * @param USBx : Selected device
  1202. * @retval speed : Host speed
  1203. * This parameter can be one of these values:
  1204. * @arg USB_OTG_SPEED_HIGH: High speed mode
  1205. * @arg USB_OTG_SPEED_FULL: Full speed mode
  1206. * @arg USB_OTG_SPEED_LOW: Low speed mode
  1207. */
  1208. uint32_t USB_GetHostSpeed (USB_OTG_GlobalTypeDef *USBx)
  1209. {
  1210. __IO uint32_t hprt0;
  1211. hprt0 = USBx_HPRT0;
  1212. return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
  1213. }
  1214. /**
  1215. * @brief Return Host Current Frame number
  1216. * @param USBx : Selected device
  1217. * @retval current frame number
  1218. */
  1219. uint32_t USB_GetCurrentFrame (USB_OTG_GlobalTypeDef *USBx)
  1220. {
  1221. return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
  1222. }
  1223. /**
  1224. * @brief Initialize a host channel
  1225. * @param USBx : Selected device
  1226. * @param ch_num : Channel number
  1227. * This parameter can be a value from 1 to 15
  1228. * @param epnum : Endpoint number
  1229. * This parameter can be a value from 1 to 15
  1230. * @param dev_address : Current device address
  1231. * This parameter can be a value from 0 to 255
  1232. * @param speed : Current device speed
  1233. * This parameter can be one of these values:
  1234. * @arg USB_OTG_SPEED_HIGH: High speed mode
  1235. * @arg USB_OTG_SPEED_FULL: Full speed mode
  1236. * @arg USB_OTG_SPEED_LOW: Low speed mode
  1237. * @param ep_type : Endpoint Type
  1238. * This parameter can be one of these values:
  1239. * @arg EP_TYPE_CTRL: Control type
  1240. * @arg EP_TYPE_ISOC: Isochronous type
  1241. * @arg EP_TYPE_BULK: Bulk type
  1242. * @arg EP_TYPE_INTR: Interrupt type
  1243. * @param mps : Max Packet Size
  1244. * This parameter can be a value from 0 to32K
  1245. * @retval HAL state
  1246. */
  1247. HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,
  1248. uint8_t ch_num,
  1249. uint8_t epnum,
  1250. uint8_t dev_address,
  1251. uint8_t speed,
  1252. uint8_t ep_type,
  1253. uint16_t mps)
  1254. {
  1255. /* Clear old interrupt conditions for this host channel. */
  1256. USBx_HC(ch_num)->HCINT = 0xFFFFFFFF;
  1257. /* Enable channel interrupts required for this transfer. */
  1258. switch (ep_type)
  1259. {
  1260. case EP_TYPE_CTRL:
  1261. case EP_TYPE_BULK:
  1262. USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
  1263. USB_OTG_HCINTMSK_STALLM |\
  1264. USB_OTG_HCINTMSK_TXERRM |\
  1265. USB_OTG_HCINTMSK_DTERRM |\
  1266. USB_OTG_HCINTMSK_AHBERR |\
  1267. USB_OTG_HCINTMSK_NAKM ;
  1268. if (epnum & 0x80)
  1269. {
  1270. USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
  1271. }
  1272. else
  1273. {
  1274. if(USBx != USB_OTG_FS)
  1275. {
  1276. USBx_HC(ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM);
  1277. }
  1278. }
  1279. break;
  1280. case EP_TYPE_INTR:
  1281. USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
  1282. USB_OTG_HCINTMSK_STALLM |\
  1283. USB_OTG_HCINTMSK_TXERRM |\
  1284. USB_OTG_HCINTMSK_DTERRM |\
  1285. USB_OTG_HCINTMSK_NAKM |\
  1286. USB_OTG_HCINTMSK_AHBERR |\
  1287. USB_OTG_HCINTMSK_FRMORM ;
  1288. if (epnum & 0x80)
  1289. {
  1290. USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
  1291. }
  1292. break;
  1293. case EP_TYPE_ISOC:
  1294. USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
  1295. USB_OTG_HCINTMSK_ACKM |\
  1296. USB_OTG_HCINTMSK_AHBERR |\
  1297. USB_OTG_HCINTMSK_FRMORM ;
  1298. if (epnum & 0x80)
  1299. {
  1300. USBx_HC(ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
  1301. }
  1302. break;
  1303. }
  1304. /* Enable the top level host channel interrupt. */
  1305. USBx_HOST->HAINTMSK |= (1 << ch_num);
  1306. /* Make sure host channel interrupts are enabled. */
  1307. USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
  1308. /* Program the HCCHAR register */
  1309. USBx_HC(ch_num)->HCCHAR = (((dev_address << 22) & USB_OTG_HCCHAR_DAD) |\
  1310. (((epnum & 0x7F)<< 11) & USB_OTG_HCCHAR_EPNUM)|\
  1311. ((((epnum & 0x80) == 0x80)<< 15) & USB_OTG_HCCHAR_EPDIR)|\
  1312. (((speed == HPRT0_PRTSPD_LOW_SPEED)<< 17) & USB_OTG_HCCHAR_LSDEV)|\
  1313. ((ep_type << 18) & USB_OTG_HCCHAR_EPTYP)|\
  1314. (mps & USB_OTG_HCCHAR_MPSIZ));
  1315. if (ep_type == EP_TYPE_INTR)
  1316. {
  1317. USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ;
  1318. }
  1319. return HAL_OK;
  1320. }
  1321. /**
  1322. * @brief Start a transfer over a host channel
  1323. * @param USBx : Selected device
  1324. * @param hc : pointer to host channel structure
  1325. * @param dma: USB dma enabled or disabled
  1326. * This parameter can be one of these values:
  1327. * 0 : DMA feature not used
  1328. * 1 : DMA feature used
  1329. * @retval HAL state
  1330. */
  1331. HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma)
  1332. {
  1333. static __IO uint32_t tmpreg = 0;
  1334. uint8_t is_oddframe = 0;
  1335. uint16_t len_words = 0;
  1336. uint16_t num_packets = 0;
  1337. uint16_t max_hc_pkt_count = 256;
  1338. if((USBx != USB_OTG_FS) && (hc->speed == USB_OTG_SPEED_HIGH))
  1339. {
  1340. if((dma == 0) && (hc->do_ping == 1))
  1341. {
  1342. USB_DoPing(USBx, hc->ch_num);
  1343. return HAL_OK;
  1344. }
  1345. else if(dma == 1)
  1346. {
  1347. USBx_HC(hc->ch_num)->HCINTMSK &= ~(USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM);
  1348. hc->do_ping = 0;
  1349. }
  1350. }
  1351. /* Compute the expected number of packets associated to the transfer */
  1352. if (hc->xfer_len > 0)
  1353. {
  1354. num_packets = (hc->xfer_len + hc->max_packet - 1) / hc->max_packet;
  1355. if (num_packets > max_hc_pkt_count)
  1356. {
  1357. num_packets = max_hc_pkt_count;
  1358. hc->xfer_len = num_packets * hc->max_packet;
  1359. }
  1360. }
  1361. else
  1362. {
  1363. num_packets = 1;
  1364. }
  1365. if (hc->ep_is_in)
  1366. {
  1367. hc->xfer_len = num_packets * hc->max_packet;
  1368. }
  1369. /* Initialize the HCTSIZn register */
  1370. USBx_HC(hc->ch_num)->HCTSIZ = (((hc->xfer_len) & USB_OTG_HCTSIZ_XFRSIZ)) |\
  1371. ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\
  1372. (((hc->data_pid) << 29) & USB_OTG_HCTSIZ_DPID);
  1373. if (dma)
  1374. {
  1375. /* xfer_buff MUST be 32-bits aligned */
  1376. USBx_HC(hc->ch_num)->HCDMA = (uint32_t)hc->xfer_buff;
  1377. }
  1378. is_oddframe = (USBx_HOST->HFNUM & 0x01) ? 0 : 1;
  1379. USBx_HC(hc->ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
  1380. USBx_HC(hc->ch_num)->HCCHAR |= (is_oddframe << 29);
  1381. /* Set host channel enable */
  1382. tmpreg = USBx_HC(hc->ch_num)->HCCHAR;
  1383. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1384. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1385. USBx_HC(hc->ch_num)->HCCHAR = tmpreg;
  1386. if (dma == 0) /* Slave mode */
  1387. {
  1388. if((hc->ep_is_in == 0) && (hc->xfer_len > 0))
  1389. {
  1390. switch(hc->ep_type)
  1391. {
  1392. /* Non periodic transfer */
  1393. case EP_TYPE_CTRL:
  1394. case EP_TYPE_BULK:
  1395. len_words = (hc->xfer_len + 3) / 4;
  1396. /* check if there is enough space in FIFO space */
  1397. if(len_words > (USBx->HNPTXSTS & 0xFFFF))
  1398. {
  1399. /* need to process data in nptxfempty interrupt */
  1400. USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
  1401. }
  1402. break;
  1403. /* Periodic transfer */
  1404. case EP_TYPE_INTR:
  1405. case EP_TYPE_ISOC:
  1406. len_words = (hc->xfer_len + 3) / 4;
  1407. /* check if there is enough space in FIFO space */
  1408. if(len_words > (USBx_HOST->HPTXSTS & 0xFFFF)) /* split the transfer */
  1409. {
  1410. /* need to process data in ptxfempty interrupt */
  1411. USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
  1412. }
  1413. break;
  1414. default:
  1415. break;
  1416. }
  1417. /* Write packet into the Tx FIFO. */
  1418. USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, hc->xfer_len, 0);
  1419. }
  1420. }
  1421. return HAL_OK;
  1422. }
  1423. /**
  1424. * @brief Read all host channel interrupts status
  1425. * @param USBx : Selected device
  1426. * @retval HAL state
  1427. */
  1428. uint32_t USB_HC_ReadInterrupt (USB_OTG_GlobalTypeDef *USBx)
  1429. {
  1430. return ((USBx_HOST->HAINT) & 0xFFFF);
  1431. }
  1432. /**
  1433. * @brief Halt a host channel
  1434. * @param USBx : Selected device
  1435. * @param hc_num : Host Channel number
  1436. * This parameter can be a value from 1 to 15
  1437. * @retval HAL state
  1438. */
  1439. HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx , uint8_t hc_num)
  1440. {
  1441. uint32_t count = 0;
  1442. /* Check for space in the request queue to issue the halt. */
  1443. if (((((USBx_HC(hc_num)->HCCHAR) & USB_OTG_HCCHAR_EPTYP) >> 18) == HCCHAR_CTRL) ||
  1444. (((((USBx_HC(hc_num)->HCCHAR) & USB_OTG_HCCHAR_EPTYP) >> 18) == HCCHAR_BULK)))
  1445. {
  1446. USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
  1447. if ((USBx->HNPTXSTS & 0xFFFF) == 0)
  1448. {
  1449. USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
  1450. USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
  1451. USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
  1452. do
  1453. {
  1454. if (++count > 1000)
  1455. {
  1456. break;
  1457. }
  1458. }
  1459. while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
  1460. }
  1461. else
  1462. {
  1463. USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
  1464. }
  1465. }
  1466. else
  1467. {
  1468. USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
  1469. if ((USBx_HOST->HPTXSTS & 0xFFFF) == 0)
  1470. {
  1471. USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
  1472. USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
  1473. USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
  1474. do
  1475. {
  1476. if (++count > 1000)
  1477. {
  1478. break;
  1479. }
  1480. }
  1481. while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
  1482. }
  1483. else
  1484. {
  1485. USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
  1486. }
  1487. }
  1488. return HAL_OK;
  1489. }
  1490. /**
  1491. * @brief Initiate Do Ping protocol
  1492. * @param USBx : Selected device
  1493. * @param hc_num : Host Channel number
  1494. * This parameter can be a value from 1 to 15
  1495. * @retval HAL state
  1496. */
  1497. HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx , uint8_t ch_num)
  1498. {
  1499. uint8_t num_packets = 1;
  1500. uint32_t tmpreg = 0;
  1501. USBx_HC(ch_num)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\
  1502. USB_OTG_HCTSIZ_DOPING;
  1503. /* Set host channel enable */
  1504. tmpreg = USBx_HC(ch_num)->HCCHAR;
  1505. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1506. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1507. USBx_HC(ch_num)->HCCHAR = tmpreg;
  1508. return HAL_OK;
  1509. }
  1510. /**
  1511. * @brief Stop Host Core
  1512. * @param USBx : Selected device
  1513. * @retval HAL state
  1514. */
  1515. HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
  1516. {
  1517. uint8_t i;
  1518. uint32_t count = 0;
  1519. uint32_t value;
  1520. USB_DisableGlobalInt(USBx);
  1521. /* Flush FIFO */
  1522. USB_FlushTxFifo(USBx, 0x10);
  1523. USB_FlushRxFifo(USBx);
  1524. /* Flush out any leftover queued requests. */
  1525. for (i = 0; i <= 15; i++)
  1526. {
  1527. value = USBx_HC(i)->HCCHAR ;
  1528. value |= USB_OTG_HCCHAR_CHDIS;
  1529. value &= ~USB_OTG_HCCHAR_CHENA;
  1530. value &= ~USB_OTG_HCCHAR_EPDIR;
  1531. USBx_HC(i)->HCCHAR = value;
  1532. }
  1533. /* Halt all channels to put them into a known state. */
  1534. for (i = 0; i <= 15; i++)
  1535. {
  1536. value = USBx_HC(i)->HCCHAR ;
  1537. value |= USB_OTG_HCCHAR_CHDIS;
  1538. value |= USB_OTG_HCCHAR_CHENA;
  1539. value &= ~USB_OTG_HCCHAR_EPDIR;
  1540. USBx_HC(i)->HCCHAR = value;
  1541. do
  1542. {
  1543. if (++count > 1000)
  1544. {
  1545. break;
  1546. }
  1547. }
  1548. while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
  1549. }
  1550. /* Clear any pending Host interrupts */
  1551. USBx_HOST->HAINT = 0xFFFFFFFF;
  1552. USBx->GINTSTS = 0xFFFFFFFF;
  1553. USB_EnableGlobalInt(USBx);
  1554. return HAL_OK;
  1555. }
  1556. /**
  1557. * @}
  1558. */
  1559. #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
  1560. /**
  1561. * @}
  1562. */
  1563. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/