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.
 
 
 

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