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.
 
 
 

1631 lines
46 KiB

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