stm32f1xx_hal_hcd.c 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626
  1. /**
  2. ******************************************************************************
  3. * @file stm32f1xx_hal_hcd.c
  4. * @author MCD Application Team
  5. * @brief HCD 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. (#)Declare a HCD_HandleTypeDef handle structure, for example:
  19. HCD_HandleTypeDef hhcd;
  20. (#)Fill parameters of Init structure in HCD handle
  21. (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...)
  22. (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API:
  23. (##) Enable the HCD/USB Low Level interface clock using the following macros
  24. (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
  25. (##) Initialize the related GPIO clocks
  26. (##) Configure HCD pin-out
  27. (##) Configure HCD NVIC interrupt
  28. (#)Associate the Upper USB Host stack to the HAL HCD Driver:
  29. (##) hhcd.pData = phost;
  30. (#)Enable HCD transmission and reception:
  31. (##) HAL_HCD_Start();
  32. @endverbatim
  33. ******************************************************************************
  34. * @attention
  35. *
  36. * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
  37. * All rights reserved.</center></h2>
  38. *
  39. * This software component is licensed by ST under BSD 3-Clause license,
  40. * the "License"; You may not use this file except in compliance with the
  41. * License. You may obtain a copy of the License at:
  42. * opensource.org/licenses/BSD-3-Clause
  43. *
  44. ******************************************************************************
  45. */
  46. /* Includes ------------------------------------------------------------------*/
  47. #include "stm32f1xx_hal.h"
  48. /** @addtogroup STM32F1xx_HAL_Driver
  49. * @{
  50. */
  51. #ifdef HAL_HCD_MODULE_ENABLED
  52. #if defined (USB_OTG_FS)
  53. /** @defgroup HCD HCD
  54. * @brief HCD HAL module driver
  55. * @{
  56. */
  57. /* Private typedef -----------------------------------------------------------*/
  58. /* Private define ------------------------------------------------------------*/
  59. /* Private macro -------------------------------------------------------------*/
  60. /* Private variables ---------------------------------------------------------*/
  61. /* Private function prototypes -----------------------------------------------*/
  62. /** @defgroup HCD_Private_Functions HCD Private Functions
  63. * @{
  64. */
  65. static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
  66. static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
  67. static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd);
  68. static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
  69. /**
  70. * @}
  71. */
  72. /* Exported functions --------------------------------------------------------*/
  73. /** @defgroup HCD_Exported_Functions HCD Exported Functions
  74. * @{
  75. */
  76. /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
  77. * @brief Initialization and Configuration functions
  78. *
  79. @verbatim
  80. ===============================================================================
  81. ##### Initialization and de-initialization functions #####
  82. ===============================================================================
  83. [..] This section provides functions allowing to:
  84. @endverbatim
  85. * @{
  86. */
  87. /**
  88. * @brief Initialize the host driver.
  89. * @param hhcd HCD handle
  90. * @retval HAL status
  91. */
  92. HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
  93. {
  94. USB_OTG_GlobalTypeDef *USBx;
  95. /* Check the HCD handle allocation */
  96. if (hhcd == NULL)
  97. {
  98. return HAL_ERROR;
  99. }
  100. /* Check the parameters */
  101. assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
  102. USBx = hhcd->Instance;
  103. if (hhcd->State == HAL_HCD_STATE_RESET)
  104. {
  105. /* Allocate lock resource and initialize it */
  106. hhcd->Lock = HAL_UNLOCKED;
  107. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  108. hhcd->SOFCallback = HAL_HCD_SOF_Callback;
  109. hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
  110. hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
  111. hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
  112. hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
  113. hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback;
  114. if (hhcd->MspInitCallback == NULL)
  115. {
  116. hhcd->MspInitCallback = HAL_HCD_MspInit;
  117. }
  118. /* Init the low level hardware */
  119. hhcd->MspInitCallback(hhcd);
  120. #else
  121. /* Init the low level hardware : GPIO, CLOCK, NVIC... */
  122. HAL_HCD_MspInit(hhcd);
  123. #endif /* (USE_HAL_HCD_REGISTER_CALLBACKS) */
  124. }
  125. hhcd->State = HAL_HCD_STATE_BUSY;
  126. /* Disable DMA mode for FS instance */
  127. if ((USBx->CID & (0x1U << 8)) == 0U)
  128. {
  129. hhcd->Init.dma_enable = 0U;
  130. }
  131. /* Disable the Interrupts */
  132. __HAL_HCD_DISABLE(hhcd);
  133. /* Init the Core (common init.) */
  134. (void)USB_CoreInit(hhcd->Instance, hhcd->Init);
  135. /* Force Host Mode*/
  136. (void)USB_SetCurrentMode(hhcd->Instance, USB_HOST_MODE);
  137. /* Init Host */
  138. (void)USB_HostInit(hhcd->Instance, hhcd->Init);
  139. hhcd->State = HAL_HCD_STATE_READY;
  140. return HAL_OK;
  141. }
  142. /**
  143. * @brief Initialize a host channel.
  144. * @param hhcd HCD handle
  145. * @param ch_num Channel number.
  146. * This parameter can be a value from 1 to 15
  147. * @param epnum Endpoint number.
  148. * This parameter can be a value from 1 to 15
  149. * @param dev_address Current device address
  150. * This parameter can be a value from 0 to 255
  151. * @param speed Current device speed.
  152. * This parameter can be one of these values:
  153. * HCD_SPEED_FULL: Full speed mode,
  154. * HCD_SPEED_LOW: Low speed mode
  155. * @param ep_type Endpoint Type.
  156. * This parameter can be one of these values:
  157. * EP_TYPE_CTRL: Control type,
  158. * EP_TYPE_ISOC: Isochronous type,
  159. * EP_TYPE_BULK: Bulk type,
  160. * EP_TYPE_INTR: Interrupt type
  161. * @param mps Max Packet Size.
  162. * This parameter can be a value from 0 to32K
  163. * @retval HAL status
  164. */
  165. HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd,
  166. uint8_t ch_num,
  167. uint8_t epnum,
  168. uint8_t dev_address,
  169. uint8_t speed,
  170. uint8_t ep_type,
  171. uint16_t mps)
  172. {
  173. HAL_StatusTypeDef status;
  174. __HAL_LOCK(hhcd);
  175. hhcd->hc[ch_num].do_ping = 0U;
  176. hhcd->hc[ch_num].dev_addr = dev_address;
  177. hhcd->hc[ch_num].max_packet = mps;
  178. hhcd->hc[ch_num].ch_num = ch_num;
  179. hhcd->hc[ch_num].ep_type = ep_type;
  180. hhcd->hc[ch_num].ep_num = epnum & 0x7FU;
  181. if ((epnum & 0x80U) == 0x80U)
  182. {
  183. hhcd->hc[ch_num].ep_is_in = 1U;
  184. }
  185. else
  186. {
  187. hhcd->hc[ch_num].ep_is_in = 0U;
  188. }
  189. hhcd->hc[ch_num].speed = speed;
  190. status = USB_HC_Init(hhcd->Instance,
  191. ch_num,
  192. epnum,
  193. dev_address,
  194. speed,
  195. ep_type,
  196. mps);
  197. __HAL_UNLOCK(hhcd);
  198. return status;
  199. }
  200. /**
  201. * @brief Halt a host channel.
  202. * @param hhcd HCD handle
  203. * @param ch_num Channel number.
  204. * This parameter can be a value from 1 to 15
  205. * @retval HAL status
  206. */
  207. HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
  208. {
  209. HAL_StatusTypeDef status = HAL_OK;
  210. __HAL_LOCK(hhcd);
  211. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  212. __HAL_UNLOCK(hhcd);
  213. return status;
  214. }
  215. /**
  216. * @brief DeInitialize the host driver.
  217. * @param hhcd HCD handle
  218. * @retval HAL status
  219. */
  220. HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
  221. {
  222. /* Check the HCD handle allocation */
  223. if (hhcd == NULL)
  224. {
  225. return HAL_ERROR;
  226. }
  227. hhcd->State = HAL_HCD_STATE_BUSY;
  228. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  229. if (hhcd->MspDeInitCallback == NULL)
  230. {
  231. hhcd->MspDeInitCallback = HAL_HCD_MspDeInit; /* Legacy weak MspDeInit */
  232. }
  233. /* DeInit the low level hardware */
  234. hhcd->MspDeInitCallback(hhcd);
  235. #else
  236. /* DeInit the low level hardware: CLOCK, NVIC.*/
  237. HAL_HCD_MspDeInit(hhcd);
  238. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  239. __HAL_HCD_DISABLE(hhcd);
  240. hhcd->State = HAL_HCD_STATE_RESET;
  241. return HAL_OK;
  242. }
  243. /**
  244. * @brief Initialize the HCD MSP.
  245. * @param hhcd HCD handle
  246. * @retval None
  247. */
  248. __weak void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
  249. {
  250. /* Prevent unused argument(s) compilation warning */
  251. UNUSED(hhcd);
  252. /* NOTE : This function should not be modified, when the callback is needed,
  253. the HAL_HCD_MspInit could be implemented in the user file
  254. */
  255. }
  256. /**
  257. * @brief DeInitialize the HCD MSP.
  258. * @param hhcd HCD handle
  259. * @retval None
  260. */
  261. __weak void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
  262. {
  263. /* Prevent unused argument(s) compilation warning */
  264. UNUSED(hhcd);
  265. /* NOTE : This function should not be modified, when the callback is needed,
  266. the HAL_HCD_MspDeInit could be implemented in the user file
  267. */
  268. }
  269. /**
  270. * @}
  271. */
  272. /** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions
  273. * @brief HCD IO operation functions
  274. *
  275. @verbatim
  276. ===============================================================================
  277. ##### IO operation functions #####
  278. ===============================================================================
  279. [..] This subsection provides a set of functions allowing to manage the USB Host Data
  280. Transfer
  281. @endverbatim
  282. * @{
  283. */
  284. /**
  285. * @brief Submit a new URB for processing.
  286. * @param hhcd HCD handle
  287. * @param ch_num Channel number.
  288. * This parameter can be a value from 1 to 15
  289. * @param direction Channel number.
  290. * This parameter can be one of these values:
  291. * 0 : Output / 1 : Input
  292. * @param ep_type Endpoint Type.
  293. * This parameter can be one of these values:
  294. * EP_TYPE_CTRL: Control type/
  295. * EP_TYPE_ISOC: Isochronous type/
  296. * EP_TYPE_BULK: Bulk type/
  297. * EP_TYPE_INTR: Interrupt type/
  298. * @param token Endpoint Type.
  299. * This parameter can be one of these values:
  300. * 0: HC_PID_SETUP / 1: HC_PID_DATA1
  301. * @param pbuff pointer to URB data
  302. * @param length Length of URB data
  303. * @param do_ping activate do ping protocol (for high speed only).
  304. * This parameter can be one of these values:
  305. * 0 : do ping inactive / 1 : do ping active
  306. * @retval HAL status
  307. */
  308. HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
  309. uint8_t ch_num,
  310. uint8_t direction,
  311. uint8_t ep_type,
  312. uint8_t token,
  313. uint8_t *pbuff,
  314. uint16_t length,
  315. uint8_t do_ping)
  316. {
  317. hhcd->hc[ch_num].ep_is_in = direction;
  318. hhcd->hc[ch_num].ep_type = ep_type;
  319. if (token == 0U)
  320. {
  321. hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
  322. hhcd->hc[ch_num].do_ping = do_ping;
  323. }
  324. else
  325. {
  326. hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  327. }
  328. /* Manage Data Toggle */
  329. switch (ep_type)
  330. {
  331. case EP_TYPE_CTRL:
  332. if ((token == 1U) && (direction == 0U)) /*send data */
  333. {
  334. if (length == 0U)
  335. {
  336. /* For Status OUT stage, Length==0, Status Out PID = 1 */
  337. hhcd->hc[ch_num].toggle_out = 1U;
  338. }
  339. /* Set the Data Toggle bit as per the Flag */
  340. if (hhcd->hc[ch_num].toggle_out == 0U)
  341. {
  342. /* Put the PID 0 */
  343. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  344. }
  345. else
  346. {
  347. /* Put the PID 1 */
  348. hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  349. }
  350. }
  351. break;
  352. case EP_TYPE_BULK:
  353. if (direction == 0U)
  354. {
  355. /* Set the Data Toggle bit as per the Flag */
  356. if (hhcd->hc[ch_num].toggle_out == 0U)
  357. {
  358. /* Put the PID 0 */
  359. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  360. }
  361. else
  362. {
  363. /* Put the PID 1 */
  364. hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  365. }
  366. }
  367. else
  368. {
  369. if (hhcd->hc[ch_num].toggle_in == 0U)
  370. {
  371. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  372. }
  373. else
  374. {
  375. hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  376. }
  377. }
  378. break;
  379. case EP_TYPE_INTR:
  380. if (direction == 0U)
  381. {
  382. /* Set the Data Toggle bit as per the Flag */
  383. if (hhcd->hc[ch_num].toggle_out == 0U)
  384. {
  385. /* Put the PID 0 */
  386. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  387. }
  388. else
  389. {
  390. /* Put the PID 1 */
  391. hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  392. }
  393. }
  394. else
  395. {
  396. if (hhcd->hc[ch_num].toggle_in == 0U)
  397. {
  398. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  399. }
  400. else
  401. {
  402. hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  403. }
  404. }
  405. break;
  406. case EP_TYPE_ISOC:
  407. hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  408. break;
  409. default:
  410. break;
  411. }
  412. hhcd->hc[ch_num].xfer_buff = pbuff;
  413. hhcd->hc[ch_num].xfer_len = length;
  414. hhcd->hc[ch_num].urb_state = URB_IDLE;
  415. hhcd->hc[ch_num].xfer_count = 0U;
  416. hhcd->hc[ch_num].ch_num = ch_num;
  417. hhcd->hc[ch_num].state = HC_IDLE;
  418. return USB_HC_StartXfer(hhcd->Instance, &hhcd->hc[ch_num]);
  419. }
  420. /**
  421. * @brief Handle HCD interrupt request.
  422. * @param hhcd HCD handle
  423. * @retval None
  424. */
  425. void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
  426. {
  427. USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  428. uint32_t USBx_BASE = (uint32_t)USBx;
  429. uint32_t i, interrupt;
  430. /* Ensure that we are in device mode */
  431. if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
  432. {
  433. /* Avoid spurious interrupt */
  434. if (__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
  435. {
  436. return;
  437. }
  438. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
  439. {
  440. /* Incorrect mode, acknowledge the interrupt */
  441. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
  442. }
  443. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
  444. {
  445. /* Incorrect mode, acknowledge the interrupt */
  446. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
  447. }
  448. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
  449. {
  450. /* Incorrect mode, acknowledge the interrupt */
  451. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
  452. }
  453. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
  454. {
  455. /* Incorrect mode, acknowledge the interrupt */
  456. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
  457. }
  458. /* Handle Host Disconnect Interrupts */
  459. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
  460. {
  461. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
  462. if ((USBx_HPRT0 & USB_OTG_HPRT_PCSTS) == 0U)
  463. {
  464. /* Handle Host Port Disconnect Interrupt */
  465. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  466. hhcd->DisconnectCallback(hhcd);
  467. #else
  468. HAL_HCD_Disconnect_Callback(hhcd);
  469. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  470. (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
  471. }
  472. }
  473. /* Handle Host Port Interrupts */
  474. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
  475. {
  476. HCD_Port_IRQHandler(hhcd);
  477. }
  478. /* Handle Host SOF Interrupt */
  479. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
  480. {
  481. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  482. hhcd->SOFCallback(hhcd);
  483. #else
  484. HAL_HCD_SOF_Callback(hhcd);
  485. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  486. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
  487. }
  488. /* Handle Host channel Interrupt */
  489. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
  490. {
  491. interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
  492. for (i = 0U; i < hhcd->Init.Host_channels; i++)
  493. {
  494. if ((interrupt & (1UL << (i & 0xFU))) != 0U)
  495. {
  496. if ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_EPDIR) == USB_OTG_HCCHAR_EPDIR)
  497. {
  498. HCD_HC_IN_IRQHandler(hhcd, (uint8_t)i);
  499. }
  500. else
  501. {
  502. HCD_HC_OUT_IRQHandler(hhcd, (uint8_t)i);
  503. }
  504. }
  505. }
  506. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
  507. }
  508. /* Handle Rx Queue Level Interrupts */
  509. if ((__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL)) != 0U)
  510. {
  511. USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  512. HCD_RXQLVL_IRQHandler(hhcd);
  513. USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  514. }
  515. }
  516. }
  517. /**
  518. * @brief SOF callback.
  519. * @param hhcd HCD handle
  520. * @retval None
  521. */
  522. __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
  523. {
  524. /* Prevent unused argument(s) compilation warning */
  525. UNUSED(hhcd);
  526. /* NOTE : This function should not be modified, when the callback is needed,
  527. the HAL_HCD_SOF_Callback could be implemented in the user file
  528. */
  529. }
  530. /**
  531. * @brief Connection Event callback.
  532. * @param hhcd HCD handle
  533. * @retval None
  534. */
  535. __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
  536. {
  537. /* Prevent unused argument(s) compilation warning */
  538. UNUSED(hhcd);
  539. /* NOTE : This function should not be modified, when the callback is needed,
  540. the HAL_HCD_Connect_Callback could be implemented in the user file
  541. */
  542. }
  543. /**
  544. * @brief Disconnection Event callback.
  545. * @param hhcd HCD handle
  546. * @retval None
  547. */
  548. __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
  549. {
  550. /* Prevent unused argument(s) compilation warning */
  551. UNUSED(hhcd);
  552. /* NOTE : This function should not be modified, when the callback is needed,
  553. the HAL_HCD_Disconnect_Callback could be implemented in the user file
  554. */
  555. }
  556. /**
  557. * @brief Port Enabled Event callback.
  558. * @param hhcd HCD handle
  559. * @retval None
  560. */
  561. __weak void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd)
  562. {
  563. /* Prevent unused argument(s) compilation warning */
  564. UNUSED(hhcd);
  565. /* NOTE : This function should not be modified, when the callback is needed,
  566. the HAL_HCD_Disconnect_Callback could be implemented in the user file
  567. */
  568. }
  569. /**
  570. * @brief Port Disabled Event callback.
  571. * @param hhcd HCD handle
  572. * @retval None
  573. */
  574. __weak void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd)
  575. {
  576. /* Prevent unused argument(s) compilation warning */
  577. UNUSED(hhcd);
  578. /* NOTE : This function should not be modified, when the callback is needed,
  579. the HAL_HCD_Disconnect_Callback could be implemented in the user file
  580. */
  581. }
  582. /**
  583. * @brief Notify URB state change callback.
  584. * @param hhcd HCD handle
  585. * @param chnum Channel number.
  586. * This parameter can be a value from 1 to 15
  587. * @param urb_state:
  588. * This parameter can be one of these values:
  589. * URB_IDLE/
  590. * URB_DONE/
  591. * URB_NOTREADY/
  592. * URB_NYET/
  593. * URB_ERROR/
  594. * URB_STALL/
  595. * @retval None
  596. */
  597. __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
  598. {
  599. /* Prevent unused argument(s) compilation warning */
  600. UNUSED(hhcd);
  601. UNUSED(chnum);
  602. UNUSED(urb_state);
  603. /* NOTE : This function should not be modified, when the callback is needed,
  604. the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
  605. */
  606. }
  607. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  608. /**
  609. * @brief Register a User USB HCD Callback
  610. * To be used instead of the weak predefined callback
  611. * @param hhcd USB HCD handle
  612. * @param CallbackID ID of the callback to be registered
  613. * This parameter can be one of the following values:
  614. * @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
  615. * @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
  616. * @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
  617. * @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enable callback ID
  618. * @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disable callback ID
  619. * @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
  620. * @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
  621. * @param pCallback pointer to the Callback function
  622. * @retval HAL status
  623. */
  624. HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID, pHCD_CallbackTypeDef pCallback)
  625. {
  626. HAL_StatusTypeDef status = HAL_OK;
  627. if (pCallback == NULL)
  628. {
  629. /* Update the error code */
  630. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  631. return HAL_ERROR;
  632. }
  633. /* Process locked */
  634. __HAL_LOCK(hhcd);
  635. if (hhcd->State == HAL_HCD_STATE_READY)
  636. {
  637. switch (CallbackID)
  638. {
  639. case HAL_HCD_SOF_CB_ID :
  640. hhcd->SOFCallback = pCallback;
  641. break;
  642. case HAL_HCD_CONNECT_CB_ID :
  643. hhcd->ConnectCallback = pCallback;
  644. break;
  645. case HAL_HCD_DISCONNECT_CB_ID :
  646. hhcd->DisconnectCallback = pCallback;
  647. break;
  648. case HAL_HCD_PORT_ENABLED_CB_ID :
  649. hhcd->PortEnabledCallback = pCallback;
  650. break;
  651. case HAL_HCD_PORT_DISABLED_CB_ID :
  652. hhcd->PortDisabledCallback = pCallback;
  653. break;
  654. case HAL_HCD_MSPINIT_CB_ID :
  655. hhcd->MspInitCallback = pCallback;
  656. break;
  657. case HAL_HCD_MSPDEINIT_CB_ID :
  658. hhcd->MspDeInitCallback = pCallback;
  659. break;
  660. default :
  661. /* Update the error code */
  662. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  663. /* Return error status */
  664. status = HAL_ERROR;
  665. break;
  666. }
  667. }
  668. else if (hhcd->State == HAL_HCD_STATE_RESET)
  669. {
  670. switch (CallbackID)
  671. {
  672. case HAL_HCD_MSPINIT_CB_ID :
  673. hhcd->MspInitCallback = pCallback;
  674. break;
  675. case HAL_HCD_MSPDEINIT_CB_ID :
  676. hhcd->MspDeInitCallback = pCallback;
  677. break;
  678. default :
  679. /* Update the error code */
  680. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  681. /* Return error status */
  682. status = HAL_ERROR;
  683. break;
  684. }
  685. }
  686. else
  687. {
  688. /* Update the error code */
  689. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  690. /* Return error status */
  691. status = HAL_ERROR;
  692. }
  693. /* Release Lock */
  694. __HAL_UNLOCK(hhcd);
  695. return status;
  696. }
  697. /**
  698. * @brief Unregister an USB HCD Callback
  699. * USB HCD callabck is redirected to the weak predefined callback
  700. * @param hhcd USB HCD handle
  701. * @param CallbackID ID of the callback to be unregistered
  702. * This parameter can be one of the following values:
  703. * @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
  704. * @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
  705. * @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
  706. * @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enabled callback ID
  707. * @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disabled callback ID
  708. * @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
  709. * @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
  710. * @retval HAL status
  711. */
  712. HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID)
  713. {
  714. HAL_StatusTypeDef status = HAL_OK;
  715. /* Process locked */
  716. __HAL_LOCK(hhcd);
  717. /* Setup Legacy weak Callbacks */
  718. if (hhcd->State == HAL_HCD_STATE_READY)
  719. {
  720. switch (CallbackID)
  721. {
  722. case HAL_HCD_SOF_CB_ID :
  723. hhcd->SOFCallback = HAL_HCD_SOF_Callback;
  724. break;
  725. case HAL_HCD_CONNECT_CB_ID :
  726. hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
  727. break;
  728. case HAL_HCD_DISCONNECT_CB_ID :
  729. hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
  730. break;
  731. case HAL_HCD_PORT_ENABLED_CB_ID :
  732. hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
  733. break;
  734. case HAL_HCD_PORT_DISABLED_CB_ID :
  735. hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
  736. break;
  737. case HAL_HCD_MSPINIT_CB_ID :
  738. hhcd->MspInitCallback = HAL_HCD_MspInit;
  739. break;
  740. case HAL_HCD_MSPDEINIT_CB_ID :
  741. hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
  742. break;
  743. default :
  744. /* Update the error code */
  745. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  746. /* Return error status */
  747. status = HAL_ERROR;
  748. break;
  749. }
  750. }
  751. else if (hhcd->State == HAL_HCD_STATE_RESET)
  752. {
  753. switch (CallbackID)
  754. {
  755. case HAL_HCD_MSPINIT_CB_ID :
  756. hhcd->MspInitCallback = HAL_HCD_MspInit;
  757. break;
  758. case HAL_HCD_MSPDEINIT_CB_ID :
  759. hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
  760. break;
  761. default :
  762. /* Update the error code */
  763. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  764. /* Return error status */
  765. status = HAL_ERROR;
  766. break;
  767. }
  768. }
  769. else
  770. {
  771. /* Update the error code */
  772. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  773. /* Return error status */
  774. status = HAL_ERROR;
  775. }
  776. /* Release Lock */
  777. __HAL_UNLOCK(hhcd);
  778. return status;
  779. }
  780. /**
  781. * @brief Register USB HCD Host Channel Notify URB Change Callback
  782. * To be used instead of the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
  783. * @param hhcd HCD handle
  784. * @param pCallback pointer to the USB HCD Host Channel Notify URB Change Callback function
  785. * @retval HAL status
  786. */
  787. HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd, pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback)
  788. {
  789. HAL_StatusTypeDef status = HAL_OK;
  790. if (pCallback == NULL)
  791. {
  792. /* Update the error code */
  793. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  794. return HAL_ERROR;
  795. }
  796. /* Process locked */
  797. __HAL_LOCK(hhcd);
  798. if (hhcd->State == HAL_HCD_STATE_READY)
  799. {
  800. hhcd->HC_NotifyURBChangeCallback = pCallback;
  801. }
  802. else
  803. {
  804. /* Update the error code */
  805. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  806. /* Return error status */
  807. status = HAL_ERROR;
  808. }
  809. /* Release Lock */
  810. __HAL_UNLOCK(hhcd);
  811. return status;
  812. }
  813. /**
  814. * @brief UnRegister the USB HCD Host Channel Notify URB Change Callback
  815. * USB HCD Host Channel Notify URB Change Callback is redirected to the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
  816. * @param hhcd HCD handle
  817. * @retval HAL status
  818. */
  819. HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd)
  820. {
  821. HAL_StatusTypeDef status = HAL_OK;
  822. /* Process locked */
  823. __HAL_LOCK(hhcd);
  824. if (hhcd->State == HAL_HCD_STATE_READY)
  825. {
  826. hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback; /* Legacy weak DataOutStageCallback */
  827. }
  828. else
  829. {
  830. /* Update the error code */
  831. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  832. /* Return error status */
  833. status = HAL_ERROR;
  834. }
  835. /* Release Lock */
  836. __HAL_UNLOCK(hhcd);
  837. return status;
  838. }
  839. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  840. /**
  841. * @}
  842. */
  843. /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
  844. * @brief Management functions
  845. *
  846. @verbatim
  847. ===============================================================================
  848. ##### Peripheral Control functions #####
  849. ===============================================================================
  850. [..]
  851. This subsection provides a set of functions allowing to control the HCD data
  852. transfers.
  853. @endverbatim
  854. * @{
  855. */
  856. /**
  857. * @brief Start the host driver.
  858. * @param hhcd HCD handle
  859. * @retval HAL status
  860. */
  861. HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
  862. {
  863. __HAL_LOCK(hhcd);
  864. __HAL_HCD_ENABLE(hhcd);
  865. (void)USB_DriveVbus(hhcd->Instance, 1U);
  866. __HAL_UNLOCK(hhcd);
  867. return HAL_OK;
  868. }
  869. /**
  870. * @brief Stop the host driver.
  871. * @param hhcd HCD handle
  872. * @retval HAL status
  873. */
  874. HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
  875. {
  876. __HAL_LOCK(hhcd);
  877. (void)USB_StopHost(hhcd->Instance);
  878. __HAL_UNLOCK(hhcd);
  879. return HAL_OK;
  880. }
  881. /**
  882. * @brief Reset the host port.
  883. * @param hhcd HCD handle
  884. * @retval HAL status
  885. */
  886. HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
  887. {
  888. return (USB_ResetPort(hhcd->Instance));
  889. }
  890. /**
  891. * @}
  892. */
  893. /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
  894. * @brief Peripheral State functions
  895. *
  896. @verbatim
  897. ===============================================================================
  898. ##### Peripheral State functions #####
  899. ===============================================================================
  900. [..]
  901. This subsection permits to get in run-time the status of the peripheral
  902. and the data flow.
  903. @endverbatim
  904. * @{
  905. */
  906. /**
  907. * @brief Return the HCD handle state.
  908. * @param hhcd HCD handle
  909. * @retval HAL state
  910. */
  911. HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd)
  912. {
  913. return hhcd->State;
  914. }
  915. /**
  916. * @brief Return URB state for a channel.
  917. * @param hhcd HCD handle
  918. * @param chnum Channel number.
  919. * This parameter can be a value from 1 to 15
  920. * @retval URB state.
  921. * This parameter can be one of these values:
  922. * URB_IDLE/
  923. * URB_DONE/
  924. * URB_NOTREADY/
  925. * URB_NYET/
  926. * URB_ERROR/
  927. * URB_STALL
  928. */
  929. HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  930. {
  931. return hhcd->hc[chnum].urb_state;
  932. }
  933. /**
  934. * @brief Return the last host transfer size.
  935. * @param hhcd HCD handle
  936. * @param chnum Channel number.
  937. * This parameter can be a value from 1 to 15
  938. * @retval last transfer size in byte
  939. */
  940. uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  941. {
  942. return hhcd->hc[chnum].xfer_count;
  943. }
  944. /**
  945. * @brief Return the Host Channel state.
  946. * @param hhcd HCD handle
  947. * @param chnum Channel number.
  948. * This parameter can be a value from 1 to 15
  949. * @retval Host channel state
  950. * This parameter can be one of these values:
  951. * HC_IDLE/
  952. * HC_XFRC/
  953. * HC_HALTED/
  954. * HC_NYET/
  955. * HC_NAK/
  956. * HC_STALL/
  957. * HC_XACTERR/
  958. * HC_BBLERR/
  959. * HC_DATATGLERR
  960. */
  961. HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  962. {
  963. return hhcd->hc[chnum].state;
  964. }
  965. /**
  966. * @brief Return the current Host frame number.
  967. * @param hhcd HCD handle
  968. * @retval Current Host frame number
  969. */
  970. uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
  971. {
  972. return (USB_GetCurrentFrame(hhcd->Instance));
  973. }
  974. /**
  975. * @brief Return the Host enumeration speed.
  976. * @param hhcd HCD handle
  977. * @retval Enumeration speed
  978. */
  979. uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
  980. {
  981. return (USB_GetHostSpeed(hhcd->Instance));
  982. }
  983. /**
  984. * @}
  985. */
  986. /**
  987. * @}
  988. */
  989. /** @addtogroup HCD_Private_Functions
  990. * @{
  991. */
  992. /**
  993. * @brief Handle Host Channel IN interrupt requests.
  994. * @param hhcd HCD handle
  995. * @param chnum Channel number.
  996. * This parameter can be a value from 1 to 15
  997. * @retval none
  998. */
  999. static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  1000. {
  1001. USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1002. uint32_t USBx_BASE = (uint32_t)USBx;
  1003. uint32_t ch_num = (uint32_t)chnum;
  1004. uint32_t tmpreg;
  1005. if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR)
  1006. {
  1007. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
  1008. __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
  1009. }
  1010. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK)
  1011. {
  1012. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK);
  1013. }
  1014. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL)
  1015. {
  1016. __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
  1017. hhcd->hc[ch_num].state = HC_STALL;
  1018. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
  1019. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL);
  1020. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1021. }
  1022. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR)
  1023. {
  1024. __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
  1025. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1026. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
  1027. hhcd->hc[ch_num].state = HC_DATATGLERR;
  1028. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR);
  1029. }
  1030. else
  1031. {
  1032. /* ... */
  1033. }
  1034. if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR)
  1035. {
  1036. __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
  1037. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1038. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR);
  1039. }
  1040. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC)
  1041. {
  1042. hhcd->hc[ch_num].state = HC_XFRC;
  1043. hhcd->hc[ch_num].ErrCnt = 0U;
  1044. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC);
  1045. if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) ||
  1046. (hhcd->hc[ch_num].ep_type == EP_TYPE_BULK))
  1047. {
  1048. __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
  1049. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1050. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
  1051. }
  1052. else if (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR)
  1053. {
  1054. USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
  1055. hhcd->hc[ch_num].urb_state = URB_DONE;
  1056. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1057. hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
  1058. #else
  1059. HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
  1060. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1061. }
  1062. else if (hhcd->hc[ch_num].ep_type == EP_TYPE_ISOC)
  1063. {
  1064. hhcd->hc[ch_num].urb_state = URB_DONE;
  1065. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1066. hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
  1067. #else
  1068. HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
  1069. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1070. }
  1071. else
  1072. {
  1073. /* ... */
  1074. }
  1075. hhcd->hc[ch_num].toggle_in ^= 1U;
  1076. }
  1077. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH)
  1078. {
  1079. __HAL_HCD_MASK_HALT_HC_INT(ch_num);
  1080. if (hhcd->hc[ch_num].state == HC_XFRC)
  1081. {
  1082. hhcd->hc[ch_num].urb_state = URB_DONE;
  1083. }
  1084. else if (hhcd->hc[ch_num].state == HC_STALL)
  1085. {
  1086. hhcd->hc[ch_num].urb_state = URB_STALL;
  1087. }
  1088. else if ((hhcd->hc[ch_num].state == HC_XACTERR) ||
  1089. (hhcd->hc[ch_num].state == HC_DATATGLERR))
  1090. {
  1091. hhcd->hc[ch_num].ErrCnt++;
  1092. if (hhcd->hc[ch_num].ErrCnt > 3U)
  1093. {
  1094. hhcd->hc[ch_num].ErrCnt = 0U;
  1095. hhcd->hc[ch_num].urb_state = URB_ERROR;
  1096. }
  1097. else
  1098. {
  1099. hhcd->hc[ch_num].urb_state = URB_NOTREADY;
  1100. }
  1101. /* re-activate the channel */
  1102. tmpreg = USBx_HC(ch_num)->HCCHAR;
  1103. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1104. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1105. USBx_HC(ch_num)->HCCHAR = tmpreg;
  1106. }
  1107. else if (hhcd->hc[ch_num].state == HC_NAK)
  1108. {
  1109. hhcd->hc[ch_num].urb_state = URB_NOTREADY;
  1110. /* re-activate the channel */
  1111. tmpreg = USBx_HC(ch_num)->HCCHAR;
  1112. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1113. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1114. USBx_HC(ch_num)->HCCHAR = tmpreg;
  1115. }
  1116. else
  1117. {
  1118. /* ... */
  1119. }
  1120. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
  1121. HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
  1122. }
  1123. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR)
  1124. {
  1125. __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
  1126. hhcd->hc[ch_num].ErrCnt++;
  1127. hhcd->hc[ch_num].state = HC_XACTERR;
  1128. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1129. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR);
  1130. }
  1131. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK)
  1132. {
  1133. if (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR)
  1134. {
  1135. hhcd->hc[ch_num].ErrCnt = 0U;
  1136. __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
  1137. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1138. }
  1139. else if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) ||
  1140. (hhcd->hc[ch_num].ep_type == EP_TYPE_BULK))
  1141. {
  1142. hhcd->hc[ch_num].ErrCnt = 0U;
  1143. hhcd->hc[ch_num].state = HC_NAK;
  1144. __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
  1145. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1146. }
  1147. else
  1148. {
  1149. /* ... */
  1150. }
  1151. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
  1152. }
  1153. else
  1154. {
  1155. /* ... */
  1156. }
  1157. }
  1158. /**
  1159. * @brief Handle Host Channel OUT interrupt requests.
  1160. * @param hhcd HCD handle
  1161. * @param chnum Channel number.
  1162. * This parameter can be a value from 1 to 15
  1163. * @retval none
  1164. */
  1165. static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  1166. {
  1167. USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1168. uint32_t USBx_BASE = (uint32_t)USBx;
  1169. uint32_t ch_num = (uint32_t)chnum;
  1170. uint32_t tmpreg;
  1171. if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR)
  1172. {
  1173. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
  1174. __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
  1175. }
  1176. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK)
  1177. {
  1178. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK);
  1179. if (hhcd->hc[ch_num].do_ping == 1U)
  1180. {
  1181. hhcd->hc[ch_num].do_ping = 0U;
  1182. hhcd->hc[ch_num].urb_state = URB_NOTREADY;
  1183. __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
  1184. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1185. }
  1186. }
  1187. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET)
  1188. {
  1189. hhcd->hc[ch_num].state = HC_NYET;
  1190. hhcd->hc[ch_num].do_ping = 1U;
  1191. hhcd->hc[ch_num].ErrCnt = 0U;
  1192. __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
  1193. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1194. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET);
  1195. }
  1196. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR)
  1197. {
  1198. __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
  1199. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1200. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR);
  1201. }
  1202. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC)
  1203. {
  1204. hhcd->hc[ch_num].ErrCnt = 0U;
  1205. __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
  1206. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1207. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC);
  1208. hhcd->hc[ch_num].state = HC_XFRC;
  1209. }
  1210. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL)
  1211. {
  1212. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL);
  1213. __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
  1214. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1215. hhcd->hc[ch_num].state = HC_STALL;
  1216. }
  1217. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK)
  1218. {
  1219. hhcd->hc[ch_num].ErrCnt = 0U;
  1220. hhcd->hc[ch_num].state = HC_NAK;
  1221. __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
  1222. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1223. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
  1224. }
  1225. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR)
  1226. {
  1227. __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
  1228. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1229. hhcd->hc[ch_num].state = HC_XACTERR;
  1230. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR);
  1231. }
  1232. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR)
  1233. {
  1234. __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
  1235. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1236. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
  1237. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR);
  1238. hhcd->hc[ch_num].state = HC_DATATGLERR;
  1239. }
  1240. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH)
  1241. {
  1242. __HAL_HCD_MASK_HALT_HC_INT(ch_num);
  1243. if (hhcd->hc[ch_num].state == HC_XFRC)
  1244. {
  1245. hhcd->hc[ch_num].urb_state = URB_DONE;
  1246. if ((hhcd->hc[ch_num].ep_type == EP_TYPE_BULK) ||
  1247. (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR))
  1248. {
  1249. hhcd->hc[ch_num].toggle_out ^= 1U;
  1250. }
  1251. }
  1252. else if (hhcd->hc[ch_num].state == HC_NAK)
  1253. {
  1254. hhcd->hc[ch_num].urb_state = URB_NOTREADY;
  1255. }
  1256. else if (hhcd->hc[ch_num].state == HC_NYET)
  1257. {
  1258. hhcd->hc[ch_num].urb_state = URB_NOTREADY;
  1259. }
  1260. else if (hhcd->hc[ch_num].state == HC_STALL)
  1261. {
  1262. hhcd->hc[ch_num].urb_state = URB_STALL;
  1263. }
  1264. else if ((hhcd->hc[ch_num].state == HC_XACTERR) ||
  1265. (hhcd->hc[ch_num].state == HC_DATATGLERR))
  1266. {
  1267. hhcd->hc[ch_num].ErrCnt++;
  1268. if (hhcd->hc[ch_num].ErrCnt > 3U)
  1269. {
  1270. hhcd->hc[ch_num].ErrCnt = 0U;
  1271. hhcd->hc[ch_num].urb_state = URB_ERROR;
  1272. }
  1273. else
  1274. {
  1275. hhcd->hc[ch_num].urb_state = URB_NOTREADY;
  1276. }
  1277. /* re-activate the channel */
  1278. tmpreg = USBx_HC(ch_num)->HCCHAR;
  1279. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1280. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1281. USBx_HC(ch_num)->HCCHAR = tmpreg;
  1282. }
  1283. else
  1284. {
  1285. /* ... */
  1286. }
  1287. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
  1288. HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
  1289. }
  1290. else
  1291. {
  1292. /* ... */
  1293. }
  1294. }
  1295. /**
  1296. * @brief Handle Rx Queue Level interrupt requests.
  1297. * @param hhcd HCD handle
  1298. * @retval none
  1299. */
  1300. static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd)
  1301. {
  1302. USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1303. uint32_t USBx_BASE = (uint32_t)USBx;
  1304. uint32_t pktsts;
  1305. uint32_t pktcnt;
  1306. uint32_t temp;
  1307. uint32_t tmpreg;
  1308. uint32_t ch_num;
  1309. temp = hhcd->Instance->GRXSTSP;
  1310. ch_num = temp & USB_OTG_GRXSTSP_EPNUM;
  1311. pktsts = (temp & USB_OTG_GRXSTSP_PKTSTS) >> 17;
  1312. pktcnt = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  1313. switch (pktsts)
  1314. {
  1315. case GRXSTS_PKTSTS_IN:
  1316. /* Read the data into the host buffer. */
  1317. if ((pktcnt > 0U) && (hhcd->hc[ch_num].xfer_buff != (void *)0))
  1318. {
  1319. (void)USB_ReadPacket(hhcd->Instance, hhcd->hc[ch_num].xfer_buff, (uint16_t)pktcnt);
  1320. /*manage multiple Xfer */
  1321. hhcd->hc[ch_num].xfer_buff += pktcnt;
  1322. hhcd->hc[ch_num].xfer_count += pktcnt;
  1323. if ((USBx_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) > 0U)
  1324. {
  1325. /* re-activate the channel when more packets are expected */
  1326. tmpreg = USBx_HC(ch_num)->HCCHAR;
  1327. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1328. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1329. USBx_HC(ch_num)->HCCHAR = tmpreg;
  1330. hhcd->hc[ch_num].toggle_in ^= 1U;
  1331. }
  1332. }
  1333. break;
  1334. case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
  1335. break;
  1336. case GRXSTS_PKTSTS_IN_XFER_COMP:
  1337. case GRXSTS_PKTSTS_CH_HALTED:
  1338. default:
  1339. break;
  1340. }
  1341. }
  1342. /**
  1343. * @brief Handle Host Port interrupt requests.
  1344. * @param hhcd HCD handle
  1345. * @retval None
  1346. */
  1347. static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd)
  1348. {
  1349. USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1350. uint32_t USBx_BASE = (uint32_t)USBx;
  1351. __IO uint32_t hprt0, hprt0_dup;
  1352. /* Handle Host Port Interrupts */
  1353. hprt0 = USBx_HPRT0;
  1354. hprt0_dup = USBx_HPRT0;
  1355. hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | \
  1356. USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
  1357. /* Check whether Port Connect detected */
  1358. if ((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
  1359. {
  1360. if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
  1361. {
  1362. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1363. hhcd->ConnectCallback(hhcd);
  1364. #else
  1365. HAL_HCD_Connect_Callback(hhcd);
  1366. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1367. }
  1368. hprt0_dup |= USB_OTG_HPRT_PCDET;
  1369. }
  1370. /* Check whether Port Enable Changed */
  1371. if ((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
  1372. {
  1373. hprt0_dup |= USB_OTG_HPRT_PENCHNG;
  1374. if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
  1375. {
  1376. if (hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
  1377. {
  1378. if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17))
  1379. {
  1380. (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_6_MHZ);
  1381. }
  1382. else
  1383. {
  1384. (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
  1385. }
  1386. }
  1387. else
  1388. {
  1389. if (hhcd->Init.speed == HCD_SPEED_FULL)
  1390. {
  1391. USBx_HOST->HFIR = 60000U;
  1392. }
  1393. }
  1394. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1395. hhcd->PortEnabledCallback(hhcd);
  1396. #else
  1397. HAL_HCD_PortEnabled_Callback(hhcd);
  1398. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1399. }
  1400. else
  1401. {
  1402. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1403. hhcd->PortDisabledCallback(hhcd);
  1404. #else
  1405. HAL_HCD_PortDisabled_Callback(hhcd);
  1406. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1407. }
  1408. }
  1409. /* Check for an overcurrent */
  1410. if ((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
  1411. {
  1412. hprt0_dup |= USB_OTG_HPRT_POCCHNG;
  1413. }
  1414. /* Clear Port Interrupts */
  1415. USBx_HPRT0 = hprt0_dup;
  1416. }
  1417. /**
  1418. * @}
  1419. */
  1420. /**
  1421. * @}
  1422. */
  1423. #endif /* defined (USB_OTG_FS) */
  1424. #endif /* HAL_HCD_MODULE_ENABLED */
  1425. /**
  1426. * @}
  1427. */
  1428. /**
  1429. * @}
  1430. */
  1431. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/