stm32f1xx_hal_pcd.c 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424
  1. /**
  2. ******************************************************************************
  3. * @file stm32f1xx_hal_pcd.c
  4. * @author MCD Application Team
  5. * @brief PCD HAL module driver.
  6. * This file provides firmware functions to manage the following
  7. * functionalities of the USB Peripheral Controller:
  8. * + Initialization and de-initialization functions
  9. * + IO operation functions
  10. * + Peripheral Control functions
  11. * + Peripheral State functions
  12. *
  13. @verbatim
  14. ==============================================================================
  15. ##### How to use this driver #####
  16. ==============================================================================
  17. [..]
  18. The PCD HAL driver can be used as follows:
  19. (#) Declare a PCD_HandleTypeDef handle structure, for example:
  20. PCD_HandleTypeDef hpcd;
  21. (#) Fill parameters of Init structure in HCD handle
  22. (#) Call HAL_PCD_Init() API to initialize the HCD peripheral (Core, Device core, ...)
  23. (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
  24. (##) Enable the PCD/USB Low Level interface clock using the following macro
  25. (+++) __HAL_RCC_USB_CLK_ENABLE(); For USB Device FS peripheral available
  26. on STM32F102xx and STM32F103xx devices
  27. (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); For USB OTG FS peripheral available
  28. on STM32F105xx and STM32F107xx devices
  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) 2016 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 "stm32f1xx_hal.h"
  68. /** @addtogroup STM32F1xx_HAL_Driver
  69. * @{
  70. */
  71. #ifdef HAL_PCD_MODULE_ENABLED
  72. #if defined(STM32F102x6) || defined(STM32F102xB) || \
  73. defined(STM32F103x6) || defined(STM32F103xB) || \
  74. defined(STM32F103xE) || defined(STM32F103xG) || \
  75. defined(STM32F105xC) || defined(STM32F107xC)
  76. /** @defgroup PCD PCD
  77. * @brief PCD HAL module driver
  78. * @{
  79. */
  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 ---------------------------------------------------------*/
  93. /** @defgroup PCD_Private_Functions PCD Private Functions
  94. * @{
  95. */
  96. #if defined (USB_OTG_FS)
  97. static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
  98. #endif /* USB_OTG_FS */
  99. #if defined (USB)
  100. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
  101. #endif /* USB */
  102. /**
  103. * @}
  104. */
  105. /* Exported functions --------------------------------------------------------*/
  106. /** @defgroup PCD_Exported_Functions PCD Exported Functions
  107. * @{
  108. */
  109. /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
  110. * @brief Initialization and Configuration functions
  111. *
  112. @verbatim
  113. ===============================================================================
  114. ##### Initialization and de-initialization functions #####
  115. ===============================================================================
  116. [..] This section provides functions allowing to:
  117. @endverbatim
  118. * @{
  119. */
  120. /**
  121. * @brief Initializes the PCD according to the specified
  122. * parameters in the PCD_InitTypeDef and create the associated handle.
  123. * @param hpcd: PCD handle
  124. * @retval HAL status
  125. */
  126. HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
  127. {
  128. uint32_t index = 0U;
  129. /* Check the PCD handle allocation */
  130. if(hpcd == NULL)
  131. {
  132. return HAL_ERROR;
  133. }
  134. /* Check the parameters */
  135. assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
  136. if(hpcd->State == HAL_PCD_STATE_RESET)
  137. {
  138. /* Allocate lock resource and initialize it */
  139. hpcd->Lock = HAL_UNLOCKED;
  140. /* Init the low level hardware : GPIO, CLOCK, NVIC... */
  141. HAL_PCD_MspInit(hpcd);
  142. }
  143. hpcd->State = HAL_PCD_STATE_BUSY;
  144. /* Disable the Interrupts */
  145. __HAL_PCD_DISABLE(hpcd);
  146. /*Init the Core (common init.) */
  147. USB_CoreInit(hpcd->Instance, hpcd->Init);
  148. /* Force Device Mode*/
  149. USB_SetCurrentMode(hpcd->Instance , USB_DEVICE_MODE);
  150. /* Init endpoints structures */
  151. for (index = 0U; index < 15U ; index++)
  152. {
  153. /* Init ep structure */
  154. hpcd->IN_ep[index].is_in = 1U;
  155. hpcd->IN_ep[index].num = index;
  156. hpcd->IN_ep[index].tx_fifo_num = index;
  157. /* Control until ep is actvated */
  158. hpcd->IN_ep[index].type = EP_TYPE_CTRL;
  159. hpcd->IN_ep[index].maxpacket = 0U;
  160. hpcd->IN_ep[index].xfer_buff = 0U;
  161. hpcd->IN_ep[index].xfer_len = 0U;
  162. }
  163. for (index = 0U; index < 15U ; index++)
  164. {
  165. hpcd->OUT_ep[index].is_in = 0U;
  166. hpcd->OUT_ep[index].num = index;
  167. hpcd->IN_ep[index].tx_fifo_num = index;
  168. /* Control until ep is activated */
  169. hpcd->OUT_ep[index].type = EP_TYPE_CTRL;
  170. hpcd->OUT_ep[index].maxpacket = 0U;
  171. hpcd->OUT_ep[index].xfer_buff = 0U;
  172. hpcd->OUT_ep[index].xfer_len = 0U;
  173. }
  174. /* Init Device */
  175. USB_DevInit(hpcd->Instance, hpcd->Init);
  176. hpcd->USB_Address = 0U;
  177. hpcd->State= HAL_PCD_STATE_READY;
  178. USB_DevDisconnect (hpcd->Instance);
  179. return HAL_OK;
  180. }
  181. /**
  182. * @brief DeInitializes the PCD peripheral
  183. * @param hpcd: PCD handle
  184. * @retval HAL status
  185. */
  186. HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
  187. {
  188. /* Check the PCD handle allocation */
  189. if(hpcd == NULL)
  190. {
  191. return HAL_ERROR;
  192. }
  193. hpcd->State = HAL_PCD_STATE_BUSY;
  194. /* Stop Device */
  195. HAL_PCD_Stop(hpcd);
  196. /* DeInit the low level hardware */
  197. HAL_PCD_MspDeInit(hpcd);
  198. hpcd->State = HAL_PCD_STATE_RESET;
  199. return HAL_OK;
  200. }
  201. /**
  202. * @brief Initializes the PCD MSP.
  203. * @param hpcd: PCD handle
  204. * @retval None
  205. */
  206. __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
  207. {
  208. /* Prevent unused argument(s) compilation warning */
  209. UNUSED(hpcd);
  210. /* NOTE : This function should not be modified, when the callback is needed,
  211. the HAL_PCD_MspInit could be implemented in the user file
  212. */
  213. }
  214. /**
  215. * @brief DeInitializes PCD MSP.
  216. * @param hpcd: PCD handle
  217. * @retval None
  218. */
  219. __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
  220. {
  221. /* Prevent unused argument(s) compilation warning */
  222. UNUSED(hpcd);
  223. /* NOTE : This function should not be modified, when the callback is needed,
  224. the HAL_PCD_MspDeInit could be implemented in the user file
  225. */
  226. }
  227. /**
  228. * @}
  229. */
  230. /** @defgroup PCD_Exported_Functions_Group2 IO operation functions
  231. * @brief Data transfers functions
  232. *
  233. @verbatim
  234. ===============================================================================
  235. ##### IO operation functions #####
  236. ===============================================================================
  237. [..]
  238. This subsection provides a set of functions allowing to manage the PCD data
  239. transfers.
  240. @endverbatim
  241. * @{
  242. */
  243. /**
  244. * @brief Start The USB Device.
  245. * @param hpcd: PCD handle
  246. * @retval HAL status
  247. */
  248. HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
  249. {
  250. __HAL_LOCK(hpcd);
  251. HAL_PCDEx_SetConnectionState (hpcd, 1);
  252. USB_DevConnect (hpcd->Instance);
  253. __HAL_PCD_ENABLE(hpcd);
  254. __HAL_UNLOCK(hpcd);
  255. return HAL_OK;
  256. }
  257. /**
  258. * @brief Stop The USB Device.
  259. * @param hpcd: PCD handle
  260. * @retval HAL status
  261. */
  262. HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
  263. {
  264. __HAL_LOCK(hpcd);
  265. __HAL_PCD_DISABLE(hpcd);
  266. USB_StopDevice(hpcd->Instance);
  267. USB_DevDisconnect (hpcd->Instance);
  268. __HAL_UNLOCK(hpcd);
  269. return HAL_OK;
  270. }
  271. #if defined (USB_OTG_FS)
  272. /**
  273. * @brief This function handles PCD interrupt request.
  274. * @param hpcd: PCD handle
  275. * @retval HAL status
  276. */
  277. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  278. {
  279. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  280. uint32_t index = 0U, ep_intr = 0U, epint = 0U, epnum = 0U;
  281. uint32_t fifoemptymsk = 0U, temp = 0U;
  282. USB_OTG_EPTypeDef *ep = NULL;
  283. /* ensure that we are in device mode */
  284. if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
  285. {
  286. /* avoid spurious interrupt */
  287. if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
  288. {
  289. return;
  290. }
  291. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
  292. {
  293. /* incorrect mode, acknowledge the interrupt */
  294. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
  295. }
  296. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
  297. {
  298. epnum = 0U;
  299. /* Read in the device interrupt bits */
  300. ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
  301. while ( ep_intr )
  302. {
  303. if (ep_intr & 0x1U)
  304. {
  305. epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum);
  306. if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
  307. {
  308. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
  309. HAL_PCD_DataOutStageCallback(hpcd, epnum);
  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 >>= 1U;
  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 = 0U;
  331. while ( ep_intr )
  332. {
  333. if (ep_intr & 0x1U) /* In ITR */
  334. {
  335. epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum);
  336. if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
  337. {
  338. fifoemptymsk = 0x1U << epnum;
  339. USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
  340. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
  341. HAL_PCD_DataInStageCallback(hpcd, epnum);
  342. }
  343. if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
  344. {
  345. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
  346. }
  347. if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
  348. {
  349. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
  350. }
  351. if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
  352. {
  353. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
  354. }
  355. if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
  356. {
  357. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
  358. }
  359. if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
  360. {
  361. PCD_WriteEmptyTxFifo(hpcd , epnum);
  362. }
  363. }
  364. epnum++;
  365. ep_intr >>= 1U;
  366. }
  367. }
  368. /* Handle Resume Interrupt */
  369. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
  370. {
  371. /* Clear the Remote Wake-up signalling */
  372. USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
  373. HAL_PCD_ResumeCallback(hpcd);
  374. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
  375. }
  376. /* Handle Suspend Interrupt */
  377. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
  378. {
  379. if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
  380. {
  381. HAL_PCD_SuspendCallback(hpcd);
  382. }
  383. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
  384. }
  385. /* Handle Reset Interrupt */
  386. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
  387. {
  388. USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
  389. USB_FlushTxFifo(hpcd->Instance , 0x10U);
  390. for (index = 0U; index < hpcd->Init.dev_endpoints ; index++)
  391. {
  392. USBx_INEP(index)->DIEPINT = 0xFFU;
  393. USBx_OUTEP(index)->DOEPINT = 0xFFU;
  394. }
  395. USBx_DEVICE->DAINT = 0xFFFFFFFFU;
  396. USBx_DEVICE->DAINTMSK |= 0x10001U;
  397. USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
  398. USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
  399. /* Set Default Address to 0 */
  400. USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
  401. /* setup EP0 to receive SETUP packets */
  402. USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
  403. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
  404. }
  405. /* Handle Enumeration done Interrupt */
  406. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
  407. {
  408. USB_ActivateSetup(hpcd->Instance);
  409. hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
  410. hpcd->Init.speed = USB_OTG_SPEED_FULL;
  411. hpcd->Init.ep0_mps = USB_OTG_FS_MAX_PACKET_SIZE ;
  412. hpcd->Instance->GUSBCFG |= (uint32_t)((USBD_FS_TRDT_VALUE << 10U) & USB_OTG_GUSBCFG_TRDT);
  413. HAL_PCD_ResetCallback(hpcd);
  414. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
  415. }
  416. /* Handle RxQLevel Interrupt */
  417. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
  418. {
  419. USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  420. temp = USBx->GRXSTSP;
  421. ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
  422. if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) == STS_DATA_UPDT)
  423. {
  424. if((temp & USB_OTG_GRXSTSP_BCNT) != 0U)
  425. {
  426. USB_ReadPacket(USBx, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4U);
  427. ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
  428. ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
  429. }
  430. }
  431. else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) == STS_SETUP_UPDT)
  432. {
  433. USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
  434. ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
  435. }
  436. USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  437. }
  438. /* Handle SOF Interrupt */
  439. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
  440. {
  441. HAL_PCD_SOFCallback(hpcd);
  442. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
  443. }
  444. /* Handle Incomplete ISO IN Interrupt */
  445. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
  446. {
  447. HAL_PCD_ISOINIncompleteCallback(hpcd, epnum);
  448. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
  449. }
  450. /* Handle Incomplete ISO OUT Interrupt */
  451. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
  452. {
  453. HAL_PCD_ISOOUTIncompleteCallback(hpcd, epnum);
  454. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
  455. }
  456. /* Handle Connection event Interrupt */
  457. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
  458. {
  459. HAL_PCD_ConnectCallback(hpcd);
  460. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
  461. }
  462. /* Handle Disconnection event Interrupt */
  463. if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
  464. {
  465. temp = hpcd->Instance->GOTGINT;
  466. if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
  467. {
  468. HAL_PCD_DisconnectCallback(hpcd);
  469. }
  470. hpcd->Instance->GOTGINT |= temp;
  471. }
  472. }
  473. }
  474. #endif /* USB_OTG_FS */
  475. #if defined (USB)
  476. /**
  477. * @brief This function handles PCD interrupt request.
  478. * @param hpcd: PCD handle
  479. * @retval HAL status
  480. */
  481. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  482. {
  483. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_CTR))
  484. {
  485. /* servicing of the endpoint correct transfer interrupt */
  486. /* clear of the CTR flag into the sub */
  487. PCD_EP_ISR_Handler(hpcd);
  488. }
  489. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_RESET))
  490. {
  491. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
  492. HAL_PCD_ResetCallback(hpcd);
  493. HAL_PCD_SetAddress(hpcd, 0U);
  494. }
  495. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_PMAOVR))
  496. {
  497. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
  498. }
  499. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ERR))
  500. {
  501. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
  502. }
  503. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP))
  504. {
  505. hpcd->Instance->CNTR &= ~(USB_CNTR_LP_MODE);
  506. hpcd->Instance->CNTR &= ~(USB_CNTR_FSUSP);
  507. HAL_PCD_ResumeCallback(hpcd);
  508. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
  509. }
  510. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SUSP))
  511. {
  512. /* Force low-power mode in the macrocell */
  513. hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
  514. /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
  515. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
  516. hpcd->Instance->CNTR |= USB_CNTR_LP_MODE;
  517. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP) == 0U)
  518. {
  519. HAL_PCD_SuspendCallback(hpcd);
  520. }
  521. }
  522. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SOF))
  523. {
  524. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
  525. HAL_PCD_SOFCallback(hpcd);
  526. }
  527. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ESOF))
  528. {
  529. /* clear ESOF flag in ISTR */
  530. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
  531. }
  532. }
  533. #endif /* USB */
  534. /**
  535. * @brief Data out stage callbacks
  536. * @param hpcd: PCD handle
  537. * @param epnum: endpoint number
  538. * @retval None
  539. */
  540. __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  541. {
  542. /* Prevent unused argument(s) compilation warning */
  543. UNUSED(hpcd);
  544. UNUSED(epnum);
  545. /* NOTE : This function should not be modified, when the callback is needed,
  546. the HAL_PCD_DataOutStageCallback could be implemented in the user file
  547. */
  548. }
  549. /**
  550. * @brief Data IN stage callbacks
  551. * @param hpcd: PCD handle
  552. * @param epnum: endpoint number
  553. * @retval None
  554. */
  555. __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  556. {
  557. /* Prevent unused argument(s) compilation warning */
  558. UNUSED(hpcd);
  559. UNUSED(epnum);
  560. /* NOTE : This function should not be modified, when the callback is needed,
  561. the HAL_PCD_DataInStageCallback could be implemented in the user file
  562. */
  563. }
  564. /**
  565. * @brief Setup stage callback
  566. * @param hpcd: PCD handle
  567. * @retval None
  568. */
  569. __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
  570. {
  571. /* Prevent unused argument(s) compilation warning */
  572. UNUSED(hpcd);
  573. /* NOTE : This function should not be modified, when the callback is needed,
  574. the HAL_PCD_SetupStageCallback could be implemented in the user file
  575. */
  576. }
  577. /**
  578. * @brief USB Start Of Frame callbacks
  579. * @param hpcd: PCD handle
  580. * @retval None
  581. */
  582. __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
  583. {
  584. /* Prevent unused argument(s) compilation warning */
  585. UNUSED(hpcd);
  586. /* NOTE : This function should not be modified, when the callback is needed,
  587. the HAL_PCD_SOFCallback could be implemented in the user file
  588. */
  589. }
  590. /**
  591. * @brief USB Reset callbacks
  592. * @param hpcd: PCD handle
  593. * @retval None
  594. */
  595. __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
  596. {
  597. /* Prevent unused argument(s) compilation warning */
  598. UNUSED(hpcd);
  599. /* NOTE : This function should not be modified, when the callback is needed,
  600. the HAL_PCD_ResetCallback could be implemented in the user file
  601. */
  602. }
  603. /**
  604. * @brief Suspend event callbacks
  605. * @param hpcd: PCD handle
  606. * @retval None
  607. */
  608. __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
  609. {
  610. /* Prevent unused argument(s) compilation warning */
  611. UNUSED(hpcd);
  612. /* NOTE : This function should not be modified, when the callback is needed,
  613. the HAL_PCD_SuspendCallback could be implemented in the user file
  614. */
  615. }
  616. /**
  617. * @brief Resume event callbacks
  618. * @param hpcd: PCD handle
  619. * @retval None
  620. */
  621. __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
  622. {
  623. /* Prevent unused argument(s) compilation warning */
  624. UNUSED(hpcd);
  625. /* NOTE : This function should not be modified, when the callback is needed,
  626. the HAL_PCD_ResumeCallback could be implemented in the user file
  627. */
  628. }
  629. /**
  630. * @brief Incomplete ISO OUT callbacks
  631. * @param hpcd: PCD handle
  632. * @param epnum: endpoint number
  633. * @retval None
  634. */
  635. __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  636. {
  637. /* Prevent unused argument(s) compilation warning */
  638. UNUSED(hpcd);
  639. UNUSED(epnum);
  640. /* NOTE : This function should not be modified, when the callback is needed,
  641. the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
  642. */
  643. }
  644. /**
  645. * @brief Incomplete ISO IN callbacks
  646. * @param hpcd: PCD handle
  647. * @param epnum: endpoint number
  648. * @retval None
  649. */
  650. __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  651. {
  652. /* Prevent unused argument(s) compilation warning */
  653. UNUSED(hpcd);
  654. UNUSED(epnum);
  655. /* NOTE : This function should not be modified, when the callback is needed,
  656. the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
  657. */
  658. }
  659. /**
  660. * @brief Connection event callbacks
  661. * @param hpcd: PCD handle
  662. * @retval None
  663. */
  664. __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
  665. {
  666. /* Prevent unused argument(s) compilation warning */
  667. UNUSED(hpcd);
  668. /* NOTE : This function should not be modified, when the callback is needed,
  669. the HAL_PCD_ConnectCallback could be implemented in the user file
  670. */
  671. }
  672. /**
  673. * @brief Disconnection event callbacks
  674. * @param hpcd: PCD handle
  675. * @retval None
  676. */
  677. __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
  678. {
  679. /* Prevent unused argument(s) compilation warning */
  680. UNUSED(hpcd);
  681. /* NOTE : This function should not be modified, when the callback is needed,
  682. the HAL_PCD_DisconnectCallback could be implemented in the user file
  683. */
  684. }
  685. /**
  686. * @}
  687. */
  688. /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
  689. * @brief management functions
  690. *
  691. @verbatim
  692. ===============================================================================
  693. ##### Peripheral Control functions #####
  694. ===============================================================================
  695. [..]
  696. This subsection provides a set of functions allowing to control the PCD data
  697. transfers.
  698. @endverbatim
  699. * @{
  700. */
  701. /**
  702. * @brief Connect the USB device
  703. * @param hpcd: PCD handle
  704. * @retval HAL status
  705. */
  706. HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
  707. {
  708. __HAL_LOCK(hpcd);
  709. HAL_PCDEx_SetConnectionState (hpcd, 1);
  710. USB_DevConnect(hpcd->Instance);
  711. __HAL_UNLOCK(hpcd);
  712. return HAL_OK;
  713. }
  714. /**
  715. * @brief Disconnect the USB device
  716. * @param hpcd: PCD handle
  717. * @retval HAL status
  718. */
  719. HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
  720. {
  721. __HAL_LOCK(hpcd);
  722. HAL_PCDEx_SetConnectionState (hpcd, 0U);
  723. USB_DevDisconnect(hpcd->Instance);
  724. __HAL_UNLOCK(hpcd);
  725. return HAL_OK;
  726. }
  727. /**
  728. * @brief Set the USB Device address
  729. * @param hpcd: PCD handle
  730. * @param address: new device address
  731. * @retval HAL status
  732. */
  733. HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
  734. {
  735. __HAL_LOCK(hpcd);
  736. hpcd->USB_Address = address;
  737. USB_SetDevAddress(hpcd->Instance, address);
  738. __HAL_UNLOCK(hpcd);
  739. return HAL_OK;
  740. }
  741. /**
  742. * @brief Open and configure an endpoint
  743. * @param hpcd: PCD handle
  744. * @param ep_addr: endpoint address
  745. * @param ep_mps: endpoint max packet size
  746. * @param ep_type: endpoint type
  747. * @retval HAL status
  748. */
  749. HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
  750. {
  751. HAL_StatusTypeDef ret = HAL_OK;
  752. PCD_EPTypeDef *ep = NULL;
  753. if ((ep_addr & 0x80U) == 0x80U)
  754. {
  755. ep = &hpcd->IN_ep[ep_addr & 0x7FU];
  756. }
  757. else
  758. {
  759. ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
  760. }
  761. ep->num = ep_addr & 0x7FU;
  762. ep->is_in = (0x80U & ep_addr) != 0U;
  763. ep->maxpacket = ep_mps;
  764. ep->type = ep_type;
  765. __HAL_LOCK(hpcd);
  766. USB_ActivateEndpoint(hpcd->Instance , ep);
  767. __HAL_UNLOCK(hpcd);
  768. return ret;
  769. }
  770. /**
  771. * @brief Deactivate an endpoint
  772. * @param hpcd: PCD handle
  773. * @param ep_addr: endpoint address
  774. * @retval HAL status
  775. */
  776. HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  777. {
  778. PCD_EPTypeDef *ep = NULL;
  779. if ((ep_addr & 0x80U) == 0x80U)
  780. {
  781. ep = &hpcd->IN_ep[ep_addr & 0x7FU];
  782. }
  783. else
  784. {
  785. ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
  786. }
  787. ep->num = ep_addr & 0x7FU;
  788. ep->is_in = (0x80U & ep_addr) != 0U;
  789. __HAL_LOCK(hpcd);
  790. USB_DeactivateEndpoint(hpcd->Instance , ep);
  791. __HAL_UNLOCK(hpcd);
  792. return HAL_OK;
  793. }
  794. /**
  795. * @brief Receive an amount of data
  796. * @param hpcd: PCD handle
  797. * @param ep_addr: endpoint address
  798. * @param pBuf: pointer to the reception buffer
  799. * @param len: amount of data to be received
  800. * @retval HAL status
  801. */
  802. HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  803. {
  804. PCD_EPTypeDef *ep = NULL;
  805. ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
  806. /*setup and start the Xfer */
  807. ep->xfer_buff = pBuf;
  808. ep->xfer_len = len;
  809. ep->xfer_count = 0U;
  810. ep->is_in = 0U;
  811. ep->num = ep_addr & 0x7FU;
  812. if ((ep_addr & 0x7FU) == 0U)
  813. {
  814. USB_EP0StartXfer(hpcd->Instance , ep);
  815. }
  816. else
  817. {
  818. USB_EPStartXfer(hpcd->Instance , ep);
  819. }
  820. return HAL_OK;
  821. }
  822. /**
  823. * @brief Get Received Data Size
  824. * @param hpcd: PCD handle
  825. * @param ep_addr: endpoint address
  826. * @retval Data Size
  827. */
  828. uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  829. {
  830. return hpcd->OUT_ep[ep_addr & 0xF].xfer_count;
  831. }
  832. /**
  833. * @brief Send an amount of data
  834. * @param hpcd: PCD handle
  835. * @param ep_addr: endpoint address
  836. * @param pBuf: pointer to the transmission buffer
  837. * @param len: amount of data to be sent
  838. * @retval HAL status
  839. */
  840. HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  841. {
  842. PCD_EPTypeDef *ep = NULL;
  843. ep = &hpcd->IN_ep[ep_addr & 0x7FU];
  844. /*setup and start the Xfer */
  845. ep->xfer_buff = pBuf;
  846. ep->xfer_len = len;
  847. ep->xfer_count = 0U;
  848. ep->is_in = 1U;
  849. ep->num = ep_addr & 0x7FU;
  850. if ((ep_addr & 0x7FU) == 0U)
  851. {
  852. USB_EP0StartXfer(hpcd->Instance , ep);
  853. }
  854. else
  855. {
  856. USB_EPStartXfer(hpcd->Instance , ep);
  857. }
  858. return HAL_OK;
  859. }
  860. /**
  861. * @brief Set a STALL condition over an endpoint
  862. * @param hpcd: PCD handle
  863. * @param ep_addr: endpoint address
  864. * @retval HAL status
  865. */
  866. HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  867. {
  868. PCD_EPTypeDef *ep = NULL;
  869. if ((0x80U & ep_addr) == 0x80U)
  870. {
  871. ep = &hpcd->IN_ep[ep_addr & 0x7FU];
  872. }
  873. else
  874. {
  875. ep = &hpcd->OUT_ep[ep_addr];
  876. }
  877. ep->is_stall = 1U;
  878. ep->num = ep_addr & 0x7FU;
  879. ep->is_in = ((ep_addr & 0x80U) == 0x80U);
  880. __HAL_LOCK(hpcd);
  881. USB_EPSetStall(hpcd->Instance , ep);
  882. if((ep_addr & 0x7FU) == 0U)
  883. {
  884. USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
  885. }
  886. __HAL_UNLOCK(hpcd);
  887. return HAL_OK;
  888. }
  889. /**
  890. * @brief Clear a STALL condition over in an endpoint
  891. * @param hpcd: PCD handle
  892. * @param ep_addr: endpoint address
  893. * @retval HAL status
  894. */
  895. HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  896. {
  897. PCD_EPTypeDef *ep = NULL;
  898. if ((0x80U & ep_addr) == 0x80U)
  899. {
  900. ep = &hpcd->IN_ep[ep_addr & 0x7FU];
  901. }
  902. else
  903. {
  904. ep = &hpcd->OUT_ep[ep_addr];
  905. }
  906. ep->is_stall = 0U;
  907. ep->num = ep_addr & 0x7FU;
  908. ep->is_in = ((ep_addr & 0x80U) == 0x80U);
  909. __HAL_LOCK(hpcd);
  910. USB_EPClearStall(hpcd->Instance , ep);
  911. __HAL_UNLOCK(hpcd);
  912. return HAL_OK;
  913. }
  914. /**
  915. * @brief Flush an endpoint
  916. * @param hpcd: PCD handle
  917. * @param ep_addr: endpoint address
  918. * @retval HAL status
  919. */
  920. HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  921. {
  922. __HAL_LOCK(hpcd);
  923. if ((ep_addr & 0x80U) == 0x80U)
  924. {
  925. USB_FlushTxFifo(hpcd->Instance, ep_addr & 0x7FU);
  926. }
  927. else
  928. {
  929. USB_FlushRxFifo(hpcd->Instance);
  930. }
  931. __HAL_UNLOCK(hpcd);
  932. return HAL_OK;
  933. }
  934. /**
  935. * @brief HAL_PCD_ActivateRemoteWakeup : active remote wakeup signalling
  936. * @param hpcd: PCD handle
  937. * @retval HAL status
  938. */
  939. HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  940. {
  941. return(USB_ActivateRemoteWakeup(hpcd->Instance));
  942. }
  943. /**
  944. * @brief HAL_PCD_DeActivateRemoteWakeup : de-active remote wakeup signalling
  945. * @param hpcd: PCD handle
  946. * @retval HAL status
  947. */
  948. HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  949. {
  950. return(USB_DeActivateRemoteWakeup(hpcd->Instance));
  951. }
  952. /**
  953. * @}
  954. */
  955. /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
  956. * @brief Peripheral State functions
  957. *
  958. @verbatim
  959. ===============================================================================
  960. ##### Peripheral State functions #####
  961. ===============================================================================
  962. [..]
  963. This subsection permits to get in run-time the status of the peripheral
  964. and the data flow.
  965. @endverbatim
  966. * @{
  967. */
  968. /**
  969. * @brief Return the PCD state
  970. * @param hpcd: PCD handle
  971. * @retval HAL state
  972. */
  973. PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
  974. {
  975. return hpcd->State;
  976. }
  977. /**
  978. * @}
  979. */
  980. /**
  981. * @}
  982. */
  983. /** @addtogroup PCD_Private_Functions
  984. * @{
  985. */
  986. #if defined (USB_OTG_FS)
  987. /**
  988. * @brief DCD_WriteEmptyTxFifo
  989. * check FIFO for the next packet to be loaded
  990. * @param hpcd: PCD handle
  991. * @param epnum : endpoint number
  992. * This parameter can be a value from 0 to 15
  993. * @retval HAL status
  994. */
  995. static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
  996. {
  997. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  998. USB_OTG_EPTypeDef *ep = NULL;
  999. int32_t len = 0;
  1000. uint32_t len32b = 0U;
  1001. uint32_t fifoemptymsk = 0U;
  1002. ep = &hpcd->IN_ep[epnum];
  1003. len = ep->xfer_len - ep->xfer_count;
  1004. if (len > ep->maxpacket)
  1005. {
  1006. len = ep->maxpacket;
  1007. }
  1008. len32b = (len + 3U) / 4U;
  1009. while ((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b &&
  1010. ep->xfer_count < ep->xfer_len &&
  1011. ep->xfer_len != 0U)
  1012. {
  1013. /* Write the FIFO */
  1014. len = ep->xfer_len - ep->xfer_count;
  1015. if ((uint32_t)len > ep->maxpacket)
  1016. {
  1017. len = ep->maxpacket;
  1018. }
  1019. len32b = (len + 3U) / 4U;
  1020. USB_WritePacket(USBx, ep->xfer_buff, epnum, len);
  1021. ep->xfer_buff += len;
  1022. ep->xfer_count += len;
  1023. }
  1024. if(len <= 0)
  1025. {
  1026. fifoemptymsk = 0x01U << epnum;
  1027. USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
  1028. }
  1029. return HAL_OK;
  1030. }
  1031. #endif /* USB_OTG_FS */
  1032. #if defined (USB)
  1033. /**
  1034. * @brief This function handles PCD Endpoint interrupt request.
  1035. * @param hpcd: PCD handle
  1036. * @retval HAL status
  1037. */
  1038. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
  1039. {
  1040. PCD_EPTypeDef *ep = NULL;
  1041. uint16_t count = 0;
  1042. uint8_t epindex = 0;
  1043. __IO uint16_t wIstr = 0;
  1044. __IO uint16_t wEPVal = 0;
  1045. /* stay in loop while pending interrupts */
  1046. while (((wIstr = hpcd->Instance->ISTR) & USB_ISTR_CTR) != 0)
  1047. {
  1048. /* extract highest priority endpoint number */
  1049. epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
  1050. if (epindex == 0)
  1051. {
  1052. /* Decode and service control endpoint interrupt */
  1053. /* DIR bit = origin of the interrupt */
  1054. if ((wIstr & USB_ISTR_DIR) == 0)
  1055. {
  1056. /* DIR = 0 */
  1057. /* DIR = 0 => IN int */
  1058. /* DIR = 0 implies that (EP_CTR_TX = 1) always */
  1059. PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1060. ep = &hpcd->IN_ep[0];
  1061. ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  1062. ep->xfer_buff += ep->xfer_count;
  1063. /* TX COMPLETE */
  1064. HAL_PCD_DataInStageCallback(hpcd, 0U);
  1065. if((hpcd->USB_Address > 0U)&& ( ep->xfer_len == 0U))
  1066. {
  1067. hpcd->Instance->DADDR = (hpcd->USB_Address | USB_DADDR_EF);
  1068. hpcd->USB_Address = 0U;
  1069. }
  1070. }
  1071. else
  1072. {
  1073. /* DIR = 1 */
  1074. /* DIR = 1 & CTR_RX => SETUP or OUT int */
  1075. /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
  1076. ep = &hpcd->OUT_ep[0U];
  1077. wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
  1078. if ((wEPVal & USB_EP_SETUP) != 0U)
  1079. {
  1080. /* Get SETUP Packet*/
  1081. ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1082. USB_ReadPMA(hpcd->Instance, (uint8_t*)hpcd->Setup ,ep->pmaadress , ep->xfer_count);
  1083. /* SETUP bit kept frozen while CTR_RX = 1*/
  1084. PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1085. /* Process SETUP Packet*/
  1086. HAL_PCD_SetupStageCallback(hpcd);
  1087. }
  1088. else if ((wEPVal & USB_EP_CTR_RX) != 0U)
  1089. {
  1090. PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1091. /* Get Control Data OUT Packet*/
  1092. ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1093. if (ep->xfer_count != 0U)
  1094. {
  1095. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, ep->xfer_count);
  1096. ep->xfer_buff+=ep->xfer_count;
  1097. }
  1098. /* Process Control Data OUT Packet*/
  1099. HAL_PCD_DataOutStageCallback(hpcd, 0U);
  1100. PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
  1101. PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
  1102. }
  1103. }
  1104. }
  1105. else
  1106. {
  1107. /* Decode and service non control endpoints interrupt */
  1108. /* process related endpoint register */
  1109. wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
  1110. if ((wEPVal & USB_EP_CTR_RX) != 0U)
  1111. {
  1112. /* clear int flag */
  1113. PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
  1114. ep = &hpcd->OUT_ep[epindex];
  1115. /* OUT double Buffering*/
  1116. if (ep->doublebuffer == 0U)
  1117. {
  1118. count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1119. if (count != 0U)
  1120. {
  1121. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
  1122. }
  1123. }
  1124. else
  1125. {
  1126. if (PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX)
  1127. {
  1128. /*read from endpoint BUF0Addr buffer*/
  1129. count = PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  1130. if (count != 0U)
  1131. {
  1132. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
  1133. }
  1134. }
  1135. else
  1136. {
  1137. /*read from endpoint BUF1Addr buffer*/
  1138. count = PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  1139. if (count != 0U)
  1140. {
  1141. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
  1142. }
  1143. }
  1144. PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_OUT);
  1145. }
  1146. /*multi-packet on the NON control OUT endpoint*/
  1147. ep->xfer_count+=count;
  1148. ep->xfer_buff+=count;
  1149. if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
  1150. {
  1151. /* RX COMPLETE */
  1152. HAL_PCD_DataOutStageCallback(hpcd, ep->num);
  1153. }
  1154. else
  1155. {
  1156. HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
  1157. }
  1158. } /* if((wEPVal & EP_CTR_RX) */
  1159. if ((wEPVal & USB_EP_CTR_TX) != 0U)
  1160. {
  1161. ep = &hpcd->IN_ep[epindex];
  1162. /* clear int flag */
  1163. PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
  1164. /* IN double Buffering*/
  1165. if (ep->doublebuffer == 0U)
  1166. {
  1167. ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  1168. if (ep->xfer_count != 0U)
  1169. {
  1170. USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, ep->xfer_count);
  1171. }
  1172. }
  1173. else
  1174. {
  1175. if (PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_TX)
  1176. {
  1177. /*read from endpoint BUF0Addr buffer*/
  1178. ep->xfer_count = PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  1179. if (ep->xfer_count != 0U)
  1180. {
  1181. USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, ep->xfer_count);
  1182. }
  1183. }
  1184. else
  1185. {
  1186. /*read from endpoint BUF1Addr buffer*/
  1187. ep->xfer_count = PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  1188. if (ep->xfer_count != 0U)
  1189. {
  1190. USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, ep->xfer_count);
  1191. }
  1192. }
  1193. PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_IN);
  1194. }
  1195. /*multi-packet on the NON control IN endpoint*/
  1196. ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  1197. ep->xfer_buff+=ep->xfer_count;
  1198. /* Zero Length Packet? */
  1199. if (ep->xfer_len == 0U)
  1200. {
  1201. /* TX COMPLETE */
  1202. HAL_PCD_DataInStageCallback(hpcd, ep->num);
  1203. }
  1204. else
  1205. {
  1206. HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
  1207. }
  1208. }
  1209. }
  1210. }
  1211. return HAL_OK;
  1212. }
  1213. #endif /* USB */
  1214. /**
  1215. * @}
  1216. */
  1217. /**
  1218. * @}
  1219. */
  1220. #endif /* STM32F102x6 || STM32F102xB || */
  1221. /* STM32F103x6 || STM32F103xB || */
  1222. /* STM32F103xE || STM32F103xG || */
  1223. /* STM32F105xC || STM32F107xC */
  1224. #endif /* HAL_PCD_MODULE_ENABLED */
  1225. /**
  1226. * @}
  1227. */
  1228. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/