Implement a secure ICS protocol targeting LoRa Node151 microcontroller for controlling irrigation.
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.
 
 
 
 
 
 

2580 lines
67 KiB

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