stm32h7xx_hal_pcd.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201
  1. /**
  2. ******************************************************************************
  3. * @file stm32h7xx_hal_pcd.c
  4. * @author MCD Application Team
  5. * @version V1.0.0
  6. * @date 21-April-2017
  7. * @brief PCD HAL module driver.
  8. * This file provides firmware functions to manage the following
  9. * functionalities of the USB Peripheral Controller:
  10. * + Initialization and de-initialization functions
  11. * + IO operation functions
  12. * + Peripheral Control functions
  13. * + Peripheral State functions
  14. *
  15. @verbatim
  16. ==============================================================================
  17. ##### How to use this driver #####
  18. ==============================================================================
  19. [..]
  20. The PCD HAL driver can be used as follows:
  21. (#) Declare a PCD_HandleTypeDef handle structure, for example:
  22. PCD_HandleTypeDef hpcd;
  23. (#) Fill parameters of Init structure in HCD handle
  24. (#) Call HAL_PCD_Init() API to initialize the HCD peripheral (Core, Device core, ...)
  25. (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
  26. (##) Enable the PCD/USB Low Level interface clock using
  27. (+++) __OTGFS-OTG_CLK_ENABLE()/__OTGHS-OTG_CLK_ENABLE();
  28. (+++) __OTGHSULPI_CLK_ENABLE(); (For High Speed Mode)
  29. (##) Initialize the related GPIO clocks
  30. (##) Configure PCD pin-out
  31. (##) Configure PCD NVIC interrupt
  32. (#)Associate the Upper USB device stack to the HAL PCD Driver:
  33. (##) hpcd.pData = pdev;
  34. (#)Enable HCD transmission and reception:
  35. (##) HAL_PCD_Start();
  36. @endverbatim
  37. ******************************************************************************
  38. * @attention
  39. *
  40. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  41. *
  42. * Redistribution and use in source and binary forms, with or without modification,
  43. * are permitted provided that the following conditions are met:
  44. * 1. Redistributions of source code must retain the above copyright notice,
  45. * this list of conditions and the following disclaimer.
  46. * 2. Redistributions in binary form must reproduce the above copyright notice,
  47. * this list of conditions and the following disclaimer in the documentation
  48. * and/or other materials provided with the distribution.
  49. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  50. * may be used to endorse or promote products derived from this software
  51. * without specific prior written permission.
  52. *
  53. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  54. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  55. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  56. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  57. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  58. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  59. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  60. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  61. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  62. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  63. *
  64. ******************************************************************************
  65. */
  66. /* Includes ------------------------------------------------------------------*/
  67. #include "stm32h7xx_hal.h"
  68. /** @addtogroup STM32H7xx_HAL_Driver
  69. * @{
  70. */
  71. /** @defgroup PCD PCD
  72. * @brief PCD HAL module driver
  73. * @{
  74. */
  75. #ifdef HAL_PCD_MODULE_ENABLED
  76. /* Private types -------------------------------------------------------------*/
  77. /* Private variables ---------------------------------------------------------*/
  78. /* Private constants ---------------------------------------------------------*/
  79. /* Private macros ------------------------------------------------------------*/
  80. /** @defgroup PCD_Private_Macros PCD Private Macros
  81. * @{
  82. */
  83. #define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b))
  84. #define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b))
  85. /**
  86. * @}
  87. */
  88. /* Private functions prototypes ----------------------------------------------*/
  89. /** @defgroup PCD_Private_Functions PCD Private Functions
  90. * @{
  91. */
  92. static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
  93. /**
  94. * @}
  95. */
  96. /* Exported functions --------------------------------------------------------*/
  97. /** @defgroup PCD_Exported_Functions PCD Exported Functions
  98. * @{
  99. */
  100. /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
  101. * @brief Initialization and Configuration functions
  102. *
  103. @verbatim
  104. ===============================================================================
  105. ##### Initialization and de-initialization functions #####
  106. ===============================================================================
  107. [..] This section provides functions allowing to:
  108. @endverbatim
  109. * @{
  110. */
  111. /**
  112. * @brief Initializes the PCD according to the specified
  113. * parameters in the PCD_InitTypeDef and create the associated handle.
  114. * @param hpcd: PCD handle
  115. * @retval HAL status
  116. */
  117. HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
  118. {
  119. uint32_t i = 0;
  120. /* Check the PCD handle allocation */
  121. if(hpcd == NULL)
  122. {
  123. return HAL_ERROR;
  124. }
  125. /* Check the parameters */
  126. assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
  127. hpcd->State = HAL_PCD_STATE_BUSY;
  128. /* Init the low level hardware : GPIO, CLOCK, NVIC... */
  129. HAL_PCD_MspInit(hpcd);
  130. /* Disable the Interrupts */
  131. __HAL_PCD_DISABLE(hpcd);
  132. /*Init the Core (common init.) */
  133. USB_CoreInit(hpcd->Instance, hpcd->Init);
  134. /* Force Device Mode*/
  135. USB_SetCurrentMode(hpcd->Instance , USB_OTG_DEVICE_MODE);
  136. /* Init endpoints structures */
  137. for (i = 0; i < 15 ; i++)
  138. {
  139. /* Init ep structure */
  140. hpcd->IN_ep[i].is_in = 1;
  141. hpcd->IN_ep[i].num = i;
  142. hpcd->IN_ep[i].tx_fifo_num = i;
  143. /* Control until ep is activated */
  144. hpcd->IN_ep[i].type = EP_TYPE_CTRL;
  145. hpcd->IN_ep[i].maxpacket = 0;
  146. hpcd->IN_ep[i].xfer_buff = 0;
  147. hpcd->IN_ep[i].xfer_len = 0;
  148. }
  149. for (i = 0; i < 15 ; i++)
  150. {
  151. hpcd->OUT_ep[i].is_in = 0;
  152. hpcd->OUT_ep[i].num = i;
  153. hpcd->IN_ep[i].tx_fifo_num = i;
  154. /* Control until ep is activated */
  155. hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
  156. hpcd->OUT_ep[i].maxpacket = 0;
  157. hpcd->OUT_ep[i].xfer_buff = 0;
  158. hpcd->OUT_ep[i].xfer_len = 0;
  159. hpcd->Instance->DIEPTXF[i] = 0;
  160. }
  161. /* Init Device */
  162. USB_DevInit(hpcd->Instance, hpcd->Init);
  163. hpcd->State= HAL_PCD_STATE_READY;
  164. /* Activate LPM */
  165. if (hpcd->Init.lpm_enable == 1)
  166. {
  167. HAL_PCDEx_ActivateLPM(hpcd);
  168. }
  169. /* Activate Battery charging */
  170. if (hpcd->Init.battery_charging_enable ==1)
  171. {
  172. HAL_PCDEx_ActivateBCD(hpcd);
  173. }
  174. USB_DevDisconnect (hpcd->Instance);
  175. return HAL_OK;
  176. }
  177. /**
  178. * @brief DeInitializes the PCD peripheral
  179. * @param hpcd: PCD handle
  180. * @retval HAL status
  181. */
  182. HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
  183. {
  184. /* Check the PCD handle allocation */
  185. if(hpcd == NULL)
  186. {
  187. return HAL_ERROR;
  188. }
  189. hpcd->State = HAL_PCD_STATE_BUSY;
  190. /* Stop Device */
  191. HAL_PCD_Stop(hpcd);
  192. /* DeInit the low level hardware */
  193. HAL_PCD_MspDeInit(hpcd);
  194. hpcd->State = HAL_PCD_STATE_RESET;
  195. return HAL_OK;
  196. }
  197. /**
  198. * @brief Initializes the PCD MSP.
  199. * @param hpcd: PCD handle
  200. * @retval None
  201. */
  202. __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
  203. {
  204. /* NOTE : This function Should not be modified, when the callback is needed,
  205. the HAL_PCD_MspInit could be implemented in the user file
  206. */
  207. }
  208. /**
  209. * @brief DeInitializes PCD MSP.
  210. * @param hpcd: PCD handle
  211. * @retval None
  212. */
  213. __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
  214. {
  215. /* NOTE : This function Should not be modified, when the callback is needed,
  216. the HAL_PCD_MspDeInit could be implemented in the user file
  217. */
  218. }
  219. /**
  220. * @}
  221. */
  222. /** @defgroup PCD_Exported_Functions_Group2 IO operation functions
  223. * @brief Data transfers functions
  224. *
  225. @verbatim
  226. ===============================================================================
  227. ##### IO operation functions #####
  228. ===============================================================================
  229. [..]
  230. This subsection provides a set of functions allowing to manage the PCD data
  231. transfers.
  232. @endverbatim
  233. * @{
  234. */
  235. /**
  236. * @brief Start The USB OTG Device.
  237. * @param hpcd: PCD handle
  238. * @retval HAL status
  239. */
  240. HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
  241. {
  242. USB_DevConnect (hpcd->Instance);
  243. __HAL_PCD_ENABLE(hpcd);
  244. return HAL_OK;
  245. }
  246. /**
  247. * @brief Stop The USB OTG Device.
  248. * @param hpcd: PCD handle
  249. * @retval HAL status
  250. */
  251. HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
  252. {
  253. __HAL_LOCK(hpcd);
  254. __HAL_PCD_DISABLE(hpcd);
  255. USB_StopDevice(hpcd->Instance);
  256. USB_DevDisconnect (hpcd->Instance);
  257. __HAL_UNLOCK(hpcd);
  258. return HAL_OK;
  259. }
  260. /**
  261. * @brief This function handles PCD interrupt request.
  262. * @param hpcd: PCD handle
  263. * @retval HAL status
  264. */
  265. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  266. {
  267. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  268. uint32_t i = 0, ep_intr = 0, epint = 0, epnum = 0;
  269. uint32_t fifoemptymsk = 0, temp = 0;
  270. USB_OTG_EPTypeDef *ep;
  271. /* ensure that we are in device mode */
  272. if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
  273. {
  274. /* avoid spurious interrupt */
  275. if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
  276. {
  277. return;
  278. }
  279. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
  280. {
  281. /* incorrect mode, acknowledge the interrupt */
  282. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
  283. }
  284. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
  285. {
  286. epnum = 0;
  287. /* Read in the device interrupt bits */
  288. ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
  289. while ( ep_intr )
  290. {
  291. if (ep_intr & 0x1)
  292. {
  293. epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum);
  294. if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
  295. {
  296. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
  297. if(hpcd->Init.dma_enable == 1)
  298. {
  299. hpcd->OUT_ep[epnum].xfer_count = hpcd->OUT_ep[epnum].maxpacket- (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ);
  300. hpcd->OUT_ep[epnum].xfer_buff += hpcd->OUT_ep[epnum].maxpacket;
  301. }
  302. HAL_PCD_DataOutStageCallback(hpcd, epnum);
  303. if(hpcd->Init.dma_enable == 1)
  304. {
  305. if((epnum == 0) && (hpcd->OUT_ep[epnum].xfer_len == 0))
  306. {
  307. /* this is ZLP, so prepare EP0 for next setup */
  308. USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup);
  309. }
  310. }
  311. }
  312. if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
  313. {
  314. /* Inform the upper layer that a setup packet is available */
  315. HAL_PCD_SetupStageCallback(hpcd);
  316. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
  317. }
  318. if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
  319. {
  320. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
  321. }
  322. }
  323. epnum++;
  324. ep_intr >>= 1;
  325. }
  326. }
  327. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
  328. {
  329. /* Read in the device interrupt bits */
  330. ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
  331. epnum = 0;
  332. while ( ep_intr )
  333. {
  334. if (ep_intr & 0x1) /* In ITR */
  335. {
  336. epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum);
  337. if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
  338. {
  339. fifoemptymsk = 0x1 << epnum;
  340. USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
  341. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
  342. if (hpcd->Init.dma_enable == 1)
  343. {
  344. hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket;
  345. }
  346. HAL_PCD_DataInStageCallback(hpcd, epnum);
  347. if (hpcd->Init.dma_enable == 1)
  348. {
  349. /* this is ZLP, so prepare EP0 for next setup */
  350. if((epnum == 0) && (hpcd->IN_ep[epnum].xfer_len == 0))
  351. {
  352. /* prepare to rx more setup packets */
  353. USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup);
  354. }
  355. }
  356. }
  357. if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
  358. {
  359. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
  360. }
  361. if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
  362. {
  363. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
  364. }
  365. if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
  366. {
  367. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
  368. }
  369. if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
  370. {
  371. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
  372. }
  373. if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
  374. {
  375. PCD_WriteEmptyTxFifo(hpcd , epnum);
  376. }
  377. }
  378. epnum++;
  379. ep_intr >>= 1;
  380. }
  381. }
  382. /* Handle Resume Interrupt */
  383. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
  384. {
  385. /* Clear the Remote Wake-up Signaling */
  386. USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
  387. if(hpcd->LPM_State == LPM_L1)
  388. {
  389. hpcd->LPM_State = LPM_L0;
  390. HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
  391. }
  392. else
  393. {
  394. HAL_PCD_ResumeCallback(hpcd);
  395. }
  396. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
  397. }
  398. /* Handle Suspend Interrupt */
  399. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
  400. {
  401. if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
  402. {
  403. HAL_PCD_SuspendCallback(hpcd);
  404. }
  405. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
  406. }
  407. /* Handle LPM Interrupt */
  408. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT))
  409. {
  410. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT);
  411. if( hpcd->LPM_State == LPM_L0)
  412. {
  413. hpcd->LPM_State = LPM_L1;
  414. hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >>2 ;
  415. HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
  416. }
  417. else
  418. {
  419. HAL_PCD_SuspendCallback(hpcd);
  420. }
  421. }
  422. /* Handle Reset Interrupt */
  423. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
  424. {
  425. USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
  426. USB_FlushTxFifo(hpcd->Instance, 0x10);
  427. for (i = 0; i < hpcd->Init.dev_endpoints ; i++)
  428. {
  429. USBx_INEP(i)->DIEPINT = 0xFF;
  430. USBx_OUTEP(i)->DOEPINT = 0xFF;
  431. }
  432. USBx_DEVICE->DAINT = 0xFFFFFFFF;
  433. USBx_DEVICE->DAINTMSK |= 0x10001;
  434. if(hpcd->Init.use_dedicated_ep1)
  435. {
  436. USBx_DEVICE->DOUTEP1MSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
  437. USBx_DEVICE->DINEP1MSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
  438. }
  439. else
  440. {
  441. USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
  442. USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
  443. }
  444. /* Set Default Address to 0 */
  445. USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
  446. /* setup EP0 to receive SETUP packets */
  447. USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup);
  448. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
  449. }
  450. /* Handle Enumeration done Interrupt */
  451. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
  452. {
  453. USB_ActivateSetup(hpcd->Instance);
  454. hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
  455. if ( USB_GetDevSpeed(hpcd->Instance) == USB_OTG_SPEED_HIGH)
  456. {
  457. hpcd->Init.speed = USB_OTG_SPEED_HIGH;
  458. hpcd->Init.ep0_mps = USB_OTG_HS_MAX_PACKET_SIZE ;
  459. hpcd->Instance->GUSBCFG |= (uint32_t)((USBD_HS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT);
  460. }
  461. else
  462. {
  463. hpcd->Init.speed = USB_OTG_SPEED_FULL;
  464. hpcd->Init.ep0_mps = USB_OTG_FS_MAX_PACKET_SIZE ;
  465. hpcd->Instance->GUSBCFG |= (uint32_t)((USBD_FS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT);
  466. }
  467. HAL_PCD_ResetCallback(hpcd);
  468. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
  469. }
  470. /* Handle RxQLevel Interrupt */
  471. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
  472. {
  473. USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  474. temp = USBx->GRXSTSP;
  475. ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
  476. if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT)
  477. {
  478. if((temp & USB_OTG_GRXSTSP_BCNT) != 0)
  479. {
  480. USB_ReadPacket(USBx, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4);
  481. ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  482. ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  483. }
  484. }
  485. else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT)
  486. {
  487. USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8);
  488. ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  489. }
  490. USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  491. }
  492. /* Handle SOF Interrupt */
  493. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
  494. {
  495. HAL_PCD_SOFCallback(hpcd);
  496. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
  497. }
  498. /* Handle Incomplete ISO IN Interrupt */
  499. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
  500. {
  501. HAL_PCD_ISOINIncompleteCallback(hpcd, epnum);
  502. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
  503. }
  504. /* Handle Incomplete ISO OUT Interrupt */
  505. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
  506. {
  507. HAL_PCD_ISOOUTIncompleteCallback(hpcd, epnum);
  508. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
  509. }
  510. /* Handle Connection event Interrupt */
  511. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
  512. {
  513. HAL_PCD_ConnectCallback(hpcd);
  514. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
  515. }
  516. /* Handle Disconnection event Interrupt */
  517. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
  518. {
  519. temp = hpcd->Instance->GOTGINT;
  520. if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
  521. {
  522. HAL_PCD_DisconnectCallback(hpcd);
  523. }
  524. hpcd->Instance->GOTGINT |= temp;
  525. }
  526. }
  527. }
  528. /**
  529. * @brief Data out stage callbacks
  530. * @param hpcd: PCD handle
  531. * @param epnum: endpoint number
  532. * @retval None
  533. */
  534. __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  535. {
  536. /* NOTE : This function Should not be modified, when the callback is needed,
  537. the HAL_PCD_DataOutStageCallback could be implemented in the user file
  538. */
  539. }
  540. /**
  541. * @brief Data IN stage callbacks
  542. * @param hpcd: PCD handle
  543. * @param epnum: endpoint number
  544. * @retval None
  545. */
  546. __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  547. {
  548. /* NOTE : This function Should not be modified, when the callback is needed,
  549. the HAL_PCD_DataInStageCallback could be implemented in the user file
  550. */
  551. }
  552. /**
  553. * @brief Setup stage callback
  554. * @param hpcd: PCD handle
  555. * @retval None
  556. */
  557. __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
  558. {
  559. /* NOTE : This function Should not be modified, when the callback is needed,
  560. the HAL_PCD_SetupStageCallback could be implemented in the user file
  561. */
  562. }
  563. /**
  564. * @brief USB Start Of Frame callbacks
  565. * @param hpcd: PCD handle
  566. * @retval None
  567. */
  568. __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
  569. {
  570. /* NOTE : This function Should not be modified, when the callback is needed,
  571. the HAL_PCD_SOFCallback could be implemented in the user file
  572. */
  573. }
  574. /**
  575. * @brief USB Reset callbacks
  576. * @param hpcd: PCD handle
  577. * @retval None
  578. */
  579. __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
  580. {
  581. /* NOTE : This function Should not be modified, when the callback is needed,
  582. the HAL_PCD_ResetCallback could be implemented in the user file
  583. */
  584. }
  585. /**
  586. * @brief Suspend event callbacks
  587. * @param hpcd: PCD handle
  588. * @retval None
  589. */
  590. __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
  591. {
  592. /* NOTE : This function Should not be modified, when the callback is needed,
  593. the HAL_PCD_SuspendCallback could be implemented in the user file
  594. */
  595. }
  596. /**
  597. * @brief Resume event callbacks
  598. * @param hpcd: PCD handle
  599. * @retval None
  600. */
  601. __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
  602. {
  603. /* NOTE : This function Should not be modified, when the callback is needed,
  604. the HAL_PCD_ResumeCallback could be implemented in the user file
  605. */
  606. }
  607. /**
  608. * @brief Incomplete ISO OUT callbacks
  609. * @param hpcd: PCD handle
  610. * @param epnum: endpoint number
  611. * @retval None
  612. */
  613. __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  614. {
  615. /* NOTE : This function Should not be modified, when the callback is needed,
  616. the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
  617. */
  618. }
  619. /**
  620. * @brief Incomplete ISO IN callbacks
  621. * @param hpcd: PCD handle
  622. * @param epnum: endpoint number
  623. * @retval None
  624. */
  625. __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  626. {
  627. /* NOTE : This function Should not be modified, when the callback is needed,
  628. the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
  629. */
  630. }
  631. /**
  632. * @brief Connection event callbacks
  633. * @param hpcd: PCD handle
  634. * @retval None
  635. */
  636. __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
  637. {
  638. /* NOTE : This function Should not be modified, when the callback is needed,
  639. the HAL_PCD_ConnectCallback could be implemented in the user file
  640. */
  641. }
  642. /**
  643. * @brief Disconnection event callbacks
  644. * @param hpcd: PCD handle
  645. * @retval None
  646. */
  647. __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
  648. {
  649. /* NOTE : This function Should not be modified, when the callback is needed,
  650. the HAL_PCD_DisconnectCallback could be implemented in the user file
  651. */
  652. }
  653. /**
  654. * @}
  655. */
  656. /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
  657. * @brief management functions
  658. *
  659. @verbatim
  660. ===============================================================================
  661. ##### Peripheral Control functions #####
  662. ===============================================================================
  663. [..]
  664. This subsection provides a set of functions allowing to control the PCD data
  665. transfers.
  666. @endverbatim
  667. * @{
  668. */
  669. /**
  670. * @brief Connect the USB device
  671. * @param hpcd: PCD handle
  672. * @retval HAL status
  673. */
  674. HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
  675. {
  676. __HAL_LOCK(hpcd);
  677. USB_DevConnect(hpcd->Instance);
  678. __HAL_UNLOCK(hpcd);
  679. return HAL_OK;
  680. }
  681. /**
  682. * @brief Disconnect the USB device
  683. * @param hpcd: PCD handle
  684. * @retval HAL status
  685. */
  686. HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
  687. {
  688. __HAL_LOCK(hpcd);
  689. USB_DevDisconnect(hpcd->Instance);
  690. __HAL_UNLOCK(hpcd);
  691. return HAL_OK;
  692. }
  693. /**
  694. * @brief Set the USB Device address
  695. * @param hpcd: PCD handle
  696. * @param address: new device address
  697. * @retval HAL status
  698. */
  699. HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
  700. {
  701. __HAL_LOCK(hpcd);
  702. USB_SetDevAddress(hpcd->Instance, address);
  703. __HAL_UNLOCK(hpcd);
  704. return HAL_OK;
  705. }
  706. /**
  707. * @brief Open and configure an endpoint
  708. * @param hpcd: PCD handle
  709. * @param ep_addr: endpoint address
  710. * @param ep_mps: endpoint max packet size
  711. * @param ep_type: endpoint type
  712. * @retval HAL status
  713. */
  714. HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
  715. {
  716. HAL_StatusTypeDef ret = HAL_OK;
  717. USB_OTG_EPTypeDef *ep;
  718. if ((ep_addr & 0x80) == 0x80)
  719. {
  720. ep = &hpcd->IN_ep[ep_addr & 0x7F];
  721. }
  722. else
  723. {
  724. ep = &hpcd->OUT_ep[ep_addr & 0x7F];
  725. }
  726. ep->num = ep_addr & 0x7F;
  727. ep->is_in = (0x80 & ep_addr) != 0;
  728. ep->maxpacket = ep_mps;
  729. ep->type = ep_type;
  730. if (ep->is_in)
  731. {
  732. /* Assign a Tx FIFO */
  733. ep->tx_fifo_num = ep->num;
  734. }
  735. /* Set initial data PID. */
  736. if (ep_type == EP_TYPE_BULK )
  737. {
  738. ep->data_pid_start = 0;
  739. }
  740. __HAL_LOCK(hpcd);
  741. USB_ActivateEndpoint(hpcd->Instance , ep);
  742. __HAL_UNLOCK(hpcd);
  743. return ret;
  744. }
  745. /**
  746. * @brief Deactivate an endpoint
  747. * @param hpcd: PCD handle
  748. * @param ep_addr: endpoint address
  749. * @retval HAL status
  750. */
  751. HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  752. {
  753. USB_OTG_EPTypeDef *ep;
  754. if ((ep_addr & 0x80) == 0x80)
  755. {
  756. ep = &hpcd->IN_ep[ep_addr & 0x7F];
  757. }
  758. else
  759. {
  760. ep = &hpcd->OUT_ep[ep_addr & 0x7F];
  761. }
  762. ep->num = ep_addr & 0x7F;
  763. ep->is_in = (0x80 & ep_addr) != 0;
  764. __HAL_LOCK(hpcd);
  765. USB_DeactivateEndpoint(hpcd->Instance , ep);
  766. __HAL_UNLOCK(hpcd);
  767. return HAL_OK;
  768. }
  769. /**
  770. * @brief Receive an amount of data
  771. * @param hpcd: PCD handle
  772. * @param ep_addr: endpoint address
  773. * @param pBuf: pointer to the reception buffer
  774. * @param len: amount of data to be received
  775. * @retval HAL status
  776. */
  777. HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  778. {
  779. USB_OTG_EPTypeDef *ep;
  780. ep = &hpcd->OUT_ep[ep_addr & 0x7F];
  781. /*setup and start the Xfer */
  782. ep->xfer_buff = pBuf;
  783. ep->xfer_len = len;
  784. ep->xfer_count = 0;
  785. ep->is_in = 0;
  786. ep->num = ep_addr & 0x7F;
  787. if (hpcd->Init.dma_enable == 1)
  788. {
  789. ep->dma_addr = (uint32_t)pBuf;
  790. }
  791. if ((ep_addr & 0x7F) == 0 )
  792. {
  793. USB_EP0StartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);
  794. }
  795. else
  796. {
  797. USB_EPStartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);
  798. }
  799. return HAL_OK;
  800. }
  801. /**
  802. * @brief Get Received Data Size
  803. * @param hpcd: PCD handle
  804. * @param ep_addr: endpoint address
  805. * @retval Data Size
  806. */
  807. uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  808. {
  809. return hpcd->OUT_ep[ep_addr & 0x7F].xfer_count;
  810. }
  811. /**
  812. * @brief Send an amount of data
  813. * @param hpcd: PCD handle
  814. * @param ep_addr: endpoint address
  815. * @param pBuf: pointer to the transmission buffer
  816. * @param len: amount of data to be sent
  817. * @retval HAL status
  818. */
  819. HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  820. {
  821. USB_OTG_EPTypeDef *ep;
  822. ep = &hpcd->IN_ep[ep_addr & 0x7F];
  823. /*setup and start the Xfer */
  824. ep->xfer_buff = pBuf;
  825. ep->xfer_len = len;
  826. ep->xfer_count = 0;
  827. ep->is_in = 1;
  828. ep->num = ep_addr & 0x7F;
  829. if (hpcd->Init.dma_enable == 1)
  830. {
  831. ep->dma_addr = (uint32_t)pBuf;
  832. }
  833. if ((ep_addr & 0x7F) == 0 )
  834. {
  835. USB_EP0StartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);
  836. }
  837. else
  838. {
  839. USB_EPStartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);
  840. }
  841. return HAL_OK;
  842. }
  843. /**
  844. * @brief Set a STALL condition over an endpoint
  845. * @param hpcd: PCD handle
  846. * @param ep_addr: endpoint address
  847. * @retval HAL status
  848. */
  849. HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  850. {
  851. USB_OTG_EPTypeDef *ep;
  852. if ((0x80 & ep_addr) == 0x80)
  853. {
  854. ep = &hpcd->IN_ep[ep_addr & 0x7F];
  855. }
  856. else
  857. {
  858. ep = &hpcd->OUT_ep[ep_addr];
  859. }
  860. ep->is_stall = 1;
  861. ep->num = ep_addr & 0x7F;
  862. ep->is_in = ((ep_addr & 0x80) == 0x80);
  863. __HAL_LOCK(hpcd);
  864. USB_EPSetStall(hpcd->Instance , ep);
  865. if((ep_addr & 0x7F) == 0)
  866. {
  867. USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup);
  868. }
  869. __HAL_UNLOCK(hpcd);
  870. return HAL_OK;
  871. }
  872. /**
  873. * @brief Clear a STALL condition over in an endpoint
  874. * @param hpcd: PCD handle
  875. * @param ep_addr: endpoint address
  876. * @retval HAL status
  877. */
  878. HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  879. {
  880. USB_OTG_EPTypeDef *ep;
  881. if ((0x80 & ep_addr) == 0x80)
  882. {
  883. ep = &hpcd->IN_ep[ep_addr & 0x7F];
  884. }
  885. else
  886. {
  887. ep = &hpcd->OUT_ep[ep_addr];
  888. }
  889. ep->is_stall = 0;
  890. ep->num = ep_addr & 0x7F;
  891. ep->is_in = ((ep_addr & 0x80) == 0x80);
  892. __HAL_LOCK(hpcd);
  893. USB_EPClearStall(hpcd->Instance , ep);
  894. __HAL_UNLOCK(hpcd);
  895. return HAL_OK;
  896. }
  897. /**
  898. * @brief Flush an endpoint
  899. * @param hpcd: PCD handle
  900. * @param ep_addr: endpoint address
  901. * @retval HAL status
  902. */
  903. HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  904. {
  905. __HAL_LOCK(hpcd);
  906. if ((ep_addr & 0x80) == 0x80)
  907. {
  908. USB_FlushTxFifo(hpcd->Instance, ep_addr & 0x7F);
  909. }
  910. else
  911. {
  912. USB_FlushRxFifo(hpcd->Instance);
  913. }
  914. __HAL_UNLOCK(hpcd);
  915. return HAL_OK;
  916. }
  917. /**
  918. * @brief HAL_PCD_ActivateRemoteWakeup : Active remote wake-up signalling
  919. * @param hpcd: PCD handle
  920. * @retval HAL status
  921. */
  922. HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  923. {
  924. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  925. if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
  926. {
  927. /* Activate Remote wake-up signaling */
  928. USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
  929. }
  930. return HAL_OK;
  931. }
  932. /**
  933. * @brief HAL_PCD_DeActivateRemoteWakeup : de-active remote wake-up signalling
  934. * @param hpcd: PCD handle
  935. * @retval HAL status
  936. */
  937. HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  938. {
  939. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  940. /* De-activate Remote wake-up signaling */
  941. USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
  942. return HAL_OK;
  943. }
  944. /**
  945. * @}
  946. */
  947. /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
  948. * @brief Peripheral State functions
  949. *
  950. @verbatim
  951. ===============================================================================
  952. ##### Peripheral State functions #####
  953. ===============================================================================
  954. [..]
  955. This subsection permits to get in run-time the status of the peripheral
  956. and the data flow.
  957. @endverbatim
  958. * @{
  959. */
  960. /**
  961. * @brief Return the PCD state
  962. * @param hpcd: PCD handle
  963. * @retval HAL state
  964. */
  965. PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
  966. {
  967. return hpcd->State;
  968. }
  969. /**
  970. * @}
  971. */
  972. /**
  973. * @}
  974. */
  975. /* Private functions ---------------------------------------------------------*/
  976. /** @addtogroup PCD_Private_Functions
  977. * @{
  978. */
  979. /**
  980. * @brief DCD_WriteEmptyTxFifo
  981. * check FIFO for the next packet to be loaded
  982. * @param hpcd: PCD handle
  983. * @param epnum : endpoint number
  984. * @retval HAL status
  985. */
  986. static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
  987. {
  988. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  989. USB_OTG_EPTypeDef *ep;
  990. int32_t len = 0;
  991. uint32_t len32b;
  992. uint32_t fifoemptymsk = 0;
  993. ep = &hpcd->IN_ep[epnum];
  994. len = ep->xfer_len - ep->xfer_count;
  995. if (len > ep->maxpacket)
  996. {
  997. len = ep->maxpacket;
  998. }
  999. len32b = (len + 3) / 4;
  1000. while ( (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b &&
  1001. ep->xfer_count < ep->xfer_len &&
  1002. ep->xfer_len != 0)
  1003. {
  1004. /* Write the FIFO */
  1005. len = ep->xfer_len - ep->xfer_count;
  1006. if (len > ep->maxpacket)
  1007. {
  1008. len = ep->maxpacket;
  1009. }
  1010. len32b = (len + 3) / 4;
  1011. USB_WritePacket(USBx, ep->xfer_buff, epnum, len, hpcd->Init.dma_enable);
  1012. ep->xfer_buff += len;
  1013. ep->xfer_count += len;
  1014. }
  1015. if(len <= 0)
  1016. {
  1017. fifoemptymsk = 0x1 << epnum;
  1018. USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
  1019. }
  1020. return HAL_OK;
  1021. }
  1022. /**
  1023. * @}
  1024. */
  1025. #endif /* HAL_PCD_MODULE_ENABLED */
  1026. /**
  1027. * @}
  1028. */
  1029. /**
  1030. * @}
  1031. */
  1032. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/