usbh_int.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. /*!
  2. \file usbh_int.c
  3. \brief USB host mode interrupt handler file
  4. */
  5. /*
  6. Copyright (C) 2017 GigaDevice
  7. 2017-02-10, V1.0.0, firmware for GD32F30x
  8. */
  9. #include "usb_core.h"
  10. #include "usb_defines.h"
  11. #include "usbh_int.h"
  12. static uint32_t usbh_intf_sof (usb_core_handle_struct *pudev);
  13. static uint32_t usbh_intf_port (usb_core_handle_struct *pudev);
  14. static uint32_t usbh_intf_hc (usb_core_handle_struct *pudev);
  15. static uint32_t usbh_intf_hc_in (usb_core_handle_struct *pudev, uint8_t channel_num);
  16. static uint32_t usbh_intf_hc_out (usb_core_handle_struct *pudev, uint8_t channel_num);
  17. static uint32_t usbh_intf_rxfifo_noempty (usb_core_handle_struct *pudev);
  18. static uint32_t usbh_intf_nptxfifo_empty (usb_core_handle_struct *pudev);
  19. static uint32_t usbh_intf_ptxfifo_empty (usb_core_handle_struct *pudev);
  20. static uint32_t usbh_intf_disconnect (usb_core_handle_struct *pudev);
  21. static uint32_t usbh_intf_iso_incomplete_xfer (usb_core_handle_struct *pudev);
  22. /*!
  23. \brief handle global host interrupt
  24. \param[in] pudev: pointer to usb device instance
  25. \param[out] none
  26. \retval operation status
  27. */
  28. uint32_t usbh_isr (usb_core_handle_struct *pudev)
  29. {
  30. uint32_t retval = 0U;
  31. uint32_t int_flag = 0U;
  32. /* check if host mode */
  33. if (USB_CURRENT_MODE_GET() == HOST_MODE) {
  34. USB_CORE_INTR_READ(int_flag);
  35. if (!int_flag) {
  36. return 0U;
  37. }
  38. /* start of frame interrupt handle */
  39. if (int_flag & GINTF_SOF) {
  40. retval |= usbh_intf_sof (pudev);
  41. }
  42. /* Rx FIFO non-empty interrupt handle */
  43. if (int_flag & GINTF_RXFNEIF) {
  44. retval |= usbh_intf_rxfifo_noempty (pudev);
  45. }
  46. /* Non-Periodic Tx FIFO empty interrupt hanlde */
  47. if (int_flag & GINTF_NPTXFEIF) {
  48. retval |= usbh_intf_nptxfifo_empty (pudev);
  49. }
  50. /* periodic Tx FIFO empty interrupt handle */
  51. if (int_flag & GINTF_PTXFEIF) {
  52. retval |= usbh_intf_ptxfifo_empty (pudev);
  53. }
  54. /* host channels interrupt handle */
  55. if (int_flag & GINTF_HCIF) {
  56. retval |= usbh_intf_hc (pudev);
  57. }
  58. /* host port interrupt handle */
  59. if (int_flag & GINTF_HPIF) {
  60. retval |= usbh_intf_port (pudev);
  61. }
  62. /* disconnect interrupt handle */
  63. if (int_flag & GINTF_DISCIF) {
  64. retval |= usbh_intf_disconnect (pudev);
  65. }
  66. /* isochronous IN transfer not complete interrupt handle */
  67. if (int_flag & GINTF_ISOONCIF) {
  68. retval |= usbh_intf_iso_incomplete_xfer (pudev);
  69. }
  70. }
  71. return retval;
  72. }
  73. /*!
  74. \brief handle the start-of-frame interrupt in host mode
  75. \param[in] pudev: pointer to usb device instance
  76. \param[out] none
  77. \retval operation status
  78. */
  79. static uint32_t usbh_intf_sof (usb_core_handle_struct *pudev)
  80. {
  81. usbh_hcd_int_fops->sof(pudev);
  82. /* clear interrupt */
  83. USB_GINTF = GINTF_SOF;
  84. return 1U;
  85. }
  86. /*!
  87. \brief handle all host channels interrupt in host mode
  88. \param[in] pudev: pointer to usb device instance
  89. \param[out] none
  90. \retval operation status
  91. */
  92. static uint32_t usbh_intf_hc (usb_core_handle_struct *pudev)
  93. {
  94. uint8_t i = 0U;
  95. uint32_t retval = 0U;
  96. for (i = 0U; i < pudev->cfg.host_channel_num; i++) {
  97. if ((USB_HACHINT & HACHINT_HACHINT) & ((uint32_t)1U << i)) {
  98. if ((USB_HCHxCTL((uint16_t)i) & HCHCTL_EPDIR) >> 15U) {
  99. retval |= usbh_intf_hc_in (pudev, i);
  100. } else {
  101. retval |= usbh_intf_hc_out (pudev, i);
  102. }
  103. }
  104. }
  105. return retval;
  106. }
  107. /*!
  108. \brief handle the disconnect interrupt
  109. \param[in] pudev: pointer to usb device instance
  110. \param[out] none
  111. \retval operation status
  112. */
  113. static uint32_t usbh_intf_disconnect (usb_core_handle_struct *pudev)
  114. {
  115. usbh_hcd_int_fops->device_disconnected(pudev);
  116. /* clear interrupt */
  117. USB_GINTF = GINTF_DISCIF;
  118. return 1U;
  119. }
  120. /*!
  121. \brief handle the non-periodic tx fifo empty interrupt
  122. \param[in] pudev: pointer to usb device instance
  123. \param[out] none
  124. \retval operation status
  125. */
  126. static uint32_t usbh_intf_nptxfifo_empty (usb_core_handle_struct *pudev)
  127. {
  128. uint8_t channel_num = 0U;
  129. uint32_t dword_len = 0U, len = 0U;
  130. usb_hostchannel_struct *puhc;
  131. channel_num = (uint8_t)((USB_HNPTFQSTAT & HNPTFQSTAT_CNUM) >> 27U);
  132. puhc = &pudev->host.host_channel[channel_num];
  133. dword_len = (puhc->xfer_len + 3U) / 4U;
  134. while (((USB_HNPTFQSTAT & HNPTFQSTAT_NPTXFS) > dword_len) && (0U != puhc->xfer_len)) {
  135. len = (USB_HNPTFQSTAT & HNPTFQSTAT_NPTXFS) * 4U;
  136. if (len > puhc->xfer_len) {
  137. /* last packet */
  138. len = (uint16_t)puhc->xfer_len;
  139. USB_GINTEN &= ~GINTF_NPTXFEIF;
  140. }
  141. dword_len = (puhc->xfer_len + 3U) / 4U;
  142. usb_fifo_write (puhc->xfer_buff, channel_num, (uint16_t)len);
  143. puhc->xfer_buff += len;
  144. puhc->xfer_len -= len;
  145. puhc->xfer_count += len;
  146. }
  147. return 1U;
  148. }
  149. /*!
  150. \brief handle the periodic tx fifo empty interrupt
  151. \param[in] pudev: pointer to usb device instance
  152. \param[out] none
  153. \retval operation status
  154. */
  155. static uint32_t usbh_intf_ptxfifo_empty (usb_core_handle_struct *pudev)
  156. {
  157. uint8_t channel_num = 0U;
  158. uint32_t dword_len = 0U, len = 0U;
  159. usb_hostchannel_struct *puhc;
  160. channel_num = (uint8_t)((USB_HPTFQSTAT & HPTFQSTAT_CNUM) >> 27U);
  161. puhc = &pudev->host.host_channel[channel_num];
  162. dword_len = (puhc->xfer_len + 3U) / 4U;
  163. while (((USB_HPTFQSTAT & HPTFQSTAT_PTXFS) > dword_len) && (0U != puhc->xfer_len)) {
  164. len = (USB_HPTFQSTAT & HPTFQSTAT_PTXFS) * 4U;
  165. if (len > puhc->xfer_len) {
  166. len = puhc->xfer_len;
  167. /* last packet */
  168. USB_GINTEN &= ~GINTF_PTXFEIF;
  169. }
  170. dword_len = (puhc->xfer_len + 3U) / 4U;
  171. usb_fifo_write (puhc->xfer_buff, channel_num, (uint16_t)len);
  172. puhc->xfer_buff += len;
  173. puhc->xfer_len -= len;
  174. puhc->xfer_count += len;
  175. }
  176. return 1U;
  177. }
  178. /*!
  179. \brief handle the host port interrupt
  180. \param[in] pudev: pointer to usb device instance
  181. \param[out] none
  182. \retval operation status
  183. */
  184. static uint32_t usbh_intf_port (usb_core_handle_struct *pudev)
  185. {
  186. uint8_t port_speed = 0U;
  187. uint8_t port_reset = 0U;
  188. uint32_t retval = 0U;
  189. __IO uint32_t hostportdup = USB_HPCS;
  190. /* clear the interrupt bits in gintsts */
  191. hostportdup &= ~HPCS_PE;
  192. hostportdup &= ~HPCS_PCD;
  193. hostportdup &= ~HPCS_PEDC;
  194. /* port connect detected */
  195. if (USB_HPCS & HPCS_PCD) {
  196. hostportdup |= HPCS_PCD;
  197. usbh_hcd_int_fops->device_connected(pudev);
  198. retval |= 1U;
  199. }
  200. /* port enable changed */
  201. if (USB_HPCS & HPCS_PEDC) {
  202. hostportdup |= HPCS_PEDC;
  203. if (USB_HPCS & HPCS_PE) {
  204. port_speed = (uint8_t)((USB_HPCS & HPCS_PS) >> 17U);
  205. if (HPRT_PRTSPD_LOW_SPEED == port_speed) {
  206. USB_HFT = 6000U;
  207. if (HCTLR_6_MHZ != (USB_HCTL & HCTL_CLKSEL)) {
  208. if (USB_CORE_EMBEDDED_PHY == pudev->cfg.phy_interface) {
  209. USB_FSLSCLOCK_INIT(HCTLR_6_MHZ);
  210. }
  211. port_reset = 1U;
  212. }
  213. } else if(HPRT_PRTSPD_FULL_SPEED == port_speed) {
  214. USB_HFT = 48000U;
  215. if (HCTLR_48_MHZ != (USB_HCTL & HCTL_CLKSEL)) {
  216. if (USB_CORE_EMBEDDED_PHY == pudev->cfg.phy_interface) {
  217. USB_FSLSCLOCK_INIT(HCTLR_48_MHZ);
  218. }
  219. port_reset = 1U;
  220. }
  221. } else {
  222. /* for high speed device and others */
  223. port_reset = 1U;
  224. }
  225. }
  226. }
  227. if (port_reset) {
  228. usb_port_reset(pudev);
  229. }
  230. /* clear port interrupts */
  231. USB_HPCS = hostportdup;
  232. return retval;
  233. }
  234. /*!
  235. \brief handle the OUT channel interrupt
  236. \param[in] pudev: pointer to usb device instance
  237. \param[in] channel_num: host channel number which is in (0..7)
  238. \param[out] none
  239. \retval operation status
  240. */
  241. static uint32_t usbh_intf_hc_out (usb_core_handle_struct *pudev, uint8_t channel_num)
  242. {
  243. uint32_t channel_intr = USB_HCHxINTF((uint16_t)channel_num);
  244. usb_hostchannel_struct *puhc = &pudev->host.host_channel[channel_num];
  245. channel_intr &= USB_HCHxINTEN((uint16_t)channel_num);
  246. if (channel_intr & HCHINTF_ACK) {
  247. if (URB_PING == puhc->urb_state) {
  248. puhc->err_count = 0U;
  249. USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
  250. usb_hostchannel_halt(pudev, channel_num);
  251. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_TF;
  252. puhc->status = HC_XF;
  253. }
  254. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_ACK;
  255. } else if (channel_intr & HCHINTF_REQOVR) {
  256. USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
  257. usb_hostchannel_halt(pudev, channel_num);
  258. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_REQOVR;
  259. } else if (channel_intr & HCHINTF_TF) {
  260. puhc->err_count = 0U;
  261. USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
  262. usb_hostchannel_halt(pudev, channel_num);
  263. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_TF;
  264. puhc->status = HC_XF;
  265. } else if (channel_intr & HCHINTF_STALL) {
  266. USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
  267. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_STALL;
  268. usb_hostchannel_halt(pudev, channel_num);
  269. puhc->status = HC_STALL;
  270. } else if (channel_intr & HCHINTF_NAK) {
  271. puhc->err_count = 0U;
  272. USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
  273. usb_hostchannel_halt(pudev, channel_num);
  274. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK;
  275. puhc->status = HC_NAK;
  276. } else if (channel_intr & HCHINTF_USBER) {
  277. USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
  278. usb_hostchannel_halt(pudev, channel_num);
  279. puhc->err_count ++;
  280. puhc->status = HC_TRACERR;
  281. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_USBER;
  282. } else if (channel_intr & HCHINTF_NYET) {
  283. puhc->err_count = 0U;
  284. USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
  285. puhc->status = HC_NYET;
  286. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NYET;
  287. } else if (channel_intr & HCHINTF_DTER) {
  288. USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
  289. usb_hostchannel_halt(pudev, channel_num);
  290. puhc->status= HC_DTGERR;
  291. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_DTER;
  292. } else if (channel_intr & HCHINTF_CH) {
  293. USB_HCHxINTEN((uint16_t)channel_num) &= ~HCHINTEN_CHIE;
  294. switch (puhc->status) {
  295. case HC_XF:
  296. puhc->urb_state = URB_DONE;
  297. if (USB_EPTYPE_BULK == ((USB_HCHxCTL((uint16_t)channel_num) & HCHCTL_EPTYPE) >> 18)) {
  298. puhc->data_tg_out ^= 1U;
  299. }
  300. break;
  301. case HC_NAK:
  302. puhc->urb_state = URB_NOTREADY;
  303. break;
  304. case HC_NYET:
  305. break;
  306. case HC_STALL:
  307. puhc->urb_state = URB_STALL;
  308. break;
  309. case HC_TRACERR:
  310. if (3U == puhc->err_count) {
  311. puhc->urb_state = URB_ERROR;
  312. puhc->err_count = 0U;
  313. }
  314. break;
  315. default:
  316. break;
  317. }
  318. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_CH;
  319. } else {
  320. /* no operation */
  321. }
  322. return 1U;
  323. }
  324. /*!
  325. \brief handle the IN channel interrupt
  326. \param[in] pudev: pointer to usb device instance
  327. \param[in] channel_num: host channel number which is in (0..7)
  328. \param[out] none
  329. \retval operation status
  330. */
  331. static uint32_t usbh_intf_hc_in (usb_core_handle_struct *pudev, uint8_t channel_num)
  332. {
  333. uint8_t endp_type = 0U;
  334. usb_hostchannel_struct *puhc = &pudev->host.host_channel[channel_num];
  335. uint32_t channle_intf = USB_HCHxINTF((uint16_t)channel_num);
  336. __IO uint32_t channel_ctrl = USB_HCHxCTL((uint16_t)channel_num);
  337. channle_intf &= USB_HCHxINTEN((uint16_t)channel_num);
  338. endp_type = (uint8_t)((channel_ctrl & HCHCTL_EPTYPE) >> 18U);
  339. if (channle_intf & HCHINTF_ACK) {
  340. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_ACK;
  341. } else if (channle_intf & HCHINTF_STALL) {
  342. USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
  343. puhc->status = HC_STALL;
  344. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK;
  345. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_STALL;
  346. /* NOTE: When there is a 'stall', reset also nak,
  347. else, the pudev->host.status = HC_STALL
  348. will be overwritten by 'nak' in code below */
  349. channle_intf &= ~HCHINTF_NAK;
  350. usb_hostchannel_halt(pudev, channel_num);
  351. } else if (channle_intf & HCHINTF_DTER) {
  352. USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
  353. usb_hostchannel_halt(pudev, channel_num);
  354. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK;
  355. puhc->status = HC_DTGERR;
  356. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_DTER;
  357. } else {
  358. /* no operation */
  359. }
  360. if (channle_intf & HCHINTF_REQOVR) {
  361. USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
  362. usb_hostchannel_halt(pudev, channel_num);
  363. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_REQOVR;
  364. } else if (channle_intf & HCHINTF_TF) {
  365. puhc->status = HC_XF;
  366. puhc->err_count = 0U;
  367. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_TF;
  368. if ((USB_EPTYPE_CTRL == endp_type) || (USB_EPTYPE_BULK == endp_type)) {
  369. USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
  370. usb_hostchannel_halt(pudev, channel_num);
  371. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK;
  372. puhc->data_tg_in ^= 1U;
  373. } else if (USB_EPTYPE_INTR == endp_type) {
  374. channel_ctrl |= HCHCTL_ODDFRM;
  375. USB_HCHxCTL((uint16_t)channel_num) = channel_ctrl;
  376. puhc->urb_state = URB_DONE;
  377. } else {
  378. /* no operation */
  379. }
  380. } else if (channle_intf & HCHINTF_CH) {
  381. USB_HCHxINTEN((uint16_t)channel_num) &= ~HCHINTEN_CHIE;
  382. switch (puhc->status) {
  383. case HC_XF:
  384. puhc->urb_state = URB_DONE;
  385. break;
  386. case HC_TRACERR:
  387. case HC_DTGERR:
  388. puhc->err_count = 0U;
  389. puhc->urb_state = URB_ERROR;
  390. break;
  391. case HC_STALL:
  392. puhc->urb_state = URB_STALL;
  393. break;
  394. default:
  395. if (USB_EPTYPE_INTR == endp_type) {
  396. puhc->data_tg_in ^= 1U;
  397. }
  398. break;
  399. }
  400. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_CH;
  401. } else if (channle_intf & HCHINTF_USBER) {
  402. USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
  403. (puhc->err_count)++;
  404. puhc->status = HC_TRACERR;
  405. usb_hostchannel_halt(pudev, channel_num);
  406. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_USBER;
  407. } else if (channle_intf & HCHINTF_NAK) {
  408. if (USB_EPTYPE_INTR == endp_type) {
  409. USB_HCHxINTEN((uint16_t)channel_num) |= HCHINTEN_CHIE;
  410. usb_hostchannel_halt(pudev, channel_num);
  411. } else if ((USB_EPTYPE_CTRL == endp_type) || (USB_EPTYPE_BULK == endp_type)) {
  412. /* re-activate the channel */
  413. channel_ctrl |= HCHCTL_CEN;
  414. channel_ctrl &= ~HCHCTL_CDIS;
  415. USB_HCHxCTL((uint16_t)channel_num) = channel_ctrl;
  416. } else {
  417. /* no operation */
  418. }
  419. puhc->status = HC_NAK;
  420. USB_HCHxINTF((uint16_t)channel_num) = HCHINTF_NAK;
  421. } else {
  422. /* no operation */
  423. }
  424. return 1U;
  425. }
  426. /*!
  427. \brief handle the rx fifo non-empty interrupt
  428. \param[in] pudev: pointer to usb device instance
  429. \param[out] none
  430. \retval operation status
  431. */
  432. static uint32_t usbh_intf_rxfifo_noempty (usb_core_handle_struct *pudev)
  433. {
  434. uint32_t count = 0U;
  435. __IO uint8_t channel_num = 0U;
  436. __IO uint32_t rx_status = 0U;
  437. uint32_t usbh_ch_ctl_reg = 0U;
  438. usb_hostchannel_struct *puhc;
  439. /* disable the Rx status queue level interrupt */
  440. USB_GINTEN &= ~GINTF_RXFNEIF;
  441. rx_status = USB_GRSTATP;
  442. channel_num = (uint8_t)(rx_status & GRSTATRP_CNUM);
  443. puhc = &pudev->host.host_channel[channel_num];
  444. switch ((rx_status & GRSTATRP_RPCKST) >> 17) {
  445. case GRSTATR_RPCKST_IN:
  446. count = (rx_status & GRSTATRP_BCOUNT) >> 4;
  447. /* read the data into the host buffer. */
  448. if ((count > 0U) && (puhc->xfer_buff != (void *)0)) {
  449. usb_fifo_read(puhc->xfer_buff, (uint16_t)count);
  450. /* manage multiple Xfer */
  451. puhc->xfer_buff += count;
  452. puhc->xfer_count += count;
  453. if (USB_HCHxLEN((uint16_t)channel_num) & HCHLEN_PCNT) {
  454. /* re-activate the channel when more packets are expected */
  455. usbh_ch_ctl_reg = USB_HCHxCTL((uint16_t)channel_num);
  456. usbh_ch_ctl_reg |= HCHCTL_CEN;
  457. usbh_ch_ctl_reg &= ~HCHCTL_CDIS;
  458. USB_HCHxCTL((uint16_t)channel_num) = usbh_ch_ctl_reg;
  459. }
  460. }
  461. break;
  462. case GRSTATR_RPCKST_IN_XFER_COMP:
  463. case GRSTATR_RPCKST_DATA_TOGGLE_ERR:
  464. case GRSTATR_RPCKST_CH_HALTED:
  465. default:
  466. break;
  467. }
  468. /* enable the Rx status queue level interrupt */
  469. USB_GINTEN |= GINTF_RXFNEIF;
  470. return 1U;
  471. }
  472. /*!
  473. \brief handle the incomplete periodic transfer interrupt
  474. \param[in] pudev: pointer to usb device instance
  475. \param[out] none
  476. \retval operation status
  477. */
  478. static uint32_t usbh_intf_iso_incomplete_xfer (usb_core_handle_struct *pudev)
  479. {
  480. __IO uint32_t gint_flag = 0U;
  481. gint_flag = USB_HCHxCTL(0U);
  482. USB_HCHxCTL(0U) = 0U;
  483. gint_flag = 0U;
  484. /* clear interrupt */
  485. gint_flag |= GINTF_ISOONCIF;
  486. USB_GINTF = gint_flag;
  487. return 1U;
  488. }