usbd_int.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. /*!
  2. \file usbd_int.c
  3. \brief USB device mode interrupt routines
  4. */
  5. /*
  6. Copyright (C) 2017 GigaDevice
  7. 2017-02-10, V1.0.0, firmware for GD32F30x
  8. */
  9. #include "usbd_int.h"
  10. #include "usbd_std.h"
  11. /* interrupt handlers */
  12. static uint32_t usbd_intf_outep (usb_core_handle_struct *pudev);
  13. static uint32_t usbd_intf_inep (usb_core_handle_struct *pudev);
  14. static uint32_t usbd_intf_earlysuspend (usb_core_handle_struct *pudev);
  15. static uint32_t usbd_intf_suspend (usb_core_handle_struct *pudev);
  16. static uint32_t usbd_intf_resume (usb_core_handle_struct *pudev);
  17. static uint32_t usbd_intf_sof (usb_core_handle_struct *pudev);
  18. static uint32_t usbd_intf_rxfifo (usb_core_handle_struct *pudev);
  19. static uint32_t usbd_intf_reset (usb_core_handle_struct *pudev);
  20. static uint32_t usbd_intf_enumfinish (usb_core_handle_struct *pudev);
  21. static uint32_t usbd_intf_isoinincomplete (usb_core_handle_struct *pudev);
  22. static uint32_t usbd_intf_isooutincomplete (usb_core_handle_struct *pudev);
  23. static uint32_t usbd_emptytxfifo_write (usb_core_handle_struct *pudev, uint8_t ep_num);
  24. #ifdef VBUS_SENSING_ENABLED
  25. static uint32_t usbd_intf_otg (usb_core_handle_struct *pudev);
  26. static uint32_t usbd_intf_sessionrequest (usb_core_handle_struct *pudev);
  27. #endif /* VBUS_SENSING_ENABLED */
  28. static usb_speed_enum USB_SPEED[4] = {
  29. [DSTAT_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ] = USB_SPEED_HIGH,
  30. [DSTAT_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ] = USB_SPEED_FULL,
  31. [DSTAT_ENUMSPD_FS_PHY_48MHZ] = USB_SPEED_FULL,
  32. [DSTAT_ENUMSPD_LS_PHY_6MHZ] = USB_SPEED_LOW
  33. };
  34. static const uint8_t EP0_MAXLEN[4] = {
  35. [DSTAT_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ] = EP0MPL_64,
  36. [DSTAT_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ] = EP0MPL_64,
  37. [DSTAT_ENUMSPD_FS_PHY_48MHZ] = EP0MPL_64,
  38. [DSTAT_ENUMSPD_LS_PHY_6MHZ] = EP0MPL_8
  39. };
  40. /*!
  41. \brief USB device-mode interrupts global service routine handler
  42. \param[in] pudev: pointer to usb device instance
  43. \param[out] none
  44. \retval operation status
  45. */
  46. uint32_t usbd_isr (usb_core_handle_struct *pudev)
  47. {
  48. uint32_t retval = 0U;
  49. uint32_t int_status = 0U, gintf = USB_GINTF, ginten = USB_GINTEN;
  50. /* ensure the core is in device mode */
  51. if (DEVICE_MODE == USB_CURRENT_MODE_GET()) {
  52. int_status = gintf & ginten;
  53. /* there are no interrupts, avoid spurious interrupt */
  54. if (!int_status) {
  55. return 0U;
  56. }
  57. /* OUT endpoints interrupts */
  58. if (int_status & GINTF_OEPIF) {
  59. retval |= usbd_intf_outep(pudev);
  60. }
  61. /* IN endpoints interrupts */
  62. if (int_status & GINTF_IEPIF) {
  63. retval |= usbd_intf_inep(pudev);
  64. }
  65. /* mode mismatch interrupt */
  66. if (int_status & GINTF_MFIF) {
  67. /* clear interrupt */
  68. USB_GINTF = GINTF_MFIF;
  69. }
  70. /* early suspend interrupt */
  71. if (int_status & GINTF_ESP) {
  72. retval |= usbd_intf_earlysuspend(pudev);
  73. }
  74. /* suspend interrupt */
  75. if (int_status & GINTF_SP) {
  76. retval |= usbd_intf_suspend(pudev);
  77. }
  78. /* wakeup interrupt */
  79. if (int_status & GINTF_WKUPIF) {
  80. retval |= usbd_intf_resume(pudev);
  81. }
  82. /* start of frame interrupt */
  83. if (int_status & GINTF_SOF) {
  84. retval |= usbd_intf_sof(pudev);
  85. }
  86. /* reveive fifo not empty interrupt */
  87. if (int_status & GINTF_RXFNEIF) {
  88. retval |= usbd_intf_rxfifo(pudev);
  89. }
  90. /* USB reset interrupt */
  91. if (int_status & GINTF_RST) {
  92. retval |= usbd_intf_reset(pudev);
  93. }
  94. /* enumeration has been finished interrupt */
  95. if (int_status & GINTF_ENUMFIF) {
  96. retval |= usbd_intf_enumfinish(pudev);
  97. }
  98. /* incomplete synchronization in transfer interrupt*/
  99. if (int_status & GINTF_ISOINCIF) {
  100. retval |= usbd_intf_isoinincomplete(pudev);
  101. }
  102. /* incomplete synchronization out transfer interrupt*/
  103. if (int_status & GINTF_ISOONCIF) {
  104. retval |= usbd_intf_isooutincomplete(pudev);
  105. }
  106. #ifdef VBUS_SENSING_ENABLED
  107. /* session request interrupt */
  108. if (int_status & GINTF_SESIF) {
  109. retval |= usbd_intf_sessionrequest(pudev);
  110. }
  111. /* OTG mode interrupt */
  112. if (int_status & GINTF_OTGIF) {
  113. retval |= usbd_intf_otg(pudev);
  114. }
  115. #endif /* VBUS_SENSING_ENABLED */
  116. }
  117. return retval;
  118. }
  119. /*!
  120. \brief indicates that an OUT endpoint has a pending interrupt
  121. \param[in] pudev: pointer to usb device instance
  122. \param[out] none
  123. \retval operation status
  124. */
  125. static uint32_t usbd_intf_outep (usb_core_handle_struct *pudev)
  126. {
  127. uint8_t endp_num = 0U;
  128. uint32_t endp_intr = 0U;
  129. __IO uint32_t out_endp_intr = 0U;
  130. /* read in the device interrupt bits */
  131. USB_DAOEP_INTR_READ(endp_intr);
  132. while (endp_intr) {
  133. if (endp_intr & 0x1U) {
  134. USB_DOEP_INTR_READ(out_endp_intr, (uint16_t)endp_num);
  135. /* transfer complete interrupt */
  136. if (out_endp_intr & DOEPINTF_TF) {
  137. USB_DOEPxINTF((uint16_t)endp_num) = DOEPINTF_TF;
  138. /* data receive is completed */
  139. usbd_out_transaction(pudev, endp_num);
  140. }
  141. /* endpoint disable interrupt */
  142. if (out_endp_intr & DOEPINTF_EPDIS) {
  143. USB_DOEPxINTF((uint16_t)endp_num) = DOEPINTF_EPDIS;
  144. }
  145. /* setup phase finished interrupt (just for control endpoints) */
  146. if (out_endp_intr & DOEPINTF_STPF) {
  147. /* setup phase is completed */
  148. usbd_setup_transaction(pudev);
  149. USB_DOEPxINTF((uint16_t)endp_num) = DOEPINTF_STPF;
  150. }
  151. /* back to back setup packets received */
  152. if (out_endp_intr & DOEPINTF_BTBSTP) {
  153. USB_DOEPxINTF((uint16_t)endp_num) = DOEPINTF_BTBSTP;
  154. }
  155. }
  156. endp_num ++;
  157. endp_intr >>= 1;
  158. }
  159. return 1U;
  160. }
  161. /*!
  162. \brief indicates that an IN endpoint has a pending interrupt
  163. \param[in] pudev: pointer to usb device instance
  164. \param[out] none
  165. \retval operation status
  166. */
  167. static uint32_t usbd_intf_inep(usb_core_handle_struct *pudev)
  168. {
  169. uint8_t endp_num = 0U;
  170. uint32_t endp_intr = 0U;
  171. __IO uint32_t in_endp_intr = 0U;
  172. /* get all in endpoints which have interrupts */
  173. USB_DAIEP_INTR_READ(endp_intr);
  174. while (endp_intr) {
  175. if (endp_intr & 0x1U) {
  176. USB_DIEP_INTR_READ(in_endp_intr, (uint16_t)endp_num);
  177. if (in_endp_intr & DIEPINTF_TF) {
  178. /* disable the fifo empty interrupt for the endpoint */
  179. USB_DIEPFEINTEN &= ~(0x1U << endp_num);
  180. USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_TF;
  181. /* data transmittion is completed */
  182. usbd_in_transaction(pudev, endp_num);
  183. }
  184. if (in_endp_intr & DIEPINTF_CITO) {
  185. USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_CITO;
  186. }
  187. if (in_endp_intr & DIEPINTF_IEPNE) {
  188. USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_IEPNE;
  189. }
  190. if (in_endp_intr & DIEPINTF_EPDIS) {
  191. USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_EPDIS;
  192. }
  193. if (in_endp_intr & DIEPINTF_TXFE) {
  194. usbd_emptytxfifo_write(pudev, endp_num);
  195. USB_DIEPxINTF((uint16_t)endp_num) = DIEPINTF_TXFE;
  196. }
  197. }
  198. endp_num ++;
  199. endp_intr >>= 1;
  200. }
  201. return 1U;
  202. }
  203. /*!
  204. \brief indicates that early SUSPEND state has been detected on the USB
  205. \param[in] pudev: pointer to usb device instance
  206. \param[out] none
  207. \retval operation status
  208. */
  209. static uint32_t usbd_intf_earlysuspend (usb_core_handle_struct *pudev)
  210. {
  211. USB_GINTEN &= ~GINTEN_ESPIE;
  212. USB_GINTF = GINTF_ESP;
  213. return 1U;
  214. }
  215. /*!
  216. \brief indicates that SUSPEND state has been detected on the USB
  217. \param[in] pudev: pointer to usb device instance
  218. \param[out] none
  219. \retval operation status
  220. */
  221. static uint32_t usbd_intf_suspend(usb_core_handle_struct *pudev)
  222. {
  223. __IO uint8_t low_power = pudev->cfg.low_power;
  224. __IO uint8_t suspend = (uint8_t)(USB_DSTAT & DSTAT_SPST);
  225. __IO uint8_t is_configured = (pudev->dev.status == USB_STATUS_CONFIGURED)? 1U : 0U;
  226. pudev->dev.prev_status = pudev->dev.status;
  227. pudev->dev.status = USB_STATUS_SUSPENDED;
  228. if (low_power && suspend && is_configured) {
  229. /* switch-off the otg clocks */
  230. USB_PWRCLKCTL |= PWRCLKCTL_SUCLK | PWRCLKCTL_SHCLK;
  231. /* enter DEEP_SLEEP mode with LDO in low power mode */
  232. pmu_to_deepsleepmode(PMU_LDO_LOWPOWER, WFI_CMD);
  233. }
  234. /* clear interrupt */
  235. USB_GINTF = GINTF_SP;
  236. return 1U;
  237. }
  238. /*!
  239. \brief indicates that the USB controller has detected a resume or remote Wake-up sequence
  240. \param[in] pudev: pointer to usb device instance
  241. \param[out] none
  242. \retval operation status
  243. */
  244. static uint32_t usbd_intf_resume (usb_core_handle_struct *pudev)
  245. {
  246. pudev->dev.status = pudev->dev.prev_status;
  247. pudev->dev.status = USB_STATUS_CONFIGURED;
  248. /* clear interrupt */
  249. USB_GINTF = GINTF_WKUPIF;
  250. return 1U;
  251. }
  252. /*!
  253. \brief handle the SOF interrupts
  254. \param[in] pudev: pointer to usb device instance
  255. \param[out] none
  256. \retval operation status
  257. */
  258. static uint32_t usbd_intf_sof(usb_core_handle_struct *pudev)
  259. {
  260. if (NULL != usbd_int_fops) {
  261. usbd_int_fops->SOF(pudev);
  262. }
  263. USB_GINTF = GINTF_SOF;
  264. return 1U;
  265. }
  266. /*!
  267. \brief handle the Rx status queue level interrupt
  268. \param[in] pudev: pointer to usb device instance
  269. \param[out] none
  270. \retval operation status
  271. */
  272. static uint32_t usbd_intf_rxfifo (usb_core_handle_struct *pudev)
  273. {
  274. usb_ep_struct *ep;
  275. uint8_t data_pid = 0U, endp_num = 0U;
  276. uint32_t bcount = 0U, packet_num = 0U;
  277. /* get the status from the top of the fifo (must be read to a variable) */
  278. __IO uint32_t rx_status = USB_GRSTATP;
  279. /* disable the rx fifo non-empty interrupt */
  280. USB_GINTEN &= ~GINTEN_RXFNEIE;
  281. endp_num = (uint8_t)(rx_status & GRSTATRP_EPNUM);
  282. bcount = (rx_status & GRSTATRP_BCOUNT) >> 4U;
  283. data_pid = (uint8_t)((rx_status & GRSTATRP_DPID) >> 15U);
  284. /* ensure no-DMA mode can work */
  285. packet_num = USB_DOEPxLEN((uint16_t)endp_num) & DEPLEN_PCNT;
  286. if ((1U == endp_num) && (0U == packet_num)) {
  287. uint32_t devepctl = USB_DOEPxCTL((uint16_t)endp_num);
  288. devepctl |= DEPCTL_SNAK;
  289. devepctl &= ~DEPCTL_EPEN;
  290. devepctl &= ~DEPCTL_EPD;
  291. USB_DOEPxCTL((uint16_t)endp_num) = devepctl;
  292. }
  293. ep = &pudev->dev.out_ep[endp_num];
  294. switch ((rx_status & GRSTATRP_RPCKST) >> 17U) {
  295. case RXSTAT_GOUT_NAK:
  296. if(0U != bcount) {
  297. return 0U;
  298. }
  299. break;
  300. case RXSTAT_DATA_UPDT:
  301. if (bcount > 0U) {
  302. usb_fifo_read(ep->xfer_buff, (uint16_t)bcount);
  303. ep->xfer_buff += bcount;
  304. ep->xfer_count += bcount;
  305. }
  306. break;
  307. case RXSTAT_XFER_COMP:
  308. if (0U != bcount) {
  309. return 0U;
  310. }
  311. break;
  312. case RXSTAT_SETUP_COMP:
  313. if(0U != bcount) {
  314. return 0U;
  315. }
  316. break;
  317. case RXSTAT_SETUP_UPDT:
  318. *(uint32_t *)0x5000081CU |= 0x00020000U;
  319. if ((0U == endp_num) && (8U == bcount) && (DPID_DATA0 == data_pid)) {
  320. /* copy the setup packet received in fifo into the setup buffer in ram */
  321. usb_fifo_read(pudev->dev.setup_packet, 8U);
  322. ep->xfer_count += bcount;
  323. }
  324. break;
  325. default:
  326. break;
  327. }
  328. /* enable the Rx fifo non-empty interrupt */
  329. USB_GINTEN |= GINTEN_RXFNEIE;
  330. return 1U;
  331. }
  332. /*!
  333. \brief handle USB reset interrupt
  334. \param[in] pudev: pointer to usb device instance
  335. \param[out] none
  336. \retval status
  337. */
  338. static uint32_t usbd_intf_reset(usb_core_handle_struct *pudev)
  339. {
  340. uint8_t i = 0U;
  341. usb_ep_struct *ep;
  342. /* clear the remote wakeup signaling */
  343. USB_DCTL &= ~DCTL_RWKUP;
  344. /* flush the tx fifo */
  345. usb_txfifo_flush(pudev, 0U);
  346. for (i = 0U; i < pudev->cfg.dev_endp_num; i++) {
  347. USB_DIEPxINTF((uint16_t)i) = 0xFFU;
  348. USB_DOEPxINTF((uint16_t)i) = 0xFFU;
  349. }
  350. /* clear all pending device endpoint interrupts */
  351. USB_DAEPINT = 0xFFFFFFFFU;
  352. /* enable endpoint 0 interrupts */
  353. USB_DAEPINTEN &= ~DAEPINTEN_OEPIE;
  354. USB_DAEPINTEN &= ~DAEPINTEN_IEPIE;
  355. USB_DAEPINTEN = (1U << 16) | 1U;
  356. /* enable out endpoint interrupts */
  357. USB_DOEPINTEN = DOEPINTEN_STPFEN | DOEPINTEN_TFEN | DOEPINTEN_EPDISEN;
  358. /* enable in endpoint interrupts */
  359. USB_DIEPINTEN = DIEPINTEN_TFEN | DIEPINTEN_CITOEN | DIEPINTEN_EPDISEN;
  360. /* reset device address */
  361. USB_DCFG &= ~DCFG_DAR;
  362. USB_DCFG |= 0U << 4U;
  363. /* configure endpoint 0 to receive setup packets */
  364. usb_ep0_startout(pudev);
  365. /* clear usb reset interrupt */
  366. USB_GINTF = GINTF_RST;
  367. /* open EP0 IN */
  368. ep = &pudev->dev.in_ep[0];
  369. USB_DIEPxCTL(0U) &= ~DEP0CTL_MPL;
  370. USB_DIEPxCTL(0U) &= ~DEPCTL_EPTYPE;
  371. USB_DIEPxCTL(0U) &= ~DIEPCTL_TXFNUM;
  372. if (!(USB_DIEPxCTL(0U) & DEP0CTL_EPACT)) {
  373. USB_DIEPxCTL(0U) |= USB_MAX_EP0_SIZE;
  374. USB_DIEPxCTL(0U) |= (USB_EPTYPE_CTRL << 18U);
  375. USB_DIEPxCTL(0U) |= DEP0CTL_EPACT;
  376. }
  377. ep->endp_mps = USB_MAX_EP0_SIZE;
  378. ep->endp_type = USB_EPTYPE_CTRL;
  379. /* open EP0 OUT */
  380. ep = &pudev->dev.out_ep[0];
  381. USB_DOEPxCTL(0U) &= ~DEP0CTL_MPL;
  382. USB_DOEPxCTL(0U) &= ~DEPCTL_EPTYPE;
  383. if (!(USB_DOEPxCTL(0U) & DEP0CTL_EPACT)) {
  384. USB_DOEPxCTL(0U) |= USB_MAX_EP0_SIZE;
  385. USB_DOEPxCTL(0U) |= (USB_EPTYPE_CTRL << 18U);
  386. USB_DOEPxCTL(0U) |= DEP0CTL_EPACT;
  387. }
  388. ep->endp_mps = USB_MAX_EP0_SIZE;
  389. ep->endp_type = USB_EPTYPE_CTRL;
  390. pudev->dev.status = USB_STATUS_DEFAULT;
  391. return 1U;
  392. }
  393. /*!
  394. \brief handle enumeration finish interrupt
  395. \param[in] pudev: pointer to usb device instance
  396. \param[out] none
  397. \retval status
  398. */
  399. static uint32_t usbd_intf_enumfinish(usb_core_handle_struct *pudev)
  400. {
  401. uint8_t enum_speed = (uint8_t)((USB_DSTAT & DSTAT_ES) >> 1U);
  402. /* set the max packet size of devie in endpoint based on the enumeration speed */
  403. USB_DIEPxCTL(0U) |= EP0_MAXLEN[enum_speed];
  404. /* clear global IN NAK */
  405. USB_DCTL &= ~DCTL_CGINAK;
  406. USB_DCTL |= DCTL_CGINAK;
  407. /* set USB turn-around time based on device speed and PHY interface */
  408. if (USB_SPEED_HIGH == USB_SPEED[enum_speed]) {
  409. pudev->cfg.core_speed = USB_CORE_SPEED_HIGH;
  410. pudev->cfg.max_packet_size = USBHS_MAX_PACKET_SIZE;
  411. USB_GUSBCS &= ~GUSBCS_UTT;
  412. USB_GUSBCS |= 0x09U << 10;
  413. } else {
  414. pudev->cfg.core_speed = USB_CORE_SPEED_FULL;
  415. pudev->cfg.max_packet_size = USBFS_MAX_PACKET_SIZE;
  416. USB_GUSBCS &= ~GUSBCS_UTT;
  417. USB_GUSBCS |= 0x05U << 10;
  418. }
  419. /* clear interrupt */
  420. USB_GINTF = GINTF_ENUMFIF;
  421. return 1U;
  422. }
  423. /*!
  424. \brief handle the ISO IN incomplete interrupt
  425. \param[in] pudev: pointer to usb device instance
  426. \param[out] none
  427. \retval status
  428. */
  429. static uint32_t usbd_intf_isoinincomplete(usb_core_handle_struct *pudev)
  430. {
  431. // USBD_DCD_INT_fops->IsoINIncomplete (pudev);
  432. /* clear interrupt */
  433. USB_GINTF = GINTF_ISOINCIF;
  434. return 1U;
  435. }
  436. /*!
  437. \brief handle the ISO OUT incomplete interrupt
  438. \param[in] pudev: pointer to usb device instance
  439. \param[out] none
  440. \retval status
  441. */
  442. static uint32_t usbd_intf_isooutincomplete(usb_core_handle_struct *pudev)
  443. {
  444. // USBD_DCD_INT_fops->IsoOUTIncomplete (pudev);
  445. /* clear interrupt */
  446. USB_GINTF = GINTF_ISOONCIF;
  447. return 1U;
  448. }
  449. /*!
  450. \brief check FIFO for the next packet to be loaded
  451. \param[in] pudev: pointer to usb device instance
  452. \param[in] ep_id: endpoint identifier which is in (0..3)
  453. \param[out] none
  454. \retval status
  455. */
  456. static uint32_t usbd_emptytxfifo_write(usb_core_handle_struct *pudev, uint8_t ep_num)
  457. {
  458. uint32_t len = 0U, word_len = 0U, fifo_empty_mask = 0U;
  459. usb_ep_struct *ep;
  460. ep = &pudev->dev.in_ep[ep_num];
  461. len = ep->xfer_len - ep->xfer_count;
  462. if (len > ep->endp_mps) {
  463. len = ep->endp_mps;
  464. }
  465. word_len = (len + 3U) / 4U;
  466. while (((USB_DIEPxTFSTAT((uint16_t)ep_num) & DIEPTFSTAT_IEPTFS) > word_len) &&
  467. (ep->xfer_count < ep->xfer_len)) {
  468. /* write the FIFO */
  469. len = ep->xfer_len - ep->xfer_count;
  470. if (len > ep->endp_mps) {
  471. len = ep->endp_mps;
  472. }
  473. word_len = (len + 3U) / 4U;
  474. usb_fifo_write (ep->xfer_buff, ep_num, (uint16_t)len);
  475. ep->xfer_buff += len;
  476. ep->xfer_count += len;
  477. if(ep->xfer_len == ep->xfer_count) {
  478. fifo_empty_mask = 0x1U << ep_num;
  479. USB_DIEPFEINTEN &= ~fifo_empty_mask;
  480. }
  481. }
  482. return 1U;
  483. }
  484. #ifdef VBUS_SENSING_ENABLED
  485. /*!
  486. \brief indicates that the USB_OTG controller has detected a connection
  487. \param[in] pudev: pointer to usb device instance
  488. \param[out] none
  489. \retval status
  490. */
  491. static uint32_t usbd_intf_sessionrequest(usb_core_handle_struct *pudev)
  492. {
  493. pudev->dev.connection_status = 1U;
  494. /* clear the interrupt bit */
  495. USB_GINTF = GINTF_SESIF;
  496. return 1;
  497. }
  498. /*!
  499. \brief indicates that the USB_OTG controller has detected an OTG event
  500. \param[in] pudev: pointer to usb device instance
  501. \param[out] none
  502. \retval status
  503. */
  504. static uint32_t usbd_intf_otg(usb_core_handle_struct *pudev)
  505. {
  506. if (USB_GOTGINTF & GOTGINTF_SESEND) {
  507. pudev->dev.class_deinit(pudev, 0);
  508. pudev->dev.connection_status = 0;
  509. }
  510. /* clear OTG interrupt */
  511. USB_GOTGINTF |= GOTGINTF_SESEND;
  512. return 1;
  513. }
  514. #endif /* VBUS_SENSING_ENABLED */