stm32l4xx_hal_hcd.c 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674
  1. /**
  2. ******************************************************************************
  3. * @file stm32l4xx_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. ******************************************************************************
  14. * @attention
  15. *
  16. * Copyright (c) 2017 STMicroelectronics.
  17. * All rights reserved.
  18. *
  19. * This software is licensed under terms that can be found in the LICENSE file
  20. * in the root directory of this software component.
  21. * If no LICENSE file comes with this software, it is provided AS-IS.
  22. *
  23. ******************************************************************************
  24. @verbatim
  25. ==============================================================================
  26. ##### How to use this driver #####
  27. ==============================================================================
  28. [..]
  29. (#)Declare a HCD_HandleTypeDef handle structure, for example:
  30. HCD_HandleTypeDef hhcd;
  31. (#)Fill parameters of Init structure in HCD handle
  32. (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...)
  33. (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API:
  34. (##) Enable the HCD/USB Low Level interface clock using the following macros
  35. (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
  36. (##) Initialize the related GPIO clocks
  37. (##) Configure HCD pin-out
  38. (##) Configure HCD NVIC interrupt
  39. (#)Associate the Upper USB Host stack to the HAL HCD Driver:
  40. (##) hhcd.pData = phost;
  41. (#)Enable HCD transmission and reception:
  42. (##) HAL_HCD_Start();
  43. @endverbatim
  44. ******************************************************************************
  45. */
  46. /* Includes ------------------------------------------------------------------*/
  47. #include "stm32l4xx_hal.h"
  48. /** @addtogroup STM32L4xx_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_DEVICE_SPEED_FULL: Full speed mode,
  154. * HCD_DEVICE_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;
  430. uint32_t interrupt;
  431. /* Ensure that we are in device mode */
  432. if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
  433. {
  434. /* Avoid spurious interrupt */
  435. if (__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
  436. {
  437. return;
  438. }
  439. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
  440. {
  441. /* Incorrect mode, acknowledge the interrupt */
  442. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
  443. }
  444. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
  445. {
  446. /* Incorrect mode, acknowledge the interrupt */
  447. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
  448. }
  449. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
  450. {
  451. /* Incorrect mode, acknowledge the interrupt */
  452. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
  453. }
  454. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
  455. {
  456. /* Incorrect mode, acknowledge the interrupt */
  457. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
  458. }
  459. /* Handle Host Disconnect Interrupts */
  460. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
  461. {
  462. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
  463. if ((USBx_HPRT0 & USB_OTG_HPRT_PCSTS) == 0U)
  464. {
  465. /* Flush USB Fifo */
  466. (void)USB_FlushTxFifo(USBx, 0x10U);
  467. (void)USB_FlushRxFifo(USBx);
  468. /* Restore FS Clock */
  469. (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
  470. /* Handle Host Port Disconnect Interrupt */
  471. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  472. hhcd->DisconnectCallback(hhcd);
  473. #else
  474. HAL_HCD_Disconnect_Callback(hhcd);
  475. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  476. }
  477. }
  478. /* Handle Host Port Interrupts */
  479. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
  480. {
  481. HCD_Port_IRQHandler(hhcd);
  482. }
  483. /* Handle Host SOF Interrupt */
  484. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
  485. {
  486. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  487. hhcd->SOFCallback(hhcd);
  488. #else
  489. HAL_HCD_SOF_Callback(hhcd);
  490. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  491. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
  492. }
  493. /* Handle Rx Queue Level Interrupts */
  494. if ((__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL)) != 0U)
  495. {
  496. USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  497. HCD_RXQLVL_IRQHandler(hhcd);
  498. USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  499. }
  500. /* Handle Host channel Interrupt */
  501. if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
  502. {
  503. interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
  504. for (i = 0U; i < hhcd->Init.Host_channels; i++)
  505. {
  506. if ((interrupt & (1UL << (i & 0xFU))) != 0U)
  507. {
  508. if ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_EPDIR) == USB_OTG_HCCHAR_EPDIR)
  509. {
  510. HCD_HC_IN_IRQHandler(hhcd, (uint8_t)i);
  511. }
  512. else
  513. {
  514. HCD_HC_OUT_IRQHandler(hhcd, (uint8_t)i);
  515. }
  516. }
  517. }
  518. __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
  519. }
  520. }
  521. }
  522. /**
  523. * @brief SOF callback.
  524. * @param hhcd HCD handle
  525. * @retval None
  526. */
  527. __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
  528. {
  529. /* Prevent unused argument(s) compilation warning */
  530. UNUSED(hhcd);
  531. /* NOTE : This function should not be modified, when the callback is needed,
  532. the HAL_HCD_SOF_Callback could be implemented in the user file
  533. */
  534. }
  535. /**
  536. * @brief Connection Event callback.
  537. * @param hhcd HCD handle
  538. * @retval None
  539. */
  540. __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
  541. {
  542. /* Prevent unused argument(s) compilation warning */
  543. UNUSED(hhcd);
  544. /* NOTE : This function should not be modified, when the callback is needed,
  545. the HAL_HCD_Connect_Callback could be implemented in the user file
  546. */
  547. }
  548. /**
  549. * @brief Disconnection Event callback.
  550. * @param hhcd HCD handle
  551. * @retval None
  552. */
  553. __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
  554. {
  555. /* Prevent unused argument(s) compilation warning */
  556. UNUSED(hhcd);
  557. /* NOTE : This function should not be modified, when the callback is needed,
  558. the HAL_HCD_Disconnect_Callback could be implemented in the user file
  559. */
  560. }
  561. /**
  562. * @brief Port Enabled Event callback.
  563. * @param hhcd HCD handle
  564. * @retval None
  565. */
  566. __weak void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd)
  567. {
  568. /* Prevent unused argument(s) compilation warning */
  569. UNUSED(hhcd);
  570. /* NOTE : This function should not be modified, when the callback is needed,
  571. the HAL_HCD_Disconnect_Callback could be implemented in the user file
  572. */
  573. }
  574. /**
  575. * @brief Port Disabled Event callback.
  576. * @param hhcd HCD handle
  577. * @retval None
  578. */
  579. __weak void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd)
  580. {
  581. /* Prevent unused argument(s) compilation warning */
  582. UNUSED(hhcd);
  583. /* NOTE : This function should not be modified, when the callback is needed,
  584. the HAL_HCD_Disconnect_Callback could be implemented in the user file
  585. */
  586. }
  587. /**
  588. * @brief Notify URB state change callback.
  589. * @param hhcd HCD handle
  590. * @param chnum Channel number.
  591. * This parameter can be a value from 1 to 15
  592. * @param urb_state:
  593. * This parameter can be one of these values:
  594. * URB_IDLE/
  595. * URB_DONE/
  596. * URB_NOTREADY/
  597. * URB_NYET/
  598. * URB_ERROR/
  599. * URB_STALL/
  600. * @retval None
  601. */
  602. __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
  603. {
  604. /* Prevent unused argument(s) compilation warning */
  605. UNUSED(hhcd);
  606. UNUSED(chnum);
  607. UNUSED(urb_state);
  608. /* NOTE : This function should not be modified, when the callback is needed,
  609. the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
  610. */
  611. }
  612. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  613. /**
  614. * @brief Register a User USB HCD Callback
  615. * To be used instead of the weak predefined callback
  616. * @param hhcd USB HCD handle
  617. * @param CallbackID ID of the callback to be registered
  618. * This parameter can be one of the following values:
  619. * @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
  620. * @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
  621. * @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
  622. * @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enable callback ID
  623. * @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disable callback ID
  624. * @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
  625. * @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
  626. * @param pCallback pointer to the Callback function
  627. * @retval HAL status
  628. */
  629. HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd,
  630. HAL_HCD_CallbackIDTypeDef CallbackID,
  631. pHCD_CallbackTypeDef pCallback)
  632. {
  633. HAL_StatusTypeDef status = HAL_OK;
  634. if (pCallback == NULL)
  635. {
  636. /* Update the error code */
  637. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  638. return HAL_ERROR;
  639. }
  640. /* Process locked */
  641. __HAL_LOCK(hhcd);
  642. if (hhcd->State == HAL_HCD_STATE_READY)
  643. {
  644. switch (CallbackID)
  645. {
  646. case HAL_HCD_SOF_CB_ID :
  647. hhcd->SOFCallback = pCallback;
  648. break;
  649. case HAL_HCD_CONNECT_CB_ID :
  650. hhcd->ConnectCallback = pCallback;
  651. break;
  652. case HAL_HCD_DISCONNECT_CB_ID :
  653. hhcd->DisconnectCallback = pCallback;
  654. break;
  655. case HAL_HCD_PORT_ENABLED_CB_ID :
  656. hhcd->PortEnabledCallback = pCallback;
  657. break;
  658. case HAL_HCD_PORT_DISABLED_CB_ID :
  659. hhcd->PortDisabledCallback = pCallback;
  660. break;
  661. case HAL_HCD_MSPINIT_CB_ID :
  662. hhcd->MspInitCallback = pCallback;
  663. break;
  664. case HAL_HCD_MSPDEINIT_CB_ID :
  665. hhcd->MspDeInitCallback = pCallback;
  666. break;
  667. default :
  668. /* Update the error code */
  669. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  670. /* Return error status */
  671. status = HAL_ERROR;
  672. break;
  673. }
  674. }
  675. else if (hhcd->State == HAL_HCD_STATE_RESET)
  676. {
  677. switch (CallbackID)
  678. {
  679. case HAL_HCD_MSPINIT_CB_ID :
  680. hhcd->MspInitCallback = pCallback;
  681. break;
  682. case HAL_HCD_MSPDEINIT_CB_ID :
  683. hhcd->MspDeInitCallback = pCallback;
  684. break;
  685. default :
  686. /* Update the error code */
  687. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  688. /* Return error status */
  689. status = HAL_ERROR;
  690. break;
  691. }
  692. }
  693. else
  694. {
  695. /* Update the error code */
  696. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  697. /* Return error status */
  698. status = HAL_ERROR;
  699. }
  700. /* Release Lock */
  701. __HAL_UNLOCK(hhcd);
  702. return status;
  703. }
  704. /**
  705. * @brief Unregister an USB HCD Callback
  706. * USB HCD callback is redirected to the weak predefined callback
  707. * @param hhcd USB HCD handle
  708. * @param CallbackID ID of the callback to be unregistered
  709. * This parameter can be one of the following values:
  710. * @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
  711. * @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
  712. * @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
  713. * @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enabled callback ID
  714. * @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disabled callback ID
  715. * @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
  716. * @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
  717. * @retval HAL status
  718. */
  719. HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID)
  720. {
  721. HAL_StatusTypeDef status = HAL_OK;
  722. /* Process locked */
  723. __HAL_LOCK(hhcd);
  724. /* Setup Legacy weak Callbacks */
  725. if (hhcd->State == HAL_HCD_STATE_READY)
  726. {
  727. switch (CallbackID)
  728. {
  729. case HAL_HCD_SOF_CB_ID :
  730. hhcd->SOFCallback = HAL_HCD_SOF_Callback;
  731. break;
  732. case HAL_HCD_CONNECT_CB_ID :
  733. hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
  734. break;
  735. case HAL_HCD_DISCONNECT_CB_ID :
  736. hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
  737. break;
  738. case HAL_HCD_PORT_ENABLED_CB_ID :
  739. hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
  740. break;
  741. case HAL_HCD_PORT_DISABLED_CB_ID :
  742. hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
  743. break;
  744. case HAL_HCD_MSPINIT_CB_ID :
  745. hhcd->MspInitCallback = HAL_HCD_MspInit;
  746. break;
  747. case HAL_HCD_MSPDEINIT_CB_ID :
  748. hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
  749. break;
  750. default :
  751. /* Update the error code */
  752. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  753. /* Return error status */
  754. status = HAL_ERROR;
  755. break;
  756. }
  757. }
  758. else if (hhcd->State == HAL_HCD_STATE_RESET)
  759. {
  760. switch (CallbackID)
  761. {
  762. case HAL_HCD_MSPINIT_CB_ID :
  763. hhcd->MspInitCallback = HAL_HCD_MspInit;
  764. break;
  765. case HAL_HCD_MSPDEINIT_CB_ID :
  766. hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
  767. break;
  768. default :
  769. /* Update the error code */
  770. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  771. /* Return error status */
  772. status = HAL_ERROR;
  773. break;
  774. }
  775. }
  776. else
  777. {
  778. /* Update the error code */
  779. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  780. /* Return error status */
  781. status = HAL_ERROR;
  782. }
  783. /* Release Lock */
  784. __HAL_UNLOCK(hhcd);
  785. return status;
  786. }
  787. /**
  788. * @brief Register USB HCD Host Channel Notify URB Change Callback
  789. * To be used instead of the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
  790. * @param hhcd HCD handle
  791. * @param pCallback pointer to the USB HCD Host Channel Notify URB Change Callback function
  792. * @retval HAL status
  793. */
  794. HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd,
  795. pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback)
  796. {
  797. HAL_StatusTypeDef status = HAL_OK;
  798. if (pCallback == NULL)
  799. {
  800. /* Update the error code */
  801. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  802. return HAL_ERROR;
  803. }
  804. /* Process locked */
  805. __HAL_LOCK(hhcd);
  806. if (hhcd->State == HAL_HCD_STATE_READY)
  807. {
  808. hhcd->HC_NotifyURBChangeCallback = pCallback;
  809. }
  810. else
  811. {
  812. /* Update the error code */
  813. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  814. /* Return error status */
  815. status = HAL_ERROR;
  816. }
  817. /* Release Lock */
  818. __HAL_UNLOCK(hhcd);
  819. return status;
  820. }
  821. /**
  822. * @brief Unregister the USB HCD Host Channel Notify URB Change Callback
  823. * USB HCD Host Channel Notify URB Change Callback is redirected
  824. * to the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
  825. * @param hhcd HCD handle
  826. * @retval HAL status
  827. */
  828. HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd)
  829. {
  830. HAL_StatusTypeDef status = HAL_OK;
  831. /* Process locked */
  832. __HAL_LOCK(hhcd);
  833. if (hhcd->State == HAL_HCD_STATE_READY)
  834. {
  835. hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback; /* Legacy weak DataOutStageCallback */
  836. }
  837. else
  838. {
  839. /* Update the error code */
  840. hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  841. /* Return error status */
  842. status = HAL_ERROR;
  843. }
  844. /* Release Lock */
  845. __HAL_UNLOCK(hhcd);
  846. return status;
  847. }
  848. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  849. /**
  850. * @}
  851. */
  852. /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
  853. * @brief Management functions
  854. *
  855. @verbatim
  856. ===============================================================================
  857. ##### Peripheral Control functions #####
  858. ===============================================================================
  859. [..]
  860. This subsection provides a set of functions allowing to control the HCD data
  861. transfers.
  862. @endverbatim
  863. * @{
  864. */
  865. /**
  866. * @brief Start the host driver.
  867. * @param hhcd HCD handle
  868. * @retval HAL status
  869. */
  870. HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
  871. {
  872. __HAL_LOCK(hhcd);
  873. /* Enable port power */
  874. (void)USB_DriveVbus(hhcd->Instance, 1U);
  875. /* Enable global interrupt */
  876. __HAL_HCD_ENABLE(hhcd);
  877. __HAL_UNLOCK(hhcd);
  878. return HAL_OK;
  879. }
  880. /**
  881. * @brief Stop the host driver.
  882. * @param hhcd HCD handle
  883. * @retval HAL status
  884. */
  885. HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
  886. {
  887. __HAL_LOCK(hhcd);
  888. (void)USB_StopHost(hhcd->Instance);
  889. __HAL_UNLOCK(hhcd);
  890. return HAL_OK;
  891. }
  892. /**
  893. * @brief Reset the host port.
  894. * @param hhcd HCD handle
  895. * @retval HAL status
  896. */
  897. HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
  898. {
  899. return (USB_ResetPort(hhcd->Instance));
  900. }
  901. /**
  902. * @}
  903. */
  904. /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
  905. * @brief Peripheral State functions
  906. *
  907. @verbatim
  908. ===============================================================================
  909. ##### Peripheral State functions #####
  910. ===============================================================================
  911. [..]
  912. This subsection permits to get in run-time the status of the peripheral
  913. and the data flow.
  914. @endverbatim
  915. * @{
  916. */
  917. /**
  918. * @brief Return the HCD handle state.
  919. * @param hhcd HCD handle
  920. * @retval HAL state
  921. */
  922. HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd)
  923. {
  924. return hhcd->State;
  925. }
  926. /**
  927. * @brief Return URB state for a channel.
  928. * @param hhcd HCD handle
  929. * @param chnum Channel number.
  930. * This parameter can be a value from 1 to 15
  931. * @retval URB state.
  932. * This parameter can be one of these values:
  933. * URB_IDLE/
  934. * URB_DONE/
  935. * URB_NOTREADY/
  936. * URB_NYET/
  937. * URB_ERROR/
  938. * URB_STALL
  939. */
  940. HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  941. {
  942. return hhcd->hc[chnum].urb_state;
  943. }
  944. /**
  945. * @brief Return the last host transfer size.
  946. * @param hhcd HCD handle
  947. * @param chnum Channel number.
  948. * This parameter can be a value from 1 to 15
  949. * @retval last transfer size in byte
  950. */
  951. uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  952. {
  953. return hhcd->hc[chnum].xfer_count;
  954. }
  955. /**
  956. * @brief Return the Host Channel state.
  957. * @param hhcd HCD handle
  958. * @param chnum Channel number.
  959. * This parameter can be a value from 1 to 15
  960. * @retval Host channel state
  961. * This parameter can be one of these values:
  962. * HC_IDLE/
  963. * HC_XFRC/
  964. * HC_HALTED/
  965. * HC_NYET/
  966. * HC_NAK/
  967. * HC_STALL/
  968. * HC_XACTERR/
  969. * HC_BBLERR/
  970. * HC_DATATGLERR
  971. */
  972. HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  973. {
  974. return hhcd->hc[chnum].state;
  975. }
  976. /**
  977. * @brief Return the current Host frame number.
  978. * @param hhcd HCD handle
  979. * @retval Current Host frame number
  980. */
  981. uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
  982. {
  983. return (USB_GetCurrentFrame(hhcd->Instance));
  984. }
  985. /**
  986. * @brief Return the Host enumeration speed.
  987. * @param hhcd HCD handle
  988. * @retval Enumeration speed
  989. */
  990. uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
  991. {
  992. return (USB_GetHostSpeed(hhcd->Instance));
  993. }
  994. /**
  995. * @}
  996. */
  997. /**
  998. * @}
  999. */
  1000. /** @addtogroup HCD_Private_Functions
  1001. * @{
  1002. */
  1003. /**
  1004. * @brief Handle Host Channel IN interrupt requests.
  1005. * @param hhcd HCD handle
  1006. * @param chnum Channel number.
  1007. * This parameter can be a value from 1 to 15
  1008. * @retval none
  1009. */
  1010. static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  1011. {
  1012. USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1013. uint32_t USBx_BASE = (uint32_t)USBx;
  1014. uint32_t ch_num = (uint32_t)chnum;
  1015. uint32_t tmpreg;
  1016. if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR)
  1017. {
  1018. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
  1019. hhcd->hc[ch_num].state = HC_XACTERR;
  1020. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1021. }
  1022. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_BBERR) == USB_OTG_HCINT_BBERR)
  1023. {
  1024. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_BBERR);
  1025. hhcd->hc[ch_num].state = HC_BBLERR;
  1026. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1027. }
  1028. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK)
  1029. {
  1030. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK);
  1031. }
  1032. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL)
  1033. {
  1034. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL);
  1035. hhcd->hc[ch_num].state = HC_STALL;
  1036. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1037. }
  1038. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR)
  1039. {
  1040. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR);
  1041. hhcd->hc[ch_num].state = HC_DATATGLERR;
  1042. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1043. }
  1044. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR)
  1045. {
  1046. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR);
  1047. hhcd->hc[ch_num].state = HC_XACTERR;
  1048. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1049. }
  1050. else
  1051. {
  1052. /* ... */
  1053. }
  1054. if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR)
  1055. {
  1056. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1057. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR);
  1058. }
  1059. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC)
  1060. {
  1061. hhcd->hc[ch_num].state = HC_XFRC;
  1062. hhcd->hc[ch_num].ErrCnt = 0U;
  1063. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC);
  1064. if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) ||
  1065. (hhcd->hc[ch_num].ep_type == EP_TYPE_BULK))
  1066. {
  1067. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1068. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
  1069. }
  1070. else if ((hhcd->hc[ch_num].ep_type == EP_TYPE_INTR) ||
  1071. (hhcd->hc[ch_num].ep_type == EP_TYPE_ISOC))
  1072. {
  1073. USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
  1074. hhcd->hc[ch_num].urb_state = URB_DONE;
  1075. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1076. hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
  1077. #else
  1078. HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
  1079. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1080. }
  1081. else
  1082. {
  1083. /* ... */
  1084. }
  1085. if (hhcd->Init.dma_enable == 1U)
  1086. {
  1087. if (((hhcd->hc[ch_num].XferSize / hhcd->hc[ch_num].max_packet) & 1U) != 0U)
  1088. {
  1089. hhcd->hc[ch_num].toggle_in ^= 1U;
  1090. }
  1091. }
  1092. else
  1093. {
  1094. hhcd->hc[ch_num].toggle_in ^= 1U;
  1095. }
  1096. }
  1097. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH)
  1098. {
  1099. if (hhcd->hc[ch_num].state == HC_XFRC)
  1100. {
  1101. hhcd->hc[ch_num].urb_state = URB_DONE;
  1102. }
  1103. else if (hhcd->hc[ch_num].state == HC_STALL)
  1104. {
  1105. hhcd->hc[ch_num].urb_state = URB_STALL;
  1106. }
  1107. else if ((hhcd->hc[ch_num].state == HC_XACTERR) ||
  1108. (hhcd->hc[ch_num].state == HC_DATATGLERR))
  1109. {
  1110. hhcd->hc[ch_num].ErrCnt++;
  1111. if (hhcd->hc[ch_num].ErrCnt > 2U)
  1112. {
  1113. hhcd->hc[ch_num].ErrCnt = 0U;
  1114. hhcd->hc[ch_num].urb_state = URB_ERROR;
  1115. }
  1116. else
  1117. {
  1118. hhcd->hc[ch_num].urb_state = URB_NOTREADY;
  1119. /* re-activate the channel */
  1120. tmpreg = USBx_HC(ch_num)->HCCHAR;
  1121. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1122. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1123. USBx_HC(ch_num)->HCCHAR = tmpreg;
  1124. }
  1125. }
  1126. else if (hhcd->hc[ch_num].state == HC_NAK)
  1127. {
  1128. hhcd->hc[ch_num].urb_state = URB_NOTREADY;
  1129. /* re-activate the channel */
  1130. tmpreg = USBx_HC(ch_num)->HCCHAR;
  1131. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1132. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1133. USBx_HC(ch_num)->HCCHAR = tmpreg;
  1134. }
  1135. else if (hhcd->hc[ch_num].state == HC_BBLERR)
  1136. {
  1137. hhcd->hc[ch_num].ErrCnt++;
  1138. hhcd->hc[ch_num].urb_state = URB_ERROR;
  1139. }
  1140. else
  1141. {
  1142. /* ... */
  1143. }
  1144. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
  1145. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1146. hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
  1147. #else
  1148. HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
  1149. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1150. }
  1151. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK)
  1152. {
  1153. if (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR)
  1154. {
  1155. hhcd->hc[ch_num].ErrCnt = 0U;
  1156. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1157. }
  1158. else if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) ||
  1159. (hhcd->hc[ch_num].ep_type == EP_TYPE_BULK))
  1160. {
  1161. hhcd->hc[ch_num].ErrCnt = 0U;
  1162. hhcd->hc[ch_num].state = HC_NAK;
  1163. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1164. }
  1165. else
  1166. {
  1167. /* ... */
  1168. }
  1169. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
  1170. }
  1171. else
  1172. {
  1173. /* ... */
  1174. }
  1175. }
  1176. /**
  1177. * @brief Handle Host Channel OUT interrupt requests.
  1178. * @param hhcd HCD handle
  1179. * @param chnum Channel number.
  1180. * This parameter can be a value from 1 to 15
  1181. * @retval none
  1182. */
  1183. static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  1184. {
  1185. USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1186. uint32_t USBx_BASE = (uint32_t)USBx;
  1187. uint32_t ch_num = (uint32_t)chnum;
  1188. uint32_t tmpreg;
  1189. uint32_t num_packets;
  1190. if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR)
  1191. {
  1192. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
  1193. hhcd->hc[ch_num].state = HC_XACTERR;
  1194. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1195. }
  1196. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK)
  1197. {
  1198. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK);
  1199. if (hhcd->hc[ch_num].do_ping == 1U)
  1200. {
  1201. hhcd->hc[ch_num].do_ping = 0U;
  1202. hhcd->hc[ch_num].urb_state = URB_NOTREADY;
  1203. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1204. }
  1205. }
  1206. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR)
  1207. {
  1208. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR);
  1209. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1210. }
  1211. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC)
  1212. {
  1213. hhcd->hc[ch_num].ErrCnt = 0U;
  1214. /* transaction completed with NYET state, update do ping state */
  1215. if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET)
  1216. {
  1217. hhcd->hc[ch_num].do_ping = 1U;
  1218. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET);
  1219. }
  1220. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC);
  1221. hhcd->hc[ch_num].state = HC_XFRC;
  1222. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1223. }
  1224. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET)
  1225. {
  1226. hhcd->hc[ch_num].state = HC_NYET;
  1227. hhcd->hc[ch_num].do_ping = 1U;
  1228. hhcd->hc[ch_num].ErrCnt = 0U;
  1229. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1230. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET);
  1231. }
  1232. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL)
  1233. {
  1234. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL);
  1235. hhcd->hc[ch_num].state = HC_STALL;
  1236. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1237. }
  1238. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK)
  1239. {
  1240. hhcd->hc[ch_num].ErrCnt = 0U;
  1241. hhcd->hc[ch_num].state = HC_NAK;
  1242. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1243. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
  1244. }
  1245. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR)
  1246. {
  1247. hhcd->hc[ch_num].state = HC_XACTERR;
  1248. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1249. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR);
  1250. }
  1251. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR)
  1252. {
  1253. hhcd->hc[ch_num].state = HC_DATATGLERR;
  1254. (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
  1255. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR);
  1256. }
  1257. else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH)
  1258. {
  1259. if (hhcd->hc[ch_num].state == HC_XFRC)
  1260. {
  1261. hhcd->hc[ch_num].urb_state = URB_DONE;
  1262. if ((hhcd->hc[ch_num].ep_type == EP_TYPE_BULK) ||
  1263. (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR))
  1264. {
  1265. if (hhcd->Init.dma_enable == 0U)
  1266. {
  1267. hhcd->hc[ch_num].toggle_out ^= 1U;
  1268. }
  1269. if ((hhcd->Init.dma_enable == 1U) && (hhcd->hc[ch_num].xfer_len > 0U))
  1270. {
  1271. num_packets = (hhcd->hc[ch_num].xfer_len + hhcd->hc[ch_num].max_packet - 1U) / hhcd->hc[ch_num].max_packet;
  1272. if ((num_packets & 1U) != 0U)
  1273. {
  1274. hhcd->hc[ch_num].toggle_out ^= 1U;
  1275. }
  1276. }
  1277. }
  1278. }
  1279. else if (hhcd->hc[ch_num].state == HC_NAK)
  1280. {
  1281. hhcd->hc[ch_num].urb_state = URB_NOTREADY;
  1282. }
  1283. else if (hhcd->hc[ch_num].state == HC_NYET)
  1284. {
  1285. hhcd->hc[ch_num].urb_state = URB_NOTREADY;
  1286. }
  1287. else if (hhcd->hc[ch_num].state == HC_STALL)
  1288. {
  1289. hhcd->hc[ch_num].urb_state = URB_STALL;
  1290. }
  1291. else if ((hhcd->hc[ch_num].state == HC_XACTERR) ||
  1292. (hhcd->hc[ch_num].state == HC_DATATGLERR))
  1293. {
  1294. hhcd->hc[ch_num].ErrCnt++;
  1295. if (hhcd->hc[ch_num].ErrCnt > 2U)
  1296. {
  1297. hhcd->hc[ch_num].ErrCnt = 0U;
  1298. hhcd->hc[ch_num].urb_state = URB_ERROR;
  1299. }
  1300. else
  1301. {
  1302. hhcd->hc[ch_num].urb_state = URB_NOTREADY;
  1303. /* re-activate the channel */
  1304. tmpreg = USBx_HC(ch_num)->HCCHAR;
  1305. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1306. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1307. USBx_HC(ch_num)->HCCHAR = tmpreg;
  1308. }
  1309. }
  1310. else
  1311. {
  1312. /* ... */
  1313. }
  1314. __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
  1315. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1316. hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
  1317. #else
  1318. HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
  1319. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1320. }
  1321. else
  1322. {
  1323. /* ... */
  1324. }
  1325. }
  1326. /**
  1327. * @brief Handle Rx Queue Level interrupt requests.
  1328. * @param hhcd HCD handle
  1329. * @retval none
  1330. */
  1331. static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd)
  1332. {
  1333. USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1334. uint32_t USBx_BASE = (uint32_t)USBx;
  1335. uint32_t pktsts;
  1336. uint32_t pktcnt;
  1337. uint32_t GrxstspReg;
  1338. uint32_t xferSizePktCnt;
  1339. uint32_t tmpreg;
  1340. uint32_t ch_num;
  1341. GrxstspReg = hhcd->Instance->GRXSTSP;
  1342. ch_num = GrxstspReg & USB_OTG_GRXSTSP_EPNUM;
  1343. pktsts = (GrxstspReg & USB_OTG_GRXSTSP_PKTSTS) >> 17;
  1344. pktcnt = (GrxstspReg & USB_OTG_GRXSTSP_BCNT) >> 4;
  1345. switch (pktsts)
  1346. {
  1347. case GRXSTS_PKTSTS_IN:
  1348. /* Read the data into the host buffer. */
  1349. if ((pktcnt > 0U) && (hhcd->hc[ch_num].xfer_buff != (void *)0))
  1350. {
  1351. if ((hhcd->hc[ch_num].xfer_count + pktcnt) <= hhcd->hc[ch_num].xfer_len)
  1352. {
  1353. (void)USB_ReadPacket(hhcd->Instance,
  1354. hhcd->hc[ch_num].xfer_buff, (uint16_t)pktcnt);
  1355. /* manage multiple Xfer */
  1356. hhcd->hc[ch_num].xfer_buff += pktcnt;
  1357. hhcd->hc[ch_num].xfer_count += pktcnt;
  1358. /* get transfer size packet count */
  1359. xferSizePktCnt = (USBx_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19;
  1360. if ((hhcd->hc[ch_num].max_packet == pktcnt) && (xferSizePktCnt > 0U))
  1361. {
  1362. /* re-activate the channel when more packets are expected */
  1363. tmpreg = USBx_HC(ch_num)->HCCHAR;
  1364. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1365. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1366. USBx_HC(ch_num)->HCCHAR = tmpreg;
  1367. hhcd->hc[ch_num].toggle_in ^= 1U;
  1368. }
  1369. }
  1370. else
  1371. {
  1372. hhcd->hc[ch_num].urb_state = URB_ERROR;
  1373. }
  1374. }
  1375. break;
  1376. case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
  1377. break;
  1378. case GRXSTS_PKTSTS_IN_XFER_COMP:
  1379. case GRXSTS_PKTSTS_CH_HALTED:
  1380. default:
  1381. break;
  1382. }
  1383. }
  1384. /**
  1385. * @brief Handle Host Port interrupt requests.
  1386. * @param hhcd HCD handle
  1387. * @retval None
  1388. */
  1389. static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd)
  1390. {
  1391. USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1392. uint32_t USBx_BASE = (uint32_t)USBx;
  1393. __IO uint32_t hprt0;
  1394. __IO uint32_t hprt0_dup;
  1395. /* Handle Host Port Interrupts */
  1396. hprt0 = USBx_HPRT0;
  1397. hprt0_dup = USBx_HPRT0;
  1398. hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | \
  1399. USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
  1400. /* Check whether Port Connect detected */
  1401. if ((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
  1402. {
  1403. if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
  1404. {
  1405. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1406. hhcd->ConnectCallback(hhcd);
  1407. #else
  1408. HAL_HCD_Connect_Callback(hhcd);
  1409. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1410. }
  1411. hprt0_dup |= USB_OTG_HPRT_PCDET;
  1412. }
  1413. /* Check whether Port Enable Changed */
  1414. if ((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
  1415. {
  1416. hprt0_dup |= USB_OTG_HPRT_PENCHNG;
  1417. if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
  1418. {
  1419. if (hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
  1420. {
  1421. if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17))
  1422. {
  1423. (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_6_MHZ);
  1424. }
  1425. else
  1426. {
  1427. (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
  1428. }
  1429. }
  1430. else
  1431. {
  1432. if (hhcd->Init.speed == HCD_SPEED_FULL)
  1433. {
  1434. USBx_HOST->HFIR = 60000U;
  1435. }
  1436. }
  1437. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1438. hhcd->PortEnabledCallback(hhcd);
  1439. #else
  1440. HAL_HCD_PortEnabled_Callback(hhcd);
  1441. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1442. }
  1443. else
  1444. {
  1445. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1446. hhcd->PortDisabledCallback(hhcd);
  1447. #else
  1448. HAL_HCD_PortDisabled_Callback(hhcd);
  1449. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1450. }
  1451. }
  1452. /* Check for an overcurrent */
  1453. if ((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
  1454. {
  1455. hprt0_dup |= USB_OTG_HPRT_POCCHNG;
  1456. }
  1457. /* Clear Port Interrupts */
  1458. USBx_HPRT0 = hprt0_dup;
  1459. }
  1460. /**
  1461. * @}
  1462. */
  1463. /**
  1464. * @}
  1465. */
  1466. #endif /* defined (USB_OTG_FS) */
  1467. #endif /* HAL_HCD_MODULE_ENABLED */
  1468. /**
  1469. * @}
  1470. */
  1471. /**
  1472. * @}
  1473. */