usb_dc_bl.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147
  1. /*
  2. * Copyright (c) 2024, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "bflb_core.h"
  7. #include "usbd_core.h"
  8. #include "hardware/usb_v2_reg.h"
  9. /* select only one mode */
  10. // #define CONFIG_USB_PINGPONG_ENABLE
  11. // #define CONFIG_USB_TRIPLE_ENABLE
  12. #define BFLB_USB_BASE ((uint32_t)0x20072000)
  13. #define BFLB_PDS_BASE ((uint32_t)0x2000e000)
  14. #define PDS_USB_CTL_OFFSET (0x500) /* usb_ctl */
  15. #define PDS_USB_PHY_CTRL_OFFSET (0x504) /* usb_phy_ctrl */
  16. /* 0x500 : usb_ctl */
  17. #define PDS_REG_USB_SW_RST_N (1 << 0U)
  18. #define PDS_REG_USB_EXT_SUSP_N (1 << 1U)
  19. #define PDS_REG_USB_WAKEUP (1 << 2U)
  20. #define PDS_REG_USB_L1_WAKEUP (1 << 3U)
  21. #define PDS_REG_USB_DRVBUS_POL (1 << 4U)
  22. #define PDS_REG_USB_IDDIG (1 << 5U)
  23. /* 0x504 : usb_phy_ctrl */
  24. #define PDS_REG_USB_PHY_PONRST (1 << 0U)
  25. #define PDS_REG_USB_PHY_OSCOUTEN (1 << 1U)
  26. #define PDS_REG_USB_PHY_XTLSEL_SHIFT (2U)
  27. #define PDS_REG_USB_PHY_XTLSEL_MASK (0x3 << PDS_REG_USB_PHY_XTLSEL_SHIFT)
  28. #define PDS_REG_USB_PHY_OUTCLKSEL (1 << 4U)
  29. #define PDS_REG_USB_PHY_PLLALIV (1 << 5U)
  30. #define PDS_REG_PU_USB20_PSW (1 << 6U)
  31. #define USB_SOF_TIMER_MASK_AFTER_RESET_HS (0x44C)
  32. #define USB_SOF_TIMER_MASK_AFTER_RESET_FS (0x2710)
  33. extern void USBD_IRQHandler(uint8_t busid);
  34. void USBD_IRQ(int irq, void *arg)
  35. {
  36. USBD_IRQHandler(0);
  37. }
  38. static void bflb_usb_phy_init(void)
  39. {
  40. uint32_t regval;
  41. /* USB_PHY_CTRL[3:2] reg_usb_phy_xtlsel=0 */
  42. /* 2000e504 = 0x40; #100; USB_PHY_CTRL[6] reg_pu_usb20_psw=1 (VCC33A) */
  43. /* 2000e504 = 0x41; #500; USB_PHY_CTRL[0] reg_usb_phy_ponrst=1 */
  44. /* 2000e500 = 0x20; #100; USB_CTL[0] reg_usb_sw_rst_n=0 */
  45. /* 2000e500 = 0x22; #500; USB_CTL[1] reg_usb_ext_susp_n=1 */
  46. /* 2000e500 = 0x23; #100; USB_CTL[0] reg_usb_sw_rst_n=1 */
  47. /* #1.2ms; wait UCLK */
  48. /* wait(soc616_b0.usb_uclk); */
  49. regval = getreg32(BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  50. regval &= ~PDS_REG_USB_PHY_XTLSEL_MASK;
  51. putreg32(regval, BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  52. regval = getreg32(BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  53. regval |= PDS_REG_PU_USB20_PSW;
  54. putreg32(regval, BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  55. regval = getreg32(BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  56. regval |= PDS_REG_USB_PHY_PONRST;
  57. putreg32(regval, BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  58. /* greater than 5T */
  59. bflb_mtimer_delay_us(1);
  60. regval = getreg32(BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  61. regval &= ~PDS_REG_USB_SW_RST_N;
  62. putreg32(regval, BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  63. /* greater than 5T */
  64. bflb_mtimer_delay_us(1);
  65. regval = getreg32(BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  66. regval |= PDS_REG_USB_EXT_SUSP_N;
  67. putreg32(regval, BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  68. /* wait UCLK 1.2ms */
  69. bflb_mtimer_delay_ms(3);
  70. regval = getreg32(BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  71. regval |= PDS_REG_USB_SW_RST_N;
  72. putreg32(regval, BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  73. bflb_mtimer_delay_ms(2);
  74. }
  75. #define USB_FIFO_F0 0
  76. #define USB_FIFO_F1 1
  77. #define USB_FIFO_F2 2
  78. #define USB_FIFO_F3 3
  79. #define USB_FIFO_CXF 0xff
  80. #define USB_FIFO_DIR_OUT 0
  81. #define USB_FIFO_DIR_IN 1
  82. #define USB_FIFO_DIR_BID 2
  83. #define USB_VDMA_DIR_FIFO2MEM 0
  84. #define USB_VDMA_DIR_MEM2FIFO 1
  85. #define USB_NUM_BIDIR_ENDPOINTS 5
  86. /* Endpoint state */
  87. struct bl_ep_state {
  88. uint16_t ep_mps; /* Endpoint max packet size */
  89. uint8_t ep_type; /* Endpoint type */
  90. uint8_t ep_stalled; /* Endpoint stall flag */
  91. uint8_t ep_enable; /* Endpoint enable */
  92. bool ep_active;
  93. uint8_t *xfer_buf;
  94. uint32_t xfer_len;
  95. uint32_t actual_xfer_len;
  96. };
  97. struct bl_udc {
  98. struct bl_ep_state in_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< IN endpoint parameters */
  99. struct bl_ep_state out_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< OUT endpoint parameters */
  100. } g_bl_udc;
  101. static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_setup_buffer[8];
  102. static void bflb_usb_reset_fifo(uint8_t fifo)
  103. {
  104. uint32_t regval;
  105. if (fifo == USB_FIFO_CXF) {
  106. regval = getreg32(BFLB_USB_BASE + USB_DEV_CXCFE_OFFSET);
  107. regval |= USB_CX_CLR;
  108. putreg32(regval, BFLB_USB_BASE + USB_DEV_CXCFE_OFFSET);
  109. } else {
  110. regval = getreg32(BFLB_USB_BASE + USB_DEV_FIBC0_OFFSET + 4 * fifo);
  111. regval |= USB_FFRST0_HOV;
  112. putreg32(regval, BFLB_USB_BASE + USB_DEV_FIBC0_OFFSET + 4 * fifo);
  113. }
  114. }
  115. void bflb_usb_get_setup_packet(uint32_t setup[2])
  116. {
  117. uint32_t regval;
  118. regval = getreg32(BFLB_USB_BASE + USB_DMA_TFN_OFFSET);
  119. regval |= USB_ACC_CXF_HOV;
  120. putreg32(regval, BFLB_USB_BASE + USB_DMA_TFN_OFFSET);
  121. setup[0] = getreg32(BFLB_USB_BASE + USB_DMA_CPS3_OFFSET);
  122. setup[1] = getreg32(BFLB_USB_BASE + USB_DMA_CPS3_OFFSET);
  123. regval = getreg32(BFLB_USB_BASE + USB_DMA_TFN_OFFSET);
  124. regval &= ~USB_ACC_CXF_HOV;
  125. putreg32(regval, BFLB_USB_BASE + USB_DMA_TFN_OFFSET);
  126. }
  127. static void bflb_usb_set_ep_fifomap(uint8_t ep_idx, uint8_t fifo)
  128. {
  129. uint32_t regval;
  130. if (ep_idx < 5) {
  131. regval = getreg32(BFLB_USB_BASE + USB_DEV_EPMAP0_OFFSET);
  132. regval &= ~(0xff << ((ep_idx - 1) * 8));
  133. regval |= (fifo << ((ep_idx - 1) * 8));
  134. regval |= (fifo << ((ep_idx - 1) * 8 + 4));
  135. putreg32(regval, BFLB_USB_BASE + USB_DEV_EPMAP0_OFFSET);
  136. } else {
  137. regval = getreg32(BFLB_USB_BASE + USB_DEV_EPMAP1_OFFSET);
  138. regval &= ~(0xff << ((ep_idx - 4 - 1) * 8));
  139. regval |= (fifo << ((ep_idx - 4 - 1) * 8));
  140. regval |= (fifo << ((ep_idx - 4 - 1) * 8 + 4));
  141. putreg32(regval, BFLB_USB_BASE + USB_DEV_EPMAP1_OFFSET);
  142. }
  143. }
  144. static void bflb_usb_set_fifo_epmap(uint8_t fifo, uint8_t ep_idx, uint8_t dir)
  145. {
  146. uint32_t regval;
  147. regval = getreg32(BFLB_USB_BASE + USB_DEV_FMAP_OFFSET);
  148. regval &= ~(0x3f << (fifo * 8));
  149. regval |= (ep_idx << (fifo * 8));
  150. regval |= (dir << (fifo * 8 + 4));
  151. putreg32(regval, BFLB_USB_BASE + USB_DEV_FMAP_OFFSET);
  152. }
  153. static void bflb_usb_set_outep_mps(uint8_t ep_idx, uint16_t ep_mps)
  154. {
  155. uint32_t regval;
  156. regval = getreg32(BFLB_USB_BASE + USB_DEV_OUTMPS1_OFFSET + (ep_idx - 1) * 4);
  157. regval &= ~USB_MAXPS_OEP1_MASK;
  158. regval |= ep_mps;
  159. putreg32(regval, BFLB_USB_BASE + USB_DEV_OUTMPS1_OFFSET + (ep_idx - 1) * 4);
  160. }
  161. static void bflb_usb_set_inep_mps(uint8_t ep_idx, uint16_t ep_mps)
  162. {
  163. uint32_t regval;
  164. regval = getreg32(BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4);
  165. regval &= ~USB_MAXPS_IEP1_MASK;
  166. regval |= ep_mps;
  167. putreg32(regval, BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4);
  168. }
  169. static uint8_t bflb_usb_get_fifo_ep(uint8_t fifo)
  170. {
  171. uint32_t regval;
  172. regval = (getreg32(BFLB_USB_BASE + USB_DEV_FMAP_OFFSET) & (0xf << (fifo * 8)));
  173. regval >>= (fifo * 8);
  174. return regval;
  175. }
  176. static void bflb_usb_fifo_config(uint8_t fifo, uint8_t ep_type, uint16_t block_size, uint8_t block_num, bool fifo_en)
  177. {
  178. uint32_t regval;
  179. if (fifo < 4) {
  180. regval = getreg32(BFLB_USB_BASE + USB_DEV_FCFG_OFFSET);
  181. regval &= ~(0x3f << (fifo * 8));
  182. regval |= (ep_type << (fifo * 8 + 0));
  183. regval |= ((block_num - 1) << (fifo * 8 + 2));
  184. if (block_size == 1024) {
  185. regval |= (1 << (fifo * 8 + 4));
  186. }
  187. if (fifo_en) {
  188. regval |= (1 << (fifo * 8 + 5));
  189. }
  190. putreg32(regval, BFLB_USB_BASE + USB_DEV_FCFG_OFFSET);
  191. }
  192. }
  193. static void bflb_usb_vdma_start_write(uint8_t fifo, const uint8_t *data, uint32_t len)
  194. {
  195. uint32_t regval;
  196. if (fifo == USB_FIFO_CXF) {
  197. regval = getreg32(BFLB_USB_BASE + USB_VDMA_CXFPS1_OFFSET);
  198. regval &= ~USB_VDMA_LEN_CXF_MASK;
  199. regval &= ~USB_VDMA_IO_CXF;
  200. regval |= USB_VDMA_TYPE_CXF;
  201. regval |= (len << USB_VDMA_LEN_CXF_SHIFT);
  202. putreg32(regval, BFLB_USB_BASE + USB_VDMA_CXFPS1_OFFSET);
  203. putreg32((uint32_t)data, BFLB_USB_BASE + USB_VDMA_CXFPS2_OFFSET);
  204. regval = getreg32(BFLB_USB_BASE + USB_VDMA_CXFPS1_OFFSET);
  205. regval |= USB_VDMA_START_CXF;
  206. putreg32(regval, BFLB_USB_BASE + USB_VDMA_CXFPS1_OFFSET);
  207. } else {
  208. regval = getreg32(BFLB_USB_BASE + USB_VDMA_F0PS1_OFFSET + fifo * 8);
  209. regval &= ~USB_VDMA_LEN_CXF_MASK;
  210. regval &= ~USB_VDMA_IO_CXF;
  211. regval |= USB_VDMA_TYPE_CXF;
  212. regval |= (len << USB_VDMA_LEN_CXF_SHIFT);
  213. putreg32(regval, BFLB_USB_BASE + USB_VDMA_F0PS1_OFFSET + fifo * 8);
  214. putreg32((uint32_t)data, BFLB_USB_BASE + USB_VDMA_F0PS2_OFFSET + fifo * 8);
  215. regval = getreg32(BFLB_USB_BASE + USB_VDMA_F0PS1_OFFSET + fifo * 8);
  216. regval |= USB_VDMA_START_CXF;
  217. putreg32(regval, BFLB_USB_BASE + USB_VDMA_F0PS1_OFFSET + fifo * 8);
  218. }
  219. }
  220. static void bflb_usb_vdma_start_read(uint8_t fifo, uint8_t *data, uint32_t len)
  221. {
  222. uint32_t regval;
  223. if (fifo == USB_FIFO_CXF) {
  224. regval = getreg32(BFLB_USB_BASE + USB_VDMA_CXFPS1_OFFSET);
  225. regval &= ~USB_VDMA_LEN_CXF_MASK;
  226. regval &= ~USB_VDMA_IO_CXF;
  227. regval &= ~USB_VDMA_TYPE_CXF;
  228. regval |= (len << USB_VDMA_LEN_CXF_SHIFT);
  229. putreg32(regval, BFLB_USB_BASE + USB_VDMA_CXFPS1_OFFSET);
  230. putreg32((uint32_t)data, BFLB_USB_BASE + USB_VDMA_CXFPS2_OFFSET);
  231. regval = getreg32(BFLB_USB_BASE + USB_VDMA_CXFPS1_OFFSET);
  232. regval |= USB_VDMA_START_CXF;
  233. putreg32(regval, BFLB_USB_BASE + USB_VDMA_CXFPS1_OFFSET);
  234. } else {
  235. regval = getreg32(BFLB_USB_BASE + USB_VDMA_F0PS1_OFFSET + fifo * 8);
  236. regval &= ~USB_VDMA_LEN_CXF_MASK;
  237. regval &= ~USB_VDMA_IO_CXF;
  238. regval &= ~USB_VDMA_TYPE_CXF;
  239. regval |= (len << USB_VDMA_LEN_CXF_SHIFT);
  240. putreg32(regval, BFLB_USB_BASE + USB_VDMA_F0PS1_OFFSET + fifo * 8);
  241. putreg32((uint32_t)data, BFLB_USB_BASE + USB_VDMA_F0PS2_OFFSET + fifo * 8);
  242. regval = getreg32(BFLB_USB_BASE + USB_VDMA_F0PS1_OFFSET + fifo * 8);
  243. regval |= USB_VDMA_START_CXF;
  244. putreg32(regval, BFLB_USB_BASE + USB_VDMA_F0PS1_OFFSET + fifo * 8);
  245. }
  246. }
  247. static uint32_t bflb_usb_vdma_get_remain_size(uint8_t fifo)
  248. {
  249. uint32_t regval;
  250. if (fifo == USB_FIFO_CXF) {
  251. regval = (getreg32(BFLB_USB_BASE + USB_VDMA_CXFPS1_OFFSET) & USB_VDMA_LEN_CXF_MASK);
  252. regval >>= USB_VDMA_LEN_CXF_SHIFT;
  253. } else {
  254. regval = (getreg32(BFLB_USB_BASE + USB_VDMA_F0PS1_OFFSET + fifo * 8) & USB_VDMA_LEN_CXF_MASK);
  255. regval >>= USB_VDMA_LEN_CXF_SHIFT;
  256. }
  257. return regval;
  258. }
  259. static inline void bflb_usb_control_transfer_done(void)
  260. {
  261. uint32_t regval;
  262. regval = getreg32(BFLB_USB_BASE + USB_DEV_CXCFE_OFFSET);
  263. regval |= USB_CX_DONE;
  264. putreg32(regval, BFLB_USB_BASE + USB_DEV_CXCFE_OFFSET);
  265. }
  266. static inline void bflb_usb_set_mult(uint8_t ep_idx, uint8_t mult)
  267. {
  268. uint32_t regval;
  269. regval = getreg32(BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4);
  270. regval &= ~USB_TX_NUM_HBW_IEP1_MASK;
  271. regval |= (mult << USB_TX_NUM_HBW_IEP1_SHIFT);
  272. putreg32(regval, BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4);
  273. }
  274. static inline void bflb_usb_send_zlp(uint8_t ep_idx)
  275. {
  276. uint32_t regval;
  277. regval = getreg32(BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4);
  278. regval |= USB_TX0BYTE_IEP1;
  279. putreg32(regval, BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4);
  280. }
  281. static inline uint32_t bflb_usb_get_tx_zlp_intstatus(void)
  282. {
  283. return getreg32(BFLB_USB_BASE + USB_DEV_TXZ_OFFSET);
  284. }
  285. static inline uint32_t bflb_usb_get_rx_zlp_intstatus(void)
  286. {
  287. return getreg32(BFLB_USB_BASE + USB_DEV_RXZ_OFFSET);
  288. }
  289. static inline void bflb_usb_clear_tx_zlp_intstatus(uint8_t ep_idx)
  290. {
  291. putreg32((1 << (ep_idx - 1)), BFLB_USB_BASE + USB_DEV_TXZ_OFFSET);
  292. }
  293. static inline void bflb_usb_clear_rx_zlp_intstatus(uint8_t ep_idx)
  294. {
  295. putreg32((1 << (ep_idx - 1)), BFLB_USB_BASE + USB_DEV_RXZ_OFFSET);
  296. }
  297. static uint32_t bflb_usb_get_source_group_intstatus(uint8_t group)
  298. {
  299. switch (group) {
  300. case 0:
  301. return (getreg32(BFLB_USB_BASE + USB_DEV_ISG0_OFFSET) & ~getreg32(BFLB_USB_BASE + USB_DEV_MISG0_OFFSET));
  302. case 1:
  303. return (getreg32(BFLB_USB_BASE + USB_DEV_ISG1_OFFSET) & ~getreg32(BFLB_USB_BASE + USB_DEV_MISG1_OFFSET));
  304. case 2:
  305. return (getreg32(BFLB_USB_BASE + USB_DEV_ISG2_OFFSET) & ~getreg32(BFLB_USB_BASE + USB_DEV_MISG2_OFFSET));
  306. case 3:
  307. return (getreg32(BFLB_USB_BASE + USB_DEV_ISG3_OFFSET) & ~getreg32(BFLB_USB_BASE + USB_DEV_MISG3_OFFSET));
  308. case 4:
  309. return (getreg32(BFLB_USB_BASE + USB_DEV_ISG4_OFFSET) & ~getreg32(BFLB_USB_BASE + USB_DEV_MISG4_OFFSET));
  310. default:
  311. break;
  312. }
  313. return 0;
  314. }
  315. static void bflb_usb_source_group_int_clear(uint8_t group, uint32_t int_clear)
  316. {
  317. switch (group) {
  318. case 0:
  319. putreg32(int_clear, BFLB_USB_BASE + USB_DEV_ISG0_OFFSET);
  320. break;
  321. case 1:
  322. putreg32(int_clear, BFLB_USB_BASE + USB_DEV_ISG1_OFFSET);
  323. break;
  324. case 2:
  325. putreg32(int_clear, BFLB_USB_BASE + USB_DEV_ISG2_OFFSET);
  326. break;
  327. case 3:
  328. putreg32(int_clear, BFLB_USB_BASE + USB_DEV_ISG3_OFFSET);
  329. break;
  330. case 4:
  331. putreg32(int_clear, BFLB_USB_BASE + USB_DEV_ISG4_OFFSET);
  332. break;
  333. default:
  334. break;
  335. }
  336. }
  337. static uint8_t usb_get_transfer_fifo(uint8_t ep_idx)
  338. {
  339. uint8_t target_fifo_id;
  340. if ((g_bl_udc.out_ep[ep_idx].ep_mps > 512) || (g_bl_udc.in_ep[ep_idx].ep_mps > 512)) {
  341. #if defined(CONFIG_USB_PINGPONG_ENABLE)
  342. target_fifo_id = USB_FIFO_F0;
  343. #elif defined(CONFIG_USB_TRIPLE_ENABLE)
  344. while (1) {
  345. }
  346. #else
  347. if (ep_idx == 1) {
  348. target_fifo_id = USB_FIFO_F0;
  349. } else {
  350. target_fifo_id = USB_FIFO_F2;
  351. }
  352. #endif
  353. } else {
  354. #if defined(CONFIG_USB_PINGPONG_ENABLE)
  355. if (ep_idx == 1) {
  356. target_fifo_id = USB_FIFO_F0;
  357. } else {
  358. target_fifo_id = USB_FIFO_F2;
  359. }
  360. #elif defined(CONFIG_USB_TRIPLE_ENABLE)
  361. if (ep_idx == 1) {
  362. target_fifo_id = USB_FIFO_F0;
  363. } else {
  364. target_fifo_id = USB_FIFO_F3;
  365. }
  366. #else
  367. target_fifo_id = (ep_idx - 1);
  368. #endif
  369. }
  370. return target_fifo_id;
  371. }
  372. int usb_dc_init(uint8_t busid)
  373. {
  374. uint32_t regval;
  375. bflb_usb_phy_init();
  376. bflb_irq_attach(37, USBD_IRQ, NULL);
  377. bflb_irq_enable(37);
  378. /* disable global irq */
  379. regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  380. regval &= ~USB_GLINT_EN_HOV;
  381. putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  382. regval = getreg32(BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  383. regval |= USB_UNPLUG;
  384. putreg32(regval, BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  385. regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  386. regval &= ~USB_CAP_RMWAKUP;
  387. regval |= USB_CHIP_EN_HOV;
  388. putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  389. regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  390. regval |= USB_SFRST_HOV;
  391. putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  392. while (getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET) & USB_SFRST_HOV) {
  393. }
  394. regval = getreg32(BFLB_USB_BASE + USB_DEV_ADR_OFFSET);
  395. regval &= ~USB_AFT_CONF;
  396. putreg32(regval, BFLB_USB_BASE + USB_DEV_ADR_OFFSET);
  397. regval = getreg32(BFLB_USB_BASE + USB_DEV_SMT_OFFSET);
  398. regval &= ~USB_SOFMT_MASK;
  399. #ifdef CONFIG_USB_HS
  400. regval |= USB_SOF_TIMER_MASK_AFTER_RESET_HS;
  401. #else
  402. regval |= USB_SOF_TIMER_MASK_AFTER_RESET_FS;
  403. #endif
  404. putreg32(regval, BFLB_USB_BASE + USB_DEV_SMT_OFFSET);
  405. /* enable setup irq in source group0 */
  406. regval = getreg32(BFLB_USB_BASE + USB_DEV_MISG0_OFFSET);
  407. regval &= ~USB_MCX_SETUP_INT;
  408. regval |= USB_MCX_IN_INT;
  409. regval |= (1 << 3);
  410. regval |= USB_MCX_OUT_INT;
  411. regval |= USB_MCX_IN_INT;
  412. regval |= USB_MCX_COMFAIL_INT;
  413. regval |= USB_MCX_COMABORT_INT;
  414. putreg32(regval, BFLB_USB_BASE + USB_DEV_MISG0_OFFSET);
  415. /* disable all fifo irq in source group1 */
  416. putreg32(0xffffffff, BFLB_USB_BASE + USB_DEV_MISG1_OFFSET);
  417. /* enable rst/tx0/rx0 irq in source group2 */
  418. regval = 0xffffffff;
  419. regval &= ~USB_MUSBRST_INT;
  420. regval &= ~USB_MSUSP_INT;
  421. regval &= ~USB_MRESM_INT;
  422. regval &= ~USB_MTX0BYTE_INT;
  423. regval &= ~USB_MRX0BYTE_INT;
  424. putreg32(regval, BFLB_USB_BASE + USB_DEV_MISG2_OFFSET);
  425. /* enable vdma cmplt and error irq in source group3 */
  426. regval = 0xffffffff;
  427. regval &= ~(USB_MVDMA_CMPLT_CXF |
  428. USB_MVDMA_CMPLT_F0 |
  429. USB_MVDMA_CMPLT_F1 |
  430. USB_MVDMA_CMPLT_F2 |
  431. USB_MVDMA_CMPLT_F3);
  432. // regval &= ~(USB_MVDMA_ERROR_CXF |
  433. // USB_MVDMA_ERROR_F0 |
  434. // USB_MVDMA_ERROR_F1 |
  435. // USB_MVDMA_ERROR_F2 |
  436. // USB_MVDMA_ERROR_F3);
  437. putreg32(regval, BFLB_USB_BASE + USB_DEV_MISG3_OFFSET);
  438. /* enable group irq */
  439. regval = getreg32(BFLB_USB_BASE + USB_DEV_MIGR_OFFSET);
  440. regval &= ~USB_MINT_G0;
  441. regval &= ~USB_MINT_G1;
  442. regval &= ~USB_MINT_G2;
  443. regval &= ~USB_MINT_G3;
  444. regval &= ~USB_MINT_G4;
  445. putreg32(regval, BFLB_USB_BASE + USB_DEV_MIGR_OFFSET);
  446. /* enable device irq */
  447. regval = getreg32(BFLB_USB_BASE + USB_GLB_INT_OFFSET);
  448. regval |= USB_MHC_INT;
  449. regval |= USB_MOTG_INT;
  450. regval &= ~USB_MDEV_INT;
  451. putreg32(regval, BFLB_USB_BASE + USB_GLB_INT_OFFSET);
  452. bflb_usb_source_group_int_clear(2, 0x3ff);
  453. bflb_usb_source_group_int_clear(3, 0xffffffff);
  454. for (uint8_t i = 1; i < 9; i++) {
  455. bflb_usb_set_ep_fifomap(i, 15);
  456. bflb_usb_set_fifo_epmap(i, 15, 0);
  457. }
  458. /* enable vdma */
  459. regval = getreg32(BFLB_USB_BASE + USB_VDMA_CTRL_OFFSET);
  460. regval |= USB_VDMA_EN;
  461. putreg32(regval, BFLB_USB_BASE + USB_VDMA_CTRL_OFFSET);
  462. regval = getreg32(BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  463. regval &= ~USB_UNPLUG;
  464. putreg32(regval, BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  465. /* enable global irq */
  466. regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  467. regval |= USB_GLINT_EN_HOV;
  468. putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  469. return 0;
  470. }
  471. int usb_dc_deinit(uint8_t busid)
  472. {
  473. uint32_t regval;
  474. /* disable global irq */
  475. regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  476. regval &= ~USB_GLINT_EN_HOV;
  477. putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  478. regval = getreg32(BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  479. regval |= USB_UNPLUG;
  480. putreg32(regval, BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  481. regval = getreg32(BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  482. regval &= ~PDS_REG_USB_PHY_XTLSEL_MASK;
  483. putreg32(regval, BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  484. regval = getreg32(BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  485. regval &= ~PDS_REG_PU_USB20_PSW;
  486. putreg32(regval, BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  487. regval = getreg32(BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  488. regval &= ~PDS_REG_USB_PHY_PONRST;
  489. putreg32(regval, BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  490. regval = getreg32(BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  491. regval &= ~PDS_REG_USB_EXT_SUSP_N;
  492. putreg32(regval, BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  493. return 0;
  494. }
  495. int usbd_set_address(uint8_t busid, const uint8_t addr)
  496. {
  497. uint32_t regval;
  498. regval = getreg32(BFLB_USB_BASE + USB_DEV_ADR_OFFSET);
  499. regval &= ~USB_DEVADR_MASK;
  500. regval |= addr;
  501. putreg32(regval, BFLB_USB_BASE + USB_DEV_ADR_OFFSET);
  502. return 0;
  503. }
  504. int usbd_set_remote_wakeup(uint8_t busid)
  505. {
  506. uint32_t regval;
  507. regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  508. regval |= USB_CAP_RMWAKUP;
  509. putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  510. bflb_mtimer_delay_ms(10);
  511. regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  512. regval &= ~USB_CAP_RMWAKUP;
  513. putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  514. return 0;
  515. }
  516. uint8_t usbd_get_port_speed(uint8_t busid)
  517. {
  518. uint8_t speed = 3;
  519. speed = (getreg32(BFLB_USB_BASE + USB_OTG_CSR_OFFSET) & USB_SPD_TYP_HOV_POV_MASK) >> USB_SPD_TYP_HOV_POV_SHIFT;
  520. if (speed == 0) {
  521. return USB_SPEED_FULL;
  522. } else if (speed == 1) {
  523. return USB_SPEED_LOW;
  524. } else if (speed == 2) {
  525. return USB_SPEED_HIGH;
  526. }
  527. return USB_SPEED_HIGH;
  528. }
  529. int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
  530. {
  531. uint8_t ep_addr;
  532. uint32_t regval;
  533. ep_addr = ep->bEndpointAddress;
  534. uint8_t ep_idx = USB_EP_GET_IDX(ep_addr);
  535. if (ep_idx > 4) {
  536. return 0;
  537. }
  538. if (USB_EP_DIR_IS_OUT(ep_addr)) {
  539. g_bl_udc.out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
  540. g_bl_udc.out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
  541. g_bl_udc.out_ep[ep_idx].ep_enable = 1U;
  542. bflb_usb_set_outep_mps(ep_idx, USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize));
  543. } else {
  544. g_bl_udc.in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
  545. g_bl_udc.in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
  546. g_bl_udc.in_ep[ep_idx].ep_enable = 1U;
  547. bflb_usb_set_inep_mps(ep_idx, USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize));
  548. bflb_usb_set_mult(ep_idx, 0);
  549. }
  550. if (ep_idx != 0) {
  551. #if !defined(CONFIG_USB_PINGPONG_ENABLE) && !defined(CONFIG_USB_TRIPLE_ENABLE)
  552. if (USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize) > 512) {
  553. bflb_usb_set_ep_fifomap(1, USB_FIFO_F0);
  554. bflb_usb_set_ep_fifomap(2, USB_FIFO_F2);
  555. bflb_usb_set_fifo_epmap(USB_FIFO_F0, 1, USB_FIFO_DIR_BID);
  556. bflb_usb_set_fifo_epmap(USB_FIFO_F1, 1, USB_FIFO_DIR_BID);
  557. bflb_usb_set_fifo_epmap(USB_FIFO_F2, 2, USB_FIFO_DIR_BID);
  558. bflb_usb_set_fifo_epmap(USB_FIFO_F3, 2, USB_FIFO_DIR_BID);
  559. if (ep_idx == 1) {
  560. bflb_usb_fifo_config(USB_FIFO_F0, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 1024, 1, true);
  561. bflb_usb_fifo_config(USB_FIFO_F1, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 1024, 1, false);
  562. } else if (ep_idx == 2) {
  563. bflb_usb_fifo_config(USB_FIFO_F2, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 1024, 1, true);
  564. bflb_usb_fifo_config(USB_FIFO_F3, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 1024, 1, false);
  565. } else {
  566. return -1;
  567. }
  568. } else {
  569. bflb_usb_set_ep_fifomap(1, USB_FIFO_F0);
  570. bflb_usb_set_ep_fifomap(2, USB_FIFO_F1);
  571. bflb_usb_set_ep_fifomap(3, USB_FIFO_F2);
  572. bflb_usb_set_ep_fifomap(4, USB_FIFO_F3);
  573. bflb_usb_set_fifo_epmap(USB_FIFO_F0, 1, USB_FIFO_DIR_BID);
  574. bflb_usb_set_fifo_epmap(USB_FIFO_F1, 2, USB_FIFO_DIR_BID);
  575. bflb_usb_set_fifo_epmap(USB_FIFO_F2, 3, USB_FIFO_DIR_BID);
  576. bflb_usb_set_fifo_epmap(USB_FIFO_F3, 4, USB_FIFO_DIR_BID);
  577. if (ep_idx == 1) {
  578. bflb_usb_fifo_config(USB_FIFO_F0, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 1, true);
  579. } else if (ep_idx == 2) {
  580. bflb_usb_fifo_config(USB_FIFO_F1, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 1, true);
  581. } else if (ep_idx == 3) {
  582. bflb_usb_fifo_config(USB_FIFO_F2, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 1, true);
  583. } else if (ep_idx == 4) {
  584. bflb_usb_fifo_config(USB_FIFO_F3, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 1, true);
  585. } else {
  586. return -1;
  587. }
  588. }
  589. #elif defined(CONFIG_USB_PINGPONG_ENABLE)
  590. if (USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize) > 512) {
  591. bflb_usb_set_ep_fifomap(1, USB_FIFO_F0);
  592. bflb_usb_set_fifo_epmap(USB_FIFO_F0, 1, USB_FIFO_DIR_BID);
  593. bflb_usb_set_fifo_epmap(USB_FIFO_F1, 1, USB_FIFO_DIR_BID);
  594. bflb_usb_set_fifo_epmap(USB_FIFO_F2, 1, USB_FIFO_DIR_BID);
  595. bflb_usb_set_fifo_epmap(USB_FIFO_F3, 1, USB_FIFO_DIR_BID);
  596. if (ep_idx == 1) {
  597. bflb_usb_fifo_config(USB_FIFO_F0, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 1024, 2, true);
  598. bflb_usb_fifo_config(USB_FIFO_F1, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 1024, 2, false);
  599. bflb_usb_fifo_config(USB_FIFO_F2, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 1024, 2, false);
  600. bflb_usb_fifo_config(USB_FIFO_F3, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 1024, 2, false);
  601. } else {
  602. return -1;
  603. }
  604. } else {
  605. bflb_usb_set_ep_fifomap(1, USB_FIFO_F0);
  606. bflb_usb_set_ep_fifomap(2, USB_FIFO_F2);
  607. bflb_usb_set_fifo_epmap(USB_FIFO_F0, 1, USB_FIFO_DIR_BID);
  608. bflb_usb_set_fifo_epmap(USB_FIFO_F1, 1, USB_FIFO_DIR_BID);
  609. bflb_usb_set_fifo_epmap(USB_FIFO_F2, 2, USB_FIFO_DIR_BID);
  610. bflb_usb_set_fifo_epmap(USB_FIFO_F3, 2, USB_FIFO_DIR_BID);
  611. if (ep_idx == 1) {
  612. bflb_usb_fifo_config(USB_FIFO_F0, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 2, true);
  613. bflb_usb_fifo_config(USB_FIFO_F1, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 2, false);
  614. } else if (ep_idx == 2) {
  615. bflb_usb_fifo_config(USB_FIFO_F2, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 2, true);
  616. bflb_usb_fifo_config(USB_FIFO_F3, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 2, false);
  617. } else {
  618. return -1;
  619. }
  620. }
  621. #elif defined(CONFIG_USB_TRIPLE_ENABLE)
  622. if (USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize) > 512) {
  623. return -1;
  624. } else {
  625. bflb_usb_set_ep_fifomap(1, USB_FIFO_F0);
  626. bflb_usb_set_ep_fifomap(2, USB_FIFO_F3);
  627. bflb_usb_set_fifo_epmap(USB_FIFO_F0, 1, USB_FIFO_DIR_BID);
  628. bflb_usb_set_fifo_epmap(USB_FIFO_F1, 1, USB_FIFO_DIR_BID);
  629. bflb_usb_set_fifo_epmap(USB_FIFO_F2, 1, USB_FIFO_DIR_BID);
  630. bflb_usb_set_fifo_epmap(USB_FIFO_F3, 2, USB_FIFO_DIR_BID);
  631. if (ep_idx == 1) {
  632. bflb_usb_fifo_config(USB_FIFO_F0, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 3, true);
  633. bflb_usb_fifo_config(USB_FIFO_F1, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 3, false);
  634. bflb_usb_fifo_config(USB_FIFO_F2, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 3, false);
  635. } else if (ep_idx == 2) {
  636. bflb_usb_fifo_config(USB_FIFO_F3, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 1, true);
  637. } else {
  638. return -1;
  639. }
  640. }
  641. #endif
  642. regval = getreg32(BFLB_USB_BASE + USB_DEV_ADR_OFFSET);
  643. regval |= USB_AFT_CONF;
  644. putreg32(regval, BFLB_USB_BASE + USB_DEV_ADR_OFFSET);
  645. }
  646. return 0;
  647. }
  648. int usbd_ep_close(uint8_t busid, const uint8_t ep)
  649. {
  650. return 0;
  651. }
  652. int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
  653. {
  654. uint32_t regval;
  655. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  656. if (ep_idx == 0) {
  657. regval = getreg32(BFLB_USB_BASE + USB_DEV_CXCFE_OFFSET);
  658. regval |= USB_CX_STL;
  659. putreg32(regval, BFLB_USB_BASE + USB_DEV_CXCFE_OFFSET);
  660. } else {
  661. if (USB_EP_DIR_IS_OUT(ep)) {
  662. regval = getreg32(BFLB_USB_BASE + USB_DEV_OUTMPS1_OFFSET + (ep_idx - 1) * 4);
  663. regval |= USB_STL_OEP1;
  664. //regval |= USB_RSTG_OEP1;
  665. putreg32(regval, BFLB_USB_BASE + USB_DEV_OUTMPS1_OFFSET + (ep_idx - 1) * 4);
  666. } else {
  667. regval = getreg32(BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4);
  668. regval |= USB_STL_IEP1;
  669. //regval |= USB_RSTG_IEP1;
  670. putreg32(regval, BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4);
  671. }
  672. }
  673. return 0;
  674. }
  675. int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
  676. {
  677. uint32_t regval;
  678. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  679. if (ep_idx == 0) {
  680. } else {
  681. if (USB_EP_DIR_IS_OUT(ep)) {
  682. regval = getreg32(BFLB_USB_BASE + USB_DEV_OUTMPS1_OFFSET + (ep_idx - 1) * 4);
  683. //regval &= ~USB_RSTG_OEP1;
  684. regval &= ~USB_STL_OEP1;
  685. putreg32(regval, BFLB_USB_BASE + USB_DEV_OUTMPS1_OFFSET + (ep_idx - 1) * 4);
  686. } else {
  687. regval = getreg32(BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4);
  688. //regval &= ~USB_RSTG_IEP1;
  689. regval &= ~USB_STL_IEP1;
  690. putreg32(regval, BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4);
  691. }
  692. }
  693. return 0;
  694. }
  695. int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
  696. {
  697. uint32_t regval;
  698. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  699. if (ep_idx == 0) {
  700. } else {
  701. if (USB_EP_DIR_IS_OUT(ep)) {
  702. regval = getreg32(BFLB_USB_BASE + USB_DEV_OUTMPS1_OFFSET + (ep_idx - 1) * 4);
  703. if (regval & USB_STL_OEP1) {
  704. *stalled = 1;
  705. } else {
  706. *stalled = 0;
  707. }
  708. } else {
  709. regval = getreg32(BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4);
  710. if (regval & USB_STL_IEP1) {
  711. *stalled = 1;
  712. } else {
  713. *stalled = 0;
  714. }
  715. }
  716. }
  717. return 0;
  718. }
  719. int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
  720. {
  721. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  722. if (!data && data_len) {
  723. return -1;
  724. }
  725. if (!g_bl_udc.in_ep[ep_idx].ep_enable) {
  726. return -2;
  727. }
  728. g_bl_udc.in_ep[ep_idx].xfer_buf = (uint8_t *)data;
  729. g_bl_udc.in_ep[ep_idx].xfer_len = data_len;
  730. g_bl_udc.in_ep[ep_idx].actual_xfer_len = 0;
  731. g_bl_udc.in_ep[ep_idx].ep_active = true;
  732. if (ep_idx == 0) {
  733. if (data_len == 0) {
  734. g_bl_udc.in_ep[ep_idx].ep_active = false;
  735. bflb_usb_control_transfer_done();
  736. } else {
  737. data_len = MIN(data_len, g_bl_udc.in_ep[ep_idx].ep_mps);
  738. g_bl_udc.in_ep[ep_idx].xfer_len = data_len;
  739. bflb_usb_vdma_start_write(USB_FIFO_CXF, data, data_len);
  740. }
  741. } else {
  742. if (data_len == 0) {
  743. bflb_usb_send_zlp(ep_idx);
  744. } else {
  745. bflb_usb_vdma_start_write(usb_get_transfer_fifo(ep_idx), data, data_len);
  746. }
  747. }
  748. return 0;
  749. }
  750. int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
  751. {
  752. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  753. if (!data && data_len) {
  754. return -1;
  755. }
  756. if (!g_bl_udc.out_ep[ep_idx].ep_enable) {
  757. return -2;
  758. }
  759. if (data_len == 0) {
  760. return 0;
  761. }
  762. g_bl_udc.out_ep[ep_idx].xfer_buf = (uint8_t *)data;
  763. g_bl_udc.out_ep[ep_idx].xfer_len = data_len;
  764. g_bl_udc.out_ep[ep_idx].actual_xfer_len = 0;
  765. g_bl_udc.out_ep[ep_idx].ep_active = true;
  766. if (ep_idx == 0) {
  767. data_len = MIN(data_len, g_bl_udc.out_ep[ep_idx].ep_mps);
  768. g_bl_udc.out_ep[ep_idx].xfer_len = data_len;
  769. bflb_usb_vdma_start_read(USB_FIFO_CXF, data, data_len);
  770. } else {
  771. bflb_usb_vdma_start_read(usb_get_transfer_fifo(ep_idx), data, data_len);
  772. }
  773. return 0;
  774. }
  775. void USBD_IRQHandler(uint8_t busid)
  776. {
  777. uint32_t glb_intstatus;
  778. uint32_t dev_intstatus;
  779. uint32_t subgroup_intstatus;
  780. uint32_t regval;
  781. uint8_t ep_idx;
  782. glb_intstatus = getreg32(BFLB_USB_BASE + USB_GLB_ISR_OFFSET);
  783. if (glb_intstatus & USB_DEV_INT) {
  784. dev_intstatus = getreg32(BFLB_USB_BASE + USB_DEV_IGR_OFFSET);
  785. if (dev_intstatus & USB_INT_G0) {
  786. subgroup_intstatus = bflb_usb_get_source_group_intstatus(0);
  787. if (subgroup_intstatus & USB_CX_SETUP_INT) {
  788. bflb_usb_vdma_start_read(USB_FIFO_CXF, g_setup_buffer, 8);
  789. while (getreg32(BFLB_USB_BASE + USB_VDMA_CXFPS1_OFFSET) & USB_VDMA_START_CXF) {
  790. }
  791. bflb_usb_source_group_int_clear(3, USB_VDMA_CMPLT_CXF);
  792. usbd_event_ep0_setup_complete_handler(0, g_setup_buffer);
  793. }
  794. }
  795. if (dev_intstatus & USB_INT_G1) {
  796. }
  797. if (dev_intstatus & USB_INT_G2) {
  798. subgroup_intstatus = bflb_usb_get_source_group_intstatus(2);
  799. if (subgroup_intstatus & USB_SUSP_INT) {
  800. bflb_usb_source_group_int_clear(2, USB_SUSP_INT);
  801. bflb_usb_reset_fifo(USB_FIFO_F0);
  802. bflb_usb_reset_fifo(USB_FIFO_F1);
  803. bflb_usb_reset_fifo(USB_FIFO_F2);
  804. bflb_usb_reset_fifo(USB_FIFO_F3);
  805. bflb_usb_reset_fifo(USB_FIFO_CXF);
  806. usbd_event_suspend_handler(0);
  807. }
  808. if (subgroup_intstatus & USB_RESM_INT) {
  809. bflb_usb_source_group_int_clear(2, USB_RESM_INT);
  810. usbd_event_resume_handler(0);
  811. }
  812. if (subgroup_intstatus & USB_TX0BYTE_INT) {
  813. for (uint8_t i = 1; i < 5; i++) {
  814. if (bflb_usb_get_tx_zlp_intstatus() & (1 << (i - 1))) {
  815. bflb_usb_clear_tx_zlp_intstatus(i);
  816. usbd_event_ep_in_complete_handler(0, i | 0x80, 0);
  817. }
  818. }
  819. bflb_usb_source_group_int_clear(2, USB_TX0BYTE_INT);
  820. }
  821. if (subgroup_intstatus & USB_RX0BYTE_INT) {
  822. for (uint8_t i = 1; i < 5; i++) {
  823. if (bflb_usb_get_rx_zlp_intstatus() & (1 << (i - 1))) {
  824. bflb_usb_clear_rx_zlp_intstatus(i);
  825. usbd_event_ep_out_complete_handler(0, i, 0);
  826. }
  827. }
  828. bflb_usb_source_group_int_clear(2, USB_RX0BYTE_INT);
  829. }
  830. if (subgroup_intstatus & USBRST_INT) {
  831. bflb_usb_source_group_int_clear(2, USBRST_INT);
  832. bflb_usb_reset_fifo(USB_FIFO_F0);
  833. bflb_usb_reset_fifo(USB_FIFO_F1);
  834. bflb_usb_reset_fifo(USB_FIFO_F2);
  835. bflb_usb_reset_fifo(USB_FIFO_F3);
  836. bflb_usb_reset_fifo(USB_FIFO_CXF);
  837. regval = getreg32(BFLB_USB_BASE + USB_DEV_SMT_OFFSET);
  838. regval &= ~USB_SOFMT_MASK;
  839. #ifdef CONFIG_USB_HS
  840. regval |= USB_SOF_TIMER_MASK_AFTER_RESET_HS;
  841. #else
  842. regval |= USB_SOF_TIMER_MASK_AFTER_RESET_FS;
  843. #endif
  844. putreg32(regval, BFLB_USB_BASE + USB_DEV_SMT_OFFSET);
  845. memset(&g_bl_udc, 0, sizeof(g_bl_udc));
  846. usbd_event_reset_handler(0);
  847. }
  848. }
  849. if (dev_intstatus & USB_INT_G3) {
  850. subgroup_intstatus = bflb_usb_get_source_group_intstatus(3);
  851. bflb_usb_source_group_int_clear(3, subgroup_intstatus);
  852. if (subgroup_intstatus & USB_VDMA_CMPLT_CXF) {
  853. if (g_bl_udc.in_ep[0].ep_active) {
  854. g_bl_udc.in_ep[0].ep_active = false;
  855. g_bl_udc.in_ep[0].actual_xfer_len = g_bl_udc.in_ep[0].xfer_len - bflb_usb_vdma_get_remain_size(USB_FIFO_CXF);
  856. if (g_bl_udc.in_ep[0].actual_xfer_len < g_bl_udc.in_ep[0].ep_mps) {
  857. bflb_usb_control_transfer_done();
  858. }
  859. usbd_event_ep_in_complete_handler(0, 0x80, g_bl_udc.in_ep[0].actual_xfer_len);
  860. } else {
  861. g_bl_udc.out_ep[0].ep_active = false;
  862. g_bl_udc.out_ep[0].actual_xfer_len = g_bl_udc.out_ep[0].xfer_len - bflb_usb_vdma_get_remain_size(USB_FIFO_CXF);
  863. usbd_event_ep_out_complete_handler(0, 0x00, g_bl_udc.out_ep[0].actual_xfer_len);
  864. }
  865. }
  866. for (uint8_t i = 0; i < 4; i++) {
  867. if (subgroup_intstatus & (1 << (i + 1))) {
  868. ep_idx = bflb_usb_get_fifo_ep(i);
  869. if (g_bl_udc.in_ep[ep_idx].ep_active) {
  870. g_bl_udc.in_ep[ep_idx].ep_active = 0;
  871. g_bl_udc.in_ep[ep_idx].actual_xfer_len = g_bl_udc.in_ep[ep_idx].xfer_len - bflb_usb_vdma_get_remain_size(i);
  872. usbd_event_ep_in_complete_handler(0, ep_idx | 0x80, g_bl_udc.in_ep[ep_idx].actual_xfer_len);
  873. } else if (g_bl_udc.out_ep[ep_idx].ep_active) {
  874. g_bl_udc.out_ep[ep_idx].ep_active = 0;
  875. g_bl_udc.out_ep[ep_idx].actual_xfer_len = g_bl_udc.out_ep[ep_idx].xfer_len - bflb_usb_vdma_get_remain_size(i);
  876. usbd_event_ep_out_complete_handler(0, ep_idx & 0x7f, g_bl_udc.out_ep[ep_idx].actual_xfer_len);
  877. }
  878. }
  879. }
  880. }
  881. if (dev_intstatus & USB_INT_G4) {
  882. }
  883. }
  884. }
  885. #ifdef CONFIG_USBDEV_TEST_MODE
  886. void usbd_execute_test_mode(uint8_t busid, uint8_t test_mode)
  887. {
  888. uint32_t regval;
  889. switch (test_mode) {
  890. case 1: // Test_J
  891. {
  892. regval = getreg32(BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  893. regval |= USB_TST_JSTA;
  894. putreg32(regval, BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  895. bflb_usb_control_transfer_done();
  896. } break;
  897. case 2: // Test_K
  898. {
  899. regval = getreg32(BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  900. regval |= USB_TST_KSTA;
  901. putreg32(regval, BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  902. bflb_usb_control_transfer_done();
  903. } break;
  904. case 3: // TEST_SE0_NAK
  905. {
  906. regval = getreg32(BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  907. regval |= USB_TST_SE0NAK;
  908. putreg32(regval, BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  909. bflb_usb_control_transfer_done();
  910. } break;
  911. case 4: // Test_Packet
  912. {
  913. bflb_usb_control_transfer_done();
  914. regval = getreg32(BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  915. regval |= USB_TST_PKT;
  916. putreg32(regval, BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  917. __attribute__((aligned(32))) uint8_t temp[53];
  918. uint8_t *pp;
  919. uint8_t i;
  920. pp = temp;
  921. for (i = 0; i < 9; i++) /*JKJKJKJK x 9*/
  922. *pp++ = 0x00;
  923. for (i = 0; i < 8; i++) /* 8*AA */
  924. *pp++ = 0xAA;
  925. for (i = 0; i < 8; i++) /* 8*EE */
  926. *pp++ = 0xEE;
  927. *pp++ = 0xFE;
  928. for (i = 0; i < 11; i++) /* 11*FF */
  929. *pp++ = 0xFF;
  930. *pp++ = 0x7F;
  931. *pp++ = 0xBF;
  932. *pp++ = 0xDF;
  933. *pp++ = 0xEF;
  934. *pp++ = 0xF7;
  935. *pp++ = 0xFB;
  936. *pp++ = 0xFD;
  937. *pp++ = 0xFC;
  938. *pp++ = 0x7E;
  939. *pp++ = 0xBF;
  940. *pp++ = 0xDF;
  941. *pp++ = 0xEF;
  942. *pp++ = 0xF7;
  943. *pp++ = 0xFB;
  944. *pp++ = 0xFD;
  945. *pp++ = 0x7E;
  946. bflb_usb_vdma_start_write(USB_FIFO_CXF, temp, 53);
  947. regval = getreg32(BFLB_USB_BASE + USB_DEV_CXCFE_OFFSET);
  948. regval |= USB_TST_PKDONE;
  949. putreg32(regval, BFLB_USB_BASE + USB_DEV_CXCFE_OFFSET);
  950. } break;
  951. case 5: // Test_Force_Enable
  952. break;
  953. default:
  954. break;
  955. }
  956. }
  957. #endif