stm32f4xx_hal_pcd.c 34 KB

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