stm32f3xx_hal_pcd.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341
  1. /*
  2. * modified by ARM
  3. */
  4. /**
  5. ******************************************************************************
  6. * @file stm32f3xx_hal_pcd.c
  7. * @author MCD Application Team
  8. * @brief PCD HAL module driver.
  9. * This file provides firmware functions to manage the following
  10. * functionalities of the USB Peripheral Controller:
  11. * + Initialization and de-initialization functions
  12. * + IO operation functions
  13. * + Peripheral Control functions
  14. * + Peripheral State functions
  15. *
  16. @verbatim
  17. ==============================================================================
  18. ##### How to use this driver #####
  19. ==============================================================================
  20. [..]
  21. The PCD HAL driver can be used as follows:
  22. (#) Declare a PCD_HandleTypeDef handle structure, for example:
  23. PCD_HandleTypeDef hpcd;
  24. (#) Fill parameters of Init structure in HCD handle
  25. (#) Call HAL_PCD_Init() API to initialize the HCD peripheral (Core, Device core, ...)
  26. (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
  27. (##) Enable the PCD/USB Low Level interface clock using
  28. (+++) __HAL_RCC_USB_CLK_ENABLE();
  29. (##) Initialize the related GPIO clocks
  30. (##) Configure PCD pin-out
  31. (##) Configure PCD NVIC interrupt
  32. (#)Associate the Upper USB device stack to the HAL PCD Driver:
  33. (##) hpcd.pData = pdev;
  34. (#)Enable HCD transmission and reception:
  35. (##) HAL_PCD_Start();
  36. @endverbatim
  37. ******************************************************************************
  38. * @attention
  39. *
  40. * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
  41. *
  42. * Redistribution and use in source and binary forms, with or without modification,
  43. * are permitted provided that the following conditions are met:
  44. * 1. Redistributions of source code must retain the above copyright notice,
  45. * this list of conditions and the following disclaimer.
  46. * 2. Redistributions in binary form must reproduce the above copyright notice,
  47. * this list of conditions and the following disclaimer in the documentation
  48. * and/or other materials provided with the distribution.
  49. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  50. * may be used to endorse or promote products derived from this software
  51. * without specific prior written permission.
  52. *
  53. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  54. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  55. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  56. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  57. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  58. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  59. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  60. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  61. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  62. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  63. *
  64. ******************************************************************************
  65. */
  66. /* Includes ------------------------------------------------------------------*/
  67. #include "stm32f3xx_hal.h"
  68. #ifdef HAL_PCD_MODULE_ENABLED
  69. #if defined(STM32F302xE) || defined(STM32F303xE) || \
  70. defined(STM32F302xC) || defined(STM32F303xC) || \
  71. defined(STM32F302x8) || \
  72. defined(STM32F373xC)
  73. /** @addtogroup STM32F3xx_HAL_Driver
  74. * @{
  75. */
  76. /** @defgroup PCD PCD
  77. * @brief PCD HAL module driver
  78. * @{
  79. */
  80. /* Private typedef -----------------------------------------------------------*/
  81. /* Private define ------------------------------------------------------------*/
  82. /** @defgroup PCD_Private_Define PCD Private Define
  83. * @{
  84. */
  85. #define BTABLE_ADDRESS (0x000U)
  86. /**
  87. * @}
  88. */
  89. /* Private macro -------------------------------------------------------------*/
  90. /* Private variables ---------------------------------------------------------*/
  91. /* Private function prototypes -----------------------------------------------*/
  92. /** @defgroup PCD_Private_Functions PCD Private Functions
  93. * @{
  94. */
  95. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
  96. /**
  97. * @}
  98. */
  99. /* Exported functions ---------------------------------------------------------*/
  100. /** @defgroup PCD_Exported_Functions PCD Exported Functions
  101. * @{
  102. */
  103. /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
  104. * @brief Initialization and Configuration functions
  105. *
  106. @verbatim
  107. ===============================================================================
  108. ##### Initialization and de-initialization functions #####
  109. ===============================================================================
  110. [..] This section provides functions allowing to:
  111. @endverbatim
  112. * @{
  113. */
  114. /**
  115. * @brief Initializes the PCD according to the specified
  116. * parameters in the PCD_InitTypeDef and create the associated handle.
  117. * @param hpcd PCD handle
  118. * @retval HAL status
  119. */
  120. HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
  121. {
  122. uint32_t i = 0U;
  123. uint32_t wInterrupt_Mask = 0U;
  124. /* Check the PCD handle allocation */
  125. if(hpcd == NULL)
  126. {
  127. return HAL_ERROR;
  128. }
  129. /* Check the parameters */
  130. assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
  131. if(hpcd->State == HAL_PCD_STATE_RESET)
  132. {
  133. /* Allocate lock resource and initialize it */
  134. hpcd->Lock = HAL_UNLOCKED;
  135. /* Init the low level hardware : GPIO, CLOCK, NVIC... */
  136. HAL_PCD_MspInit(hpcd);
  137. }
  138. hpcd->State = HAL_PCD_STATE_BUSY;
  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. /* Control until ep is actvated */
  146. hpcd->IN_ep[i].type = PCD_EP_TYPE_CTRL;
  147. hpcd->IN_ep[i].maxpacket = 0U;
  148. hpcd->IN_ep[i].xfer_buff = 0U;
  149. hpcd->IN_ep[i].xfer_len = 0U;
  150. }
  151. for (i = 0U; i < hpcd->Init.dev_endpoints ; i++)
  152. {
  153. hpcd->OUT_ep[i].is_in = 0U;
  154. hpcd->OUT_ep[i].num = i;
  155. /* Control until ep is activated */
  156. hpcd->OUT_ep[i].type = PCD_EP_TYPE_CTRL;
  157. hpcd->OUT_ep[i].maxpacket = 0U;
  158. hpcd->OUT_ep[i].xfer_buff = 0U;
  159. hpcd->OUT_ep[i].xfer_len = 0U;
  160. }
  161. /* Init Device */
  162. /*CNTR_FRES = 1U*/
  163. hpcd->Instance->CNTR = USB_CNTR_FRES;
  164. /*CNTR_FRES = 0U*/
  165. hpcd->Instance->CNTR = 0U;
  166. /*Clear pending interrupts*/
  167. hpcd->Instance->ISTR = 0U;
  168. /*Set Btable Adress*/
  169. hpcd->Instance->BTABLE = BTABLE_ADDRESS;
  170. /*set wInterrupt_Mask global variable*/
  171. wInterrupt_Mask = USB_CNTR_CTRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \
  172. | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_RESETM;
  173. /*Set interrupt mask*/
  174. hpcd->Instance->CNTR = wInterrupt_Mask;
  175. hpcd->USB_Address = 0U;
  176. hpcd->State= HAL_PCD_STATE_READY;
  177. return HAL_OK;
  178. }
  179. /**
  180. * @brief DeInitializes the PCD peripheral
  181. * @param hpcd PCD handle
  182. * @retval HAL status
  183. */
  184. HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
  185. {
  186. /* Check the PCD handle allocation */
  187. if(hpcd == NULL)
  188. {
  189. return HAL_ERROR;
  190. }
  191. hpcd->State = HAL_PCD_STATE_BUSY;
  192. /* Stop Device */
  193. HAL_PCD_Stop(hpcd);
  194. /* DeInit the low level hardware */
  195. HAL_PCD_MspDeInit(hpcd);
  196. hpcd->State = HAL_PCD_STATE_RESET;
  197. return HAL_OK;
  198. }
  199. /**
  200. * @brief Initializes the PCD MSP.
  201. * @param hpcd PCD handle
  202. * @retval None
  203. */
  204. __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
  205. {
  206. /* Prevent unused argument(s) compilation warning */
  207. UNUSED(hpcd);
  208. /* NOTE : This function should not be modified, when the callback is needed,
  209. the HAL_PCD_MspInit could be implemented in the user file
  210. */
  211. }
  212. /**
  213. * @brief DeInitializes PCD MSP.
  214. * @param hpcd PCD handle
  215. * @retval None
  216. */
  217. __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
  218. {
  219. /* Prevent unused argument(s) compilation warning */
  220. UNUSED(hpcd);
  221. /* NOTE : This function should not be modified, when the callback is needed,
  222. the HAL_PCD_MspDeInit could be implemented in the user file
  223. */
  224. }
  225. /**
  226. * @}
  227. */
  228. /** @defgroup PCD_Exported_Functions_Group2 IO operation functions
  229. * @brief Data transfers functions
  230. *
  231. @verbatim
  232. ===============================================================================
  233. ##### IO operation functions #####
  234. ===============================================================================
  235. [..]
  236. This subsection provides a set of functions allowing to manage the PCD data
  237. transfers.
  238. @endverbatim
  239. * @{
  240. */
  241. /**
  242. * @brief Start the USB device.
  243. * @param hpcd PCD handle
  244. * @retval HAL status
  245. */
  246. HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
  247. {
  248. /* DP Pull-Down is external */
  249. HAL_PCDEx_SetConnectionState (hpcd, 1U);
  250. return HAL_OK;
  251. }
  252. /**
  253. * @brief Stop the USB device.
  254. * @param hpcd PCD handle
  255. * @retval HAL status
  256. */
  257. HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
  258. {
  259. __HAL_LOCK(hpcd);
  260. /* disable all interrupts and force USB reset */
  261. hpcd->Instance->CNTR = USB_CNTR_FRES;
  262. /* clear interrupt status register */
  263. hpcd->Instance->ISTR = 0U;
  264. /* switch-off device */
  265. hpcd->Instance->CNTR = (USB_CNTR_FRES | USB_CNTR_PDWN);
  266. __HAL_UNLOCK(hpcd);
  267. return HAL_OK;
  268. }
  269. /**
  270. * @}
  271. */
  272. /**
  273. * @}
  274. */
  275. /** @addtogroup PCD_Private_Functions PCD Private Functions
  276. * @{
  277. */
  278. /**
  279. * @brief This function handles PCD Endpoint interrupt request.
  280. * @param hpcd PCD handle
  281. * @retval HAL status
  282. */
  283. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
  284. {
  285. PCD_EPTypeDef *ep;
  286. uint16_t count=0U;
  287. uint8_t EPindex;
  288. __IO uint16_t wIstr;
  289. __IO uint16_t wEPVal = 0U;
  290. /* stay in loop while pending interrupts */
  291. while (((wIstr = hpcd->Instance->ISTR) & USB_ISTR_CTR) != 0U)
  292. {
  293. /* extract highest priority endpoint number */
  294. EPindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
  295. if (EPindex == 0U)
  296. {
  297. /* Decode and service control endpoint interrupt */
  298. /* DIR bit = origin of the interrupt */
  299. if ((wIstr & USB_ISTR_DIR) == 0U)
  300. {
  301. /* DIR = 0U */
  302. /* DIR = 0 => IN int */
  303. /* DIR = 0 implies that (EP_CTR_TX = 1U) always */
  304. PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  305. ep = &hpcd->IN_ep[0];
  306. ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  307. ep->xfer_buff += ep->xfer_count;
  308. /* TX COMPLETE */
  309. HAL_PCD_DataInStageCallback(hpcd, 0U);
  310. if((hpcd->USB_Address > 0U)&& ( ep->xfer_len == 0U))
  311. {
  312. hpcd->Instance->DADDR = (hpcd->USB_Address | USB_DADDR_EF);
  313. hpcd->USB_Address = 0U;
  314. }
  315. }
  316. else
  317. {
  318. /* DIR = 1U */
  319. /* DIR = 1U & CTR_RX => SETUP or OUT int */
  320. /* DIR = 1U & (CTR_TX | CTR_RX) => 2 int pending */
  321. ep = &hpcd->OUT_ep[0];
  322. wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
  323. if ((wEPVal & USB_EP_SETUP) != 0U)
  324. {
  325. /* Get SETUP Packet*/
  326. ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  327. PCD_ReadPMA(hpcd->Instance, (uint8_t*)(void*)hpcd->Setup ,ep->pmaadress , ep->xfer_count);
  328. /* SETUP bit kept frozen while CTR_RX = 1U*/
  329. PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  330. /* Process SETUP Packet*/
  331. HAL_PCD_SetupStageCallback(hpcd);
  332. }
  333. else if ((wEPVal & USB_EP_CTR_RX) != 0U)
  334. {
  335. PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  336. /* Get Control Data OUT Packet*/
  337. ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  338. if (ep->xfer_count != 0U)
  339. {
  340. PCD_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, ep->xfer_count);
  341. ep->xfer_buff+=ep->xfer_count;
  342. }
  343. /* Process Control Data OUT Packet*/
  344. HAL_PCD_DataOutStageCallback(hpcd, 0U);
  345. PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket)
  346. PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID)
  347. }
  348. }
  349. }
  350. else
  351. {
  352. /* Decode and service non control endpoints interrupt */
  353. /* process related endpoint register */
  354. wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, EPindex);
  355. if ((wEPVal & USB_EP_CTR_RX) != 0U)
  356. {
  357. /* clear int flag */
  358. PCD_CLEAR_RX_EP_CTR(hpcd->Instance, EPindex);
  359. ep = &hpcd->OUT_ep[EPindex];
  360. /* OUT double Buffering*/
  361. if (ep->doublebuffer == 0U)
  362. {
  363. count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  364. if (count != 0U)
  365. {
  366. PCD_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
  367. }
  368. }
  369. else
  370. {
  371. if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num)& USB_EP_DTOG_RX) == USB_EP_DTOG_RX)
  372. {
  373. /*read from endpoint BUF0Addr buffer*/
  374. count = PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  375. if (count != 0U)
  376. {
  377. PCD_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
  378. }
  379. }
  380. else
  381. {
  382. /*read from endpoint BUF1Addr buffer*/
  383. count = PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  384. if (count != 0U)
  385. {
  386. PCD_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
  387. }
  388. }
  389. PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_OUT)
  390. }
  391. /*multi-packet on the NON control OUT endpoint*/
  392. ep->xfer_count+=count;
  393. ep->xfer_buff+=count;
  394. if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
  395. {
  396. /* RX COMPLETE */
  397. HAL_PCD_DataOutStageCallback(hpcd, ep->num);
  398. }
  399. else
  400. {
  401. count = ep->xfer_count;
  402. HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
  403. ep->xfer_count = count;
  404. }
  405. } /* if((wEPVal & EP_CTR_RX) */
  406. if ((wEPVal & USB_EP_CTR_TX) != 0U)
  407. {
  408. ep = &hpcd->IN_ep[EPindex];
  409. /* clear int flag */
  410. PCD_CLEAR_TX_EP_CTR(hpcd->Instance, EPindex);
  411. /* IN double Buffering*/
  412. if (ep->doublebuffer == 0U)
  413. {
  414. ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  415. if (ep->xfer_count != 0U)
  416. {
  417. PCD_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, ep->xfer_count);
  418. }
  419. }
  420. else
  421. {
  422. if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num)& USB_EP_DTOG_TX) == USB_EP_DTOG_TX)
  423. {
  424. /*read from endpoint BUF0Addr buffer*/
  425. ep->xfer_count = PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  426. if (ep->xfer_count != 0U)
  427. {
  428. PCD_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, ep->xfer_count);
  429. }
  430. }
  431. else
  432. {
  433. /*read from endpoint BUF1Addr buffer*/
  434. ep->xfer_count = PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  435. if (ep->xfer_count != 0U)
  436. {
  437. PCD_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, ep->xfer_count);
  438. }
  439. }
  440. PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_IN)
  441. }
  442. /*multi-packet on the NON control IN endpoint*/
  443. ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  444. ep->xfer_buff+=ep->xfer_count;
  445. /* Zero Length Packet? */
  446. if (ep->xfer_len == 0U)
  447. {
  448. /* TX COMPLETE */
  449. HAL_PCD_DataInStageCallback(hpcd, ep->num);
  450. }
  451. else
  452. {
  453. HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
  454. }
  455. }
  456. }
  457. }
  458. return HAL_OK;
  459. }
  460. /**
  461. * @}
  462. */
  463. /** @addtogroup PCD_Exported_Functions
  464. * @{
  465. */
  466. /** @defgroup PCD_Exported_Functions_Group2 IO operation functions
  467. * @{
  468. */
  469. /**
  470. * @brief This function handles PCD interrupt request.
  471. * @param hpcd PCD handle
  472. * @retval HAL status
  473. */
  474. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  475. {
  476. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_CTR))
  477. {
  478. /* servicing of the endpoint correct transfer interrupt */
  479. /* clear of the CTR flag into the sub */
  480. PCD_EP_ISR_Handler(hpcd);
  481. }
  482. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_RESET))
  483. {
  484. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
  485. HAL_PCD_ResetCallback(hpcd);
  486. HAL_PCD_SetAddress(hpcd, 0U);
  487. }
  488. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_PMAOVR))
  489. {
  490. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
  491. }
  492. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ERR))
  493. {
  494. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
  495. }
  496. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP))
  497. {
  498. hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LPMODE);
  499. hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP);
  500. HAL_PCD_ResumeCallback(hpcd);
  501. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
  502. }
  503. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SUSP))
  504. {
  505. /* Force low-power mode in the macrocell */
  506. hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
  507. /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
  508. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
  509. hpcd->Instance->CNTR |= USB_CNTR_LPMODE;
  510. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP) == 0U)
  511. {
  512. HAL_PCD_SuspendCallback(hpcd);
  513. }
  514. }
  515. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SOF))
  516. {
  517. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
  518. HAL_PCD_SOFCallback(hpcd);
  519. }
  520. if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ESOF))
  521. {
  522. /* clear ESOF flag in ISTR */
  523. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
  524. }
  525. }
  526. /**
  527. * @brief Data out stage callbacks
  528. * @param hpcd PCD handle
  529. * @param epnum endpoint number
  530. * @retval None
  531. */
  532. __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  533. {
  534. /* Prevent unused argument(s) compilation warning */
  535. UNUSED(hpcd);
  536. UNUSED(epnum);
  537. /* NOTE : This function should not be modified, when the callback is needed,
  538. the HAL_PCD_DataOutStageCallback could be implemented in the user file
  539. */
  540. }
  541. /**
  542. * @brief Data IN stage callbacks
  543. * @param hpcd PCD handle
  544. * @param epnum endpoint number
  545. * @retval None
  546. */
  547. __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  548. {
  549. /* Prevent unused argument(s) compilation warning */
  550. UNUSED(hpcd);
  551. UNUSED(epnum);
  552. /* NOTE : This function should not be modified, when the callback is needed,
  553. the HAL_PCD_DataInStageCallback could be implemented in the user file
  554. */
  555. }
  556. /**
  557. * @brief Setup stage callback
  558. * @param hpcd PCD handle
  559. * @retval None
  560. */
  561. __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
  562. {
  563. /* Prevent unused argument(s) compilation warning */
  564. UNUSED(hpcd);
  565. /* NOTE : This function should not be modified, when the callback is needed,
  566. the HAL_PCD_SetupStageCallback could be implemented in the user file
  567. */
  568. }
  569. /**
  570. * @brief USB Start Of Frame callbacks
  571. * @param hpcd PCD handle
  572. * @retval None
  573. */
  574. __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
  575. {
  576. /* Prevent unused argument(s) compilation warning */
  577. UNUSED(hpcd);
  578. /* NOTE : This function should not be modified, when the callback is needed,
  579. the HAL_PCD_SOFCallback could be implemented in the user file
  580. */
  581. }
  582. /**
  583. * @brief USB Reset callbacks
  584. * @param hpcd PCD handle
  585. * @retval None
  586. */
  587. __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
  588. {
  589. /* Prevent unused argument(s) compilation warning */
  590. UNUSED(hpcd);
  591. /* NOTE : This function should not be modified, when the callback is needed,
  592. the HAL_PCD_ResetCallback could be implemented in the user file
  593. */
  594. }
  595. /**
  596. * @brief Suspend event callbacks
  597. * @param hpcd PCD handle
  598. * @retval None
  599. */
  600. __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
  601. {
  602. /* Prevent unused argument(s) compilation warning */
  603. UNUSED(hpcd);
  604. /* NOTE : This function should not be modified, when the callback is needed,
  605. the HAL_PCD_SuspendCallback could be implemented in the user file
  606. */
  607. }
  608. /**
  609. * @brief Resume event callbacks
  610. * @param hpcd PCD handle
  611. * @retval None
  612. */
  613. __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
  614. {
  615. /* Prevent unused argument(s) compilation warning */
  616. UNUSED(hpcd);
  617. /* NOTE : This function should not be modified, when the callback is needed,
  618. the HAL_PCD_ResumeCallback could be implemented in the user file
  619. */
  620. }
  621. /**
  622. * @brief Incomplete ISO OUT callbacks
  623. * @param hpcd PCD handle
  624. * @param epnum endpoint number
  625. * @retval None
  626. */
  627. __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  628. {
  629. /* Prevent unused argument(s) compilation warning */
  630. UNUSED(hpcd);
  631. UNUSED(epnum);
  632. /* NOTE : This function should not be modified, when the callback is needed,
  633. the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
  634. */
  635. }
  636. /**
  637. * @brief Incomplete ISO IN callbacks
  638. * @param hpcd PCD handle
  639. * @param epnum endpoint number
  640. * @retval None
  641. */
  642. __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  643. {
  644. /* Prevent unused argument(s) compilation warning */
  645. UNUSED(hpcd);
  646. UNUSED(epnum);
  647. /* NOTE : This function should not be modified, when the callback is needed,
  648. the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
  649. */
  650. }
  651. /**
  652. * @brief Connection event callbacks
  653. * @param hpcd PCD handle
  654. * @retval None
  655. */
  656. __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
  657. {
  658. /* Prevent unused argument(s) compilation warning */
  659. UNUSED(hpcd);
  660. /* NOTE : This function should not be modified, when the callback is needed,
  661. the HAL_PCD_ConnectCallback could be implemented in the user file
  662. */
  663. }
  664. /**
  665. * @brief Disconnection event callbacks
  666. * @param hpcd PCD handle
  667. * @retval None
  668. */
  669. __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
  670. {
  671. /* Prevent unused argument(s) compilation warning */
  672. UNUSED(hpcd);
  673. /* NOTE : This function should not be modified, when the callback is needed,
  674. the HAL_PCD_DisconnectCallback could be implemented in the user file
  675. */
  676. }
  677. /**
  678. * @}
  679. */
  680. /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
  681. * @brief management functions
  682. *
  683. @verbatim
  684. ===============================================================================
  685. ##### Peripheral Control functions #####
  686. ===============================================================================
  687. [..]
  688. This subsection provides a set of functions allowing to control the PCD data
  689. transfers.
  690. @endverbatim
  691. * @{
  692. */
  693. /**
  694. * @brief Connect the USB device
  695. * @param hpcd PCD handle
  696. * @retval HAL status
  697. */
  698. HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
  699. {
  700. __HAL_LOCK(hpcd);
  701. /* Enabling DP Pull-Down bit to Connect internal pull-up on USB DP line */
  702. HAL_PCDEx_SetConnectionState(hpcd, 1U);
  703. __HAL_UNLOCK(hpcd);
  704. return HAL_OK;
  705. }
  706. /**
  707. * @brief Disconnect the USB device
  708. * @param hpcd PCD handle
  709. * @retval HAL status
  710. */
  711. HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
  712. {
  713. __HAL_LOCK(hpcd);
  714. /* Disable DP Pull-Down bit*/
  715. HAL_PCDEx_SetConnectionState(hpcd, 0U);
  716. __HAL_UNLOCK(hpcd);
  717. return HAL_OK;
  718. }
  719. /**
  720. * @brief Set the USB Device address
  721. * @param hpcd PCD handle
  722. * @param address new device address
  723. * @retval HAL status
  724. */
  725. HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
  726. {
  727. __HAL_LOCK(hpcd);
  728. if(address == 0U)
  729. {
  730. /* set device address and enable function */
  731. hpcd->Instance->DADDR = USB_DADDR_EF;
  732. }
  733. else /* USB Address will be applied later */
  734. {
  735. hpcd->USB_Address = address;
  736. }
  737. __HAL_UNLOCK(hpcd);
  738. return HAL_OK;
  739. }
  740. /**
  741. * @brief Open and configure an endpoint
  742. * @param hpcd PCD handle
  743. * @param ep_addr endpoint address
  744. * @param ep_mps endpoint max packet size
  745. * @param ep_type endpoint type
  746. * @retval HAL status
  747. */
  748. HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
  749. {
  750. HAL_StatusTypeDef ret = HAL_OK;
  751. PCD_EPTypeDef *ep;
  752. if ((ep_addr & 0x80U) == 0x80U)
  753. {
  754. ep = &hpcd->IN_ep[ep_addr & 0x7FU];
  755. }
  756. else
  757. {
  758. ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
  759. }
  760. ep->num = ep_addr & 0x7FU;
  761. ep->is_in = (0x80U & ep_addr) != 0U;
  762. ep->maxpacket = ep_mps;
  763. ep->type = ep_type;
  764. __HAL_LOCK(hpcd);
  765. /* initialize Endpoint */
  766. switch (ep->type)
  767. {
  768. case PCD_EP_TYPE_CTRL:
  769. PCD_SET_EPTYPE(hpcd->Instance, ep->num, USB_EP_CONTROL);
  770. break;
  771. case PCD_EP_TYPE_BULK:
  772. PCD_SET_EPTYPE(hpcd->Instance, ep->num, USB_EP_BULK);
  773. break;
  774. case PCD_EP_TYPE_INTR:
  775. PCD_SET_EPTYPE(hpcd->Instance, ep->num, USB_EP_INTERRUPT);
  776. break;
  777. case PCD_EP_TYPE_ISOC:
  778. PCD_SET_EPTYPE(hpcd->Instance, ep->num, USB_EP_ISOCHRONOUS);
  779. break;
  780. default:
  781. break;
  782. }
  783. PCD_SET_EP_ADDRESS(hpcd->Instance, ep->num, ep->num);
  784. if (ep->doublebuffer == 0U)
  785. {
  786. if (ep->is_in)
  787. {
  788. /*Set the endpoint Transmit buffer address */
  789. PCD_SET_EP_TX_ADDRESS(hpcd->Instance, ep->num, ep->pmaadress);
  790. PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num)
  791. /* Configure NAK status for the Endpoint*/
  792. PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_NAK)
  793. }
  794. else
  795. {
  796. /*Set the endpoint Receive buffer address */
  797. PCD_SET_EP_RX_ADDRESS(hpcd->Instance, ep->num, ep->pmaadress);
  798. /*Set the endpoint Receive buffer counter*/
  799. PCD_SET_EP_RX_CNT(hpcd->Instance, ep->num, ep->maxpacket)
  800. PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num)
  801. /* Configure VALID status for the Endpoint*/
  802. PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_VALID)
  803. }
  804. }
  805. /*Double Buffer*/
  806. else
  807. {
  808. /*Set the endpoint as double buffered*/
  809. PCD_SET_EP_DBUF(hpcd->Instance, ep->num);
  810. /*Set buffer address for double buffered mode*/
  811. PCD_SET_EP_DBUF_ADDR(hpcd->Instance, ep->num,ep->pmaaddr0, ep->pmaaddr1)
  812. if (ep->is_in==0U)
  813. {
  814. /* Clear the data toggle bits for the endpoint IN/OUT*/
  815. PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num)
  816. PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num)
  817. /* Reset value of the data toggle bits for the endpoint out*/
  818. PCD_TX_DTOG(hpcd->Instance, ep->num);
  819. PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_VALID)
  820. PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_DIS)
  821. }
  822. else
  823. {
  824. /* Clear the data toggle bits for the endpoint IN/OUT*/
  825. PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num)
  826. PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num)
  827. PCD_RX_DTOG(hpcd->Instance, ep->num);
  828. /* Configure DISABLE status for the Endpoint*/
  829. PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_DIS)
  830. PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_DIS)
  831. }
  832. }
  833. __HAL_UNLOCK(hpcd);
  834. return ret;
  835. }
  836. /**
  837. * @brief Deactivate an endpoint
  838. * @param hpcd PCD handle
  839. * @param ep_addr endpoint address
  840. * @retval HAL status
  841. */
  842. HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  843. {
  844. PCD_EPTypeDef *ep;
  845. if ((ep_addr & 0x80U) == 0x80U)
  846. {
  847. ep = &hpcd->IN_ep[ep_addr & 0x7F];
  848. }
  849. else
  850. {
  851. ep = &hpcd->OUT_ep[ep_addr & 0x7F];
  852. }
  853. ep->num = ep_addr & 0x7FU;
  854. ep->is_in = (0x80U & ep_addr) != 0U;
  855. __HAL_LOCK(hpcd);
  856. if (ep->doublebuffer == 0U)
  857. {
  858. if (ep->is_in)
  859. {
  860. PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num)
  861. /* Configure DISABLE status for the Endpoint*/
  862. PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_DIS)
  863. }
  864. else
  865. {
  866. PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num)
  867. /* Configure DISABLE status for the Endpoint*/
  868. PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_DIS)
  869. }
  870. }
  871. /*Double Buffer*/
  872. else
  873. {
  874. if (ep->is_in==0U)
  875. {
  876. /* Clear the data toggle bits for the endpoint IN/OUT*/
  877. PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num)
  878. PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num)
  879. /* Reset value of the data toggle bits for the endpoint out*/
  880. PCD_TX_DTOG(hpcd->Instance, ep->num);
  881. PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_DIS)
  882. PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_DIS)
  883. }
  884. else
  885. {
  886. /* Clear the data toggle bits for the endpoint IN/OUT*/
  887. PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num)
  888. PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num)
  889. PCD_RX_DTOG(hpcd->Instance, ep->num);
  890. /* Configure DISABLE status for the Endpoint*/
  891. PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_DIS)
  892. PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_DIS)
  893. }
  894. }
  895. __HAL_UNLOCK(hpcd);
  896. return HAL_OK;
  897. }
  898. /**
  899. * @brief Receive an amount of data
  900. * @param hpcd PCD handle
  901. * @param ep_addr endpoint address
  902. * @param pBuf pointer to the reception buffer
  903. * @param len amount of data to be received
  904. * @retval HAL status
  905. */
  906. HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  907. {
  908. PCD_EPTypeDef *ep;
  909. ep = &hpcd->OUT_ep[ep_addr & 0x7F];
  910. /*setup and start the Xfer */
  911. ep->xfer_buff = pBuf;
  912. ep->xfer_len = len;
  913. ep->xfer_count = 0U;
  914. ep->is_in = 0U;
  915. ep->num = ep_addr & 0x7FU;
  916. /* Multi packet transfer*/
  917. if (ep->xfer_len > ep->maxpacket)
  918. {
  919. len=ep->maxpacket;
  920. ep->xfer_len-=len;
  921. }
  922. else
  923. {
  924. len=ep->xfer_len;
  925. ep->xfer_len =0U;
  926. }
  927. /* configure and validate Rx endpoint */
  928. if (ep->doublebuffer == 0U)
  929. {
  930. /*Set RX buffer count*/
  931. PCD_SET_EP_RX_CNT(hpcd->Instance, ep->num, len)
  932. }
  933. else
  934. {
  935. /*Set the Double buffer counter*/
  936. PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, len)
  937. }
  938. PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_VALID)
  939. return HAL_OK;
  940. }
  941. /**
  942. * @brief Get Received Data Size
  943. * @param hpcd PCD handle
  944. * @param ep_addr endpoint address
  945. * @retval Data Size
  946. */
  947. uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  948. {
  949. return hpcd->OUT_ep[ep_addr & 0x7F].xfer_count;
  950. }
  951. /**
  952. * @brief Send an amount of data
  953. * @param hpcd PCD handle
  954. * @param ep_addr endpoint address
  955. * @param pBuf pointer to the transmission buffer
  956. * @param len amount of data to be sent
  957. * @retval HAL status
  958. */
  959. HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  960. {
  961. PCD_EPTypeDef *ep;
  962. uint16_t pmabuffer = 0U;
  963. ep = &hpcd->IN_ep[ep_addr & 0x7F];
  964. /*setup and start the Xfer */
  965. ep->xfer_buff = pBuf;
  966. ep->xfer_len = len;
  967. ep->xfer_count = 0U;
  968. ep->is_in = 1U;
  969. ep->num = ep_addr & 0x7FU;
  970. /*Multi packet transfer*/
  971. if (ep->xfer_len > ep->maxpacket)
  972. {
  973. len=ep->maxpacket;
  974. ep->xfer_len-=len;
  975. }
  976. else
  977. {
  978. len=ep->xfer_len;
  979. ep->xfer_len =0U;
  980. }
  981. /* configure and validate Tx endpoint */
  982. if (ep->doublebuffer == 0U)
  983. {
  984. PCD_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, len);
  985. PCD_SET_EP_TX_CNT(hpcd->Instance, ep->num, len);
  986. }
  987. else
  988. {
  989. /*Write the data to the USB endpoint*/
  990. if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num)& USB_EP_DTOG_TX) == USB_EP_DTOG_TX)
  991. {
  992. pmabuffer = ep->pmaaddr1;
  993. }
  994. else
  995. {
  996. pmabuffer = ep->pmaaddr0;
  997. }
  998. PCD_WritePMA(hpcd->Instance, ep->xfer_buff, pmabuffer, len);
  999. PCD_FreeUserBuffer(hpcd->Instance, ep->num, ep->is_in)
  1000. }
  1001. PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_VALID)
  1002. return HAL_OK;
  1003. }
  1004. /**
  1005. * @brief Set a STALL condition over an endpoint
  1006. * @param hpcd PCD handle
  1007. * @param ep_addr endpoint address
  1008. * @retval HAL status
  1009. */
  1010. HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1011. {
  1012. PCD_EPTypeDef *ep;
  1013. __HAL_LOCK(hpcd);
  1014. if ((0x80U & ep_addr) == 0x80U)
  1015. {
  1016. ep = &hpcd->IN_ep[ep_addr & 0x7F];
  1017. }
  1018. else
  1019. {
  1020. ep = &hpcd->OUT_ep[ep_addr];
  1021. }
  1022. ep->is_stall = 1U;
  1023. ep->num = ep_addr & 0x7FU;
  1024. ep->is_in = ((ep_addr & 0x80U) == 0x80U);
  1025. if (ep->num == 0U)
  1026. {
  1027. /* This macro sets STALL status for RX & TX*/
  1028. PCD_SET_EP_TXRX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_STALL, USB_EP_TX_STALL)
  1029. }
  1030. else
  1031. {
  1032. if (ep->is_in)
  1033. {
  1034. PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num , USB_EP_TX_STALL)
  1035. }
  1036. else
  1037. {
  1038. PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num , USB_EP_RX_STALL)
  1039. }
  1040. }
  1041. __HAL_UNLOCK(hpcd);
  1042. return HAL_OK;
  1043. }
  1044. /**
  1045. * @brief Clear a STALL condition over in an endpoint
  1046. * @param hpcd PCD handle
  1047. * @param ep_addr endpoint address
  1048. * @retval HAL status
  1049. */
  1050. HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1051. {
  1052. PCD_EPTypeDef *ep;
  1053. if ((0x80U & ep_addr) == 0x80U)
  1054. {
  1055. ep = &hpcd->IN_ep[ep_addr & 0x7F];
  1056. }
  1057. else
  1058. {
  1059. ep = &hpcd->OUT_ep[ep_addr];
  1060. }
  1061. ep->is_stall = 0U;
  1062. ep->num = ep_addr & 0x7FU;
  1063. ep->is_in = ((ep_addr & 0x80U) == 0x80U);
  1064. __HAL_LOCK(hpcd);
  1065. if (ep->is_in)
  1066. {
  1067. PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num)
  1068. PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_VALID)
  1069. }
  1070. else
  1071. {
  1072. PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num)
  1073. PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_VALID)
  1074. }
  1075. __HAL_UNLOCK(hpcd);
  1076. return HAL_OK;
  1077. }
  1078. /**
  1079. * @brief Flush an endpoint
  1080. * @param hpcd PCD handle
  1081. * @param ep_addr endpoint address
  1082. * @retval HAL status
  1083. */
  1084. HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1085. {
  1086. return HAL_OK;
  1087. }
  1088. /**
  1089. * @brief HAL_PCD_ActivateRemoteWakeup : active remote wakeup signalling
  1090. * @param hpcd PCD handle
  1091. * @retval HAL status
  1092. */
  1093. HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1094. {
  1095. hpcd->Instance->CNTR |= USB_CNTR_RESUME;
  1096. return HAL_OK;
  1097. }
  1098. /**
  1099. * @brief HAL_PCD_DeActivateRemoteWakeup : de-active remote wakeup signalling
  1100. * @param hpcd PCD handle
  1101. * @retval HAL status
  1102. */
  1103. HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1104. {
  1105. hpcd->Instance->CNTR &=~((uint32_t)USB_CNTR_RESUME);
  1106. return HAL_OK;
  1107. }
  1108. /**
  1109. * @}
  1110. */
  1111. /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
  1112. * @brief Peripheral State functions
  1113. *
  1114. @verbatim
  1115. ===============================================================================
  1116. ##### Peripheral State functions #####
  1117. ===============================================================================
  1118. [..]
  1119. This subsection permits to get in run-time the status of the peripheral
  1120. and the data flow.
  1121. @endverbatim
  1122. * @{
  1123. */
  1124. /**
  1125. * @brief Return the PCD state
  1126. * @param hpcd PCD handle
  1127. * @retval HAL state
  1128. */
  1129. PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
  1130. {
  1131. return hpcd->State;
  1132. }
  1133. /**
  1134. * @}
  1135. */
  1136. /**
  1137. * @}
  1138. */
  1139. /**
  1140. * @}
  1141. */
  1142. /**
  1143. * @}
  1144. */
  1145. #endif /* STM32F302xE || STM32F303xE || */
  1146. /* STM32F302xC || STM32F303xC || */
  1147. /* STM32F302x8 || */
  1148. /* STM32F373xC */
  1149. #endif /* HAL_PCD_MODULE_ENABLED */
  1150. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/