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.
 
 
 

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