stm32h7xx_hal_pcd.c 61 KB

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