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.
 
 
 

1820 lines
52 KiB

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