stm32f4xx_hal_pcd.c 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208
  1. /**
  2. ******************************************************************************
  3. * @file stm32f4xx_hal_pcd.c
  4. * @author MCD Application Team
  5. * @version V1.3.0
  6. * @date 09-March-2015
  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) 2015 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 "stm32f4xx_hal.h"
  68. /** @addtogroup STM32F4xx_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. #ifdef USB_OTG_GLPMCFG_LPMEN
  165. /* Activate LPM */
  166. if (hpcd->Init.lpm_enable == 1)
  167. {
  168. HAL_PCDEx_ActivateLPM(hpcd);
  169. }
  170. #endif /* USB_OTG_GLPMCFG_LPMEN */
  171. USB_DevDisconnect (hpcd->Instance);
  172. return HAL_OK;
  173. }
  174. /**
  175. * @brief DeInitializes the PCD peripheral
  176. * @param hpcd: PCD handle
  177. * @retval HAL status
  178. */
  179. HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
  180. {
  181. /* Check the PCD handle allocation */
  182. if(hpcd == NULL)
  183. {
  184. return HAL_ERROR;
  185. }
  186. hpcd->State = HAL_PCD_STATE_BUSY;
  187. /* Stop Device */
  188. HAL_PCD_Stop(hpcd);
  189. /* DeInit the low level hardware */
  190. HAL_PCD_MspDeInit(hpcd);
  191. hpcd->State = HAL_PCD_STATE_RESET;
  192. return HAL_OK;
  193. }
  194. /**
  195. * @brief Initializes the PCD MSP.
  196. * @param hpcd: PCD handle
  197. * @retval None
  198. */
  199. __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
  200. {
  201. /* NOTE : This function Should not be modified, when the callback is needed,
  202. the HAL_PCD_MspInit could be implemented in the user file
  203. */
  204. }
  205. /**
  206. * @brief DeInitializes PCD MSP.
  207. * @param hpcd: PCD handle
  208. * @retval None
  209. */
  210. __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
  211. {
  212. /* NOTE : This function Should not be modified, when the callback is needed,
  213. the HAL_PCD_MspDeInit could be implemented in the user file
  214. */
  215. }
  216. /**
  217. * @}
  218. */
  219. /** @defgroup PCD_Exported_Functions_Group2 IO operation functions
  220. * @brief Data transfers functions
  221. *
  222. @verbatim
  223. ===============================================================================
  224. ##### IO operation functions #####
  225. ===============================================================================
  226. [..]
  227. This subsection provides a set of functions allowing to manage the PCD data
  228. transfers.
  229. @endverbatim
  230. * @{
  231. */
  232. /**
  233. * @brief Start The USB OTG Device.
  234. * @param hpcd: PCD handle
  235. * @retval HAL status
  236. */
  237. HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
  238. {
  239. __HAL_LOCK(hpcd);
  240. USB_DevConnect (hpcd->Instance);
  241. __HAL_PCD_ENABLE(hpcd);
  242. __HAL_UNLOCK(hpcd);
  243. return HAL_OK;
  244. }
  245. /**
  246. * @brief Stop The USB OTG Device.
  247. * @param hpcd: PCD handle
  248. * @retval HAL status
  249. */
  250. HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
  251. {
  252. __HAL_LOCK(hpcd);
  253. __HAL_PCD_DISABLE(hpcd);
  254. USB_StopDevice(hpcd->Instance);
  255. USB_DevDisconnect(hpcd->Instance);
  256. __HAL_UNLOCK(hpcd);
  257. return HAL_OK;
  258. }
  259. /**
  260. * @brief This function handles PCD interrupt request.
  261. * @param hpcd: PCD handle
  262. * @retval HAL status
  263. */
  264. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  265. {
  266. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  267. uint32_t i = 0, ep_intr = 0, epint = 0, epnum = 0;
  268. uint32_t fifoemptymsk = 0, temp = 0;
  269. USB_OTG_EPTypeDef *ep;
  270. /* ensure that we are in device mode */
  271. if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
  272. {
  273. /* avoid spurious interrupt */
  274. if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
  275. {
  276. return;
  277. }
  278. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
  279. {
  280. /* incorrect mode, acknowledge the interrupt */
  281. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
  282. }
  283. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
  284. {
  285. epnum = 0;
  286. /* Read in the device interrupt bits */
  287. ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
  288. while ( ep_intr )
  289. {
  290. if (ep_intr & 0x1)
  291. {
  292. epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum);
  293. if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
  294. {
  295. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
  296. if(hpcd->Init.dma_enable == 1)
  297. {
  298. hpcd->OUT_ep[epnum].xfer_count = hpcd->OUT_ep[epnum].maxpacket- (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ);
  299. hpcd->OUT_ep[epnum].xfer_buff += hpcd->OUT_ep[epnum].maxpacket;
  300. }
  301. HAL_PCD_DataOutStageCallback(hpcd, epnum);
  302. if(hpcd->Init.dma_enable == 1)
  303. {
  304. if((epnum == 0) && (hpcd->OUT_ep[epnum].xfer_len == 0))
  305. {
  306. /* this is ZLP, so prepare EP0 for next setup */
  307. USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup);
  308. }
  309. }
  310. }
  311. if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
  312. {
  313. /* Inform the upper layer that a setup packet is available */
  314. HAL_PCD_SetupStageCallback(hpcd);
  315. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
  316. }
  317. if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
  318. {
  319. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
  320. }
  321. }
  322. epnum++;
  323. ep_intr >>= 1;
  324. }
  325. }
  326. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
  327. {
  328. /* Read in the device interrupt bits */
  329. ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
  330. epnum = 0;
  331. while ( ep_intr )
  332. {
  333. if (ep_intr & 0x1) /* In ITR */
  334. {
  335. epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum);
  336. if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
  337. {
  338. fifoemptymsk = 0x1 << epnum;
  339. USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
  340. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
  341. if (hpcd->Init.dma_enable == 1)
  342. {
  343. hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket;
  344. }
  345. HAL_PCD_DataInStageCallback(hpcd, epnum);
  346. if (hpcd->Init.dma_enable == 1)
  347. {
  348. /* this is ZLP, so prepare EP0 for next setup */
  349. if((epnum == 0) && (hpcd->IN_ep[epnum].xfer_len == 0))
  350. {
  351. /* prepare to rx more setup packets */
  352. USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup);
  353. }
  354. }
  355. }
  356. if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
  357. {
  358. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
  359. }
  360. if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
  361. {
  362. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
  363. }
  364. if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
  365. {
  366. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
  367. }
  368. if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
  369. {
  370. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
  371. }
  372. if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
  373. {
  374. PCD_WriteEmptyTxFifo(hpcd , epnum);
  375. }
  376. }
  377. epnum++;
  378. ep_intr >>= 1;
  379. }
  380. }
  381. /* Handle Resume Interrupt */
  382. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
  383. {
  384. /* Clear the Remote Wake-up Signaling */
  385. USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
  386. #ifdef USB_OTG_GLPMCFG_LPMEN
  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. #endif /* USB_OTG_GLPMCFG_LPMEN */
  394. {
  395. HAL_PCD_ResumeCallback(hpcd);
  396. }
  397. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
  398. }
  399. /* Handle Suspend Interrupt */
  400. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
  401. {
  402. if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
  403. {
  404. HAL_PCD_SuspendCallback(hpcd);
  405. }
  406. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
  407. }
  408. #ifdef USB_OTG_GLPMCFG_LPMEN
  409. /* Handle LPM Interrupt */
  410. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT))
  411. {
  412. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT);
  413. if( hpcd->LPM_State == LPM_L0)
  414. {
  415. hpcd->LPM_State = LPM_L1;
  416. hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >>2 ;
  417. HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
  418. }
  419. else
  420. {
  421. HAL_PCD_SuspendCallback(hpcd);
  422. }
  423. }
  424. #endif /* USB_OTG_GLPMCFG_LPMEN */
  425. /* Handle Reset Interrupt */
  426. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
  427. {
  428. USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
  429. USB_FlushTxFifo(hpcd->Instance , 0 );
  430. for (i = 0; i < hpcd->Init.dev_endpoints ; i++)
  431. {
  432. USBx_INEP(i)->DIEPINT = 0xFF;
  433. USBx_OUTEP(i)->DOEPINT = 0xFF;
  434. }
  435. USBx_DEVICE->DAINT = 0xFFFFFFFF;
  436. USBx_DEVICE->DAINTMSK |= 0x10001;
  437. if(hpcd->Init.use_dedicated_ep1)
  438. {
  439. USBx_DEVICE->DOUTEP1MSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
  440. USBx_DEVICE->DINEP1MSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
  441. }
  442. else
  443. {
  444. USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
  445. USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
  446. }
  447. /* Set Default Address to 0 */
  448. USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
  449. /* setup EP0 to receive SETUP packets */
  450. USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup);
  451. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
  452. }
  453. /* Handle Enumeration done Interrupt */
  454. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
  455. {
  456. USB_ActivateSetup(hpcd->Instance);
  457. hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
  458. if ( USB_GetDevSpeed(hpcd->Instance) == USB_OTG_SPEED_HIGH)
  459. {
  460. hpcd->Init.speed = USB_OTG_SPEED_HIGH;
  461. hpcd->Init.ep0_mps = USB_OTG_HS_MAX_PACKET_SIZE ;
  462. hpcd->Instance->GUSBCFG |= (USB_OTG_GUSBCFG_TRDT_0 | USB_OTG_GUSBCFG_TRDT_3);
  463. }
  464. else
  465. {
  466. hpcd->Init.speed = USB_OTG_SPEED_FULL;
  467. hpcd->Init.ep0_mps = USB_OTG_FS_MAX_PACKET_SIZE ;
  468. hpcd->Instance->GUSBCFG |= (USB_OTG_GUSBCFG_TRDT_0 | USB_OTG_GUSBCFG_TRDT_2);
  469. }
  470. HAL_PCD_ResetCallback(hpcd);
  471. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
  472. }
  473. /* Handle RxQLevel Interrupt */
  474. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
  475. {
  476. USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  477. temp = USBx->GRXSTSP;
  478. ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
  479. if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT)
  480. {
  481. if((temp & USB_OTG_GRXSTSP_BCNT) != 0)
  482. {
  483. USB_ReadPacket(USBx, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4);
  484. ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  485. ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  486. }
  487. }
  488. else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT)
  489. {
  490. USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8);
  491. ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  492. }
  493. USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  494. }
  495. /* Handle SOF Interrupt */
  496. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
  497. {
  498. HAL_PCD_SOFCallback(hpcd);
  499. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
  500. }
  501. /* Handle Incomplete ISO IN Interrupt */
  502. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
  503. {
  504. HAL_PCD_ISOINIncompleteCallback(hpcd, epnum);
  505. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
  506. }
  507. /* Handle Incomplete ISO OUT Interrupt */
  508. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
  509. {
  510. HAL_PCD_ISOOUTIncompleteCallback(hpcd, epnum);
  511. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
  512. }
  513. /* Handle Connection event Interrupt */
  514. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
  515. {
  516. HAL_PCD_ConnectCallback(hpcd);
  517. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
  518. }
  519. /* Handle Disconnection event Interrupt */
  520. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
  521. {
  522. temp = hpcd->Instance->GOTGINT;
  523. if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
  524. {
  525. HAL_PCD_DisconnectCallback(hpcd);
  526. }
  527. hpcd->Instance->GOTGINT |= temp;
  528. }
  529. }
  530. }
  531. /**
  532. * @brief Data OUT stage callbacks
  533. * @param hpcd: PCD handle
  534. * @param epnum: endpoint number
  535. * @retval None
  536. */
  537. __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  538. {
  539. /* NOTE : This function Should not be modified, when the callback is needed,
  540. the HAL_PCD_DataOutStageCallback could be implemented in the user file
  541. */
  542. }
  543. /**
  544. * @brief Data IN stage callbacks
  545. * @param hpcd: PCD handle
  546. * @param epnum: endpoint number
  547. * @retval None
  548. */
  549. __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  550. {
  551. /* NOTE : This function Should not be modified, when the callback is needed,
  552. the HAL_PCD_DataInStageCallback could be implemented in the user file
  553. */
  554. }
  555. /**
  556. * @brief Setup stage callback
  557. * @param hpcd: PCD handle
  558. * @retval None
  559. */
  560. __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
  561. {
  562. /* NOTE : This function Should not be modified, when the callback is needed,
  563. the HAL_PCD_SetupStageCallback could be implemented in the user file
  564. */
  565. }
  566. /**
  567. * @brief USB Start Of Frame callbacks
  568. * @param hpcd: PCD handle
  569. * @retval None
  570. */
  571. __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
  572. {
  573. /* NOTE : This function Should not be modified, when the callback is needed,
  574. the HAL_PCD_SOFCallback could be implemented in the user file
  575. */
  576. }
  577. /**
  578. * @brief USB Reset callbacks
  579. * @param hpcd: PCD handle
  580. * @retval None
  581. */
  582. __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
  583. {
  584. /* NOTE : This function Should not be modified, when the callback is needed,
  585. the HAL_PCD_ResetCallback could be implemented in the user file
  586. */
  587. }
  588. /**
  589. * @brief Suspend event callbacks
  590. * @param hpcd: PCD handle
  591. * @retval None
  592. */
  593. __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
  594. {
  595. /* NOTE : This function Should not be modified, when the callback is needed,
  596. the HAL_PCD_SuspendCallback could be implemented in the user file
  597. */
  598. }
  599. /**
  600. * @brief Resume event callbacks
  601. * @param hpcd: PCD handle
  602. * @retval None
  603. */
  604. __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
  605. {
  606. /* NOTE : This function Should not be modified, when the callback is needed,
  607. the HAL_PCD_ResumeCallback could be implemented in the user file
  608. */
  609. }
  610. /**
  611. * @brief Incomplete ISO OUT callbacks
  612. * @param hpcd: PCD handle
  613. * @param epnum: endpoint number
  614. * @retval None
  615. */
  616. __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  617. {
  618. /* NOTE : This function Should not be modified, when the callback is needed,
  619. the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
  620. */
  621. }
  622. /**
  623. * @brief Incomplete ISO IN callbacks
  624. * @param hpcd: PCD handle
  625. * @param epnum: endpoint number
  626. * @retval None
  627. */
  628. __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  629. {
  630. /* NOTE : This function Should not be modified, when the callback is needed,
  631. the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
  632. */
  633. }
  634. /**
  635. * @brief Connection event callbacks
  636. * @param hpcd: PCD handle
  637. * @retval None
  638. */
  639. __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
  640. {
  641. /* NOTE : This function Should not be modified, when the callback is needed,
  642. the HAL_PCD_ConnectCallback could be implemented in the user file
  643. */
  644. }
  645. /**
  646. * @brief Disconnection event callbacks
  647. * @param hpcd: PCD handle
  648. * @retval None
  649. */
  650. __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
  651. {
  652. /* NOTE : This function Should not be modified, when the callback is needed,
  653. the HAL_PCD_DisconnectCallback could be implemented in the user file
  654. */
  655. }
  656. /**
  657. * @}
  658. */
  659. /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
  660. * @brief management functions
  661. *
  662. @verbatim
  663. ===============================================================================
  664. ##### Peripheral Control functions #####
  665. ===============================================================================
  666. [..]
  667. This subsection provides a set of functions allowing to control the PCD data
  668. transfers.
  669. @endverbatim
  670. * @{
  671. */
  672. /**
  673. * @brief Connect the USB device
  674. * @param hpcd: PCD handle
  675. * @retval HAL status
  676. */
  677. HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
  678. {
  679. __HAL_LOCK(hpcd);
  680. USB_DevConnect(hpcd->Instance);
  681. __HAL_UNLOCK(hpcd);
  682. return HAL_OK;
  683. }
  684. /**
  685. * @brief Disconnect the USB device
  686. * @param hpcd: PCD handle
  687. * @retval HAL status
  688. */
  689. HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
  690. {
  691. __HAL_LOCK(hpcd);
  692. USB_DevDisconnect(hpcd->Instance);
  693. __HAL_UNLOCK(hpcd);
  694. return HAL_OK;
  695. }
  696. /**
  697. * @brief Set the USB Device address
  698. * @param hpcd: PCD handle
  699. * @param address: new device address
  700. * @retval HAL status
  701. */
  702. HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
  703. {
  704. __HAL_LOCK(hpcd);
  705. USB_SetDevAddress(hpcd->Instance, address);
  706. __HAL_UNLOCK(hpcd);
  707. return HAL_OK;
  708. }
  709. /**
  710. * @brief Open and configure an endpoint
  711. * @param hpcd: PCD handle
  712. * @param ep_addr: endpoint address
  713. * @param ep_mps: endpoint max packet size
  714. * @param ep_type: endpoint type
  715. * @retval HAL status
  716. */
  717. HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
  718. {
  719. HAL_StatusTypeDef ret = HAL_OK;
  720. USB_OTG_EPTypeDef *ep;
  721. if ((ep_addr & 0x80) == 0x80)
  722. {
  723. ep = &hpcd->IN_ep[ep_addr & 0x7F];
  724. }
  725. else
  726. {
  727. ep = &hpcd->OUT_ep[ep_addr & 0x7F];
  728. }
  729. ep->num = ep_addr & 0x7F;
  730. ep->is_in = (0x80 & ep_addr) != 0;
  731. ep->maxpacket = ep_mps;
  732. ep->type = ep_type;
  733. if (ep->is_in)
  734. {
  735. /* Assign a Tx FIFO */
  736. ep->tx_fifo_num = ep->num;
  737. }
  738. /* Set initial data PID. */
  739. if (ep_type == EP_TYPE_BULK )
  740. {
  741. ep->data_pid_start = 0;
  742. }
  743. __HAL_LOCK(hpcd);
  744. USB_ActivateEndpoint(hpcd->Instance , ep);
  745. __HAL_UNLOCK(hpcd);
  746. return ret;
  747. }
  748. /**
  749. * @brief Deactivate an endpoint
  750. * @param hpcd: PCD handle
  751. * @param ep_addr: endpoint address
  752. * @retval HAL status
  753. */
  754. HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  755. {
  756. USB_OTG_EPTypeDef *ep;
  757. if ((ep_addr & 0x80) == 0x80)
  758. {
  759. ep = &hpcd->IN_ep[ep_addr & 0x7F];
  760. }
  761. else
  762. {
  763. ep = &hpcd->OUT_ep[ep_addr & 0x7F];
  764. }
  765. ep->num = ep_addr & 0x7F;
  766. ep->is_in = (0x80 & ep_addr) != 0;
  767. __HAL_LOCK(hpcd);
  768. USB_DeactivateEndpoint(hpcd->Instance , ep);
  769. __HAL_UNLOCK(hpcd);
  770. return HAL_OK;
  771. }
  772. /**
  773. * @brief Receive an amount of data
  774. * @param hpcd: PCD handle
  775. * @param ep_addr: endpoint address
  776. * @param pBuf: pointer to the reception buffer
  777. * @param len: amount of data to be received
  778. * @retval HAL status
  779. */
  780. HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  781. {
  782. USB_OTG_EPTypeDef *ep;
  783. ep = &hpcd->OUT_ep[ep_addr & 0x7F];
  784. /*setup and start the Xfer */
  785. ep->xfer_buff = pBuf;
  786. ep->xfer_len = len;
  787. ep->xfer_count = 0;
  788. ep->is_in = 0;
  789. ep->num = ep_addr & 0x7F;
  790. if (hpcd->Init.dma_enable == 1)
  791. {
  792. ep->dma_addr = (uint32_t)pBuf;
  793. }
  794. __HAL_LOCK(hpcd);
  795. if ((ep_addr & 0x7F) == 0 )
  796. {
  797. USB_EP0StartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);
  798. }
  799. else
  800. {
  801. USB_EPStartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);
  802. }
  803. __HAL_UNLOCK(hpcd);
  804. return HAL_OK;
  805. }
  806. /**
  807. * @brief Get Received Data Size
  808. * @param hpcd: PCD handle
  809. * @param ep_addr: endpoint address
  810. * @retval Data Size
  811. */
  812. uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  813. {
  814. return hpcd->OUT_ep[ep_addr & 0x7F].xfer_count;
  815. }
  816. /**
  817. * @brief Send an amount of data
  818. * @param hpcd: PCD handle
  819. * @param ep_addr: endpoint address
  820. * @param pBuf: pointer to the transmission buffer
  821. * @param len: amount of data to be sent
  822. * @retval HAL status
  823. */
  824. HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  825. {
  826. USB_OTG_EPTypeDef *ep;
  827. ep = &hpcd->IN_ep[ep_addr & 0x7F];
  828. /*setup and start the Xfer */
  829. ep->xfer_buff = pBuf;
  830. ep->xfer_len = len;
  831. ep->xfer_count = 0;
  832. ep->is_in = 1;
  833. ep->num = ep_addr & 0x7F;
  834. if (hpcd->Init.dma_enable == 1)
  835. {
  836. ep->dma_addr = (uint32_t)pBuf;
  837. }
  838. __HAL_LOCK(hpcd);
  839. if ((ep_addr & 0x7F) == 0 )
  840. {
  841. USB_EP0StartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);
  842. }
  843. else
  844. {
  845. USB_EPStartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);
  846. }
  847. __HAL_UNLOCK(hpcd);
  848. return HAL_OK;
  849. }
  850. /**
  851. * @brief Set a STALL condition over an endpoint
  852. * @param hpcd: PCD handle
  853. * @param ep_addr: endpoint address
  854. * @retval HAL status
  855. */
  856. HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  857. {
  858. USB_OTG_EPTypeDef *ep;
  859. if ((0x80 & ep_addr) == 0x80)
  860. {
  861. ep = &hpcd->IN_ep[ep_addr & 0x7F];
  862. }
  863. else
  864. {
  865. ep = &hpcd->OUT_ep[ep_addr];
  866. }
  867. ep->is_stall = 1;
  868. ep->num = ep_addr & 0x7F;
  869. ep->is_in = ((ep_addr & 0x80) == 0x80);
  870. __HAL_LOCK(hpcd);
  871. USB_EPSetStall(hpcd->Instance , ep);
  872. if((ep_addr & 0x7F) == 0)
  873. {
  874. USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup);
  875. }
  876. __HAL_UNLOCK(hpcd);
  877. return HAL_OK;
  878. }
  879. /**
  880. * @brief Clear a STALL condition over in an endpoint
  881. * @param hpcd: PCD handle
  882. * @param ep_addr: endpoint address
  883. * @retval HAL status
  884. */
  885. HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  886. {
  887. USB_OTG_EPTypeDef *ep;
  888. if ((0x80 & ep_addr) == 0x80)
  889. {
  890. ep = &hpcd->IN_ep[ep_addr & 0x7F];
  891. }
  892. else
  893. {
  894. ep = &hpcd->OUT_ep[ep_addr];
  895. }
  896. ep->is_stall = 0;
  897. ep->num = ep_addr & 0x7F;
  898. ep->is_in = ((ep_addr & 0x80) == 0x80);
  899. __HAL_LOCK(hpcd);
  900. USB_EPClearStall(hpcd->Instance , ep);
  901. __HAL_UNLOCK(hpcd);
  902. return HAL_OK;
  903. }
  904. /**
  905. * @brief Flush an endpoint
  906. * @param hpcd: PCD handle
  907. * @param ep_addr: endpoint address
  908. * @retval HAL status
  909. */
  910. HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  911. {
  912. __HAL_LOCK(hpcd);
  913. if ((ep_addr & 0x80) == 0x80)
  914. {
  915. USB_FlushTxFifo(hpcd->Instance, ep_addr & 0x7F);
  916. }
  917. else
  918. {
  919. USB_FlushRxFifo(hpcd->Instance);
  920. }
  921. __HAL_UNLOCK(hpcd);
  922. return HAL_OK;
  923. }
  924. /**
  925. * @brief HAL_PCD_ActivateRemoteWakeup : Active remote wake-up signalling
  926. * @param hpcd: PCD handle
  927. * @retval HAL status
  928. */
  929. HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  930. {
  931. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  932. if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
  933. {
  934. /* Activate Remote wake-up signaling */
  935. USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
  936. }
  937. return HAL_OK;
  938. }
  939. /**
  940. * @brief HAL_PCD_DeActivateRemoteWakeup : de-active remote wake-up signalling
  941. * @param hpcd: PCD handle
  942. * @retval HAL status
  943. */
  944. HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  945. {
  946. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  947. /* De-activate Remote wake-up signaling */
  948. USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
  949. return HAL_OK;
  950. }
  951. /**
  952. * @}
  953. */
  954. /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
  955. * @brief Peripheral State functions
  956. *
  957. @verbatim
  958. ===============================================================================
  959. ##### Peripheral State functions #####
  960. ===============================================================================
  961. [..]
  962. This subsection permits to get in run-time the status of the peripheral
  963. and the data flow.
  964. @endverbatim
  965. * @{
  966. */
  967. /**
  968. * @brief Return the PCD state
  969. * @param hpcd: PCD handle
  970. * @retval HAL state
  971. */
  972. PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
  973. {
  974. return hpcd->State;
  975. }
  976. /**
  977. * @}
  978. */
  979. /**
  980. * @}
  981. */
  982. /* Private functions ---------------------------------------------------------*/
  983. /** @addtogroup PCD_Private_Functions
  984. * @{
  985. */
  986. /**
  987. * @brief DCD_WriteEmptyTxFifo
  988. * check FIFO for the next packet to be loaded
  989. * @param hpcd: PCD handle
  990. * @param epnum : endpoint number
  991. * @retval HAL status
  992. */
  993. static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
  994. {
  995. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  996. USB_OTG_EPTypeDef *ep;
  997. int32_t len = 0;
  998. uint32_t len32b;
  999. uint32_t fifoemptymsk = 0;
  1000. ep = &hpcd->IN_ep[epnum];
  1001. len = ep->xfer_len - ep->xfer_count;
  1002. if (len > ep->maxpacket)
  1003. {
  1004. len = ep->maxpacket;
  1005. }
  1006. len32b = (len + 3) / 4;
  1007. while ( (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b &&
  1008. ep->xfer_count < ep->xfer_len &&
  1009. ep->xfer_len != 0)
  1010. {
  1011. /* Write the FIFO */
  1012. len = ep->xfer_len - ep->xfer_count;
  1013. if (len > ep->maxpacket)
  1014. {
  1015. len = ep->maxpacket;
  1016. }
  1017. len32b = (len + 3) / 4;
  1018. USB_WritePacket(USBx, ep->xfer_buff, epnum, len, hpcd->Init.dma_enable);
  1019. ep->xfer_buff += len;
  1020. ep->xfer_count += len;
  1021. }
  1022. if(len <= 0)
  1023. {
  1024. fifoemptymsk = 0x1 << epnum;
  1025. USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
  1026. }
  1027. return HAL_OK;
  1028. }
  1029. /**
  1030. * @}
  1031. */
  1032. #endif /* HAL_PCD_MODULE_ENABLED */
  1033. /**
  1034. * @}
  1035. */
  1036. /**
  1037. * @}
  1038. */
  1039. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/