stm32f7xx_hal_pcd.c 61 KB

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