You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

stm32l1xx_hal_pcd.c 42KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680
  1. /**
  2. ******************************************************************************
  3. * @file stm32l1xx_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 "stm32l1xx_hal.h"
  49. /** @addtogroup STM32L1xx_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)
  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. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
  75. /**
  76. * @}
  77. */
  78. /* Exported functions --------------------------------------------------------*/
  79. /** @defgroup PCD_Exported_Functions PCD Exported Functions
  80. * @{
  81. */
  82. /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
  83. * @brief Initialization and Configuration functions
  84. *
  85. @verbatim
  86. ===============================================================================
  87. ##### Initialization and de-initialization functions #####
  88. ===============================================================================
  89. [..] This section provides functions allowing to:
  90. @endverbatim
  91. * @{
  92. */
  93. /**
  94. * @brief Initializes the PCD according to the specified
  95. * parameters in the PCD_InitTypeDef and initialize the associated handle.
  96. * @param hpcd PCD handle
  97. * @retval HAL status
  98. */
  99. HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
  100. {
  101. uint8_t i;
  102. /* Check the PCD handle allocation */
  103. if (hpcd == NULL)
  104. {
  105. return HAL_ERROR;
  106. }
  107. /* Check the parameters */
  108. assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
  109. if (hpcd->State == HAL_PCD_STATE_RESET)
  110. {
  111. /* Allocate lock resource and initialize it */
  112. hpcd->Lock = HAL_UNLOCKED;
  113. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  114. hpcd->SOFCallback = HAL_PCD_SOFCallback;
  115. hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
  116. hpcd->ResetCallback = HAL_PCD_ResetCallback;
  117. hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
  118. hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
  119. hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
  120. hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
  121. hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback;
  122. hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback;
  123. hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback;
  124. hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback;
  125. if (hpcd->MspInitCallback == NULL)
  126. {
  127. hpcd->MspInitCallback = HAL_PCD_MspInit;
  128. }
  129. /* Init the low level hardware */
  130. hpcd->MspInitCallback(hpcd);
  131. #else
  132. /* Init the low level hardware : GPIO, CLOCK, NVIC... */
  133. HAL_PCD_MspInit(hpcd);
  134. #endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */
  135. }
  136. hpcd->State = HAL_PCD_STATE_BUSY;
  137. /* Disable the Interrupts */
  138. __HAL_PCD_DISABLE(hpcd);
  139. /* Init endpoints structures */
  140. for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  141. {
  142. /* Init ep structure */
  143. hpcd->IN_ep[i].is_in = 1U;
  144. hpcd->IN_ep[i].num = i;
  145. hpcd->IN_ep[i].tx_fifo_num = i;
  146. /* Control until ep is activated */
  147. hpcd->IN_ep[i].type = EP_TYPE_CTRL;
  148. hpcd->IN_ep[i].maxpacket = 0U;
  149. hpcd->IN_ep[i].xfer_buff = 0U;
  150. hpcd->IN_ep[i].xfer_len = 0U;
  151. }
  152. for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  153. {
  154. hpcd->OUT_ep[i].is_in = 0U;
  155. hpcd->OUT_ep[i].num = i;
  156. /* Control until ep is activated */
  157. hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
  158. hpcd->OUT_ep[i].maxpacket = 0U;
  159. hpcd->OUT_ep[i].xfer_buff = 0U;
  160. hpcd->OUT_ep[i].xfer_len = 0U;
  161. }
  162. /* Init Device */
  163. (void)USB_DevInit(hpcd->Instance, hpcd->Init);
  164. hpcd->USB_Address = 0U;
  165. hpcd->State = HAL_PCD_STATE_READY;
  166. return HAL_OK;
  167. }
  168. /**
  169. * @brief DeInitializes the PCD peripheral.
  170. * @param hpcd PCD handle
  171. * @retval HAL status
  172. */
  173. HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
  174. {
  175. /* Check the PCD handle allocation */
  176. if (hpcd == NULL)
  177. {
  178. return HAL_ERROR;
  179. }
  180. hpcd->State = HAL_PCD_STATE_BUSY;
  181. /* Stop Device */
  182. (void)HAL_PCD_Stop(hpcd);
  183. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  184. if (hpcd->MspDeInitCallback == NULL)
  185. {
  186. hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit */
  187. }
  188. /* DeInit the low level hardware */
  189. hpcd->MspDeInitCallback(hpcd);
  190. #else
  191. /* DeInit the low level hardware: CLOCK, NVIC.*/
  192. HAL_PCD_MspDeInit(hpcd);
  193. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  194. hpcd->State = HAL_PCD_STATE_RESET;
  195. return HAL_OK;
  196. }
  197. /**
  198. * @brief Initializes the PCD MSP.
  199. * @param hpcd PCD handle
  200. * @retval None
  201. */
  202. __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
  203. {
  204. /* Prevent unused argument(s) compilation warning */
  205. UNUSED(hpcd);
  206. /* NOTE : This function should not be modified, when the callback is needed,
  207. the HAL_PCD_MspInit could be implemented in the user file
  208. */
  209. }
  210. /**
  211. * @brief DeInitializes PCD MSP.
  212. * @param hpcd PCD handle
  213. * @retval None
  214. */
  215. __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
  216. {
  217. /* Prevent unused argument(s) compilation warning */
  218. UNUSED(hpcd);
  219. /* NOTE : This function should not be modified, when the callback is needed,
  220. the HAL_PCD_MspDeInit could be implemented in the user file
  221. */
  222. }
  223. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  224. /**
  225. * @brief Register a User USB PCD Callback
  226. * To be used instead of the weak predefined callback
  227. * @param hpcd USB PCD handle
  228. * @param CallbackID ID of the callback to be registered
  229. * This parameter can be one of the following values:
  230. * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
  231. * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
  232. * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
  233. * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
  234. * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
  235. * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
  236. * @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
  237. * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
  238. * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
  239. * @param pCallback pointer to the Callback function
  240. * @retval HAL status
  241. */
  242. HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID, pPCD_CallbackTypeDef pCallback)
  243. {
  244. HAL_StatusTypeDef status = HAL_OK;
  245. if (pCallback == NULL)
  246. {
  247. /* Update the error code */
  248. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  249. return HAL_ERROR;
  250. }
  251. /* Process locked */
  252. __HAL_LOCK(hpcd);
  253. if (hpcd->State == HAL_PCD_STATE_READY)
  254. {
  255. switch (CallbackID)
  256. {
  257. case HAL_PCD_SOF_CB_ID :
  258. hpcd->SOFCallback = pCallback;
  259. break;
  260. case HAL_PCD_SETUPSTAGE_CB_ID :
  261. hpcd->SetupStageCallback = pCallback;
  262. break;
  263. case HAL_PCD_RESET_CB_ID :
  264. hpcd->ResetCallback = pCallback;
  265. break;
  266. case HAL_PCD_SUSPEND_CB_ID :
  267. hpcd->SuspendCallback = pCallback;
  268. break;
  269. case HAL_PCD_RESUME_CB_ID :
  270. hpcd->ResumeCallback = pCallback;
  271. break;
  272. case HAL_PCD_CONNECT_CB_ID :
  273. hpcd->ConnectCallback = pCallback;
  274. break;
  275. case HAL_PCD_DISCONNECT_CB_ID :
  276. hpcd->DisconnectCallback = pCallback;
  277. break;
  278. case HAL_PCD_MSPINIT_CB_ID :
  279. hpcd->MspInitCallback = pCallback;
  280. break;
  281. case HAL_PCD_MSPDEINIT_CB_ID :
  282. hpcd->MspDeInitCallback = pCallback;
  283. break;
  284. default :
  285. /* Update the error code */
  286. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  287. /* Return error status */
  288. status = HAL_ERROR;
  289. break;
  290. }
  291. }
  292. else if (hpcd->State == HAL_PCD_STATE_RESET)
  293. {
  294. switch (CallbackID)
  295. {
  296. case HAL_PCD_MSPINIT_CB_ID :
  297. hpcd->MspInitCallback = pCallback;
  298. break;
  299. case HAL_PCD_MSPDEINIT_CB_ID :
  300. hpcd->MspDeInitCallback = pCallback;
  301. break;
  302. default :
  303. /* Update the error code */
  304. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  305. /* Return error status */
  306. status = HAL_ERROR;
  307. break;
  308. }
  309. }
  310. else
  311. {
  312. /* Update the error code */
  313. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  314. /* Return error status */
  315. status = HAL_ERROR;
  316. }
  317. /* Release Lock */
  318. __HAL_UNLOCK(hpcd);
  319. return status;
  320. }
  321. /**
  322. * @brief Unregister an USB PCD Callback
  323. * USB PCD callabck is redirected to the weak predefined callback
  324. * @param hpcd USB PCD handle
  325. * @param CallbackID ID of the callback to be unregistered
  326. * This parameter can be one of the following values:
  327. * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
  328. * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
  329. * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
  330. * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
  331. * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
  332. * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
  333. * @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
  334. * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
  335. * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
  336. * @retval HAL status
  337. */
  338. HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID)
  339. {
  340. HAL_StatusTypeDef status = HAL_OK;
  341. /* Process locked */
  342. __HAL_LOCK(hpcd);
  343. /* Setup Legacy weak Callbacks */
  344. if (hpcd->State == HAL_PCD_STATE_READY)
  345. {
  346. switch (CallbackID)
  347. {
  348. case HAL_PCD_SOF_CB_ID :
  349. hpcd->SOFCallback = HAL_PCD_SOFCallback;
  350. break;
  351. case HAL_PCD_SETUPSTAGE_CB_ID :
  352. hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
  353. break;
  354. case HAL_PCD_RESET_CB_ID :
  355. hpcd->ResetCallback = HAL_PCD_ResetCallback;
  356. break;
  357. case HAL_PCD_SUSPEND_CB_ID :
  358. hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
  359. break;
  360. case HAL_PCD_RESUME_CB_ID :
  361. hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
  362. break;
  363. case HAL_PCD_CONNECT_CB_ID :
  364. hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
  365. break;
  366. case HAL_PCD_DISCONNECT_CB_ID :
  367. hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
  368. break;
  369. case HAL_PCD_MSPINIT_CB_ID :
  370. hpcd->MspInitCallback = HAL_PCD_MspInit;
  371. break;
  372. case HAL_PCD_MSPDEINIT_CB_ID :
  373. hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
  374. break;
  375. default :
  376. /* Update the error code */
  377. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  378. /* Return error status */
  379. status = HAL_ERROR;
  380. break;
  381. }
  382. }
  383. else if (hpcd->State == HAL_PCD_STATE_RESET)
  384. {
  385. switch (CallbackID)
  386. {
  387. case HAL_PCD_MSPINIT_CB_ID :
  388. hpcd->MspInitCallback = HAL_PCD_MspInit;
  389. break;
  390. case HAL_PCD_MSPDEINIT_CB_ID :
  391. hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
  392. break;
  393. default :
  394. /* Update the error code */
  395. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  396. /* Return error status */
  397. status = HAL_ERROR;
  398. break;
  399. }
  400. }
  401. else
  402. {
  403. /* Update the error code */
  404. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  405. /* Return error status */
  406. status = HAL_ERROR;
  407. }
  408. /* Release Lock */
  409. __HAL_UNLOCK(hpcd);
  410. return status;
  411. }
  412. /**
  413. * @brief Register USB PCD Data OUT Stage Callback
  414. * To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback
  415. * @param hpcd PCD handle
  416. * @param pCallback pointer to the USB PCD Data OUT Stage Callback function
  417. * @retval HAL status
  418. */
  419. HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataOutStageCallbackTypeDef pCallback)
  420. {
  421. HAL_StatusTypeDef status = HAL_OK;
  422. if (pCallback == NULL)
  423. {
  424. /* Update the error code */
  425. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  426. return HAL_ERROR;
  427. }
  428. /* Process locked */
  429. __HAL_LOCK(hpcd);
  430. if (hpcd->State == HAL_PCD_STATE_READY)
  431. {
  432. hpcd->DataOutStageCallback = pCallback;
  433. }
  434. else
  435. {
  436. /* Update the error code */
  437. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  438. /* Return error status */
  439. status = HAL_ERROR;
  440. }
  441. /* Release Lock */
  442. __HAL_UNLOCK(hpcd);
  443. return status;
  444. }
  445. /**
  446. * @brief UnRegister the USB PCD Data OUT Stage Callback
  447. * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback
  448. * @param hpcd PCD handle
  449. * @retval HAL status
  450. */
  451. HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd)
  452. {
  453. HAL_StatusTypeDef status = HAL_OK;
  454. /* Process locked */
  455. __HAL_LOCK(hpcd);
  456. if (hpcd->State == HAL_PCD_STATE_READY)
  457. {
  458. hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback */
  459. }
  460. else
  461. {
  462. /* Update the error code */
  463. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  464. /* Return error status */
  465. status = HAL_ERROR;
  466. }
  467. /* Release Lock */
  468. __HAL_UNLOCK(hpcd);
  469. return status;
  470. }
  471. /**
  472. * @brief Register USB PCD Data IN Stage Callback
  473. * To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback
  474. * @param hpcd PCD handle
  475. * @param pCallback pointer to the USB PCD Data IN Stage Callback function
  476. * @retval HAL status
  477. */
  478. HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataInStageCallbackTypeDef pCallback)
  479. {
  480. HAL_StatusTypeDef status = HAL_OK;
  481. if (pCallback == NULL)
  482. {
  483. /* Update the error code */
  484. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  485. return HAL_ERROR;
  486. }
  487. /* Process locked */
  488. __HAL_LOCK(hpcd);
  489. if (hpcd->State == HAL_PCD_STATE_READY)
  490. {
  491. hpcd->DataInStageCallback = pCallback;
  492. }
  493. else
  494. {
  495. /* Update the error code */
  496. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  497. /* Return error status */
  498. status = HAL_ERROR;
  499. }
  500. /* Release Lock */
  501. __HAL_UNLOCK(hpcd);
  502. return status;
  503. }
  504. /**
  505. * @brief UnRegister the USB PCD Data IN Stage Callback
  506. * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback
  507. * @param hpcd PCD handle
  508. * @retval HAL status
  509. */
  510. HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd)
  511. {
  512. HAL_StatusTypeDef status = HAL_OK;
  513. /* Process locked */
  514. __HAL_LOCK(hpcd);
  515. if (hpcd->State == HAL_PCD_STATE_READY)
  516. {
  517. hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback */
  518. }
  519. else
  520. {
  521. /* Update the error code */
  522. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  523. /* Return error status */
  524. status = HAL_ERROR;
  525. }
  526. /* Release Lock */
  527. __HAL_UNLOCK(hpcd);
  528. return status;
  529. }
  530. /**
  531. * @brief Register USB PCD Iso OUT incomplete Callback
  532. * To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
  533. * @param hpcd PCD handle
  534. * @param pCallback pointer to the USB PCD Iso OUT incomplete Callback function
  535. * @retval HAL status
  536. */
  537. HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoOutIncpltCallbackTypeDef pCallback)
  538. {
  539. HAL_StatusTypeDef status = HAL_OK;
  540. if (pCallback == NULL)
  541. {
  542. /* Update the error code */
  543. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  544. return HAL_ERROR;
  545. }
  546. /* Process locked */
  547. __HAL_LOCK(hpcd);
  548. if (hpcd->State == HAL_PCD_STATE_READY)
  549. {
  550. hpcd->ISOOUTIncompleteCallback = pCallback;
  551. }
  552. else
  553. {
  554. /* Update the error code */
  555. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  556. /* Return error status */
  557. status = HAL_ERROR;
  558. }
  559. /* Release Lock */
  560. __HAL_UNLOCK(hpcd);
  561. return status;
  562. }
  563. /**
  564. * @brief UnRegister the USB PCD Iso OUT incomplete Callback
  565. * USB PCD Iso OUT incomplete Callback is redirected to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
  566. * @param hpcd PCD handle
  567. * @retval HAL status
  568. */
  569. HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
  570. {
  571. HAL_StatusTypeDef status = HAL_OK;
  572. /* Process locked */
  573. __HAL_LOCK(hpcd);
  574. if (hpcd->State == HAL_PCD_STATE_READY)
  575. {
  576. hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback */
  577. }
  578. else
  579. {
  580. /* Update the error code */
  581. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  582. /* Return error status */
  583. status = HAL_ERROR;
  584. }
  585. /* Release Lock */
  586. __HAL_UNLOCK(hpcd);
  587. return status;
  588. }
  589. /**
  590. * @brief Register USB PCD Iso IN incomplete Callback
  591. * To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
  592. * @param hpcd PCD handle
  593. * @param pCallback pointer to the USB PCD Iso IN incomplete Callback function
  594. * @retval HAL status
  595. */
  596. HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoInIncpltCallbackTypeDef pCallback)
  597. {
  598. HAL_StatusTypeDef status = HAL_OK;
  599. if (pCallback == NULL)
  600. {
  601. /* Update the error code */
  602. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  603. return HAL_ERROR;
  604. }
  605. /* Process locked */
  606. __HAL_LOCK(hpcd);
  607. if (hpcd->State == HAL_PCD_STATE_READY)
  608. {
  609. hpcd->ISOINIncompleteCallback = pCallback;
  610. }
  611. else
  612. {
  613. /* Update the error code */
  614. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  615. /* Return error status */
  616. status = HAL_ERROR;
  617. }
  618. /* Release Lock */
  619. __HAL_UNLOCK(hpcd);
  620. return status;
  621. }
  622. /**
  623. * @brief UnRegister the USB PCD Iso IN incomplete Callback
  624. * USB PCD Iso IN incomplete Callback is redirected to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
  625. * @param hpcd PCD handle
  626. * @retval HAL status
  627. */
  628. HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
  629. {
  630. HAL_StatusTypeDef status = HAL_OK;
  631. /* Process locked */
  632. __HAL_LOCK(hpcd);
  633. if (hpcd->State == HAL_PCD_STATE_READY)
  634. {
  635. hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback */
  636. }
  637. else
  638. {
  639. /* Update the error code */
  640. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  641. /* Return error status */
  642. status = HAL_ERROR;
  643. }
  644. /* Release Lock */
  645. __HAL_UNLOCK(hpcd);
  646. return status;
  647. }
  648. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  649. /**
  650. * @}
  651. */
  652. /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
  653. * @brief Data transfers functions
  654. *
  655. @verbatim
  656. ===============================================================================
  657. ##### IO operation functions #####
  658. ===============================================================================
  659. [..]
  660. This subsection provides a set of functions allowing to manage the PCD data
  661. transfers.
  662. @endverbatim
  663. * @{
  664. */
  665. /**
  666. * @brief Start the USB device
  667. * @param hpcd PCD handle
  668. * @retval HAL status
  669. */
  670. HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
  671. {
  672. __HAL_LOCK(hpcd);
  673. HAL_PCDEx_SetConnectionState(hpcd, 1U);
  674. (void)USB_DevConnect(hpcd->Instance);
  675. __HAL_PCD_ENABLE(hpcd);
  676. __HAL_UNLOCK(hpcd);
  677. return HAL_OK;
  678. }
  679. /**
  680. * @brief Stop the USB device.
  681. * @param hpcd PCD handle
  682. * @retval HAL status
  683. */
  684. HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
  685. {
  686. __HAL_LOCK(hpcd);
  687. __HAL_PCD_DISABLE(hpcd);
  688. (void)USB_StopDevice(hpcd->Instance);
  689. __HAL_UNLOCK(hpcd);
  690. return HAL_OK;
  691. }
  692. /**
  693. * @brief This function handles PCD interrupt request.
  694. * @param hpcd PCD handle
  695. * @retval HAL status
  696. */
  697. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  698. {
  699. if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_CTR))
  700. {
  701. /* servicing of the endpoint correct transfer interrupt */
  702. /* clear of the CTR flag into the sub */
  703. (void)PCD_EP_ISR_Handler(hpcd);
  704. }
  705. if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_RESET))
  706. {
  707. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
  708. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  709. hpcd->ResetCallback(hpcd);
  710. #else
  711. HAL_PCD_ResetCallback(hpcd);
  712. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  713. (void)HAL_PCD_SetAddress(hpcd, 0U);
  714. }
  715. if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_PMAOVR))
  716. {
  717. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
  718. }
  719. if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ERR))
  720. {
  721. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
  722. }
  723. if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP))
  724. {
  725. hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LPMODE);
  726. hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP);
  727. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  728. hpcd->ResumeCallback(hpcd);
  729. #else
  730. HAL_PCD_ResumeCallback(hpcd);
  731. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  732. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
  733. }
  734. if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SUSP))
  735. {
  736. /* Force low-power mode in the macrocell */
  737. hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
  738. /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
  739. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
  740. hpcd->Instance->CNTR |= USB_CNTR_LPMODE;
  741. if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP) == 0U)
  742. {
  743. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  744. hpcd->SuspendCallback(hpcd);
  745. #else
  746. HAL_PCD_SuspendCallback(hpcd);
  747. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  748. }
  749. }
  750. if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SOF))
  751. {
  752. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
  753. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  754. hpcd->SOFCallback(hpcd);
  755. #else
  756. HAL_PCD_SOFCallback(hpcd);
  757. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  758. }
  759. if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ESOF))
  760. {
  761. /* clear ESOF flag in ISTR */
  762. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
  763. }
  764. }
  765. /**
  766. * @brief Data OUT stage callback.
  767. * @param hpcd PCD handle
  768. * @param epnum endpoint number
  769. * @retval None
  770. */
  771. __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  772. {
  773. /* Prevent unused argument(s) compilation warning */
  774. UNUSED(hpcd);
  775. UNUSED(epnum);
  776. /* NOTE : This function should not be modified, when the callback is needed,
  777. the HAL_PCD_DataOutStageCallback could be implemented in the user file
  778. */
  779. }
  780. /**
  781. * @brief Data IN stage callback
  782. * @param hpcd PCD handle
  783. * @param epnum endpoint number
  784. * @retval None
  785. */
  786. __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  787. {
  788. /* Prevent unused argument(s) compilation warning */
  789. UNUSED(hpcd);
  790. UNUSED(epnum);
  791. /* NOTE : This function should not be modified, when the callback is needed,
  792. the HAL_PCD_DataInStageCallback could be implemented in the user file
  793. */
  794. }
  795. /**
  796. * @brief Setup stage callback
  797. * @param hpcd PCD handle
  798. * @retval None
  799. */
  800. __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
  801. {
  802. /* Prevent unused argument(s) compilation warning */
  803. UNUSED(hpcd);
  804. /* NOTE : This function should not be modified, when the callback is needed,
  805. the HAL_PCD_SetupStageCallback could be implemented in the user file
  806. */
  807. }
  808. /**
  809. * @brief USB Start Of Frame callback.
  810. * @param hpcd PCD handle
  811. * @retval None
  812. */
  813. __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
  814. {
  815. /* Prevent unused argument(s) compilation warning */
  816. UNUSED(hpcd);
  817. /* NOTE : This function should not be modified, when the callback is needed,
  818. the HAL_PCD_SOFCallback could be implemented in the user file
  819. */
  820. }
  821. /**
  822. * @brief USB Reset callback.
  823. * @param hpcd PCD handle
  824. * @retval None
  825. */
  826. __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
  827. {
  828. /* Prevent unused argument(s) compilation warning */
  829. UNUSED(hpcd);
  830. /* NOTE : This function should not be modified, when the callback is needed,
  831. the HAL_PCD_ResetCallback could be implemented in the user file
  832. */
  833. }
  834. /**
  835. * @brief Suspend event callback.
  836. * @param hpcd PCD handle
  837. * @retval None
  838. */
  839. __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
  840. {
  841. /* Prevent unused argument(s) compilation warning */
  842. UNUSED(hpcd);
  843. /* NOTE : This function should not be modified, when the callback is needed,
  844. the HAL_PCD_SuspendCallback could be implemented in the user file
  845. */
  846. }
  847. /**
  848. * @brief Resume event callback.
  849. * @param hpcd PCD handle
  850. * @retval None
  851. */
  852. __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
  853. {
  854. /* Prevent unused argument(s) compilation warning */
  855. UNUSED(hpcd);
  856. /* NOTE : This function should not be modified, when the callback is needed,
  857. the HAL_PCD_ResumeCallback could be implemented in the user file
  858. */
  859. }
  860. /**
  861. * @brief Incomplete ISO OUT callback.
  862. * @param hpcd PCD handle
  863. * @param epnum endpoint number
  864. * @retval None
  865. */
  866. __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  867. {
  868. /* Prevent unused argument(s) compilation warning */
  869. UNUSED(hpcd);
  870. UNUSED(epnum);
  871. /* NOTE : This function should not be modified, when the callback is needed,
  872. the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
  873. */
  874. }
  875. /**
  876. * @brief Incomplete ISO IN callback.
  877. * @param hpcd PCD handle
  878. * @param epnum endpoint number
  879. * @retval None
  880. */
  881. __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  882. {
  883. /* Prevent unused argument(s) compilation warning */
  884. UNUSED(hpcd);
  885. UNUSED(epnum);
  886. /* NOTE : This function should not be modified, when the callback is needed,
  887. the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
  888. */
  889. }
  890. /**
  891. * @brief Connection event callback.
  892. * @param hpcd PCD handle
  893. * @retval None
  894. */
  895. __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
  896. {
  897. /* Prevent unused argument(s) compilation warning */
  898. UNUSED(hpcd);
  899. /* NOTE : This function should not be modified, when the callback is needed,
  900. the HAL_PCD_ConnectCallback could be implemented in the user file
  901. */
  902. }
  903. /**
  904. * @brief Disconnection event callback.
  905. * @param hpcd PCD handle
  906. * @retval None
  907. */
  908. __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
  909. {
  910. /* Prevent unused argument(s) compilation warning */
  911. UNUSED(hpcd);
  912. /* NOTE : This function should not be modified, when the callback is needed,
  913. the HAL_PCD_DisconnectCallback could be implemented in the user file
  914. */
  915. }
  916. /**
  917. * @}
  918. */
  919. /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
  920. * @brief management functions
  921. *
  922. @verbatim
  923. ===============================================================================
  924. ##### Peripheral Control functions #####
  925. ===============================================================================
  926. [..]
  927. This subsection provides a set of functions allowing to control the PCD data
  928. transfers.
  929. @endverbatim
  930. * @{
  931. */
  932. /**
  933. * @brief Connect the USB device
  934. * @param hpcd PCD handle
  935. * @retval HAL status
  936. */
  937. HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
  938. {
  939. __HAL_LOCK(hpcd);
  940. HAL_PCDEx_SetConnectionState(hpcd, 1U);
  941. (void)USB_DevConnect(hpcd->Instance);
  942. __HAL_UNLOCK(hpcd);
  943. return HAL_OK;
  944. }
  945. /**
  946. * @brief Disconnect the USB device.
  947. * @param hpcd PCD handle
  948. * @retval HAL status
  949. */
  950. HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
  951. {
  952. __HAL_LOCK(hpcd);
  953. HAL_PCDEx_SetConnectionState(hpcd, 0U);
  954. (void)USB_DevDisconnect(hpcd->Instance);
  955. __HAL_UNLOCK(hpcd);
  956. return HAL_OK;
  957. }
  958. /**
  959. * @brief Set the USB Device address.
  960. * @param hpcd PCD handle
  961. * @param address new device address
  962. * @retval HAL status
  963. */
  964. HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
  965. {
  966. __HAL_LOCK(hpcd);
  967. hpcd->USB_Address = address;
  968. (void)USB_SetDevAddress(hpcd->Instance, address);
  969. __HAL_UNLOCK(hpcd);
  970. return HAL_OK;
  971. }
  972. /**
  973. * @brief Open and configure an endpoint.
  974. * @param hpcd PCD handle
  975. * @param ep_addr endpoint address
  976. * @param ep_mps endpoint max packet size
  977. * @param ep_type endpoint type
  978. * @retval HAL status
  979. */
  980. HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
  981. {
  982. HAL_StatusTypeDef ret = HAL_OK;
  983. PCD_EPTypeDef *ep;
  984. if ((ep_addr & 0x80U) == 0x80U)
  985. {
  986. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  987. ep->is_in = 1U;
  988. }
  989. else
  990. {
  991. ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  992. ep->is_in = 0U;
  993. }
  994. ep->num = ep_addr & EP_ADDR_MSK;
  995. ep->maxpacket = ep_mps;
  996. ep->type = ep_type;
  997. if (ep->is_in != 0U)
  998. {
  999. /* Assign a Tx FIFO */
  1000. ep->tx_fifo_num = ep->num;
  1001. }
  1002. /* Set initial data PID. */
  1003. if (ep_type == EP_TYPE_BULK)
  1004. {
  1005. ep->data_pid_start = 0U;
  1006. }
  1007. __HAL_LOCK(hpcd);
  1008. (void)USB_ActivateEndpoint(hpcd->Instance, ep);
  1009. __HAL_UNLOCK(hpcd);
  1010. return ret;
  1011. }
  1012. /**
  1013. * @brief Deactivate an endpoint.
  1014. * @param hpcd PCD handle
  1015. * @param ep_addr endpoint address
  1016. * @retval HAL status
  1017. */
  1018. HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1019. {
  1020. PCD_EPTypeDef *ep;
  1021. if ((ep_addr & 0x80U) == 0x80U)
  1022. {
  1023. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1024. ep->is_in = 1U;
  1025. }
  1026. else
  1027. {
  1028. ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1029. ep->is_in = 0U;
  1030. }
  1031. ep->num = ep_addr & EP_ADDR_MSK;
  1032. __HAL_LOCK(hpcd);
  1033. (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
  1034. __HAL_UNLOCK(hpcd);
  1035. return HAL_OK;
  1036. }
  1037. /**
  1038. * @brief Receive an amount of data.
  1039. * @param hpcd PCD handle
  1040. * @param ep_addr endpoint address
  1041. * @param pBuf pointer to the reception buffer
  1042. * @param len amount of data to be received
  1043. * @retval HAL status
  1044. */
  1045. HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  1046. {
  1047. PCD_EPTypeDef *ep;
  1048. ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1049. /*setup and start the Xfer */
  1050. ep->xfer_buff = pBuf;
  1051. ep->xfer_len = len;
  1052. ep->xfer_count = 0U;
  1053. ep->is_in = 0U;
  1054. ep->num = ep_addr & EP_ADDR_MSK;
  1055. if ((ep_addr & EP_ADDR_MSK) == 0U)
  1056. {
  1057. (void)USB_EP0StartXfer(hpcd->Instance, ep);
  1058. }
  1059. else
  1060. {
  1061. (void)USB_EPStartXfer(hpcd->Instance, ep);
  1062. }
  1063. return HAL_OK;
  1064. }
  1065. /**
  1066. * @brief Get Received Data Size
  1067. * @param hpcd PCD handle
  1068. * @param ep_addr endpoint address
  1069. * @retval Data Size
  1070. */
  1071. uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1072. {
  1073. return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count;
  1074. }
  1075. /**
  1076. * @brief Send an amount of data
  1077. * @param hpcd PCD handle
  1078. * @param ep_addr endpoint address
  1079. * @param pBuf pointer to the transmission buffer
  1080. * @param len amount of data to be sent
  1081. * @retval HAL status
  1082. */
  1083. HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  1084. {
  1085. PCD_EPTypeDef *ep;
  1086. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1087. /*setup and start the Xfer */
  1088. ep->xfer_buff = pBuf;
  1089. ep->xfer_len = len;
  1090. ep->xfer_count = 0U;
  1091. ep->is_in = 1U;
  1092. ep->num = ep_addr & EP_ADDR_MSK;
  1093. if ((ep_addr & EP_ADDR_MSK) == 0U)
  1094. {
  1095. (void)USB_EP0StartXfer(hpcd->Instance, ep);
  1096. }
  1097. else
  1098. {
  1099. (void)USB_EPStartXfer(hpcd->Instance, ep);
  1100. }
  1101. return HAL_OK;
  1102. }
  1103. /**
  1104. * @brief Set a STALL condition over an endpoint
  1105. * @param hpcd PCD handle
  1106. * @param ep_addr endpoint address
  1107. * @retval HAL status
  1108. */
  1109. HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1110. {
  1111. PCD_EPTypeDef *ep;
  1112. if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints)
  1113. {
  1114. return HAL_ERROR;
  1115. }
  1116. if ((0x80U & ep_addr) == 0x80U)
  1117. {
  1118. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1119. ep->is_in = 1U;
  1120. }
  1121. else
  1122. {
  1123. ep = &hpcd->OUT_ep[ep_addr];
  1124. ep->is_in = 0U;
  1125. }
  1126. ep->is_stall = 1U;
  1127. ep->num = ep_addr & EP_ADDR_MSK;
  1128. __HAL_LOCK(hpcd);
  1129. (void)USB_EPSetStall(hpcd->Instance, ep);
  1130. if ((ep_addr & EP_ADDR_MSK) == 0U)
  1131. {
  1132. (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
  1133. }
  1134. __HAL_UNLOCK(hpcd);
  1135. return HAL_OK;
  1136. }
  1137. /**
  1138. * @brief Clear a STALL condition over in an endpoint
  1139. * @param hpcd PCD handle
  1140. * @param ep_addr endpoint address
  1141. * @retval HAL status
  1142. */
  1143. HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1144. {
  1145. PCD_EPTypeDef *ep;
  1146. if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
  1147. {
  1148. return HAL_ERROR;
  1149. }
  1150. if ((0x80U & ep_addr) == 0x80U)
  1151. {
  1152. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1153. ep->is_in = 1U;
  1154. }
  1155. else
  1156. {
  1157. ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1158. ep->is_in = 0U;
  1159. }
  1160. ep->is_stall = 0U;
  1161. ep->num = ep_addr & EP_ADDR_MSK;
  1162. __HAL_LOCK(hpcd);
  1163. (void)USB_EPClearStall(hpcd->Instance, ep);
  1164. __HAL_UNLOCK(hpcd);
  1165. return HAL_OK;
  1166. }
  1167. /**
  1168. * @brief Flush an endpoint
  1169. * @param hpcd PCD handle
  1170. * @param ep_addr endpoint address
  1171. * @retval HAL status
  1172. */
  1173. HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1174. {
  1175. /* Prevent unused argument(s) compilation warning */
  1176. UNUSED(hpcd);
  1177. UNUSED(ep_addr);
  1178. return HAL_OK;
  1179. }
  1180. /**
  1181. * @brief Activate remote wakeup signalling
  1182. * @param hpcd PCD handle
  1183. * @retval HAL status
  1184. */
  1185. HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1186. {
  1187. return (USB_ActivateRemoteWakeup(hpcd->Instance));
  1188. }
  1189. /**
  1190. * @brief De-activate remote wakeup signalling.
  1191. * @param hpcd PCD handle
  1192. * @retval HAL status
  1193. */
  1194. HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1195. {
  1196. return (USB_DeActivateRemoteWakeup(hpcd->Instance));
  1197. }
  1198. /**
  1199. * @}
  1200. */
  1201. /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
  1202. * @brief Peripheral State functions
  1203. *
  1204. @verbatim
  1205. ===============================================================================
  1206. ##### Peripheral State functions #####
  1207. ===============================================================================
  1208. [..]
  1209. This subsection permits to get in run-time the status of the peripheral
  1210. and the data flow.
  1211. @endverbatim
  1212. * @{
  1213. */
  1214. /**
  1215. * @brief Return the PCD handle state.
  1216. * @param hpcd PCD handle
  1217. * @retval HAL state
  1218. */
  1219. PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
  1220. {
  1221. return hpcd->State;
  1222. }
  1223. /**
  1224. * @}
  1225. */
  1226. /**
  1227. * @}
  1228. */
  1229. /* Private functions ---------------------------------------------------------*/
  1230. /** @addtogroup PCD_Private_Functions
  1231. * @{
  1232. */
  1233. /**
  1234. * @brief This function handles PCD Endpoint interrupt request.
  1235. * @param hpcd PCD handle
  1236. * @retval HAL status
  1237. */
  1238. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
  1239. {
  1240. PCD_EPTypeDef *ep;
  1241. uint16_t count;
  1242. uint16_t wIstr;
  1243. uint16_t wEPVal;
  1244. uint8_t epindex;
  1245. /* stay in loop while pending interrupts */
  1246. while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U)
  1247. {
  1248. wIstr = hpcd->Instance->ISTR;
  1249. /* extract highest priority endpoint number */
  1250. epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
  1251. if (epindex == 0U)
  1252. {
  1253. /* Decode and service control endpoint interrupt */
  1254. /* DIR bit = origin of the interrupt */
  1255. if ((wIstr & USB_ISTR_DIR) == 0U)
  1256. {
  1257. /* DIR = 0 */
  1258. /* DIR = 0 => IN int */
  1259. /* DIR = 0 implies that (EP_CTR_TX = 1) always */
  1260. PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1261. ep = &hpcd->IN_ep[0];
  1262. ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  1263. ep->xfer_buff += ep->xfer_count;
  1264. /* TX COMPLETE */
  1265. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1266. hpcd->DataInStageCallback(hpcd, 0U);
  1267. #else
  1268. HAL_PCD_DataInStageCallback(hpcd, 0U);
  1269. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1270. if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U))
  1271. {
  1272. hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF);
  1273. hpcd->USB_Address = 0U;
  1274. }
  1275. }
  1276. else
  1277. {
  1278. /* DIR = 1 */
  1279. /* DIR = 1 & CTR_RX => SETUP or OUT int */
  1280. /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
  1281. ep = &hpcd->OUT_ep[0];
  1282. wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
  1283. if ((wEPVal & USB_EP_SETUP) != 0U)
  1284. {
  1285. /* Get SETUP Packet*/
  1286. ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1287. USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup, ep->pmaadress, (uint16_t)ep->xfer_count);
  1288. /* SETUP bit kept frozen while CTR_RX = 1*/
  1289. PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1290. /* Process SETUP Packet*/
  1291. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1292. hpcd->SetupStageCallback(hpcd);
  1293. #else
  1294. HAL_PCD_SetupStageCallback(hpcd);
  1295. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1296. }
  1297. else if ((wEPVal & USB_EP_CTR_RX) != 0U)
  1298. {
  1299. PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1300. /* Get Control Data OUT Packet*/
  1301. ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1302. if (ep->xfer_count != 0U)
  1303. {
  1304. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, (uint16_t)ep->xfer_count);
  1305. ep->xfer_buff += ep->xfer_count;
  1306. }
  1307. /* Process Control Data OUT Packet*/
  1308. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1309. hpcd->DataOutStageCallback(hpcd, 0U);
  1310. #else
  1311. HAL_PCD_DataOutStageCallback(hpcd, 0U);
  1312. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1313. PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
  1314. PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
  1315. }
  1316. }
  1317. }
  1318. else
  1319. {
  1320. /* Decode and service non control endpoints interrupt */
  1321. /* process related endpoint register */
  1322. wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
  1323. if ((wEPVal & USB_EP_CTR_RX) != 0U)
  1324. {
  1325. /* clear int flag */
  1326. PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
  1327. ep = &hpcd->OUT_ep[epindex];
  1328. /* OUT double Buffering*/
  1329. if (ep->doublebuffer == 0U)
  1330. {
  1331. count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1332. if (count != 0U)
  1333. {
  1334. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
  1335. }
  1336. }
  1337. else
  1338. {
  1339. if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U)
  1340. {
  1341. /*read from endpoint BUF0Addr buffer*/
  1342. count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  1343. if (count != 0U)
  1344. {
  1345. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
  1346. }
  1347. }
  1348. else
  1349. {
  1350. /*read from endpoint BUF1Addr buffer*/
  1351. count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  1352. if (count != 0U)
  1353. {
  1354. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
  1355. }
  1356. }
  1357. /* free EP OUT Buffer */
  1358. PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U);
  1359. }
  1360. /*multi-packet on the NON control OUT endpoint*/
  1361. ep->xfer_count += count;
  1362. ep->xfer_buff += count;
  1363. if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
  1364. {
  1365. /* RX COMPLETE */
  1366. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1367. hpcd->DataOutStageCallback(hpcd, ep->num);
  1368. #else
  1369. HAL_PCD_DataOutStageCallback(hpcd, ep->num);
  1370. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1371. }
  1372. else
  1373. {
  1374. (void)HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
  1375. }
  1376. } /* if((wEPVal & EP_CTR_RX) */
  1377. if ((wEPVal & USB_EP_CTR_TX) != 0U)
  1378. {
  1379. ep = &hpcd->IN_ep[epindex];
  1380. /* clear int flag */
  1381. PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
  1382. /*multi-packet on the NON control IN endpoint*/
  1383. ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  1384. ep->xfer_buff += ep->xfer_count;
  1385. /* Zero Length Packet? */
  1386. if (ep->xfer_len == 0U)
  1387. {
  1388. /* TX COMPLETE */
  1389. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1390. hpcd->DataInStageCallback(hpcd, ep->num);
  1391. #else
  1392. HAL_PCD_DataInStageCallback(hpcd, ep->num);
  1393. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1394. }
  1395. else
  1396. {
  1397. (void)HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
  1398. }
  1399. }
  1400. }
  1401. }
  1402. return HAL_OK;
  1403. }
  1404. /**
  1405. * @}
  1406. */
  1407. #endif /* defined (USB) */
  1408. #endif /* HAL_PCD_MODULE_ENABLED */
  1409. /**
  1410. * @}
  1411. */
  1412. /**
  1413. * @}
  1414. */
  1415. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/