usb_dc_bl.c 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157
  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 device-A for device */
  379. regval = getreg32(BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  380. regval |= PDS_REG_USB_IDDIG;
  381. putreg32(regval, BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  382. /* disable global irq */
  383. regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  384. regval &= ~USB_GLINT_EN_HOV;
  385. putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  386. regval = getreg32(BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  387. regval |= USB_UNPLUG;
  388. putreg32(regval, BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  389. regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  390. regval &= ~USB_CAP_RMWAKUP;
  391. regval |= USB_CHIP_EN_HOV;
  392. putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  393. regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  394. regval |= USB_SFRST_HOV;
  395. #ifdef CONFIG_USB_HS
  396. regval &= ~USB_FORCE_FS;
  397. #else
  398. regval |= USB_FORCE_FS;
  399. #endif
  400. putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  401. while (getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET) & USB_SFRST_HOV) {
  402. }
  403. regval = getreg32(BFLB_USB_BASE + USB_DEV_ADR_OFFSET);
  404. regval &= ~USB_AFT_CONF;
  405. putreg32(regval, BFLB_USB_BASE + USB_DEV_ADR_OFFSET);
  406. regval = getreg32(BFLB_USB_BASE + USB_DEV_SMT_OFFSET);
  407. regval &= ~USB_SOFMT_MASK;
  408. #ifdef CONFIG_USB_HS
  409. regval |= USB_SOF_TIMER_MASK_AFTER_RESET_HS;
  410. #else
  411. regval |= USB_SOF_TIMER_MASK_AFTER_RESET_FS;
  412. #endif
  413. putreg32(regval, BFLB_USB_BASE + USB_DEV_SMT_OFFSET);
  414. /* enable setup irq in source group0 */
  415. regval = getreg32(BFLB_USB_BASE + USB_DEV_MISG0_OFFSET);
  416. regval &= ~USB_MCX_SETUP_INT;
  417. regval |= USB_MCX_IN_INT;
  418. regval |= (1 << 3);
  419. regval |= USB_MCX_OUT_INT;
  420. regval |= USB_MCX_IN_INT;
  421. regval |= USB_MCX_COMFAIL_INT;
  422. regval |= USB_MCX_COMABORT_INT;
  423. putreg32(regval, BFLB_USB_BASE + USB_DEV_MISG0_OFFSET);
  424. /* disable all fifo irq in source group1 */
  425. putreg32(0xffffffff, BFLB_USB_BASE + USB_DEV_MISG1_OFFSET);
  426. /* enable rst/tx0/rx0 irq in source group2 */
  427. regval = 0xffffffff;
  428. regval &= ~USB_MUSBRST_INT;
  429. regval &= ~USB_MSUSP_INT;
  430. regval &= ~USB_MRESM_INT;
  431. regval &= ~USB_MTX0BYTE_INT;
  432. regval &= ~USB_MRX0BYTE_INT;
  433. putreg32(regval, BFLB_USB_BASE + USB_DEV_MISG2_OFFSET);
  434. /* enable vdma cmplt and error irq in source group3 */
  435. regval = 0xffffffff;
  436. regval &= ~(USB_MVDMA_CMPLT_CXF |
  437. USB_MVDMA_CMPLT_F0 |
  438. USB_MVDMA_CMPLT_F1 |
  439. USB_MVDMA_CMPLT_F2 |
  440. USB_MVDMA_CMPLT_F3);
  441. // regval &= ~(USB_MVDMA_ERROR_CXF |
  442. // USB_MVDMA_ERROR_F0 |
  443. // USB_MVDMA_ERROR_F1 |
  444. // USB_MVDMA_ERROR_F2 |
  445. // USB_MVDMA_ERROR_F3);
  446. putreg32(regval, BFLB_USB_BASE + USB_DEV_MISG3_OFFSET);
  447. /* enable group irq */
  448. regval = getreg32(BFLB_USB_BASE + USB_DEV_MIGR_OFFSET);
  449. regval &= ~USB_MINT_G0;
  450. regval &= ~USB_MINT_G1;
  451. regval &= ~USB_MINT_G2;
  452. regval &= ~USB_MINT_G3;
  453. regval &= ~USB_MINT_G4;
  454. putreg32(regval, BFLB_USB_BASE + USB_DEV_MIGR_OFFSET);
  455. /* enable device irq */
  456. regval = getreg32(BFLB_USB_BASE + USB_GLB_INT_OFFSET);
  457. regval |= USB_MHC_INT;
  458. regval |= USB_MOTG_INT;
  459. regval &= ~USB_MDEV_INT;
  460. putreg32(regval, BFLB_USB_BASE + USB_GLB_INT_OFFSET);
  461. bflb_usb_source_group_int_clear(2, 0x3ff);
  462. bflb_usb_source_group_int_clear(3, 0xffffffff);
  463. for (uint8_t i = 1; i < 9; i++) {
  464. bflb_usb_set_ep_fifomap(i, 15);
  465. bflb_usb_set_fifo_epmap(i, 15, 0);
  466. }
  467. /* enable vdma */
  468. regval = getreg32(BFLB_USB_BASE + USB_VDMA_CTRL_OFFSET);
  469. regval |= USB_VDMA_EN;
  470. putreg32(regval, BFLB_USB_BASE + USB_VDMA_CTRL_OFFSET);
  471. regval = getreg32(BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  472. regval &= ~USB_UNPLUG;
  473. putreg32(regval, BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  474. /* enable 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. return 0;
  479. }
  480. int usb_dc_deinit(uint8_t busid)
  481. {
  482. uint32_t regval;
  483. /* disable global irq */
  484. regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  485. regval &= ~USB_GLINT_EN_HOV;
  486. putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  487. regval = getreg32(BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  488. regval |= USB_UNPLUG;
  489. putreg32(regval, BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  490. regval = getreg32(BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  491. regval &= ~PDS_REG_USB_PHY_XTLSEL_MASK;
  492. putreg32(regval, BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  493. regval = getreg32(BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  494. regval &= ~PDS_REG_PU_USB20_PSW;
  495. putreg32(regval, BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  496. regval = getreg32(BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  497. regval &= ~PDS_REG_USB_PHY_PONRST;
  498. putreg32(regval, BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  499. regval = getreg32(BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  500. regval &= ~PDS_REG_USB_EXT_SUSP_N;
  501. putreg32(regval, BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  502. return 0;
  503. }
  504. int usbd_set_address(uint8_t busid, const uint8_t addr)
  505. {
  506. uint32_t regval;
  507. regval = getreg32(BFLB_USB_BASE + USB_DEV_ADR_OFFSET);
  508. regval &= ~USB_DEVADR_MASK;
  509. regval |= addr;
  510. putreg32(regval, BFLB_USB_BASE + USB_DEV_ADR_OFFSET);
  511. return 0;
  512. }
  513. int usbd_set_remote_wakeup(uint8_t busid)
  514. {
  515. uint32_t regval;
  516. regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  517. regval |= USB_CAP_RMWAKUP;
  518. putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  519. bflb_mtimer_delay_ms(10);
  520. regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  521. regval &= ~USB_CAP_RMWAKUP;
  522. putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET);
  523. return 0;
  524. }
  525. uint8_t usbd_get_port_speed(uint8_t busid)
  526. {
  527. uint8_t speed = 3;
  528. speed = (getreg32(BFLB_USB_BASE + USB_OTG_CSR_OFFSET) & USB_SPD_TYP_HOV_POV_MASK) >> USB_SPD_TYP_HOV_POV_SHIFT;
  529. if (speed == 0) {
  530. return USB_SPEED_FULL;
  531. } else if (speed == 1) {
  532. return USB_SPEED_LOW;
  533. } else if (speed == 2) {
  534. return USB_SPEED_HIGH;
  535. }
  536. return USB_SPEED_HIGH;
  537. }
  538. int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
  539. {
  540. uint8_t ep_addr;
  541. uint32_t regval;
  542. ep_addr = ep->bEndpointAddress;
  543. uint8_t ep_idx = USB_EP_GET_IDX(ep_addr);
  544. if (ep_idx > 4) {
  545. return 0;
  546. }
  547. if (USB_EP_DIR_IS_OUT(ep_addr)) {
  548. g_bl_udc.out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
  549. g_bl_udc.out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
  550. g_bl_udc.out_ep[ep_idx].ep_enable = 1U;
  551. bflb_usb_set_outep_mps(ep_idx, USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize));
  552. } else {
  553. g_bl_udc.in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
  554. g_bl_udc.in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
  555. g_bl_udc.in_ep[ep_idx].ep_enable = 1U;
  556. bflb_usb_set_inep_mps(ep_idx, USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize));
  557. bflb_usb_set_mult(ep_idx, 0);
  558. }
  559. if (ep_idx != 0) {
  560. #if !defined(CONFIG_USB_PINGPONG_ENABLE) && !defined(CONFIG_USB_TRIPLE_ENABLE)
  561. if (USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize) > 512) {
  562. bflb_usb_set_ep_fifomap(1, USB_FIFO_F0);
  563. bflb_usb_set_ep_fifomap(2, USB_FIFO_F2);
  564. bflb_usb_set_fifo_epmap(USB_FIFO_F0, 1, USB_FIFO_DIR_BID);
  565. bflb_usb_set_fifo_epmap(USB_FIFO_F1, 1, USB_FIFO_DIR_BID);
  566. bflb_usb_set_fifo_epmap(USB_FIFO_F2, 2, USB_FIFO_DIR_BID);
  567. bflb_usb_set_fifo_epmap(USB_FIFO_F3, 2, USB_FIFO_DIR_BID);
  568. if (ep_idx == 1) {
  569. bflb_usb_fifo_config(USB_FIFO_F0, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 1024, 1, true);
  570. bflb_usb_fifo_config(USB_FIFO_F1, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 1024, 1, false);
  571. } else if (ep_idx == 2) {
  572. bflb_usb_fifo_config(USB_FIFO_F2, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 1024, 1, true);
  573. bflb_usb_fifo_config(USB_FIFO_F3, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 1024, 1, false);
  574. } else {
  575. return -1;
  576. }
  577. } else {
  578. bflb_usb_set_ep_fifomap(1, USB_FIFO_F0);
  579. bflb_usb_set_ep_fifomap(2, USB_FIFO_F1);
  580. bflb_usb_set_ep_fifomap(3, USB_FIFO_F2);
  581. bflb_usb_set_ep_fifomap(4, USB_FIFO_F3);
  582. bflb_usb_set_fifo_epmap(USB_FIFO_F0, 1, USB_FIFO_DIR_BID);
  583. bflb_usb_set_fifo_epmap(USB_FIFO_F1, 2, USB_FIFO_DIR_BID);
  584. bflb_usb_set_fifo_epmap(USB_FIFO_F2, 3, USB_FIFO_DIR_BID);
  585. bflb_usb_set_fifo_epmap(USB_FIFO_F3, 4, USB_FIFO_DIR_BID);
  586. if (ep_idx == 1) {
  587. bflb_usb_fifo_config(USB_FIFO_F0, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 1, true);
  588. } else if (ep_idx == 2) {
  589. bflb_usb_fifo_config(USB_FIFO_F1, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 1, true);
  590. } else if (ep_idx == 3) {
  591. bflb_usb_fifo_config(USB_FIFO_F2, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 1, true);
  592. } else if (ep_idx == 4) {
  593. bflb_usb_fifo_config(USB_FIFO_F3, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 1, true);
  594. } else {
  595. return -1;
  596. }
  597. }
  598. #elif defined(CONFIG_USB_PINGPONG_ENABLE)
  599. if (USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize) > 512) {
  600. bflb_usb_set_ep_fifomap(1, USB_FIFO_F0);
  601. bflb_usb_set_fifo_epmap(USB_FIFO_F0, 1, USB_FIFO_DIR_BID);
  602. bflb_usb_set_fifo_epmap(USB_FIFO_F1, 1, USB_FIFO_DIR_BID);
  603. bflb_usb_set_fifo_epmap(USB_FIFO_F2, 1, USB_FIFO_DIR_BID);
  604. bflb_usb_set_fifo_epmap(USB_FIFO_F3, 1, USB_FIFO_DIR_BID);
  605. if (ep_idx == 1) {
  606. bflb_usb_fifo_config(USB_FIFO_F0, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 1024, 2, true);
  607. bflb_usb_fifo_config(USB_FIFO_F1, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 1024, 2, false);
  608. bflb_usb_fifo_config(USB_FIFO_F2, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 1024, 2, false);
  609. bflb_usb_fifo_config(USB_FIFO_F3, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 1024, 2, false);
  610. } else {
  611. return -1;
  612. }
  613. } else {
  614. bflb_usb_set_ep_fifomap(1, USB_FIFO_F0);
  615. bflb_usb_set_ep_fifomap(2, USB_FIFO_F2);
  616. bflb_usb_set_fifo_epmap(USB_FIFO_F0, 1, USB_FIFO_DIR_BID);
  617. bflb_usb_set_fifo_epmap(USB_FIFO_F1, 1, USB_FIFO_DIR_BID);
  618. bflb_usb_set_fifo_epmap(USB_FIFO_F2, 2, USB_FIFO_DIR_BID);
  619. bflb_usb_set_fifo_epmap(USB_FIFO_F3, 2, USB_FIFO_DIR_BID);
  620. if (ep_idx == 1) {
  621. bflb_usb_fifo_config(USB_FIFO_F0, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 2, true);
  622. bflb_usb_fifo_config(USB_FIFO_F1, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 2, false);
  623. } else if (ep_idx == 2) {
  624. bflb_usb_fifo_config(USB_FIFO_F2, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 2, true);
  625. bflb_usb_fifo_config(USB_FIFO_F3, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 2, false);
  626. } else {
  627. return -1;
  628. }
  629. }
  630. #elif defined(CONFIG_USB_TRIPLE_ENABLE)
  631. if (USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize) > 512) {
  632. return -1;
  633. } else {
  634. bflb_usb_set_ep_fifomap(1, USB_FIFO_F0);
  635. bflb_usb_set_ep_fifomap(2, USB_FIFO_F3);
  636. bflb_usb_set_fifo_epmap(USB_FIFO_F0, 1, USB_FIFO_DIR_BID);
  637. bflb_usb_set_fifo_epmap(USB_FIFO_F1, 1, USB_FIFO_DIR_BID);
  638. bflb_usb_set_fifo_epmap(USB_FIFO_F2, 1, USB_FIFO_DIR_BID);
  639. bflb_usb_set_fifo_epmap(USB_FIFO_F3, 2, USB_FIFO_DIR_BID);
  640. if (ep_idx == 1) {
  641. bflb_usb_fifo_config(USB_FIFO_F0, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 3, true);
  642. bflb_usb_fifo_config(USB_FIFO_F1, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 3, false);
  643. bflb_usb_fifo_config(USB_FIFO_F2, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 3, false);
  644. } else if (ep_idx == 2) {
  645. bflb_usb_fifo_config(USB_FIFO_F3, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), 512, 1, true);
  646. } else {
  647. return -1;
  648. }
  649. }
  650. #endif
  651. regval = getreg32(BFLB_USB_BASE + USB_DEV_ADR_OFFSET);
  652. regval |= USB_AFT_CONF;
  653. putreg32(regval, BFLB_USB_BASE + USB_DEV_ADR_OFFSET);
  654. }
  655. return 0;
  656. }
  657. int usbd_ep_close(uint8_t busid, const uint8_t ep)
  658. {
  659. return 0;
  660. }
  661. int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
  662. {
  663. uint32_t regval;
  664. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  665. if (ep_idx == 0) {
  666. regval = getreg32(BFLB_USB_BASE + USB_DEV_CXCFE_OFFSET);
  667. regval |= USB_CX_STL;
  668. putreg32(regval, BFLB_USB_BASE + USB_DEV_CXCFE_OFFSET);
  669. } else {
  670. if (USB_EP_DIR_IS_OUT(ep)) {
  671. regval = getreg32(BFLB_USB_BASE + USB_DEV_OUTMPS1_OFFSET + (ep_idx - 1) * 4);
  672. regval |= USB_STL_OEP1;
  673. //regval |= USB_RSTG_OEP1;
  674. putreg32(regval, BFLB_USB_BASE + USB_DEV_OUTMPS1_OFFSET + (ep_idx - 1) * 4);
  675. } else {
  676. regval = getreg32(BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4);
  677. regval |= USB_STL_IEP1;
  678. //regval |= USB_RSTG_IEP1;
  679. putreg32(regval, BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4);
  680. }
  681. }
  682. return 0;
  683. }
  684. int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
  685. {
  686. uint32_t regval;
  687. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  688. if (ep_idx == 0) {
  689. } else {
  690. if (USB_EP_DIR_IS_OUT(ep)) {
  691. regval = getreg32(BFLB_USB_BASE + USB_DEV_OUTMPS1_OFFSET + (ep_idx - 1) * 4);
  692. //regval &= ~USB_RSTG_OEP1;
  693. regval &= ~USB_STL_OEP1;
  694. putreg32(regval, BFLB_USB_BASE + USB_DEV_OUTMPS1_OFFSET + (ep_idx - 1) * 4);
  695. } else {
  696. regval = getreg32(BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4);
  697. //regval &= ~USB_RSTG_IEP1;
  698. regval &= ~USB_STL_IEP1;
  699. putreg32(regval, BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4);
  700. }
  701. }
  702. return 0;
  703. }
  704. int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
  705. {
  706. uint32_t regval;
  707. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  708. if (ep_idx == 0) {
  709. } else {
  710. if (USB_EP_DIR_IS_OUT(ep)) {
  711. regval = getreg32(BFLB_USB_BASE + USB_DEV_OUTMPS1_OFFSET + (ep_idx - 1) * 4);
  712. if (regval & USB_STL_OEP1) {
  713. *stalled = 1;
  714. } else {
  715. *stalled = 0;
  716. }
  717. } else {
  718. regval = getreg32(BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4);
  719. if (regval & USB_STL_IEP1) {
  720. *stalled = 1;
  721. } else {
  722. *stalled = 0;
  723. }
  724. }
  725. }
  726. return 0;
  727. }
  728. int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
  729. {
  730. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  731. if (!data && data_len) {
  732. return -1;
  733. }
  734. if (!g_bl_udc.in_ep[ep_idx].ep_enable) {
  735. return -2;
  736. }
  737. g_bl_udc.in_ep[ep_idx].xfer_buf = (uint8_t *)data;
  738. g_bl_udc.in_ep[ep_idx].xfer_len = data_len;
  739. g_bl_udc.in_ep[ep_idx].actual_xfer_len = 0;
  740. g_bl_udc.in_ep[ep_idx].ep_active = true;
  741. if (ep_idx == 0) {
  742. if (data_len == 0) {
  743. g_bl_udc.in_ep[ep_idx].ep_active = false;
  744. bflb_usb_control_transfer_done();
  745. } else {
  746. data_len = MIN(data_len, g_bl_udc.in_ep[ep_idx].ep_mps);
  747. g_bl_udc.in_ep[ep_idx].xfer_len = data_len;
  748. bflb_usb_vdma_start_write(USB_FIFO_CXF, data, data_len);
  749. }
  750. } else {
  751. if (data_len == 0) {
  752. bflb_usb_send_zlp(ep_idx);
  753. } else {
  754. bflb_usb_vdma_start_write(usb_get_transfer_fifo(ep_idx), data, data_len);
  755. }
  756. }
  757. return 0;
  758. }
  759. int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
  760. {
  761. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  762. if (!data && data_len) {
  763. return -1;
  764. }
  765. if (!g_bl_udc.out_ep[ep_idx].ep_enable) {
  766. return -2;
  767. }
  768. if (data_len == 0) {
  769. return 0;
  770. }
  771. g_bl_udc.out_ep[ep_idx].xfer_buf = (uint8_t *)data;
  772. g_bl_udc.out_ep[ep_idx].xfer_len = data_len;
  773. g_bl_udc.out_ep[ep_idx].actual_xfer_len = 0;
  774. g_bl_udc.out_ep[ep_idx].ep_active = true;
  775. if (ep_idx == 0) {
  776. data_len = MIN(data_len, g_bl_udc.out_ep[ep_idx].ep_mps);
  777. g_bl_udc.out_ep[ep_idx].xfer_len = data_len;
  778. bflb_usb_vdma_start_read(USB_FIFO_CXF, data, data_len);
  779. } else {
  780. bflb_usb_vdma_start_read(usb_get_transfer_fifo(ep_idx), data, data_len);
  781. }
  782. return 0;
  783. }
  784. void USBD_IRQHandler(uint8_t busid)
  785. {
  786. uint32_t glb_intstatus;
  787. uint32_t dev_intstatus;
  788. uint32_t subgroup_intstatus;
  789. uint32_t regval;
  790. uint8_t ep_idx;
  791. glb_intstatus = getreg32(BFLB_USB_BASE + USB_GLB_ISR_OFFSET);
  792. if (glb_intstatus & USB_DEV_INT) {
  793. dev_intstatus = getreg32(BFLB_USB_BASE + USB_DEV_IGR_OFFSET);
  794. if (dev_intstatus & USB_INT_G0) {
  795. subgroup_intstatus = bflb_usb_get_source_group_intstatus(0);
  796. if (subgroup_intstatus & USB_CX_SETUP_INT) {
  797. bflb_usb_vdma_start_read(USB_FIFO_CXF, g_setup_buffer, 8);
  798. while (getreg32(BFLB_USB_BASE + USB_VDMA_CXFPS1_OFFSET) & USB_VDMA_START_CXF) {
  799. }
  800. bflb_usb_source_group_int_clear(3, USB_VDMA_CMPLT_CXF);
  801. usbd_event_ep0_setup_complete_handler(0, g_setup_buffer);
  802. }
  803. }
  804. if (dev_intstatus & USB_INT_G1) {
  805. }
  806. if (dev_intstatus & USB_INT_G2) {
  807. subgroup_intstatus = bflb_usb_get_source_group_intstatus(2);
  808. if (subgroup_intstatus & USB_SUSP_INT) {
  809. bflb_usb_source_group_int_clear(2, USB_SUSP_INT);
  810. bflb_usb_reset_fifo(USB_FIFO_F0);
  811. bflb_usb_reset_fifo(USB_FIFO_F1);
  812. bflb_usb_reset_fifo(USB_FIFO_F2);
  813. bflb_usb_reset_fifo(USB_FIFO_F3);
  814. bflb_usb_reset_fifo(USB_FIFO_CXF);
  815. usbd_event_suspend_handler(0);
  816. }
  817. if (subgroup_intstatus & USB_RESM_INT) {
  818. bflb_usb_source_group_int_clear(2, USB_RESM_INT);
  819. usbd_event_resume_handler(0);
  820. }
  821. if (subgroup_intstatus & USB_TX0BYTE_INT) {
  822. for (uint8_t i = 1; i < 5; i++) {
  823. if (bflb_usb_get_tx_zlp_intstatus() & (1 << (i - 1))) {
  824. bflb_usb_clear_tx_zlp_intstatus(i);
  825. usbd_event_ep_in_complete_handler(0, i | 0x80, 0);
  826. }
  827. }
  828. bflb_usb_source_group_int_clear(2, USB_TX0BYTE_INT);
  829. }
  830. if (subgroup_intstatus & USB_RX0BYTE_INT) {
  831. for (uint8_t i = 1; i < 5; i++) {
  832. if (bflb_usb_get_rx_zlp_intstatus() & (1 << (i - 1))) {
  833. bflb_usb_clear_rx_zlp_intstatus(i);
  834. usbd_event_ep_out_complete_handler(0, i, 0);
  835. }
  836. }
  837. bflb_usb_source_group_int_clear(2, USB_RX0BYTE_INT);
  838. }
  839. if (subgroup_intstatus & USBRST_INT) {
  840. bflb_usb_source_group_int_clear(2, USBRST_INT);
  841. bflb_usb_reset_fifo(USB_FIFO_F0);
  842. bflb_usb_reset_fifo(USB_FIFO_F1);
  843. bflb_usb_reset_fifo(USB_FIFO_F2);
  844. bflb_usb_reset_fifo(USB_FIFO_F3);
  845. bflb_usb_reset_fifo(USB_FIFO_CXF);
  846. regval = getreg32(BFLB_USB_BASE + USB_DEV_SMT_OFFSET);
  847. regval &= ~USB_SOFMT_MASK;
  848. #ifdef CONFIG_USB_HS
  849. regval |= USB_SOF_TIMER_MASK_AFTER_RESET_HS;
  850. #else
  851. regval |= USB_SOF_TIMER_MASK_AFTER_RESET_FS;
  852. #endif
  853. putreg32(regval, BFLB_USB_BASE + USB_DEV_SMT_OFFSET);
  854. memset(&g_bl_udc, 0, sizeof(g_bl_udc));
  855. usbd_event_reset_handler(0);
  856. }
  857. }
  858. if (dev_intstatus & USB_INT_G3) {
  859. subgroup_intstatus = bflb_usb_get_source_group_intstatus(3);
  860. bflb_usb_source_group_int_clear(3, subgroup_intstatus);
  861. if (subgroup_intstatus & USB_VDMA_CMPLT_CXF) {
  862. if (g_bl_udc.in_ep[0].ep_active) {
  863. g_bl_udc.in_ep[0].ep_active = false;
  864. 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);
  865. if (g_bl_udc.in_ep[0].actual_xfer_len < g_bl_udc.in_ep[0].ep_mps) {
  866. bflb_usb_control_transfer_done();
  867. }
  868. usbd_event_ep_in_complete_handler(0, 0x80, g_bl_udc.in_ep[0].actual_xfer_len);
  869. } else {
  870. g_bl_udc.out_ep[0].ep_active = false;
  871. 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);
  872. usbd_event_ep_out_complete_handler(0, 0x00, g_bl_udc.out_ep[0].actual_xfer_len);
  873. }
  874. }
  875. for (uint8_t i = 0; i < 4; i++) {
  876. if (subgroup_intstatus & (1 << (i + 1))) {
  877. ep_idx = bflb_usb_get_fifo_ep(i);
  878. if (g_bl_udc.in_ep[ep_idx].ep_active) {
  879. g_bl_udc.in_ep[ep_idx].ep_active = 0;
  880. 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);
  881. usbd_event_ep_in_complete_handler(0, ep_idx | 0x80, g_bl_udc.in_ep[ep_idx].actual_xfer_len);
  882. } else if (g_bl_udc.out_ep[ep_idx].ep_active) {
  883. g_bl_udc.out_ep[ep_idx].ep_active = 0;
  884. 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);
  885. usbd_event_ep_out_complete_handler(0, ep_idx & 0x7f, g_bl_udc.out_ep[ep_idx].actual_xfer_len);
  886. }
  887. }
  888. }
  889. }
  890. if (dev_intstatus & USB_INT_G4) {
  891. }
  892. }
  893. }
  894. #ifdef CONFIG_USBDEV_TEST_MODE
  895. void usbd_execute_test_mode(uint8_t busid, uint8_t test_mode)
  896. {
  897. uint32_t regval;
  898. switch (test_mode) {
  899. case 1: // Test_J
  900. {
  901. regval = getreg32(BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  902. regval |= USB_TST_JSTA;
  903. putreg32(regval, BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  904. bflb_usb_control_transfer_done();
  905. } break;
  906. case 2: // Test_K
  907. {
  908. regval = getreg32(BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  909. regval |= USB_TST_KSTA;
  910. putreg32(regval, BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  911. bflb_usb_control_transfer_done();
  912. } break;
  913. case 3: // TEST_SE0_NAK
  914. {
  915. regval = getreg32(BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  916. regval |= USB_TST_SE0NAK;
  917. putreg32(regval, BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  918. bflb_usb_control_transfer_done();
  919. } break;
  920. case 4: // Test_Packet
  921. {
  922. bflb_usb_control_transfer_done();
  923. regval = getreg32(BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  924. regval |= USB_TST_PKT;
  925. putreg32(regval, BFLB_USB_BASE + USB_PHY_TST_OFFSET);
  926. __attribute__((aligned(32))) uint8_t temp[53];
  927. uint8_t *pp;
  928. uint8_t i;
  929. pp = temp;
  930. for (i = 0; i < 9; i++) /*JKJKJKJK x 9*/
  931. *pp++ = 0x00;
  932. for (i = 0; i < 8; i++) /* 8*AA */
  933. *pp++ = 0xAA;
  934. for (i = 0; i < 8; i++) /* 8*EE */
  935. *pp++ = 0xEE;
  936. *pp++ = 0xFE;
  937. for (i = 0; i < 11; i++) /* 11*FF */
  938. *pp++ = 0xFF;
  939. *pp++ = 0x7F;
  940. *pp++ = 0xBF;
  941. *pp++ = 0xDF;
  942. *pp++ = 0xEF;
  943. *pp++ = 0xF7;
  944. *pp++ = 0xFB;
  945. *pp++ = 0xFD;
  946. *pp++ = 0xFC;
  947. *pp++ = 0x7E;
  948. *pp++ = 0xBF;
  949. *pp++ = 0xDF;
  950. *pp++ = 0xEF;
  951. *pp++ = 0xF7;
  952. *pp++ = 0xFB;
  953. *pp++ = 0xFD;
  954. *pp++ = 0x7E;
  955. bflb_usb_vdma_start_write(USB_FIFO_CXF, temp, 53);
  956. regval = getreg32(BFLB_USB_BASE + USB_DEV_CXCFE_OFFSET);
  957. regval |= USB_TST_PKDONE;
  958. putreg32(regval, BFLB_USB_BASE + USB_DEV_CXCFE_OFFSET);
  959. } break;
  960. case 5: // Test_Force_Enable
  961. break;
  962. default:
  963. break;
  964. }
  965. }
  966. #endif