stm32f1xx_hal_pcd.c 66 KB

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