usbd_int.c 21 KB

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