usb_dc_aic.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304
  1. /*
  2. * Copyright (c) 2023, Artinchip Technology Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <rtconfig.h>
  7. #include "usbd_core.h"
  8. #include "usb_dc_aic_reg.h"
  9. // clang-format off
  10. #ifndef __UNALIGNED_UINT32_WRITE
  11. #pragma GCC diagnostic push
  12. #pragma GCC diagnostic ignored "-Wpacked"
  13. #pragma GCC diagnostic ignored "-Wattributes"
  14. __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
  15. #pragma GCC diagnostic pop
  16. #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
  17. #endif
  18. #ifndef __UNALIGNED_UINT32_READ
  19. #pragma GCC diagnostic push
  20. #pragma GCC diagnostic ignored "-Wpacked"
  21. #pragma GCC diagnostic ignored "-Wattributes"
  22. __PACKED_STRUCT T_UINT32_READ { uint32_t v; };
  23. #pragma GCC diagnostic pop
  24. #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
  25. #endif
  26. // clang-format on
  27. #define FS_PORT 0
  28. #define HS_PORT 1
  29. #ifndef CONFIG_USB_AIC_DC_PORT
  30. #error "please select CONFIG_USB_AIC_DC_PORT with FS_PORT or HS_PORT"
  31. #endif
  32. #ifndef USB_BASE
  33. #define USB_BASE CONFIG_USB_AIC_DC_BASE
  34. #endif
  35. #ifdef LPKG_CHERRYUSB_DEVICE_HID_IO_TEMPLATE
  36. #define USB_RAM_SIZE 1024 /* define with maximum value*/
  37. #else
  38. #define USB_RAM_SIZE 512 /* define with maximum value*/
  39. #endif
  40. #ifndef USB_NUM_BIDIR_ENDPOINTS
  41. #define USB_NUM_BIDIR_ENDPOINTS 5 /* define with minimum value*/
  42. #endif
  43. #define AIC_UDC_REG ((AIC_UDC_RegDef *)(USB_BASE))
  44. #define AIC_EP_FIFO(i) *(__IO uint32_t *)(USB_BASE + AIC_EP_FIFO_BASE + ((i)*AIC_EP_FIFO_SIZE))
  45. static uint8_t g_aic_udc_ibuf[USB_RAM_SIZE] __ALIGNED(CACHE_LINE_SIZE);
  46. static uint8_t g_aic_udc_obuf[USB_RAM_SIZE] __ALIGNED(CACHE_LINE_SIZE);
  47. /* Endpoint state */
  48. struct aic_ep_state {
  49. uint16_t ep_mps; /* Endpoint max packet size */
  50. uint8_t ep_type; /* Endpoint type */
  51. uint8_t ep_stalled; /* Endpoint stall flag */
  52. uint8_t *xfer_buf;
  53. #ifdef CONFIG_USB_AIC_DMA_ENABLE
  54. uint8_t *xfer_align_buf;
  55. uint32_t xfer_align_len;
  56. #endif
  57. uint32_t xfer_len;
  58. uint32_t actual_xfer_len;
  59. };
  60. extern uint32_t usbd_clk;
  61. /* Driver state */
  62. /*USB_NOCACHE_RAM_SECTION*/ struct aic_udc {
  63. USB_MEM_ALIGNX struct usb_setup_packet setup;
  64. USB_MEM_ALIGNX struct aic_ep_state in_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< IN endpoint parameters*/
  65. struct aic_ep_state out_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< OUT endpoint parameters */
  66. uint32_t tx_fifo_map;
  67. } g_aic_udc;
  68. uint8_t rst_allow = 0;
  69. uint8_t ep0_ctrl_stage = 0; /* 1 = setup stage, 2 = data stage, 3 = status stage */
  70. #ifdef CONFIG_USB_AIC_DMA_ENABLE
  71. void aic_udc_dcache_clean(uintptr_t addr, uint32_t len)
  72. {
  73. aicos_dcache_clean_range((size_t *)addr, len);
  74. }
  75. void aic_udc_dcache_invalidate(uintptr_t addr, uint32_t len)
  76. {
  77. aicos_dcache_invalid_range((size_t *)addr, len);
  78. }
  79. void aic_udc_dcache_clean_invalidate(uintptr_t addr, uint32_t len)
  80. {
  81. aicos_dcache_clean_invalid_range((size_t *)addr, len);
  82. }
  83. static int aic_udc_ep_buf_alloc(struct aic_ep_state *ep, uint32_t len,
  84. uint8_t *sbuf)
  85. {
  86. ep->xfer_len = len;
  87. if (len % CACHE_LINE_SIZE)
  88. ep->xfer_align_len = ALIGN_UP(len, CACHE_LINE_SIZE);
  89. else
  90. ep->xfer_align_len = len;
  91. if (ep->xfer_align_len > USB_RAM_SIZE) {
  92. ep->xfer_align_buf = aicos_malloc_align(0, ep->xfer_align_len,
  93. CACHE_LINE_SIZE);
  94. if (!ep->xfer_align_buf) {
  95. USB_LOG_ERR("alloc error.\r\n");
  96. return -5;
  97. }
  98. } else {
  99. ep->xfer_align_buf = sbuf;
  100. }
  101. return 0;
  102. }
  103. static void aic_udc_ep_buf_free(struct aic_ep_state *ep, uint8_t *sbuf)
  104. {
  105. if (!ep->xfer_align_buf)
  106. return;
  107. /* Whether the buf is allocated dynamically */
  108. if (ep->xfer_align_buf != sbuf)
  109. aicos_free_align(0, ep->xfer_align_buf);
  110. ep->xfer_align_buf = NULL;
  111. ep->xfer_align_len = 0;
  112. }
  113. static int aic_udc_ibuf_alloc(struct aic_ep_state *ep, uint32_t len)
  114. {
  115. return aic_udc_ep_buf_alloc(ep, len, g_aic_udc_ibuf);
  116. }
  117. static int aic_udc_obuf_alloc(struct aic_ep_state *ep, uint32_t len)
  118. {
  119. return aic_udc_ep_buf_alloc(ep, len, g_aic_udc_obuf);
  120. }
  121. static void aic_udc_ibuf_free(struct aic_ep_state *ep)
  122. {
  123. aic_udc_ep_buf_free(ep, g_aic_udc_ibuf);
  124. }
  125. static void aic_udc_obuf_free(struct aic_ep_state *ep)
  126. {
  127. aic_udc_ep_buf_free(ep, g_aic_udc_obuf);
  128. }
  129. #else
  130. #define aic_udc_dcache_clean(addr, len)
  131. #define aic_udc_dcache_invalidate(addr, len)
  132. #define aic_udc_dcache_clean_invalidate(addr, len)
  133. #endif
  134. static void aic_set_dma_nextep(void)
  135. {
  136. uint32_t i;
  137. /* dma to set the next-endpoint pointer. */
  138. for (i = 0; i < USB_NUM_BIDIR_ENDPOINTS; i++) {
  139. uint32_t next = ((i + 1) % USB_NUM_BIDIR_ENDPOINTS) << DEPCTL_NEXT_EP_BIT;
  140. AIC_UDC_REG->inepcfg[i] &= ~DEPCTL_NEXT_EP_MASK;
  141. AIC_UDC_REG->inepcfg[i] |= next;
  142. }
  143. }
  144. static inline int aic_reset(void)
  145. {
  146. uint32_t count = 0U;
  147. /* Wait for AHB master IDLE state. */
  148. do {
  149. if (++count > 200000U) {
  150. return -1;
  151. }
  152. } while ((AIC_UDC_REG->ahbbasic & AHBBASIC_AHBIDLE) == 0U);
  153. /* Core Soft Reset */
  154. count = 0U;
  155. AIC_UDC_REG->usbdevinit |= USBDEVINIT_CSFTRST;
  156. do {
  157. if (++count > 200000U) {
  158. return -1;
  159. }
  160. } while ((AIC_UDC_REG->usbdevinit & USBDEVINIT_CSFTRST) == USBDEVINIT_CSFTRST);
  161. return 0;
  162. }
  163. static inline int aic_core_init(void)
  164. {
  165. int ret;
  166. uint32_t usb_gusbcfg =
  167. 0 << 19 /* ULPI Clock SuspendM */
  168. | 0 << 18 /* ULPI Phy Auto Resume */
  169. | 0 << 15 /* PHY Low Power Clock sel */
  170. | 0x5 << 10 /* USB Turnaround time (0x5 for HS phy) */
  171. | 0 << 7 /* ULPI DDR sel 0:single 8bit, 1:double 4bit */
  172. /*| 0 << 6 0: high speed utmi+, 1: full speed serial*/
  173. #ifdef FPGA_BOARD_ARTINCHIP
  174. | 1 << 4 /* 0: utmi+, 1:ulpi*/
  175. #else
  176. | 0 << 4 /* 0: utmi+, 1:ulpi*/
  177. #endif
  178. | 0 << 3 /* UTMI+ PHY 0:8bit, 1:16bit (ULPI PHY set 8bit) */
  179. | 0x7 << 0; /* HS/FS timeout calibration**/
  180. /* Reset after a PHY select */
  181. ret = aic_reset();
  182. /* Activate the USB Transceiver */
  183. AIC_UDC_REG->usbphyif = usb_gusbcfg;
  184. aic_set_dma_nextep();
  185. return ret;
  186. }
  187. static inline int aic_flush_rxfifo(void)
  188. {
  189. uint32_t count = 0;
  190. AIC_UDC_REG->usbdevinit |= USBDEVINIT_RXFFLSH;
  191. do {
  192. if (++count > 200000U) {
  193. return -1;
  194. }
  195. } while ((AIC_UDC_REG->usbdevinit & USBDEVINIT_RXFFLSH) == USBDEVINIT_RXFFLSH);
  196. return 0;
  197. }
  198. static inline int aic_flush_txfifo(uint32_t num)
  199. {
  200. uint32_t count = 0U;
  201. AIC_UDC_REG->usbdevinit |= USBDEVINIT_TXFNUM(num & USBDEVINIT_TXFNUM_LIMIT);
  202. do {
  203. if (++count > 200000U) {
  204. return -1;
  205. }
  206. } while ((AIC_UDC_REG->usbdevinit & USBDEVINIT_TXFFLSH) == USBDEVINIT_TXFFLSH);
  207. return 0;
  208. }
  209. static void aic_set_turnaroundtime(uint32_t hclk, uint8_t speed)
  210. {
  211. uint32_t UsbTrd;
  212. /* The USBTRD is configured according to the tables below, depending on AHB frequency
  213. used by application. In the low AHB frequency range it is used to stretch enough the USB response
  214. time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
  215. latency to the Data FIFO */
  216. if (speed == USB_ENUM_SPEED_FULL) {
  217. if ((hclk >= 14200000U) && (hclk < 15000000U)) {
  218. /* hclk Clock Range between 14.2-15 MHz */
  219. UsbTrd = 0xFU;
  220. } else if ((hclk >= 15000000U) && (hclk < 16000000U)) {
  221. /* hclk Clock Range between 15-16 MHz */
  222. UsbTrd = 0xEU;
  223. } else if ((hclk >= 16000000U) && (hclk < 17200000U)) {
  224. /* hclk Clock Range between 16-17.2 MHz */
  225. UsbTrd = 0xDU;
  226. } else if ((hclk >= 17200000U) && (hclk < 18500000U)) {
  227. /* hclk Clock Range between 17.2-18.5 MHz */
  228. UsbTrd = 0xCU;
  229. } else if ((hclk >= 18500000U) && (hclk < 20000000U)) {
  230. /* hclk Clock Range between 18.5-20 MHz */
  231. UsbTrd = 0xBU;
  232. } else if ((hclk >= 20000000U) && (hclk < 21800000U)) {
  233. /* hclk Clock Range between 20-21.8 MHz */
  234. UsbTrd = 0xAU;
  235. } else if ((hclk >= 21800000U) && (hclk < 24000000U)) {
  236. /* hclk Clock Range between 21.8-24 MHz */
  237. UsbTrd = 0x9U;
  238. } else if ((hclk >= 24000000U) && (hclk < 27700000U)) {
  239. /* hclk Clock Range between 24-27.7 MHz */
  240. UsbTrd = 0x8U;
  241. } else if ((hclk >= 27700000U) && (hclk < 32000000U)) {
  242. /* hclk Clock Range between 27.7-32 MHz */
  243. UsbTrd = 0x7U;
  244. } else {/* if(hclk >= 32000000) */
  245. /* hclk Clock Range between 32-200 MHz */
  246. UsbTrd = 0x6U;
  247. }
  248. } else if (speed == USB_ENUM_SPEED_HIGH) {
  249. UsbTrd = USBPHYIF_HS_TRDT_VALUE;
  250. } else {
  251. UsbTrd = USBPHYIF_DEFAULT_TRDT_VALUE;
  252. }
  253. AIC_UDC_REG->usbphyif |= USBPHYIF_TOUTCAL_LIMIT;
  254. AIC_UDC_REG->usbphyif &= ~USBPHYIF_USBTRDTIM_MASK;
  255. AIC_UDC_REG->usbphyif |= (uint32_t)((UsbTrd << USBPHYIF_USBTRDTIM_SHIFT)
  256. & USBPHYIF_USBTRDTIM_MASK);
  257. }
  258. #if 0
  259. static void aic_set_txfifo(uint8_t fifo, uint16_t size)
  260. {
  261. uint8_t i;
  262. uint32_t Tx_Offset;
  263. /* TXn min size = 16 words. (n : Transmit FIFO index)
  264. When a TxFIFO is not used, the Configuration should be as follows:
  265. case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes)
  266. --> Txm can use the space allocated for Txn.
  267. case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes)
  268. --> Txn should be configured with the minimum space of 16 words
  269. The FIFO is used optimally when used TxFIFOs are allocated in the top
  270. of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
  271. When DMA is used 3n * FIFO locations should be reserved for internal DMA registers */
  272. Tx_Offset = AIC_UDC_REG->rxfifosiz;
  273. if (fifo == 0U) {
  274. AIC_UDC_REG->nptxfifosiz = ((uint32_t)size << 16) | Tx_Offset;
  275. } else {
  276. Tx_Offset += (AIC_UDC_REG->nptxfifosiz) >> 16;
  277. for (i = 0U; i < (fifo - 1U); i++) {
  278. Tx_Offset += (AIC_UDC_REG->txfifosiz[i] >> 16);
  279. }
  280. /* Multiply Tx_Size by 2 to get higher performance */
  281. AIC_UDC_REG->txfifosiz[fifo - 1U] = ((uint32_t)size << 16) | Tx_Offset;
  282. }
  283. }
  284. #endif
  285. static uint8_t aic_get_devspeed(void)
  286. {
  287. uint8_t speed;
  288. uint32_t DevEnumSpeed = AIC_UDC_REG->usblinests & USB_ENUM_SPEED_MASK;
  289. if (DevEnumSpeed == USB_HIGH_30_60MHZ) {
  290. speed = USB_ENUM_SPEED_HIGH;
  291. } else if (DevEnumSpeed == USB_FULL_30_60MHZ) {
  292. speed = USB_ENUM_SPEED_FULL;
  293. } else {
  294. speed = 0xFU;
  295. }
  296. return speed;
  297. }
  298. static void aic_ep0_start_read_setup(uint8_t *psetup)
  299. {
  300. g_aic_udc.out_ep[0].xfer_buf = psetup;
  301. g_aic_udc.out_ep[0].xfer_len = 8;
  302. ep0_ctrl_stage = 1;
  303. aic_udc_dcache_invalidate((uintptr_t)psetup, CACHE_LINE_SIZE);
  304. AIC_UDC_REG->outeptsfsiz[0] = 0U;
  305. AIC_UDC_REG->outeptsfsiz[0] |= (DXEPTSIZ_PKT_CNT_MASK & (1U << 19));
  306. AIC_UDC_REG->outeptsfsiz[0] |= (3U * 8U);
  307. AIC_UDC_REG->outeptsfsiz[0] |= DXEPTSIZ_MULCNT_MASK;
  308. #ifdef CONFIG_USB_AIC_DMA_ENABLE
  309. AIC_UDC_REG->outepdmaaddr[0] = (uint32_t)(uintptr_t)psetup;
  310. #endif
  311. /* EP enable */
  312. AIC_UDC_REG->outepcfg[0] |= DEPCTL_CNAK | DEPCTL_EPENA | DEPCTL_USBACTEP;
  313. }
  314. void aic_ep_write(uint8_t ep_idx, uint8_t *src, uint16_t len)
  315. {
  316. uint32_t *pSrc = (uint32_t *)src;
  317. uint32_t count32b, i;
  318. count32b = ((uint32_t)len + 3U) / 4U;
  319. for (i = 0U; i < count32b; i++) {
  320. AIC_EP_FIFO(ep_idx) = __UNALIGNED_UINT32_READ(pSrc);
  321. pSrc++;
  322. }
  323. }
  324. void aic_ep_read(uint8_t *dest, uint16_t len)
  325. {
  326. uint32_t *pDest = (uint32_t *)dest;
  327. uint32_t i;
  328. uint32_t count32b = ((uint32_t)len + 3U) / 4U;
  329. for (i = 0U; i < count32b; i++) {
  330. __UNALIGNED_UINT32_WRITE(pDest, AIC_EP_FIFO(0U));
  331. pDest++;
  332. }
  333. }
  334. #ifndef CONFIG_USB_AIC_DMA_ENABLE
  335. static void aic_tx_fifo_empty_procecss(uint8_t ep_idx)
  336. {
  337. uint32_t len;
  338. //uint32_t len32b;
  339. len = g_aic_udc.in_ep[ep_idx].xfer_len - g_aic_udc.in_ep[ep_idx].actual_xfer_len;
  340. if (len > g_aic_udc.in_ep[ep_idx].ep_mps) {
  341. len = g_aic_udc.in_ep[ep_idx].ep_mps;
  342. }
  343. //len32b = (len + 3U) / 4U;
  344. while (/*((AIC_UDC_REG->ineptxsts[ep_idx] & INEPTXSTS_IN_EP_TXFIFO_STS) >= len32b) &&*/
  345. (g_aic_udc.in_ep[ep_idx].actual_xfer_len < g_aic_udc.in_ep[ep_idx].xfer_len) && (g_aic_udc.in_ep[ep_idx].xfer_len != 0U)) {
  346. /* Write the FIFO */
  347. len = g_aic_udc.in_ep[ep_idx].xfer_len - g_aic_udc.in_ep[ep_idx].actual_xfer_len;
  348. if (len > g_aic_udc.in_ep[ep_idx].ep_mps) {
  349. len = g_aic_udc.in_ep[ep_idx].ep_mps;
  350. }
  351. aic_ep_write(ep_idx, g_aic_udc.in_ep[ep_idx].xfer_buf, len);
  352. g_aic_udc.in_ep[ep_idx].xfer_buf += len;
  353. g_aic_udc.in_ep[ep_idx].actual_xfer_len += len;
  354. }
  355. }
  356. #endif
  357. /**
  358. * @brief aic_get_glb_intstatus: return the global USB interrupt status
  359. * @retval status
  360. */
  361. static inline uint32_t aic_get_glb_intstatus(void)
  362. {
  363. uint32_t tmpreg;
  364. tmpreg = AIC_UDC_REG->usbintsts;
  365. tmpreg &= AIC_UDC_REG->usbintmsk;
  366. return tmpreg;
  367. }
  368. /**
  369. * @brief aic_get_outeps_intstatus: return the USB device OUT endpoints interrupt status
  370. * @retval status
  371. */
  372. static inline uint32_t aic_get_outeps_intstatus(void)
  373. {
  374. uint32_t tmpreg;
  375. tmpreg = AIC_UDC_REG->usbepint;
  376. tmpreg &= AIC_UDC_REG->usbepintmsk;
  377. return ((tmpreg & 0xffff0000U) >> 16);
  378. }
  379. /**
  380. * @brief aic_get_ineps_intstatus: return the USB device IN endpoints interrupt status
  381. * @retval status
  382. */
  383. static inline uint32_t aic_get_ineps_intstatus(void)
  384. {
  385. uint32_t tmpreg;
  386. tmpreg = AIC_UDC_REG->usbepint;
  387. tmpreg &= AIC_UDC_REG->usbepintmsk;
  388. return ((tmpreg & 0xFFFFU));
  389. }
  390. /**
  391. * @brief Returns Device OUT EP Interrupt register
  392. * @param epnum endpoint number
  393. * This parameter can be a value from 0 to 15
  394. * @retval Device OUT EP Interrupt register
  395. */
  396. static inline uint32_t aic_get_outep_intstatus(uint8_t epnum)
  397. {
  398. uint32_t tmpreg;
  399. tmpreg = AIC_UDC_REG->outepint[epnum];
  400. tmpreg &= AIC_UDC_REG->outepintmsk;
  401. return tmpreg;
  402. }
  403. /**
  404. * @brief Returns Device IN EP Interrupt register
  405. * @param epnum endpoint number
  406. * This parameter can be a value from 0 to 15
  407. * @retval Device IN EP Interrupt register
  408. */
  409. static inline uint32_t aic_get_inep_intstatus(uint8_t epnum)
  410. {
  411. uint32_t tmpreg;
  412. tmpreg = AIC_UDC_REG->inepint[epnum];
  413. tmpreg &= AIC_UDC_REG->inepintmsk;
  414. return tmpreg;
  415. }
  416. __WEAK void usb_dc_low_level_init(void)
  417. {
  418. }
  419. __WEAK void usb_dc_low_level_deinit(void)
  420. {
  421. }
  422. int usb_dc_rst(void)
  423. {
  424. for (uint8_t i = 0U; i < USB_NUM_BIDIR_ENDPOINTS; i++) {
  425. if (i == 0U) {
  426. AIC_UDC_REG->inepcfg[i] = DEPCTL_SNAK;
  427. AIC_UDC_REG->outepcfg[i] = DEPCTL_SNAK;
  428. } else {
  429. usbd_ep_close(i);
  430. usbd_ep_close(i | 0x80);
  431. }
  432. AIC_UDC_REG->ineptsfsiz[i] = 0U;
  433. AIC_UDC_REG->inepint[i] = 0xFBFFU;
  434. AIC_UDC_REG->outeptsfsiz[i] = 0U;
  435. AIC_UDC_REG->outepint[i] = 0xFBFFU;
  436. }
  437. AIC_UDC_REG->usbepintmsk |= 0x10001U;
  438. AIC_UDC_REG->outepintmsk = CTRL_OUT_EP_SETUP_PHASE_DONE | TRANSFER_DONE;
  439. AIC_UDC_REG->inepintmsk = TRANSFER_DONE;
  440. #ifndef CONFIG_USB_AIC_DMA_ENABLE
  441. AIC_UDC_REG->inepintmsk |= INTKN_TXFEMP;
  442. #endif
  443. aic_flush_txfifo(0x10U);
  444. aic_flush_rxfifo();
  445. aic_set_dma_nextep();
  446. #ifdef CONFIG_USB_AIC_DMA_ENABLE
  447. for (uint8_t i = 0U; i < USB_NUM_BIDIR_ENDPOINTS; i++) {
  448. aic_udc_obuf_free(&g_aic_udc.out_ep[i]);
  449. aic_udc_ibuf_free(&g_aic_udc.in_ep[i]);
  450. }
  451. #endif
  452. memset(&g_aic_udc, 0, sizeof(struct aic_udc));
  453. usbd_event_reset_handler(0);
  454. /* Start reading setup */
  455. aic_ep0_start_read_setup((uint8_t *)&g_aic_udc.setup);
  456. return 0;
  457. }
  458. int usb_dc_init(uint8_t busid)
  459. {
  460. int ret;
  461. uint32_t base = 0;
  462. memset(&g_aic_udc, 0, sizeof(struct aic_udc));
  463. usb_dc_low_level_init();
  464. /* Disconnect */
  465. AIC_UDC_REG->usbdevfunc |= USBDEVFUNC_SFTDISCON;
  466. /* Disable Interrupt */
  467. AIC_UDC_REG->usbdevinit &= ~USBDEVINIT_GLBL_INTR_EN;
  468. ret = aic_core_init();
  469. for (uint8_t i = 0U; i < 2U; i++) {
  470. AIC_UDC_REG->txfifosiz[i] = 0U;
  471. }
  472. /* Device mode configuration */
  473. AIC_UDC_REG->usbdevconf |= PERIOD_FRAME_INTERVAL_80;
  474. #if defined(CONFIG_USB_HS)
  475. /* Set Core speed to High speed mode */
  476. AIC_UDC_REG->usbdevconf |= DEV_SPEED_HIGH_SPEED_20;
  477. #else
  478. AIC_UDC_REG->usbdevconf |= DEV_SPEED_FULL_SPEED_20;
  479. #endif
  480. ret = aic_flush_txfifo(0x10U);
  481. ret = aic_flush_rxfifo();
  482. /* Clear all pending Device Interrupts */
  483. AIC_UDC_REG->inepintmsk = 0U;
  484. AIC_UDC_REG->outepintmsk = 0U;
  485. AIC_UDC_REG->usbepintmsk = 0U;
  486. /* Disable all interrupts. */
  487. AIC_UDC_REG->usbintmsk = 0U;
  488. /* Clear any pending interrupts */
  489. AIC_UDC_REG->usbintsts = 0xBFFFFFFFU;
  490. /* Enable interrupts matching to the Device mode ONLY */
  491. AIC_UDC_REG->usbintmsk = INT_RESET | INT_ENUMDONE |
  492. INT_OUT_EP | INT_IN_EP |
  493. INT_INCOMP_ISO_IN_INT | INT_INCOMP_ISO_OUT_INT;
  494. #ifdef CONFIG_USB_AIC_DMA_ENABLE
  495. AIC_UDC_REG->usbdevinit |= (USBDEVINIT_HBSTLEN_INCR4 << USBDEVINIT_HBSTLEN_SHIFT);
  496. AIC_UDC_REG->usbdevinit |= USBDEVINIT_DMA_EN;
  497. #else
  498. AIC_UDC_REG->usbintmsk |= INT_RX_FIFO_NOT_EMPTY;
  499. #endif
  500. /* Assign FIFO */
  501. base = 0;
  502. AIC_UDC_REG->rxfifosiz = AIC_RX_FIFO_SIZE;
  503. base += AIC_RX_FIFO_SIZE;
  504. AIC_UDC_REG->nptxfifosiz = (AIC_NP_TX_FIFO_SIZE << 16) | base;
  505. base += AIC_NP_TX_FIFO_SIZE;
  506. AIC_UDC_REG->txfifosiz[0] = (AIC_PERIOD_TX_FIFO1_SIZE << 16) | base;
  507. base += AIC_PERIOD_TX_FIFO1_SIZE;
  508. AIC_UDC_REG->txfifosiz[1] = (AIC_PERIOD_TX_FIFO2_SIZE << 16) | base;
  509. usb_dc_rst();
  510. /* Enable Interrupt */
  511. AIC_UDC_REG->usbdevinit |= USBDEVINIT_GLBL_INTR_EN;
  512. /* Connect */
  513. AIC_UDC_REG->usbdevfunc &= ~USBDEVFUNC_SFTDISCON;
  514. return ret;
  515. }
  516. int usb_dc_deinit(uint8_t busid)
  517. {
  518. /* Clear Pending interrupt */
  519. for (uint8_t i = 0U; i < USB_NUM_BIDIR_ENDPOINTS; i++) {
  520. AIC_UDC_REG->outepint[i] = 0xFB7FU;
  521. AIC_UDC_REG->inepint[i] = 0xFB7FU;
  522. }
  523. /* Clear interrupt masks */
  524. AIC_UDC_REG->inepintmsk = 0U;
  525. AIC_UDC_REG->outepintmsk = 0U;
  526. AIC_UDC_REG->usbepintmsk = 0U;
  527. /* Flush the FIFO */
  528. aic_flush_txfifo(0x10U);
  529. aic_flush_rxfifo();
  530. AIC_UDC_REG->usbdevfunc |= USBDEVFUNC_SFTDISCON;
  531. usb_dc_low_level_deinit();
  532. return 0;
  533. }
  534. int usbd_set_address(uint8_t busid, const uint8_t addr)
  535. {
  536. AIC_UDC_REG->usbdevconf &= ~(DEVICE_ADDRESS_MASK);
  537. AIC_UDC_REG->usbdevconf |= ((uint32_t)addr << 4) & DEVICE_ADDRESS_MASK;
  538. rst_allow = 1;
  539. return 0;
  540. }
  541. int usbd_set_remote_wakeup(uint8_t busid)
  542. {
  543. return -1;
  544. }
  545. uint8_t usbd_get_port_speed(uint8_t busid)
  546. {
  547. uint8_t speed;
  548. uint32_t DevEnumSpeed = AIC_UDC_REG->usblinests & USB_ENUM_SPEED_MASK;
  549. if (DevEnumSpeed == USB_HIGH_30_60MHZ) {
  550. speed = USB_SPEED_HIGH;
  551. } else if (DevEnumSpeed == USB_FULL_30_60MHZ) {
  552. speed = USB_SPEED_FULL;
  553. } else {
  554. speed = USB_SPEED_FULL;
  555. }
  556. return speed;
  557. }
  558. int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
  559. {
  560. uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress);
  561. uint16_t ep_mps;
  562. uint8_t tx_fifo_num = 0;
  563. uint32_t i;
  564. if (ep_idx > (USB_NUM_BIDIR_ENDPOINTS - 1)) {
  565. USB_LOG_ERR("Ep addr %d overflow\r\n", ep->bEndpointAddress);
  566. return -1;
  567. }
  568. if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
  569. g_aic_udc.out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
  570. g_aic_udc.out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
  571. AIC_UDC_REG->usbepintmsk |= DAINT_OUT_MASK & (uint32_t)(1UL << (16 + ep_idx));
  572. ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
  573. if (ep_idx == 0) {
  574. switch (ep_mps) {
  575. case 8:
  576. ep_mps = DEPCTL0_MPS_8;
  577. break;
  578. case 16:
  579. ep_mps = DEPCTL0_MPS_16;
  580. break;
  581. case 32:
  582. ep_mps = DEPCTL0_MPS_32;
  583. break;
  584. case 64:
  585. ep_mps = DEPCTL0_MPS_64;
  586. break;
  587. }
  588. }
  589. AIC_UDC_REG->outepcfg[ep_idx] |= (ep_mps & DEPCTL_MPS_MASK) |
  590. ((uint32_t)USB_GET_ENDPOINT_TYPE(ep->bmAttributes) << 18) |
  591. DEPCTL_SETD0PID |
  592. DEPCTL_USBACTEP;
  593. } else {
  594. g_aic_udc.in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
  595. g_aic_udc.in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
  596. AIC_UDC_REG->usbepintmsk |= DAINT_IN_MASK & (uint32_t)(1UL << ep_idx);
  597. /* Period IN EP alloc fifo num */
  598. if (( USB_GET_ENDPOINT_TYPE(ep->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT) ||
  599. ( USB_GET_ENDPOINT_TYPE(ep->bmAttributes) == USB_ENDPOINT_TYPE_ISOCHRONOUS)) {
  600. for (i=1; i<=2; i++) {
  601. if (g_aic_udc.tx_fifo_map & (1<<i))
  602. continue;
  603. g_aic_udc.tx_fifo_map |= (1 << i);
  604. tx_fifo_num = i;
  605. break;
  606. }
  607. if (tx_fifo_num == 0)
  608. return -1;
  609. aic_flush_txfifo(tx_fifo_num);
  610. }
  611. AIC_UDC_REG->inepcfg[ep_idx] |= (USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize) & DEPCTL_MPS_MASK) |
  612. ((uint32_t)USB_GET_ENDPOINT_TYPE(ep->bmAttributes) << 18) |
  613. (tx_fifo_num << 22) |
  614. DEPCTL_SETD0PID |
  615. DEPCTL_USBACTEP;
  616. }
  617. return 0;
  618. }
  619. int usbd_ep_close(uint8_t busid, const uint8_t ep)
  620. {
  621. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  622. uint8_t tx_fifo_num = 0;
  623. int i = 0;
  624. #define DIS_EP_TIMOUT 100
  625. if (USB_EP_DIR_IS_OUT(ep)) {
  626. if (AIC_UDC_REG->outepcfg[ep_idx] & DEPCTL_EPENA) {
  627. /* (1) Wait for global nak to take effect */
  628. if (!(AIC_UDC_REG->usbintsts & INT_GOUTNAKEFF))
  629. AIC_UDC_REG->usbdevfunc |= USBDEVFUNC_SGOUTNAK;
  630. for (i = 0; i < DIS_EP_TIMOUT; i++) {
  631. if (AIC_UDC_REG->usbintsts & INT_GOUTNAKEFF)
  632. break;
  633. aic_udelay(1);
  634. }
  635. if (i == DIS_EP_TIMOUT)
  636. USB_LOG_ERR("%s: timeout USBINTSTS.GOUTNAKEFF\n", __func__);
  637. /* (2) Disable ep */
  638. AIC_UDC_REG->outepcfg[ep_idx] |= DEPCTL_SNAK;
  639. AIC_UDC_REG->outepcfg[ep_idx] |= DEPCTL_EPDIS;
  640. for (i = 0; i < DIS_EP_TIMOUT; i++) {
  641. if (AIC_UDC_REG->outepint[ep_idx] & EPDISBLD)
  642. break;
  643. aic_udelay(1);
  644. }
  645. if (i == DIS_EP_TIMOUT)
  646. USB_LOG_ERR("%s: timeout OUTEPCFG.EPDisable\n", __func__);
  647. /* Clear EPDISBLD interrupt */
  648. AIC_UDC_REG->outepint[ep_idx] |= EPDISBLD;
  649. /* (3) Remove global NAKs */
  650. AIC_UDC_REG->usbdevfunc |= USBDEVFUNC_CGOUTNAK;
  651. }
  652. AIC_UDC_REG->usbepintmsk &= ~(DAINT_OUT_MASK & (uint32_t)(1UL << (16 + ep_idx)));
  653. AIC_UDC_REG->outepcfg[ep_idx] = 0;
  654. } else {
  655. tx_fifo_num = (AIC_UDC_REG->inepcfg[ep_idx] & DEPCTL_TXFIFONUM_MASK) >> DEPCTL_TXFIFONUM_SHIFT;
  656. if (AIC_UDC_REG->inepcfg[ep_idx] & DEPCTL_EPENA) {
  657. if (tx_fifo_num) {
  658. /* (1) Wait for Nak effect */
  659. AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_SNAK;
  660. for (i = 0; i < DIS_EP_TIMOUT; i++) {
  661. if (AIC_UDC_REG->inepint[ep_idx] & INEP_NAKEFF)
  662. break;
  663. aic_udelay(1);
  664. }
  665. if (i == DIS_EP_TIMOUT)
  666. USB_LOG_ERR("%s: timeout INEPINT.NAKEFF\n", __func__);
  667. } else {
  668. /* (1) Wait for Nak effect */
  669. AIC_UDC_REG->usbdevfunc |= USBDEVFUNC_SGNPINNAK;
  670. for (i = 0; i < DIS_EP_TIMOUT; i++) {
  671. if (AIC_UDC_REG->usbintsts & INT_GINNAKEFF)
  672. break;
  673. aic_udelay(1);
  674. }
  675. if (i == DIS_EP_TIMOUT)
  676. USB_LOG_ERR("%s: timeout USBINTSTS.GOUTNAKEFF\n", __func__);
  677. }
  678. /* (2) Disable ep */
  679. AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_SNAK;
  680. AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_EPDIS;
  681. for (i = 0; i < DIS_EP_TIMOUT; i++) {
  682. if (AIC_UDC_REG->inepint[ep_idx] & EPDISBLD)
  683. break;
  684. aic_udelay(1);
  685. }
  686. if (i == DIS_EP_TIMOUT)
  687. USB_LOG_ERR("%s: timeout OUTEPCFG.EPDisable\n", __func__);
  688. /* Clear EPDISBLD interrupt */
  689. AIC_UDC_REG->inepint[ep_idx] |= EPDISBLD;
  690. /* (3) Clear Global In NP NAK in Shared FIFO for non periodic ep */
  691. if (!tx_fifo_num)
  692. AIC_UDC_REG->usbdevfunc |= USBDEVFUNC_CGNPINNAK;
  693. }
  694. AIC_UDC_REG->usbepintmsk &= ~(DAINT_OUT_MASK & (uint32_t)(1UL << ep_idx));
  695. AIC_UDC_REG->inepcfg[ep_idx] = 0;
  696. /* Flush TX FIFO */
  697. aic_flush_txfifo(tx_fifo_num);
  698. /* Period IN EP free fifo num */
  699. if (tx_fifo_num > 0)
  700. g_aic_udc.tx_fifo_map &= ~(1<<tx_fifo_num);
  701. }
  702. #ifdef CONFIG_USB_AIC_DMA_ENABLE
  703. if (USB_EP_DIR_IS_OUT(ep)) {
  704. aic_udc_obuf_free(&g_aic_udc.out_ep[ep_idx]);
  705. } else {
  706. aic_udc_ibuf_free(&g_aic_udc.in_ep[ep_idx]);
  707. }
  708. #endif
  709. return 0;
  710. }
  711. int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
  712. {
  713. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  714. if (USB_EP_DIR_IS_OUT(ep)) {
  715. if (((AIC_UDC_REG->outepcfg[ep_idx] & DEPCTL_EPENA) == 0U) && (ep_idx != 0U)) {
  716. AIC_UDC_REG->outepcfg[ep_idx] &= ~(DEPCTL_EPDIS);
  717. }
  718. AIC_UDC_REG->outepcfg[ep_idx] |= DEPCTL_STALL;
  719. } else {
  720. if (((AIC_UDC_REG->inepcfg[ep_idx] & DEPCTL_EPENA) == 0U) && (ep_idx != 0U)) {
  721. AIC_UDC_REG->inepcfg[ep_idx] &= ~(DEPCTL_EPDIS);
  722. }
  723. AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_STALL;
  724. }
  725. #ifdef CONFIG_USB_AIC_DMA_ENABLE
  726. if (ep_idx == 0) {
  727. aic_ep0_start_read_setup((uint8_t *)&g_aic_udc.setup);
  728. }
  729. #endif
  730. return 0;
  731. }
  732. int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
  733. {
  734. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  735. if (USB_EP_DIR_IS_OUT(ep)) {
  736. AIC_UDC_REG->outepcfg[ep_idx] &= ~DEPCTL_STALL;
  737. if ((g_aic_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) ||
  738. (g_aic_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) {
  739. AIC_UDC_REG->outepcfg[ep_idx] |= DEPCTL_SETD0PID; /* DATA0 */
  740. }
  741. } else {
  742. AIC_UDC_REG->inepcfg[ep_idx] &= ~DEPCTL_STALL;
  743. if ((g_aic_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) ||
  744. (g_aic_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) {
  745. AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_SETD0PID; /* DATA0 */
  746. }
  747. }
  748. return 0;
  749. }
  750. int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
  751. {
  752. if (USB_EP_DIR_IS_OUT(ep)) {
  753. } else {
  754. }
  755. return 0;
  756. }
  757. int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
  758. {
  759. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  760. uint32_t pktcnt = 0;
  761. if (!data && data_len) {
  762. return -1;
  763. }
  764. if (AIC_UDC_REG->inepcfg[ep_idx] & DEPCTL_EPENA) {
  765. return -2;
  766. }
  767. if (ep_idx && !(AIC_UDC_REG->inepcfg[ep_idx] & DEPCTL_MPS_MASK)) {
  768. return -3;
  769. }
  770. if ((uint32_t)(uintptr_t)data & 0x03) {
  771. return -4;
  772. }
  773. g_aic_udc.in_ep[ep_idx].xfer_buf = (uint8_t *)data;
  774. g_aic_udc.in_ep[ep_idx].xfer_len = data_len;
  775. g_aic_udc.in_ep[ep_idx].actual_xfer_len = 0;
  776. #ifdef CONFIG_USB_AIC_DMA_ENABLE
  777. if ((ep_idx != 0) && (data_len > 0) &&
  778. ((((uint32_t)(uintptr_t)data % CACHE_LINE_SIZE) != 0) ||
  779. (((uint32_t)(uintptr_t)(data + data_len) % CACHE_LINE_SIZE) != 0))) {
  780. if (g_aic_udc.in_ep[ep_idx].xfer_align_len != data_len) {
  781. int ret = 0;
  782. aic_udc_ibuf_free(&g_aic_udc.in_ep[ep_idx]);
  783. ret = aic_udc_ibuf_alloc(&g_aic_udc.in_ep[ep_idx], data_len);
  784. if (ret)
  785. return ret;
  786. }
  787. memcpy(g_aic_udc.in_ep[ep_idx].xfer_align_buf, data, data_len);
  788. data = g_aic_udc.in_ep[ep_idx].xfer_align_buf;
  789. } else {
  790. aic_udc_ibuf_free(&g_aic_udc.in_ep[ep_idx]);
  791. }
  792. if (data_len>0)
  793. aic_udc_dcache_clean((uintptr_t)data, ALIGN_UP(data_len, CACHE_LINE_SIZE));
  794. #endif
  795. AIC_UDC_REG->ineptsfsiz[ep_idx] &= ~(DXEPTSIZ_PKT_CNT_MASK);
  796. AIC_UDC_REG->ineptsfsiz[ep_idx] &= ~(DXEPTSIZ_XFER_SIZE_MASK);
  797. AIC_UDC_REG->ineptsfsiz[ep_idx] &= ~(DXEPTSIZ_MULCNT_MASK);
  798. if (data_len == 0) {
  799. AIC_UDC_REG->ineptsfsiz[ep_idx] |= (DXEPTSIZ_PKT_CNT_MASK & (1U << 19));
  800. AIC_UDC_REG->inepcfg[ep_idx] |= (DEPCTL_CNAK | DEPCTL_EPENA);
  801. return 0;
  802. }
  803. if (ep_idx == 0) {
  804. if (data_len > g_aic_udc.in_ep[ep_idx].ep_mps) {
  805. data_len = g_aic_udc.in_ep[ep_idx].ep_mps;
  806. }
  807. g_aic_udc.in_ep[ep_idx].xfer_len = data_len;
  808. AIC_UDC_REG->ineptsfsiz[ep_idx] |= (DXEPTSIZ_PKT_CNT_MASK & (1U << 19));
  809. AIC_UDC_REG->ineptsfsiz[ep_idx] |= (DXEPTSIZ_XFER_SIZE_MASK & data_len);
  810. } else {
  811. pktcnt = (uint16_t)((data_len + g_aic_udc.in_ep[ep_idx].ep_mps - 1U) / g_aic_udc.in_ep[ep_idx].ep_mps);
  812. AIC_UDC_REG->ineptsfsiz[ep_idx] |= (DXEPTSIZ_PKT_CNT_MASK & (pktcnt << 19));
  813. AIC_UDC_REG->ineptsfsiz[ep_idx] |= (DXEPTSIZ_XFER_SIZE_MASK & data_len);
  814. }
  815. if ((g_aic_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) ||
  816. (g_aic_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT)) {
  817. AIC_UDC_REG->ineptsfsiz[ep_idx] |= (1<<DXEPTSIZ_MULCNT_SHIFT);
  818. }
  819. if (g_aic_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
  820. if ((AIC_UDC_REG->usblinests & (1U << 8)) == 0U) {
  821. AIC_UDC_REG->inepcfg[ep_idx] &= ~DEPCTL_SETD0PID;
  822. AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_SETD1PID;
  823. } else {
  824. AIC_UDC_REG->inepcfg[ep_idx] &= ~DEPCTL_SETD1PID;
  825. AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_SETD0PID;
  826. }
  827. AIC_UDC_REG->ineptsfsiz[ep_idx] &= ~(DXEPTSIZ_MULCNT_MASK);
  828. AIC_UDC_REG->ineptsfsiz[ep_idx] |= (1U << DXEPTSIZ_MULCNT_SHIFT);
  829. } else if (g_aic_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) {
  830. AIC_UDC_REG->ineptsfsiz[ep_idx] &= ~(DXEPTSIZ_MULCNT_MASK);
  831. AIC_UDC_REG->ineptsfsiz[ep_idx] |= (1U << DXEPTSIZ_MULCNT_SHIFT);
  832. }
  833. #ifdef CONFIG_USB_AIC_DMA_ENABLE
  834. AIC_UDC_REG->inepdmaaddr[ep_idx] = (uint32_t)(uintptr_t)data;
  835. #endif
  836. AIC_UDC_REG->inepcfg[ep_idx] |= (DEPCTL_CNAK | DEPCTL_EPENA);
  837. return 0;
  838. }
  839. int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
  840. {
  841. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  842. uint32_t pktcnt = 0;
  843. if (!data && data_len) {
  844. return -1;
  845. }
  846. if (AIC_UDC_REG->outepcfg[ep_idx] & DEPCTL_EPENA) {
  847. return -2;
  848. }
  849. if (ep_idx && !(AIC_UDC_REG->outepcfg[ep_idx] & DEPCTL_MPS_MASK)) {
  850. return -3;
  851. }
  852. if (((uint32_t)(uintptr_t)data) & 0x03) {
  853. return -4;
  854. }
  855. g_aic_udc.out_ep[ep_idx].xfer_buf = (uint8_t *)data;
  856. g_aic_udc.out_ep[ep_idx].xfer_len = data_len;
  857. g_aic_udc.out_ep[ep_idx].actual_xfer_len = 0;
  858. #ifdef CONFIG_USB_AIC_DMA_ENABLE
  859. if ((ep_idx != 0) && (data_len > 0) &&
  860. ((((uint32_t)(uintptr_t)data % CACHE_LINE_SIZE) != 0) ||
  861. (((uint32_t)(uintptr_t)(data + data_len) % CACHE_LINE_SIZE) != 0))) {
  862. if (g_aic_udc.out_ep[ep_idx].xfer_align_len != data_len) {
  863. int ret = 0;
  864. aic_udc_obuf_free(&g_aic_udc.out_ep[ep_idx]);
  865. ret = aic_udc_obuf_alloc(&g_aic_udc.out_ep[ep_idx], data_len);
  866. if (ret)
  867. return ret;
  868. }
  869. data = g_aic_udc.out_ep[ep_idx].xfer_align_buf;
  870. } else {
  871. aic_udc_obuf_free(&g_aic_udc.out_ep[ep_idx]);
  872. }
  873. if (data_len > 0)
  874. aic_udc_dcache_invalidate((uintptr_t)data, ALIGN_UP(data_len, CACHE_LINE_SIZE));
  875. #endif
  876. AIC_UDC_REG->outeptsfsiz[ep_idx] &= ~(DXEPTSIZ_PKT_CNT_MASK);
  877. AIC_UDC_REG->outeptsfsiz[ep_idx] &= ~(DXEPTSIZ_XFER_SIZE_MASK);
  878. if (data_len == 0) {
  879. AIC_UDC_REG->outeptsfsiz[ep_idx] |= (DXEPTSIZ_PKT_CNT_MASK & (1 << 19));
  880. AIC_UDC_REG->outeptsfsiz[ep_idx] |= (DXEPTSIZ_XFER_SIZE_MASK & g_aic_udc.out_ep[ep_idx].ep_mps);
  881. AIC_UDC_REG->outepcfg[ep_idx] |= (DEPCTL_CNAK | DEPCTL_EPENA);
  882. return 0;
  883. }
  884. if (ep_idx == 0) {
  885. if (data_len > g_aic_udc.out_ep[ep_idx].ep_mps) {
  886. data_len = g_aic_udc.out_ep[ep_idx].ep_mps;
  887. }
  888. g_aic_udc.out_ep[ep_idx].xfer_len = data_len;
  889. AIC_UDC_REG->outeptsfsiz[ep_idx] |= (DXEPTSIZ_PKT_CNT_MASK & (1U << 19));
  890. AIC_UDC_REG->outeptsfsiz[ep_idx] |= (DXEPTSIZ_XFER_SIZE_MASK & data_len);
  891. } else {
  892. pktcnt = (uint16_t)((data_len + g_aic_udc.out_ep[ep_idx].ep_mps - 1U) / g_aic_udc.out_ep[ep_idx].ep_mps);
  893. AIC_UDC_REG->outeptsfsiz[ep_idx] |= (DXEPTSIZ_PKT_CNT_MASK & (pktcnt << 19));
  894. AIC_UDC_REG->outeptsfsiz[ep_idx] |= (DXEPTSIZ_XFER_SIZE_MASK & data_len);
  895. }
  896. #ifdef CONFIG_USB_AIC_DMA_ENABLE
  897. AIC_UDC_REG->outepdmaaddr[ep_idx] = (uint32_t)(uintptr_t)data;
  898. #endif
  899. if (g_aic_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
  900. if ((AIC_UDC_REG->usblinests & (1U << 8)) == 0U) {
  901. AIC_UDC_REG->outepcfg[ep_idx] &= ~DEPCTL_SETD0PID;
  902. AIC_UDC_REG->outepcfg[ep_idx] |= DEPCTL_SETD1PID;
  903. } else {
  904. AIC_UDC_REG->outepcfg[ep_idx] &= ~DEPCTL_SETD1PID;
  905. AIC_UDC_REG->outepcfg[ep_idx] |= DEPCTL_SETD0PID;
  906. }
  907. }
  908. AIC_UDC_REG->outepcfg[ep_idx] |= (DEPCTL_CNAK | DEPCTL_EPENA);
  909. return 0;
  910. }
  911. void USBD_IRQHandler(void)
  912. {
  913. uint32_t gint_status, ep_idx, ep_intr, epint, daintmask;
  914. gint_status = aic_get_glb_intstatus();
  915. /* Avoid spurious interrupt */
  916. if (gint_status == 0) {
  917. return;
  918. }
  919. #ifndef CONFIG_USB_AIC_DMA_ENABLE
  920. uint32_t temp;
  921. uint32_t read_count;
  922. /* Handle RxQLevel Interrupt */
  923. if (gint_status & INT_RX_FIFO_NOT_EMPTY) {
  924. AIC_UDC_REG->usbintmsk &= ~(INT_RX_FIFO_NOT_EMPTY);
  925. temp = AIC_UDC_REG->rxfifosts_pop;
  926. ep_idx = temp & RXFIFOSTS_EPNUM_MASK;
  927. if ((temp & RXFIFOSTS_PKTSTS_MASK) == PKTSTS_OUT_DATA_PKT_REC) {
  928. read_count = (temp & RXFIFOSTS_BCNT_MASK) >> 4;
  929. if (read_count != 0) {
  930. aic_ep_read(g_aic_udc.out_ep[ep_idx].xfer_buf, read_count);
  931. g_aic_udc.out_ep[ep_idx].xfer_buf += read_count;
  932. }
  933. } else if ((temp & RXFIFOSTS_PKTSTS_MASK) == PKTSTS_SETUP_DATA_PKT_REC) {
  934. read_count = (temp & RXFIFOSTS_BCNT_MASK) >> 4;
  935. aic_ep_read((uint8_t *)&g_aic_udc.setup, read_count);
  936. } else {
  937. /* ... */
  938. }
  939. AIC_UDC_REG->usbintmsk |= INT_RX_FIFO_NOT_EMPTY;
  940. }
  941. #endif
  942. if (gint_status & INT_OUT_EP) {
  943. ep_idx = 0;
  944. ep_intr = aic_get_outeps_intstatus();
  945. while (ep_intr != 0U) {
  946. if ((ep_intr & 0x1U) != 0U) {
  947. epint = aic_get_outep_intstatus(ep_idx);
  948. uint32_t DoepintReg = AIC_UDC_REG->outepint[ep_idx];
  949. AIC_UDC_REG->outepint[ep_idx] = DoepintReg;
  950. struct aic_ep_state *ep = &g_aic_udc.out_ep[ep_idx];
  951. if ((epint & TRANSFER_DONE) == TRANSFER_DONE) {
  952. #ifdef CONFIG_USB_AIC_DMA_ENABLE
  953. if (ep->xfer_align_buf)
  954. memcpy(ep->xfer_buf, ep->xfer_align_buf, ep->xfer_len);
  955. #endif
  956. if ((ep_idx == 0)) {
  957. if (ep0_ctrl_stage == 1) {
  958. ep0_ctrl_stage = 2;
  959. usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&g_aic_udc.setup);
  960. } else {
  961. if (ep->xfer_len == 0) {
  962. /* Out status, start reading setup */
  963. aic_ep0_start_read_setup((uint8_t *)&g_aic_udc.setup);
  964. } else {
  965. ep->actual_xfer_len = ep->xfer_len - ((AIC_UDC_REG->outeptsfsiz[ep_idx]) & DXEPTSIZ_XFER_SIZE_MASK);
  966. ep->xfer_len = 0;
  967. usbd_event_ep_out_complete_handler(0, 0x00, ep->actual_xfer_len);
  968. }
  969. }
  970. } else {
  971. ep->actual_xfer_len = ep->xfer_len - ((AIC_UDC_REG->outeptsfsiz[ep_idx]) & DXEPTSIZ_XFER_SIZE_MASK);
  972. ep->xfer_len = 0;
  973. usbd_event_ep_out_complete_handler(0, ep_idx, ep->actual_xfer_len);
  974. }
  975. }
  976. if ((epint & CTRL_OUT_EP_SETUP_PHASE_DONE) == CTRL_OUT_EP_SETUP_PHASE_DONE) {
  977. if (ep0_ctrl_stage == 1) {
  978. ep0_ctrl_stage = 2;
  979. usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&g_aic_udc.setup);
  980. }
  981. }
  982. }
  983. ep_intr >>= 1U;
  984. ep_idx++;
  985. }
  986. }
  987. #ifndef CONFIG_USB_AIC_DMA_ENABLE
  988. if (gint_status & INT_NP_TX_FIFO_EMPTY) {
  989. AIC_UDC_REG->usbintmsk &= ~(INT_NP_TX_FIFO_EMPTY);
  990. aic_tx_fifo_empty_procecss(0);
  991. }
  992. #endif
  993. if (gint_status & INT_IN_EP) {
  994. ep_idx = 0U;
  995. ep_intr = aic_get_ineps_intstatus();
  996. while (ep_intr != 0U) {
  997. if ((ep_intr & 0x1U) != 0U) {
  998. epint = aic_get_inep_intstatus(ep_idx);
  999. uint32_t DiepintReg = AIC_UDC_REG->inepint[ep_idx];
  1000. AIC_UDC_REG->inepint[ep_idx] = DiepintReg;
  1001. if ((epint & TRANSFER_DONE) == TRANSFER_DONE) {
  1002. if (ep_idx == 0) {
  1003. g_aic_udc.in_ep[ep_idx].actual_xfer_len = g_aic_udc.in_ep[ep_idx].xfer_len - ((AIC_UDC_REG->ineptsfsiz[ep_idx]) & DXEPTSIZ_XFER_SIZE_MASK);
  1004. g_aic_udc.in_ep[ep_idx].xfer_len = 0;
  1005. usbd_event_ep_in_complete_handler(0, 0x80, g_aic_udc.in_ep[ep_idx].actual_xfer_len);
  1006. if (g_aic_udc.setup.wLength && ((g_aic_udc.setup.bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_OUT)) {
  1007. /* In status, start reading setup */
  1008. aic_ep0_start_read_setup((uint8_t *)&g_aic_udc.setup);
  1009. } else if (g_aic_udc.setup.wLength == 0) {
  1010. /* In status, start reading setup */
  1011. aic_ep0_start_read_setup((uint8_t *)&g_aic_udc.setup);
  1012. }
  1013. } else {
  1014. g_aic_udc.in_ep[ep_idx].actual_xfer_len = g_aic_udc.in_ep[ep_idx].xfer_len - ((AIC_UDC_REG->ineptsfsiz[ep_idx]) & DXEPTSIZ_XFER_SIZE_MASK);
  1015. g_aic_udc.in_ep[ep_idx].xfer_len = 0;
  1016. usbd_event_ep_in_complete_handler(0, ep_idx | 0x80, g_aic_udc.in_ep[ep_idx].actual_xfer_len);
  1017. }
  1018. }
  1019. #ifndef CONFIG_USB_AIC_DMA_ENABLE
  1020. if ((epint & INTKN_TXFEMP) == INTKN_TXFEMP) {
  1021. aic_tx_fifo_empty_procecss(ep_idx);
  1022. }
  1023. #endif
  1024. }
  1025. ep_intr >>= 1U;
  1026. ep_idx++;
  1027. }
  1028. }
  1029. if (gint_status & INT_RESET) {
  1030. AIC_UDC_REG->usbintsts |= INT_RESET;
  1031. AIC_UDC_REG->usbdevfunc &= ~USBDEVFUNC_RMTWKUPSIG;
  1032. usb_dc_rst();
  1033. }
  1034. if (gint_status & INT_ENUMDONE) {
  1035. AIC_UDC_REG->usbintsts |= INT_ENUMDONE;
  1036. aic_set_turnaroundtime(usbd_clk, aic_get_devspeed());
  1037. AIC_UDC_REG->usbdevfunc |= USBDEVFUNC_CGNPINNAK;
  1038. }
  1039. if (gint_status & INT_INCOMP_ISO_OUT_INT) {
  1040. daintmask = AIC_UDC_REG->usbepintmsk;
  1041. daintmask >>= 16;
  1042. for (ep_idx = 1; ep_idx < USB_NUM_BIDIR_ENDPOINTS; ep_idx++) {
  1043. if ((BIT(ep_idx) & ~daintmask) || (g_aic_udc.out_ep[ep_idx].ep_type != USB_ENDPOINT_TYPE_ISOCHRONOUS))
  1044. continue;
  1045. if (!(AIC_UDC_REG->outepcfg[ep_idx] & DEPCTL_USBACTEP))
  1046. continue;
  1047. if ((AIC_UDC_REG->usblinests & (1U << 8)) != 0U) {
  1048. AIC_UDC_REG->outepcfg[ep_idx] |= DEPCTL_SETD0PID;
  1049. AIC_UDC_REG->outepcfg[ep_idx] &= ~DEPCTL_SETD1PID;
  1050. } else {
  1051. AIC_UDC_REG->outepcfg[ep_idx] &= ~DEPCTL_SETD0PID;
  1052. AIC_UDC_REG->outepcfg[ep_idx] |= DEPCTL_SETD1PID;
  1053. }
  1054. }
  1055. AIC_UDC_REG->usbintsts |= INT_INCOMP_ISO_OUT_INT;
  1056. }
  1057. if (gint_status & INT_INCOMP_ISO_IN_INT) {
  1058. daintmask = AIC_UDC_REG->usbepintmsk;
  1059. daintmask >>= 16;
  1060. for (ep_idx = 1; ep_idx < USB_NUM_BIDIR_ENDPOINTS; ep_idx++) {
  1061. if (((BIT(ep_idx) & ~daintmask)) || (g_aic_udc.in_ep[ep_idx].ep_type != USB_ENDPOINT_TYPE_ISOCHRONOUS))
  1062. continue;
  1063. if (!(AIC_UDC_REG->inepcfg[ep_idx] & DEPCTL_USBACTEP))
  1064. continue;
  1065. if ((AIC_UDC_REG->usblinests & (1U << 8)) != 0U) {
  1066. AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_SETD0PID;
  1067. AIC_UDC_REG->inepcfg[ep_idx] &= ~DEPCTL_SETD1PID;
  1068. } else {
  1069. AIC_UDC_REG->inepcfg[ep_idx] &= ~DEPCTL_SETD0PID;
  1070. AIC_UDC_REG->inepcfg[ep_idx] |= DEPCTL_SETD1PID;
  1071. }
  1072. }
  1073. AIC_UDC_REG->usbintsts |= INT_INCOMP_ISO_IN_INT;
  1074. }
  1075. if (gint_status & INT_SOF) {
  1076. AIC_UDC_REG->usbintsts |= INT_SOF;
  1077. }
  1078. if (gint_status & INT_SUSPEND) {
  1079. AIC_UDC_REG->usbintsts |= INT_SUSPEND;
  1080. }
  1081. if (gint_status & INT_RESUME) {
  1082. AIC_UDC_REG->usbintsts |= INT_RESUME;
  1083. }
  1084. }