stm32f4xx_hal_pcd.c 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223
  1. /**
  2. ******************************************************************************
  3. * @file stm32f4xx_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 PCD 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
  25. (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
  26. (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode)
  27. (##) Initialize the related GPIO clocks
  28. (##) Configure PCD pin-out
  29. (##) Configure PCD NVIC interrupt
  30. (#)Associate the Upper USB device stack to the HAL PCD Driver:
  31. (##) hpcd.pData = pdev;
  32. (#)Enable PCD transmission and reception:
  33. (##) HAL_PCD_Start();
  34. @endverbatim
  35. ******************************************************************************
  36. * @attention
  37. *
  38. * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
  39. * All rights reserved.</center></h2>
  40. *
  41. * This software component is licensed by ST under BSD 3-Clause license,
  42. * the "License"; You may not use this file except in compliance with the
  43. * License. You may obtain a copy of the License at:
  44. * opensource.org/licenses/BSD-3-Clause
  45. *
  46. ******************************************************************************
  47. */
  48. /* Includes ------------------------------------------------------------------*/
  49. #include "stm32f4xx_hal.h"
  50. /** @addtogroup STM32F4xx_HAL_Driver
  51. * @{
  52. */
  53. /** @defgroup PCD PCD
  54. * @brief PCD HAL module driver
  55. * @{
  56. */
  57. #ifdef HAL_PCD_MODULE_ENABLED
  58. #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
  59. /* Private types -------------------------------------------------------------*/
  60. /* Private variables ---------------------------------------------------------*/
  61. /* Private constants ---------------------------------------------------------*/
  62. /* Private macros ------------------------------------------------------------*/
  63. /** @defgroup PCD_Private_Macros PCD Private Macros
  64. * @{
  65. */
  66. #define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b))
  67. #define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b))
  68. /**
  69. * @}
  70. */
  71. /* Private functions prototypes ----------------------------------------------*/
  72. /** @defgroup PCD_Private_Functions PCD Private Functions
  73. * @{
  74. */
  75. #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
  76. static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
  77. static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
  78. static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
  79. #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
  80. /**
  81. * @}
  82. */
  83. /* Exported functions --------------------------------------------------------*/
  84. /** @defgroup PCD_Exported_Functions PCD Exported Functions
  85. * @{
  86. */
  87. /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
  88. * @brief Initialization and Configuration functions
  89. *
  90. @verbatim
  91. ===============================================================================
  92. ##### Initialization and de-initialization functions #####
  93. ===============================================================================
  94. [..] This section provides functions allowing to:
  95. @endverbatim
  96. * @{
  97. */
  98. /**
  99. * @brief Initializes the PCD according to the specified
  100. * parameters in the PCD_InitTypeDef and initialize the associated handle.
  101. * @param hpcd PCD handle
  102. * @retval HAL status
  103. */
  104. HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
  105. {
  106. USB_OTG_GlobalTypeDef *USBx;
  107. uint8_t i;
  108. /* Check the PCD handle allocation */
  109. if (hpcd == NULL)
  110. {
  111. return HAL_ERROR;
  112. }
  113. /* Check the parameters */
  114. assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
  115. USBx = hpcd->Instance;
  116. if (hpcd->State == HAL_PCD_STATE_RESET)
  117. {
  118. /* Allocate lock resource and initialize it */
  119. hpcd->Lock = HAL_UNLOCKED;
  120. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  121. hpcd->SOFCallback = HAL_PCD_SOFCallback;
  122. hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
  123. hpcd->ResetCallback = HAL_PCD_ResetCallback;
  124. hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
  125. hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
  126. hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
  127. hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
  128. hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback;
  129. hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback;
  130. hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback;
  131. hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback;
  132. hpcd->LPMCallback = HAL_PCDEx_LPM_Callback;
  133. hpcd->BCDCallback = HAL_PCDEx_BCD_Callback;
  134. if (hpcd->MspInitCallback == NULL)
  135. {
  136. hpcd->MspInitCallback = HAL_PCD_MspInit;
  137. }
  138. /* Init the low level hardware */
  139. hpcd->MspInitCallback(hpcd);
  140. #else
  141. /* Init the low level hardware : GPIO, CLOCK, NVIC... */
  142. HAL_PCD_MspInit(hpcd);
  143. #endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */
  144. }
  145. hpcd->State = HAL_PCD_STATE_BUSY;
  146. /* Disable DMA mode for FS instance */
  147. if ((USBx->CID & (0x1U << 8)) == 0U)
  148. {
  149. hpcd->Init.dma_enable = 0U;
  150. }
  151. /* Disable the Interrupts */
  152. __HAL_PCD_DISABLE(hpcd);
  153. /*Init the Core (common init.) */
  154. if (USB_CoreInit(hpcd->Instance, hpcd->Init) != HAL_OK)
  155. {
  156. hpcd->State = HAL_PCD_STATE_ERROR;
  157. return HAL_ERROR;
  158. }
  159. /* Force Device Mode*/
  160. (void)USB_SetCurrentMode(hpcd->Instance, USB_DEVICE_MODE);
  161. /* Init endpoints structures */
  162. for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  163. {
  164. /* Init ep structure */
  165. hpcd->IN_ep[i].is_in = 1U;
  166. hpcd->IN_ep[i].num = i;
  167. hpcd->IN_ep[i].tx_fifo_num = i;
  168. /* Control until ep is activated */
  169. hpcd->IN_ep[i].type = EP_TYPE_CTRL;
  170. hpcd->IN_ep[i].maxpacket = 0U;
  171. hpcd->IN_ep[i].xfer_buff = 0U;
  172. hpcd->IN_ep[i].xfer_len = 0U;
  173. }
  174. for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  175. {
  176. hpcd->OUT_ep[i].is_in = 0U;
  177. hpcd->OUT_ep[i].num = i;
  178. /* Control until ep is activated */
  179. hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
  180. hpcd->OUT_ep[i].maxpacket = 0U;
  181. hpcd->OUT_ep[i].xfer_buff = 0U;
  182. hpcd->OUT_ep[i].xfer_len = 0U;
  183. }
  184. /* Init Device */
  185. if (USB_DevInit(hpcd->Instance, hpcd->Init) != HAL_OK)
  186. {
  187. hpcd->State = HAL_PCD_STATE_ERROR;
  188. return HAL_ERROR;
  189. }
  190. hpcd->USB_Address = 0U;
  191. hpcd->State = HAL_PCD_STATE_READY;
  192. #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
  193. /* Activate LPM */
  194. if (hpcd->Init.lpm_enable == 1U)
  195. {
  196. (void)HAL_PCDEx_ActivateLPM(hpcd);
  197. }
  198. #endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) */
  199. (void)USB_DevDisconnect(hpcd->Instance);
  200. return HAL_OK;
  201. }
  202. /**
  203. * @brief DeInitializes the PCD peripheral.
  204. * @param hpcd PCD handle
  205. * @retval HAL status
  206. */
  207. HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
  208. {
  209. /* Check the PCD handle allocation */
  210. if (hpcd == NULL)
  211. {
  212. return HAL_ERROR;
  213. }
  214. hpcd->State = HAL_PCD_STATE_BUSY;
  215. /* Stop Device */
  216. (void)HAL_PCD_Stop(hpcd);
  217. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  218. if (hpcd->MspDeInitCallback == NULL)
  219. {
  220. hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit */
  221. }
  222. /* DeInit the low level hardware */
  223. hpcd->MspDeInitCallback(hpcd);
  224. #else
  225. /* DeInit the low level hardware: CLOCK, NVIC.*/
  226. HAL_PCD_MspDeInit(hpcd);
  227. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  228. hpcd->State = HAL_PCD_STATE_RESET;
  229. return HAL_OK;
  230. }
  231. /**
  232. * @brief Initializes the PCD MSP.
  233. * @param hpcd PCD handle
  234. * @retval None
  235. */
  236. __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
  237. {
  238. /* Prevent unused argument(s) compilation warning */
  239. UNUSED(hpcd);
  240. /* NOTE : This function should not be modified, when the callback is needed,
  241. the HAL_PCD_MspInit could be implemented in the user file
  242. */
  243. }
  244. /**
  245. * @brief DeInitializes PCD MSP.
  246. * @param hpcd PCD handle
  247. * @retval None
  248. */
  249. __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
  250. {
  251. /* Prevent unused argument(s) compilation warning */
  252. UNUSED(hpcd);
  253. /* NOTE : This function should not be modified, when the callback is needed,
  254. the HAL_PCD_MspDeInit could be implemented in the user file
  255. */
  256. }
  257. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  258. /**
  259. * @brief Register a User USB PCD Callback
  260. * To be used instead of the weak predefined callback
  261. * @param hpcd USB PCD handle
  262. * @param CallbackID ID of the callback to be registered
  263. * This parameter can be one of the following values:
  264. * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
  265. * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
  266. * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
  267. * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
  268. * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
  269. * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
  270. * @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
  271. * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
  272. * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
  273. * @param pCallback pointer to the Callback function
  274. * @retval HAL status
  275. */
  276. HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID, pPCD_CallbackTypeDef pCallback)
  277. {
  278. HAL_StatusTypeDef status = HAL_OK;
  279. if (pCallback == NULL)
  280. {
  281. /* Update the error code */
  282. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  283. return HAL_ERROR;
  284. }
  285. /* Process locked */
  286. __HAL_LOCK(hpcd);
  287. if (hpcd->State == HAL_PCD_STATE_READY)
  288. {
  289. switch (CallbackID)
  290. {
  291. case HAL_PCD_SOF_CB_ID :
  292. hpcd->SOFCallback = pCallback;
  293. break;
  294. case HAL_PCD_SETUPSTAGE_CB_ID :
  295. hpcd->SetupStageCallback = pCallback;
  296. break;
  297. case HAL_PCD_RESET_CB_ID :
  298. hpcd->ResetCallback = pCallback;
  299. break;
  300. case HAL_PCD_SUSPEND_CB_ID :
  301. hpcd->SuspendCallback = pCallback;
  302. break;
  303. case HAL_PCD_RESUME_CB_ID :
  304. hpcd->ResumeCallback = pCallback;
  305. break;
  306. case HAL_PCD_CONNECT_CB_ID :
  307. hpcd->ConnectCallback = pCallback;
  308. break;
  309. case HAL_PCD_DISCONNECT_CB_ID :
  310. hpcd->DisconnectCallback = pCallback;
  311. break;
  312. case HAL_PCD_MSPINIT_CB_ID :
  313. hpcd->MspInitCallback = pCallback;
  314. break;
  315. case HAL_PCD_MSPDEINIT_CB_ID :
  316. hpcd->MspDeInitCallback = pCallback;
  317. break;
  318. default :
  319. /* Update the error code */
  320. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  321. /* Return error status */
  322. status = HAL_ERROR;
  323. break;
  324. }
  325. }
  326. else if (hpcd->State == HAL_PCD_STATE_RESET)
  327. {
  328. switch (CallbackID)
  329. {
  330. case HAL_PCD_MSPINIT_CB_ID :
  331. hpcd->MspInitCallback = pCallback;
  332. break;
  333. case HAL_PCD_MSPDEINIT_CB_ID :
  334. hpcd->MspDeInitCallback = pCallback;
  335. break;
  336. default :
  337. /* Update the error code */
  338. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  339. /* Return error status */
  340. status = HAL_ERROR;
  341. break;
  342. }
  343. }
  344. else
  345. {
  346. /* Update the error code */
  347. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  348. /* Return error status */
  349. status = HAL_ERROR;
  350. }
  351. /* Release Lock */
  352. __HAL_UNLOCK(hpcd);
  353. return status;
  354. }
  355. /**
  356. * @brief Unregister an USB PCD Callback
  357. * USB PCD callabck is redirected to the weak predefined callback
  358. * @param hpcd USB PCD handle
  359. * @param CallbackID ID of the callback to be unregistered
  360. * This parameter can be one of the following values:
  361. * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
  362. * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
  363. * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
  364. * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
  365. * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
  366. * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
  367. * @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
  368. * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
  369. * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
  370. * @retval HAL status
  371. */
  372. HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID)
  373. {
  374. HAL_StatusTypeDef status = HAL_OK;
  375. /* Process locked */
  376. __HAL_LOCK(hpcd);
  377. /* Setup Legacy weak Callbacks */
  378. if (hpcd->State == HAL_PCD_STATE_READY)
  379. {
  380. switch (CallbackID)
  381. {
  382. case HAL_PCD_SOF_CB_ID :
  383. hpcd->SOFCallback = HAL_PCD_SOFCallback;
  384. break;
  385. case HAL_PCD_SETUPSTAGE_CB_ID :
  386. hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
  387. break;
  388. case HAL_PCD_RESET_CB_ID :
  389. hpcd->ResetCallback = HAL_PCD_ResetCallback;
  390. break;
  391. case HAL_PCD_SUSPEND_CB_ID :
  392. hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
  393. break;
  394. case HAL_PCD_RESUME_CB_ID :
  395. hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
  396. break;
  397. case HAL_PCD_CONNECT_CB_ID :
  398. hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
  399. break;
  400. case HAL_PCD_DISCONNECT_CB_ID :
  401. hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
  402. break;
  403. case HAL_PCD_MSPINIT_CB_ID :
  404. hpcd->MspInitCallback = HAL_PCD_MspInit;
  405. break;
  406. case HAL_PCD_MSPDEINIT_CB_ID :
  407. hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
  408. break;
  409. default :
  410. /* Update the error code */
  411. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  412. /* Return error status */
  413. status = HAL_ERROR;
  414. break;
  415. }
  416. }
  417. else if (hpcd->State == HAL_PCD_STATE_RESET)
  418. {
  419. switch (CallbackID)
  420. {
  421. case HAL_PCD_MSPINIT_CB_ID :
  422. hpcd->MspInitCallback = HAL_PCD_MspInit;
  423. break;
  424. case HAL_PCD_MSPDEINIT_CB_ID :
  425. hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
  426. break;
  427. default :
  428. /* Update the error code */
  429. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  430. /* Return error status */
  431. status = HAL_ERROR;
  432. break;
  433. }
  434. }
  435. else
  436. {
  437. /* Update the error code */
  438. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  439. /* Return error status */
  440. status = HAL_ERROR;
  441. }
  442. /* Release Lock */
  443. __HAL_UNLOCK(hpcd);
  444. return status;
  445. }
  446. /**
  447. * @brief Register USB PCD Data OUT Stage Callback
  448. * To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback
  449. * @param hpcd PCD handle
  450. * @param pCallback pointer to the USB PCD Data OUT Stage Callback function
  451. * @retval HAL status
  452. */
  453. HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataOutStageCallbackTypeDef pCallback)
  454. {
  455. HAL_StatusTypeDef status = HAL_OK;
  456. if (pCallback == NULL)
  457. {
  458. /* Update the error code */
  459. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  460. return HAL_ERROR;
  461. }
  462. /* Process locked */
  463. __HAL_LOCK(hpcd);
  464. if (hpcd->State == HAL_PCD_STATE_READY)
  465. {
  466. hpcd->DataOutStageCallback = pCallback;
  467. }
  468. else
  469. {
  470. /* Update the error code */
  471. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  472. /* Return error status */
  473. status = HAL_ERROR;
  474. }
  475. /* Release Lock */
  476. __HAL_UNLOCK(hpcd);
  477. return status;
  478. }
  479. /**
  480. * @brief UnRegister the USB PCD Data OUT Stage Callback
  481. * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback
  482. * @param hpcd PCD handle
  483. * @retval HAL status
  484. */
  485. HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd)
  486. {
  487. HAL_StatusTypeDef status = HAL_OK;
  488. /* Process locked */
  489. __HAL_LOCK(hpcd);
  490. if (hpcd->State == HAL_PCD_STATE_READY)
  491. {
  492. hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback */
  493. }
  494. else
  495. {
  496. /* Update the error code */
  497. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  498. /* Return error status */
  499. status = HAL_ERROR;
  500. }
  501. /* Release Lock */
  502. __HAL_UNLOCK(hpcd);
  503. return status;
  504. }
  505. /**
  506. * @brief Register USB PCD Data IN Stage Callback
  507. * To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback
  508. * @param hpcd PCD handle
  509. * @param pCallback pointer to the USB PCD Data IN Stage Callback function
  510. * @retval HAL status
  511. */
  512. HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataInStageCallbackTypeDef pCallback)
  513. {
  514. HAL_StatusTypeDef status = HAL_OK;
  515. if (pCallback == NULL)
  516. {
  517. /* Update the error code */
  518. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  519. return HAL_ERROR;
  520. }
  521. /* Process locked */
  522. __HAL_LOCK(hpcd);
  523. if (hpcd->State == HAL_PCD_STATE_READY)
  524. {
  525. hpcd->DataInStageCallback = pCallback;
  526. }
  527. else
  528. {
  529. /* Update the error code */
  530. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  531. /* Return error status */
  532. status = HAL_ERROR;
  533. }
  534. /* Release Lock */
  535. __HAL_UNLOCK(hpcd);
  536. return status;
  537. }
  538. /**
  539. * @brief UnRegister the USB PCD Data IN Stage Callback
  540. * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback
  541. * @param hpcd PCD handle
  542. * @retval HAL status
  543. */
  544. HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd)
  545. {
  546. HAL_StatusTypeDef status = HAL_OK;
  547. /* Process locked */
  548. __HAL_LOCK(hpcd);
  549. if (hpcd->State == HAL_PCD_STATE_READY)
  550. {
  551. hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback */
  552. }
  553. else
  554. {
  555. /* Update the error code */
  556. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  557. /* Return error status */
  558. status = HAL_ERROR;
  559. }
  560. /* Release Lock */
  561. __HAL_UNLOCK(hpcd);
  562. return status;
  563. }
  564. /**
  565. * @brief Register USB PCD Iso OUT incomplete Callback
  566. * To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
  567. * @param hpcd PCD handle
  568. * @param pCallback pointer to the USB PCD Iso OUT incomplete Callback function
  569. * @retval HAL status
  570. */
  571. HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoOutIncpltCallbackTypeDef pCallback)
  572. {
  573. HAL_StatusTypeDef status = HAL_OK;
  574. if (pCallback == NULL)
  575. {
  576. /* Update the error code */
  577. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  578. return HAL_ERROR;
  579. }
  580. /* Process locked */
  581. __HAL_LOCK(hpcd);
  582. if (hpcd->State == HAL_PCD_STATE_READY)
  583. {
  584. hpcd->ISOOUTIncompleteCallback = pCallback;
  585. }
  586. else
  587. {
  588. /* Update the error code */
  589. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  590. /* Return error status */
  591. status = HAL_ERROR;
  592. }
  593. /* Release Lock */
  594. __HAL_UNLOCK(hpcd);
  595. return status;
  596. }
  597. /**
  598. * @brief UnRegister the USB PCD Iso OUT incomplete Callback
  599. * USB PCD Iso OUT incomplete Callback is redirected to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
  600. * @param hpcd PCD handle
  601. * @retval HAL status
  602. */
  603. HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
  604. {
  605. HAL_StatusTypeDef status = HAL_OK;
  606. /* Process locked */
  607. __HAL_LOCK(hpcd);
  608. if (hpcd->State == HAL_PCD_STATE_READY)
  609. {
  610. hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback */
  611. }
  612. else
  613. {
  614. /* Update the error code */
  615. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  616. /* Return error status */
  617. status = HAL_ERROR;
  618. }
  619. /* Release Lock */
  620. __HAL_UNLOCK(hpcd);
  621. return status;
  622. }
  623. /**
  624. * @brief Register USB PCD Iso IN incomplete Callback
  625. * To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
  626. * @param hpcd PCD handle
  627. * @param pCallback pointer to the USB PCD Iso IN incomplete Callback function
  628. * @retval HAL status
  629. */
  630. HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoInIncpltCallbackTypeDef pCallback)
  631. {
  632. HAL_StatusTypeDef status = HAL_OK;
  633. if (pCallback == NULL)
  634. {
  635. /* Update the error code */
  636. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  637. return HAL_ERROR;
  638. }
  639. /* Process locked */
  640. __HAL_LOCK(hpcd);
  641. if (hpcd->State == HAL_PCD_STATE_READY)
  642. {
  643. hpcd->ISOINIncompleteCallback = pCallback;
  644. }
  645. else
  646. {
  647. /* Update the error code */
  648. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  649. /* Return error status */
  650. status = HAL_ERROR;
  651. }
  652. /* Release Lock */
  653. __HAL_UNLOCK(hpcd);
  654. return status;
  655. }
  656. /**
  657. * @brief UnRegister the USB PCD Iso IN incomplete Callback
  658. * USB PCD Iso IN incomplete Callback is redirected to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
  659. * @param hpcd PCD handle
  660. * @retval HAL status
  661. */
  662. HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
  663. {
  664. HAL_StatusTypeDef status = HAL_OK;
  665. /* Process locked */
  666. __HAL_LOCK(hpcd);
  667. if (hpcd->State == HAL_PCD_STATE_READY)
  668. {
  669. hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback */
  670. }
  671. else
  672. {
  673. /* Update the error code */
  674. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  675. /* Return error status */
  676. status = HAL_ERROR;
  677. }
  678. /* Release Lock */
  679. __HAL_UNLOCK(hpcd);
  680. return status;
  681. }
  682. /**
  683. * @brief Register USB PCD BCD Callback
  684. * To be used instead of the weak HAL_PCDEx_BCD_Callback() predefined callback
  685. * @param hpcd PCD handle
  686. * @param pCallback pointer to the USB PCD BCD Callback function
  687. * @retval HAL status
  688. */
  689. HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback)
  690. {
  691. HAL_StatusTypeDef status = HAL_OK;
  692. if (pCallback == NULL)
  693. {
  694. /* Update the error code */
  695. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  696. return HAL_ERROR;
  697. }
  698. /* Process locked */
  699. __HAL_LOCK(hpcd);
  700. if (hpcd->State == HAL_PCD_STATE_READY)
  701. {
  702. hpcd->BCDCallback = pCallback;
  703. }
  704. else
  705. {
  706. /* Update the error code */
  707. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  708. /* Return error status */
  709. status = HAL_ERROR;
  710. }
  711. /* Release Lock */
  712. __HAL_UNLOCK(hpcd);
  713. return status;
  714. }
  715. /**
  716. * @brief UnRegister the USB PCD BCD Callback
  717. * USB BCD Callback is redirected to the weak HAL_PCDEx_BCD_Callback() predefined callback
  718. * @param hpcd PCD handle
  719. * @retval HAL status
  720. */
  721. HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd)
  722. {
  723. HAL_StatusTypeDef status = HAL_OK;
  724. /* Process locked */
  725. __HAL_LOCK(hpcd);
  726. if (hpcd->State == HAL_PCD_STATE_READY)
  727. {
  728. hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; /* Legacy weak HAL_PCDEx_BCD_Callback */
  729. }
  730. else
  731. {
  732. /* Update the error code */
  733. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  734. /* Return error status */
  735. status = HAL_ERROR;
  736. }
  737. /* Release Lock */
  738. __HAL_UNLOCK(hpcd);
  739. return status;
  740. }
  741. /**
  742. * @brief Register USB PCD LPM Callback
  743. * To be used instead of the weak HAL_PCDEx_LPM_Callback() predefined callback
  744. * @param hpcd PCD handle
  745. * @param pCallback pointer to the USB PCD LPM Callback function
  746. * @retval HAL status
  747. */
  748. HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback)
  749. {
  750. HAL_StatusTypeDef status = HAL_OK;
  751. if (pCallback == NULL)
  752. {
  753. /* Update the error code */
  754. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  755. return HAL_ERROR;
  756. }
  757. /* Process locked */
  758. __HAL_LOCK(hpcd);
  759. if (hpcd->State == HAL_PCD_STATE_READY)
  760. {
  761. hpcd->LPMCallback = pCallback;
  762. }
  763. else
  764. {
  765. /* Update the error code */
  766. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  767. /* Return error status */
  768. status = HAL_ERROR;
  769. }
  770. /* Release Lock */
  771. __HAL_UNLOCK(hpcd);
  772. return status;
  773. }
  774. /**
  775. * @brief UnRegister the USB PCD LPM Callback
  776. * USB LPM Callback is redirected to the weak HAL_PCDEx_LPM_Callback() predefined callback
  777. * @param hpcd PCD handle
  778. * @retval HAL status
  779. */
  780. HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd)
  781. {
  782. HAL_StatusTypeDef status = HAL_OK;
  783. /* Process locked */
  784. __HAL_LOCK(hpcd);
  785. if (hpcd->State == HAL_PCD_STATE_READY)
  786. {
  787. hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; /* Legacy weak HAL_PCDEx_LPM_Callback */
  788. }
  789. else
  790. {
  791. /* Update the error code */
  792. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  793. /* Return error status */
  794. status = HAL_ERROR;
  795. }
  796. /* Release Lock */
  797. __HAL_UNLOCK(hpcd);
  798. return status;
  799. }
  800. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  801. /**
  802. * @}
  803. */
  804. /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
  805. * @brief Data transfers functions
  806. *
  807. @verbatim
  808. ===============================================================================
  809. ##### IO operation functions #####
  810. ===============================================================================
  811. [..]
  812. This subsection provides a set of functions allowing to manage the PCD data
  813. transfers.
  814. @endverbatim
  815. * @{
  816. */
  817. /**
  818. * @brief Start the USB device
  819. * @param hpcd PCD handle
  820. * @retval HAL status
  821. */
  822. HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
  823. {
  824. #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
  825. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  826. #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
  827. __HAL_LOCK(hpcd);
  828. #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
  829. if ((hpcd->Init.battery_charging_enable == 1U) &&
  830. (hpcd->Init.phy_itface != USB_OTG_ULPI_PHY))
  831. {
  832. /* Enable USB Transceiver */
  833. USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
  834. }
  835. #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
  836. (void)USB_DevConnect(hpcd->Instance);
  837. __HAL_PCD_ENABLE(hpcd);
  838. __HAL_UNLOCK(hpcd);
  839. return HAL_OK;
  840. }
  841. /**
  842. * @brief Stop the USB device.
  843. * @param hpcd PCD handle
  844. * @retval HAL status
  845. */
  846. HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
  847. {
  848. __HAL_LOCK(hpcd);
  849. __HAL_PCD_DISABLE(hpcd);
  850. if (USB_StopDevice(hpcd->Instance) != HAL_OK)
  851. {
  852. __HAL_UNLOCK(hpcd);
  853. return HAL_ERROR;
  854. }
  855. (void)USB_DevDisconnect(hpcd->Instance);
  856. __HAL_UNLOCK(hpcd);
  857. return HAL_OK;
  858. }
  859. #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
  860. /**
  861. * @brief Handles PCD interrupt request.
  862. * @param hpcd PCD handle
  863. * @retval HAL status
  864. */
  865. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  866. {
  867. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  868. uint32_t USBx_BASE = (uint32_t)USBx;
  869. uint32_t i, ep_intr, epint, epnum;
  870. uint32_t fifoemptymsk, temp;
  871. USB_OTG_EPTypeDef *ep;
  872. /* ensure that we are in device mode */
  873. if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
  874. {
  875. /* avoid spurious interrupt */
  876. if (__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
  877. {
  878. return;
  879. }
  880. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
  881. {
  882. /* incorrect mode, acknowledge the interrupt */
  883. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
  884. }
  885. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
  886. {
  887. epnum = 0U;
  888. /* Read in the device interrupt bits */
  889. ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
  890. while (ep_intr != 0U)
  891. {
  892. if ((ep_intr & 0x1U) != 0U)
  893. {
  894. epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum);
  895. if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
  896. {
  897. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
  898. (void)PCD_EP_OutXfrComplete_int(hpcd, epnum);
  899. }
  900. if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
  901. {
  902. /* Class B setup phase done for previous decoded setup */
  903. (void)PCD_EP_OutSetupPacket_int(hpcd, epnum);
  904. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
  905. }
  906. if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
  907. {
  908. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
  909. }
  910. /* Clear Status Phase Received interrupt */
  911. if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
  912. {
  913. if (hpcd->Init.dma_enable == 1U)
  914. {
  915. (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
  916. }
  917. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
  918. }
  919. /* Clear OUT NAK interrupt */
  920. if ((epint & USB_OTG_DOEPINT_NAK) == USB_OTG_DOEPINT_NAK)
  921. {
  922. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_NAK);
  923. }
  924. }
  925. epnum++;
  926. ep_intr >>= 1U;
  927. }
  928. }
  929. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
  930. {
  931. /* Read in the device interrupt bits */
  932. ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
  933. epnum = 0U;
  934. while (ep_intr != 0U)
  935. {
  936. if ((ep_intr & 0x1U) != 0U) /* In ITR */
  937. {
  938. epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum);
  939. if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
  940. {
  941. fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
  942. USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
  943. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
  944. if (hpcd->Init.dma_enable == 1U)
  945. {
  946. hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket;
  947. }
  948. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  949. hpcd->DataInStageCallback(hpcd, (uint8_t)epnum);
  950. #else
  951. HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum);
  952. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  953. if (hpcd->Init.dma_enable == 1U)
  954. {
  955. /* this is ZLP, so prepare EP0 for next setup */
  956. if ((epnum == 0U) && (hpcd->IN_ep[epnum].xfer_len == 0U))
  957. {
  958. /* prepare to rx more setup packets */
  959. (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
  960. }
  961. }
  962. }
  963. if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
  964. {
  965. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
  966. }
  967. if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
  968. {
  969. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
  970. }
  971. if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
  972. {
  973. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
  974. }
  975. if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
  976. {
  977. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
  978. }
  979. if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
  980. {
  981. (void)PCD_WriteEmptyTxFifo(hpcd, epnum);
  982. }
  983. }
  984. epnum++;
  985. ep_intr >>= 1U;
  986. }
  987. }
  988. /* Handle Resume Interrupt */
  989. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
  990. {
  991. /* Clear the Remote Wake-up Signaling */
  992. USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
  993. if (hpcd->LPM_State == LPM_L1)
  994. {
  995. hpcd->LPM_State = LPM_L0;
  996. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  997. hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE);
  998. #else
  999. HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
  1000. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1001. }
  1002. else
  1003. {
  1004. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1005. hpcd->ResumeCallback(hpcd);
  1006. #else
  1007. HAL_PCD_ResumeCallback(hpcd);
  1008. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1009. }
  1010. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
  1011. }
  1012. /* Handle Suspend Interrupt */
  1013. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
  1014. {
  1015. if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
  1016. {
  1017. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1018. hpcd->SuspendCallback(hpcd);
  1019. #else
  1020. HAL_PCD_SuspendCallback(hpcd);
  1021. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1022. }
  1023. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
  1024. }
  1025. #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
  1026. /* Handle LPM Interrupt */
  1027. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT))
  1028. {
  1029. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT);
  1030. if (hpcd->LPM_State == LPM_L0)
  1031. {
  1032. hpcd->LPM_State = LPM_L1;
  1033. hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >> 2U;
  1034. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1035. hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE);
  1036. #else
  1037. HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
  1038. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1039. }
  1040. else
  1041. {
  1042. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1043. hpcd->SuspendCallback(hpcd);
  1044. #else
  1045. HAL_PCD_SuspendCallback(hpcd);
  1046. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1047. }
  1048. }
  1049. #endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) */
  1050. /* Handle Reset Interrupt */
  1051. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
  1052. {
  1053. USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
  1054. (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
  1055. for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  1056. {
  1057. USBx_INEP(i)->DIEPINT = 0xFB7FU;
  1058. USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
  1059. USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
  1060. USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
  1061. }
  1062. USBx_DEVICE->DAINTMSK |= 0x10001U;
  1063. if (hpcd->Init.use_dedicated_ep1 != 0U)
  1064. {
  1065. USBx_DEVICE->DOUTEP1MSK |= USB_OTG_DOEPMSK_STUPM |
  1066. USB_OTG_DOEPMSK_XFRCM |
  1067. USB_OTG_DOEPMSK_EPDM;
  1068. USBx_DEVICE->DINEP1MSK |= USB_OTG_DIEPMSK_TOM |
  1069. USB_OTG_DIEPMSK_XFRCM |
  1070. USB_OTG_DIEPMSK_EPDM;
  1071. }
  1072. else
  1073. {
  1074. USBx_DEVICE->DOEPMSK |= USB_OTG_DOEPMSK_STUPM |
  1075. USB_OTG_DOEPMSK_XFRCM |
  1076. USB_OTG_DOEPMSK_EPDM |
  1077. USB_OTG_DOEPMSK_OTEPSPRM |
  1078. USB_OTG_DOEPMSK_NAKM;
  1079. USBx_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_TOM |
  1080. USB_OTG_DIEPMSK_XFRCM |
  1081. USB_OTG_DIEPMSK_EPDM;
  1082. }
  1083. /* Set Default Address to 0 */
  1084. USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
  1085. /* setup EP0 to receive SETUP packets */
  1086. (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable,
  1087. (uint8_t *)hpcd->Setup);
  1088. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
  1089. }
  1090. /* Handle Enumeration done Interrupt */
  1091. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
  1092. {
  1093. (void)USB_ActivateSetup(hpcd->Instance);
  1094. hpcd->Init.speed = USB_GetDevSpeed(hpcd->Instance);
  1095. /* Set USB Turnaround time */
  1096. (void)USB_SetTurnaroundTime(hpcd->Instance,
  1097. HAL_RCC_GetHCLKFreq(),
  1098. (uint8_t)hpcd->Init.speed);
  1099. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1100. hpcd->ResetCallback(hpcd);
  1101. #else
  1102. HAL_PCD_ResetCallback(hpcd);
  1103. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1104. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
  1105. }
  1106. /* Handle RxQLevel Interrupt */
  1107. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
  1108. {
  1109. USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  1110. temp = USBx->GRXSTSP;
  1111. ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
  1112. if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT)
  1113. {
  1114. if ((temp & USB_OTG_GRXSTSP_BCNT) != 0U)
  1115. {
  1116. (void)USB_ReadPacket(USBx, ep->xfer_buff,
  1117. (uint16_t)((temp & USB_OTG_GRXSTSP_BCNT) >> 4));
  1118. ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  1119. ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  1120. }
  1121. }
  1122. else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT)
  1123. {
  1124. (void)USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
  1125. ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  1126. }
  1127. else
  1128. {
  1129. /* ... */
  1130. }
  1131. USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  1132. }
  1133. /* Handle SOF Interrupt */
  1134. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
  1135. {
  1136. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1137. hpcd->SOFCallback(hpcd);
  1138. #else
  1139. HAL_PCD_SOFCallback(hpcd);
  1140. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1141. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
  1142. }
  1143. /* Handle Incomplete ISO IN Interrupt */
  1144. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
  1145. {
  1146. /* Keep application checking the corresponding Iso IN endpoint
  1147. causing the incomplete Interrupt */
  1148. epnum = 0U;
  1149. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1150. hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
  1151. #else
  1152. HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
  1153. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1154. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
  1155. }
  1156. /* Handle Incomplete ISO OUT Interrupt */
  1157. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
  1158. {
  1159. /* Keep application checking the corresponding Iso OUT endpoint
  1160. causing the incomplete Interrupt */
  1161. epnum = 0U;
  1162. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1163. hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
  1164. #else
  1165. HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
  1166. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1167. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
  1168. }
  1169. /* Handle Connection event Interrupt */
  1170. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
  1171. {
  1172. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1173. hpcd->ConnectCallback(hpcd);
  1174. #else
  1175. HAL_PCD_ConnectCallback(hpcd);
  1176. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1177. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
  1178. }
  1179. /* Handle Disconnection event Interrupt */
  1180. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
  1181. {
  1182. temp = hpcd->Instance->GOTGINT;
  1183. if ((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
  1184. {
  1185. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1186. hpcd->DisconnectCallback(hpcd);
  1187. #else
  1188. HAL_PCD_DisconnectCallback(hpcd);
  1189. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1190. }
  1191. hpcd->Instance->GOTGINT |= temp;
  1192. }
  1193. }
  1194. }
  1195. #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
  1196. /**
  1197. * @brief Data OUT stage callback.
  1198. * @param hpcd PCD handle
  1199. * @param epnum endpoint number
  1200. * @retval None
  1201. */
  1202. __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1203. {
  1204. /* Prevent unused argument(s) compilation warning */
  1205. UNUSED(hpcd);
  1206. UNUSED(epnum);
  1207. /* NOTE : This function should not be modified, when the callback is needed,
  1208. the HAL_PCD_DataOutStageCallback could be implemented in the user file
  1209. */
  1210. }
  1211. /**
  1212. * @brief Data IN stage callback
  1213. * @param hpcd PCD handle
  1214. * @param epnum endpoint number
  1215. * @retval None
  1216. */
  1217. __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1218. {
  1219. /* Prevent unused argument(s) compilation warning */
  1220. UNUSED(hpcd);
  1221. UNUSED(epnum);
  1222. /* NOTE : This function should not be modified, when the callback is needed,
  1223. the HAL_PCD_DataInStageCallback could be implemented in the user file
  1224. */
  1225. }
  1226. /**
  1227. * @brief Setup stage callback
  1228. * @param hpcd PCD handle
  1229. * @retval None
  1230. */
  1231. __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
  1232. {
  1233. /* Prevent unused argument(s) compilation warning */
  1234. UNUSED(hpcd);
  1235. /* NOTE : This function should not be modified, when the callback is needed,
  1236. the HAL_PCD_SetupStageCallback could be implemented in the user file
  1237. */
  1238. }
  1239. /**
  1240. * @brief USB Start Of Frame callback.
  1241. * @param hpcd PCD handle
  1242. * @retval None
  1243. */
  1244. __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
  1245. {
  1246. /* Prevent unused argument(s) compilation warning */
  1247. UNUSED(hpcd);
  1248. /* NOTE : This function should not be modified, when the callback is needed,
  1249. the HAL_PCD_SOFCallback could be implemented in the user file
  1250. */
  1251. }
  1252. /**
  1253. * @brief USB Reset callback.
  1254. * @param hpcd PCD handle
  1255. * @retval None
  1256. */
  1257. __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
  1258. {
  1259. /* Prevent unused argument(s) compilation warning */
  1260. UNUSED(hpcd);
  1261. /* NOTE : This function should not be modified, when the callback is needed,
  1262. the HAL_PCD_ResetCallback could be implemented in the user file
  1263. */
  1264. }
  1265. /**
  1266. * @brief Suspend event callback.
  1267. * @param hpcd PCD handle
  1268. * @retval None
  1269. */
  1270. __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
  1271. {
  1272. /* Prevent unused argument(s) compilation warning */
  1273. UNUSED(hpcd);
  1274. /* NOTE : This function should not be modified, when the callback is needed,
  1275. the HAL_PCD_SuspendCallback could be implemented in the user file
  1276. */
  1277. }
  1278. /**
  1279. * @brief Resume event callback.
  1280. * @param hpcd PCD handle
  1281. * @retval None
  1282. */
  1283. __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
  1284. {
  1285. /* Prevent unused argument(s) compilation warning */
  1286. UNUSED(hpcd);
  1287. /* NOTE : This function should not be modified, when the callback is needed,
  1288. the HAL_PCD_ResumeCallback could be implemented in the user file
  1289. */
  1290. }
  1291. /**
  1292. * @brief Incomplete ISO OUT callback.
  1293. * @param hpcd PCD handle
  1294. * @param epnum endpoint number
  1295. * @retval None
  1296. */
  1297. __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1298. {
  1299. /* Prevent unused argument(s) compilation warning */
  1300. UNUSED(hpcd);
  1301. UNUSED(epnum);
  1302. /* NOTE : This function should not be modified, when the callback is needed,
  1303. the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
  1304. */
  1305. }
  1306. /**
  1307. * @brief Incomplete ISO IN callback.
  1308. * @param hpcd PCD handle
  1309. * @param epnum endpoint number
  1310. * @retval None
  1311. */
  1312. __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1313. {
  1314. /* Prevent unused argument(s) compilation warning */
  1315. UNUSED(hpcd);
  1316. UNUSED(epnum);
  1317. /* NOTE : This function should not be modified, when the callback is needed,
  1318. the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
  1319. */
  1320. }
  1321. /**
  1322. * @brief Connection event callback.
  1323. * @param hpcd PCD handle
  1324. * @retval None
  1325. */
  1326. __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
  1327. {
  1328. /* Prevent unused argument(s) compilation warning */
  1329. UNUSED(hpcd);
  1330. /* NOTE : This function should not be modified, when the callback is needed,
  1331. the HAL_PCD_ConnectCallback could be implemented in the user file
  1332. */
  1333. }
  1334. /**
  1335. * @brief Disconnection event callback.
  1336. * @param hpcd PCD handle
  1337. * @retval None
  1338. */
  1339. __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
  1340. {
  1341. /* Prevent unused argument(s) compilation warning */
  1342. UNUSED(hpcd);
  1343. /* NOTE : This function should not be modified, when the callback is needed,
  1344. the HAL_PCD_DisconnectCallback could be implemented in the user file
  1345. */
  1346. }
  1347. /**
  1348. * @}
  1349. */
  1350. /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
  1351. * @brief management functions
  1352. *
  1353. @verbatim
  1354. ===============================================================================
  1355. ##### Peripheral Control functions #####
  1356. ===============================================================================
  1357. [..]
  1358. This subsection provides a set of functions allowing to control the PCD data
  1359. transfers.
  1360. @endverbatim
  1361. * @{
  1362. */
  1363. /**
  1364. * @brief Connect the USB device
  1365. * @param hpcd PCD handle
  1366. * @retval HAL status
  1367. */
  1368. HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
  1369. {
  1370. #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
  1371. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  1372. #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
  1373. __HAL_LOCK(hpcd);
  1374. #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
  1375. if ((hpcd->Init.battery_charging_enable == 1U) &&
  1376. (hpcd->Init.phy_itface != USB_OTG_ULPI_PHY))
  1377. {
  1378. /* Enable USB Transceiver */
  1379. USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
  1380. }
  1381. #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
  1382. (void)USB_DevConnect(hpcd->Instance);
  1383. __HAL_UNLOCK(hpcd);
  1384. return HAL_OK;
  1385. }
  1386. /**
  1387. * @brief Disconnect the USB device.
  1388. * @param hpcd PCD handle
  1389. * @retval HAL status
  1390. */
  1391. HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
  1392. {
  1393. __HAL_LOCK(hpcd);
  1394. (void)USB_DevDisconnect(hpcd->Instance);
  1395. __HAL_UNLOCK(hpcd);
  1396. return HAL_OK;
  1397. }
  1398. /**
  1399. * @brief Set the USB Device address.
  1400. * @param hpcd PCD handle
  1401. * @param address new device address
  1402. * @retval HAL status
  1403. */
  1404. HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
  1405. {
  1406. __HAL_LOCK(hpcd);
  1407. hpcd->USB_Address = address;
  1408. (void)USB_SetDevAddress(hpcd->Instance, address);
  1409. __HAL_UNLOCK(hpcd);
  1410. return HAL_OK;
  1411. }
  1412. /**
  1413. * @brief Open and configure an endpoint.
  1414. * @param hpcd PCD handle
  1415. * @param ep_addr endpoint address
  1416. * @param ep_mps endpoint max packet size
  1417. * @param ep_type endpoint type
  1418. * @retval HAL status
  1419. */
  1420. HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
  1421. {
  1422. HAL_StatusTypeDef ret = HAL_OK;
  1423. PCD_EPTypeDef *ep;
  1424. if ((ep_addr & 0x80U) == 0x80U)
  1425. {
  1426. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1427. ep->is_in = 1U;
  1428. }
  1429. else
  1430. {
  1431. ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1432. ep->is_in = 0U;
  1433. }
  1434. ep->num = ep_addr & EP_ADDR_MSK;
  1435. ep->maxpacket = ep_mps;
  1436. ep->type = ep_type;
  1437. if (ep->is_in != 0U)
  1438. {
  1439. /* Assign a Tx FIFO */
  1440. ep->tx_fifo_num = ep->num;
  1441. }
  1442. /* Set initial data PID. */
  1443. if (ep_type == EP_TYPE_BULK)
  1444. {
  1445. ep->data_pid_start = 0U;
  1446. }
  1447. __HAL_LOCK(hpcd);
  1448. (void)USB_ActivateEndpoint(hpcd->Instance, ep);
  1449. __HAL_UNLOCK(hpcd);
  1450. return ret;
  1451. }
  1452. /**
  1453. * @brief Deactivate an endpoint.
  1454. * @param hpcd PCD handle
  1455. * @param ep_addr endpoint address
  1456. * @retval HAL status
  1457. */
  1458. HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1459. {
  1460. PCD_EPTypeDef *ep;
  1461. if ((ep_addr & 0x80U) == 0x80U)
  1462. {
  1463. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1464. ep->is_in = 1U;
  1465. }
  1466. else
  1467. {
  1468. ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1469. ep->is_in = 0U;
  1470. }
  1471. ep->num = ep_addr & EP_ADDR_MSK;
  1472. __HAL_LOCK(hpcd);
  1473. (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
  1474. __HAL_UNLOCK(hpcd);
  1475. return HAL_OK;
  1476. }
  1477. /**
  1478. * @brief Receive an amount of data.
  1479. * @param hpcd PCD handle
  1480. * @param ep_addr endpoint address
  1481. * @param pBuf pointer to the reception buffer
  1482. * @param len amount of data to be received
  1483. * @retval HAL status
  1484. */
  1485. HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  1486. {
  1487. PCD_EPTypeDef *ep;
  1488. ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1489. /*setup and start the Xfer */
  1490. ep->xfer_buff = pBuf;
  1491. ep->xfer_len = len;
  1492. ep->xfer_count = 0U;
  1493. ep->is_in = 0U;
  1494. ep->num = ep_addr & EP_ADDR_MSK;
  1495. if (hpcd->Init.dma_enable == 1U)
  1496. {
  1497. ep->dma_addr = (uint32_t)pBuf;
  1498. }
  1499. if ((ep_addr & EP_ADDR_MSK) == 0U)
  1500. {
  1501. (void)USB_EP0StartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable);
  1502. }
  1503. else
  1504. {
  1505. (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable);
  1506. }
  1507. return HAL_OK;
  1508. }
  1509. /**
  1510. * @brief Get Received Data Size
  1511. * @param hpcd PCD handle
  1512. * @param ep_addr endpoint address
  1513. * @retval Data Size
  1514. */
  1515. uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1516. {
  1517. return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count;
  1518. }
  1519. /**
  1520. * @brief Send an amount of data
  1521. * @param hpcd PCD handle
  1522. * @param ep_addr endpoint address
  1523. * @param pBuf pointer to the transmission buffer
  1524. * @param len amount of data to be sent
  1525. * @retval HAL status
  1526. */
  1527. HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  1528. {
  1529. PCD_EPTypeDef *ep;
  1530. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1531. /*setup and start the Xfer */
  1532. ep->xfer_buff = pBuf;
  1533. ep->xfer_len = len;
  1534. ep->xfer_count = 0U;
  1535. ep->is_in = 1U;
  1536. ep->num = ep_addr & EP_ADDR_MSK;
  1537. if (hpcd->Init.dma_enable == 1U)
  1538. {
  1539. ep->dma_addr = (uint32_t)pBuf;
  1540. }
  1541. if ((ep_addr & EP_ADDR_MSK) == 0U)
  1542. {
  1543. (void)USB_EP0StartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable);
  1544. }
  1545. else
  1546. {
  1547. (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable);
  1548. }
  1549. return HAL_OK;
  1550. }
  1551. /**
  1552. * @brief Set a STALL condition over an endpoint
  1553. * @param hpcd PCD handle
  1554. * @param ep_addr endpoint address
  1555. * @retval HAL status
  1556. */
  1557. HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1558. {
  1559. PCD_EPTypeDef *ep;
  1560. if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints)
  1561. {
  1562. return HAL_ERROR;
  1563. }
  1564. if ((0x80U & ep_addr) == 0x80U)
  1565. {
  1566. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1567. ep->is_in = 1U;
  1568. }
  1569. else
  1570. {
  1571. ep = &hpcd->OUT_ep[ep_addr];
  1572. ep->is_in = 0U;
  1573. }
  1574. ep->is_stall = 1U;
  1575. ep->num = ep_addr & EP_ADDR_MSK;
  1576. __HAL_LOCK(hpcd);
  1577. (void)USB_EPSetStall(hpcd->Instance, ep);
  1578. if ((ep_addr & EP_ADDR_MSK) == 0U)
  1579. {
  1580. (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup);
  1581. }
  1582. __HAL_UNLOCK(hpcd);
  1583. return HAL_OK;
  1584. }
  1585. /**
  1586. * @brief Clear a STALL condition over in an endpoint
  1587. * @param hpcd PCD handle
  1588. * @param ep_addr endpoint address
  1589. * @retval HAL status
  1590. */
  1591. HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1592. {
  1593. PCD_EPTypeDef *ep;
  1594. if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
  1595. {
  1596. return HAL_ERROR;
  1597. }
  1598. if ((0x80U & ep_addr) == 0x80U)
  1599. {
  1600. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1601. ep->is_in = 1U;
  1602. }
  1603. else
  1604. {
  1605. ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1606. ep->is_in = 0U;
  1607. }
  1608. ep->is_stall = 0U;
  1609. ep->num = ep_addr & EP_ADDR_MSK;
  1610. __HAL_LOCK(hpcd);
  1611. (void)USB_EPClearStall(hpcd->Instance, ep);
  1612. __HAL_UNLOCK(hpcd);
  1613. return HAL_OK;
  1614. }
  1615. /**
  1616. * @brief Flush an endpoint
  1617. * @param hpcd PCD handle
  1618. * @param ep_addr endpoint address
  1619. * @retval HAL status
  1620. */
  1621. HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1622. {
  1623. __HAL_LOCK(hpcd);
  1624. if ((ep_addr & 0x80U) == 0x80U)
  1625. {
  1626. (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & EP_ADDR_MSK);
  1627. }
  1628. else
  1629. {
  1630. (void)USB_FlushRxFifo(hpcd->Instance);
  1631. }
  1632. __HAL_UNLOCK(hpcd);
  1633. return HAL_OK;
  1634. }
  1635. /**
  1636. * @brief Activate remote wakeup signalling
  1637. * @param hpcd PCD handle
  1638. * @retval HAL status
  1639. */
  1640. HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1641. {
  1642. return (USB_ActivateRemoteWakeup(hpcd->Instance));
  1643. }
  1644. /**
  1645. * @brief De-activate remote wakeup signalling.
  1646. * @param hpcd PCD handle
  1647. * @retval HAL status
  1648. */
  1649. HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1650. {
  1651. return (USB_DeActivateRemoteWakeup(hpcd->Instance));
  1652. }
  1653. /**
  1654. * @}
  1655. */
  1656. /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
  1657. * @brief Peripheral State functions
  1658. *
  1659. @verbatim
  1660. ===============================================================================
  1661. ##### Peripheral State functions #####
  1662. ===============================================================================
  1663. [..]
  1664. This subsection permits to get in run-time the status of the peripheral
  1665. and the data flow.
  1666. @endverbatim
  1667. * @{
  1668. */
  1669. /**
  1670. * @brief Return the PCD handle state.
  1671. * @param hpcd PCD handle
  1672. * @retval HAL state
  1673. */
  1674. PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
  1675. {
  1676. return hpcd->State;
  1677. }
  1678. /**
  1679. * @}
  1680. */
  1681. /**
  1682. * @}
  1683. */
  1684. /* Private functions ---------------------------------------------------------*/
  1685. /** @addtogroup PCD_Private_Functions
  1686. * @{
  1687. */
  1688. #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
  1689. /**
  1690. * @brief Check FIFO for the next packet to be loaded.
  1691. * @param hpcd PCD handle
  1692. * @param epnum endpoint number
  1693. * @retval HAL status
  1694. */
  1695. static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
  1696. {
  1697. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  1698. uint32_t USBx_BASE = (uint32_t)USBx;
  1699. USB_OTG_EPTypeDef *ep;
  1700. uint32_t len;
  1701. uint32_t len32b;
  1702. uint32_t fifoemptymsk;
  1703. ep = &hpcd->IN_ep[epnum];
  1704. if (ep->xfer_count > ep->xfer_len)
  1705. {
  1706. return HAL_ERROR;
  1707. }
  1708. len = ep->xfer_len - ep->xfer_count;
  1709. if (len > ep->maxpacket)
  1710. {
  1711. len = ep->maxpacket;
  1712. }
  1713. len32b = (len + 3U) / 4U;
  1714. while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) &&
  1715. (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U))
  1716. {
  1717. /* Write the FIFO */
  1718. len = ep->xfer_len - ep->xfer_count;
  1719. if (len > ep->maxpacket)
  1720. {
  1721. len = ep->maxpacket;
  1722. }
  1723. len32b = (len + 3U) / 4U;
  1724. (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len,
  1725. (uint8_t)hpcd->Init.dma_enable);
  1726. ep->xfer_buff += len;
  1727. ep->xfer_count += len;
  1728. }
  1729. if (ep->xfer_len <= ep->xfer_count)
  1730. {
  1731. fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
  1732. USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
  1733. }
  1734. return HAL_OK;
  1735. }
  1736. /**
  1737. * @brief process EP OUT transfer complete interrupt.
  1738. * @param hpcd PCD handle
  1739. * @param epnum endpoint number
  1740. * @retval HAL status
  1741. */
  1742. static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
  1743. {
  1744. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  1745. uint32_t USBx_BASE = (uint32_t)USBx;
  1746. uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
  1747. uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
  1748. if (hpcd->Init.dma_enable == 1U)
  1749. {
  1750. if ((DoepintReg & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) /* Class C */
  1751. {
  1752. /* StupPktRcvd = 1 this is a setup packet */
  1753. if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
  1754. ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
  1755. {
  1756. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
  1757. }
  1758. /* Inform the upper layer that a setup packet is available */
  1759. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1760. hpcd->SetupStageCallback(hpcd);
  1761. #else
  1762. HAL_PCD_SetupStageCallback(hpcd);
  1763. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1764. (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
  1765. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
  1766. }
  1767. else if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) /* Class E */
  1768. {
  1769. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
  1770. }
  1771. else if ((DoepintReg & (USB_OTG_DOEPINT_STUP | USB_OTG_DOEPINT_OTEPSPR)) == 0U)
  1772. {
  1773. /* StupPktRcvd = 1 this is a setup packet */
  1774. if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
  1775. ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
  1776. {
  1777. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
  1778. }
  1779. else
  1780. {
  1781. /* out data packet received over EP0 */
  1782. hpcd->OUT_ep[epnum].xfer_count =
  1783. hpcd->OUT_ep[epnum].maxpacket -
  1784. (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ);
  1785. hpcd->OUT_ep[epnum].xfer_buff += hpcd->OUT_ep[epnum].maxpacket;
  1786. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1787. hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
  1788. #else
  1789. HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
  1790. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1791. if ((epnum == 0U) && (hpcd->OUT_ep[epnum].xfer_len == 0U))
  1792. {
  1793. /* this is ZLP, so prepare EP0 for next setup */
  1794. (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
  1795. }
  1796. }
  1797. }
  1798. else
  1799. {
  1800. /* ... */
  1801. }
  1802. }
  1803. else
  1804. {
  1805. if (gSNPSiD == USB_OTG_CORE_ID_310A)
  1806. {
  1807. /* StupPktRcvd = 1 this is a setup packet */
  1808. if ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)
  1809. {
  1810. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
  1811. }
  1812. else
  1813. {
  1814. if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
  1815. {
  1816. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
  1817. }
  1818. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1819. hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
  1820. #else
  1821. HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
  1822. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1823. }
  1824. }
  1825. else
  1826. {
  1827. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1828. hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
  1829. #else
  1830. HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
  1831. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1832. }
  1833. }
  1834. return HAL_OK;
  1835. }
  1836. /**
  1837. * @brief process EP OUT setup packet received interrupt.
  1838. * @param hpcd PCD handle
  1839. * @param epnum endpoint number
  1840. * @retval HAL status
  1841. */
  1842. static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
  1843. {
  1844. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  1845. uint32_t USBx_BASE = (uint32_t)USBx;
  1846. uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
  1847. uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
  1848. if (hpcd->Init.dma_enable == 1U)
  1849. {
  1850. /* StupPktRcvd = 1 pending setup packet int */
  1851. if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
  1852. ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
  1853. {
  1854. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
  1855. }
  1856. }
  1857. else
  1858. {
  1859. if ((gSNPSiD == USB_OTG_CORE_ID_310A) &&
  1860. ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
  1861. {
  1862. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
  1863. }
  1864. }
  1865. /* Inform the upper layer that a setup packet is available */
  1866. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1867. hpcd->SetupStageCallback(hpcd);
  1868. #else
  1869. HAL_PCD_SetupStageCallback(hpcd);
  1870. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1871. if ((gSNPSiD > USB_OTG_CORE_ID_300A) && (hpcd->Init.dma_enable == 1U))
  1872. {
  1873. (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
  1874. }
  1875. return HAL_OK;
  1876. }
  1877. #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
  1878. /**
  1879. * @}
  1880. */
  1881. #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
  1882. #endif /* HAL_PCD_MODULE_ENABLED */
  1883. /**
  1884. * @}
  1885. */
  1886. /**
  1887. * @}
  1888. */
  1889. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/