usb_hc_dwc2.c 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133
  1. /*
  2. * Copyright (c) 2022, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "usbh_core.h"
  7. #include "usbh_hub.h"
  8. #include "usb_dwc2_reg.h"
  9. #ifndef CONFIG_USBHOST_PIPE_NUM
  10. #define CONFIG_USBHOST_PIPE_NUM 12
  11. #endif
  12. /* largest non-periodic USB packet used / 4 */
  13. #ifndef CONFIG_USB_DWC2_NPTX_FIFO_SIZE
  14. #define CONFIG_USB_DWC2_NPTX_FIFO_SIZE (512 / 4)
  15. #endif
  16. /* largest periodic USB packet used / 4 */
  17. #ifndef CONFIG_USB_DWC2_PTX_FIFO_SIZE
  18. #define CONFIG_USB_DWC2_PTX_FIFO_SIZE (1024 / 4)
  19. #endif
  20. /*
  21. * (largest USB packet used / 4) + 1 for status information + 1 transfer complete +
  22. * 1 location each for Bulk/Control endpoint for handling NAK/NYET scenario
  23. */
  24. #ifndef CONFIG_USB_DWC2_RX_FIFO_SIZE
  25. #define CONFIG_USB_DWC2_RX_FIFO_SIZE ((1012 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE) / 4)
  26. #endif
  27. #define USB_OTG_GLB ((DWC2_GlobalTypeDef *)(bus->hcd.reg_base))
  28. #define USB_OTG_PCGCCTL *(__IO uint32_t *)((uint32_t)bus->hcd.reg_base + USB_OTG_PCGCCTL_BASE)
  29. #define USB_OTG_HPRT *(__IO uint32_t *)((uint32_t)bus->hcd.reg_base + USB_OTG_HOST_PORT_BASE)
  30. #define USB_OTG_HOST ((DWC2_HostTypeDef *)(bus->hcd.reg_base + USB_OTG_HOST_BASE))
  31. #define USB_OTG_HC(i) ((DWC2_HostChannelTypeDef *)(bus->hcd.reg_base + USB_OTG_HOST_CHANNEL_BASE + ((i)*USB_OTG_HOST_CHANNEL_SIZE)))
  32. struct dwc2_chan {
  33. uint8_t ep0_state;
  34. uint16_t num_packets;
  35. uint32_t xferlen;
  36. uint8_t chidx;
  37. bool inuse;
  38. usb_osal_sem_t waitsem;
  39. struct usbh_urb *urb;
  40. uint32_t iso_frame_idx;
  41. };
  42. struct dwc2_hcd {
  43. volatile bool port_csc;
  44. volatile bool port_pec;
  45. volatile bool port_occ;
  46. struct dwc2_chan chan_pool[CONFIG_USBHOST_PIPE_NUM];
  47. } g_dwc2_hcd[CONFIG_USBHOST_MAX_BUS];
  48. #define DWC2_EP0_STATE_SETUP 0
  49. #define DWC2_EP0_STATE_INDATA 1
  50. #define DWC2_EP0_STATE_OUTDATA 2
  51. #define DWC2_EP0_STATE_INSTATUS 3
  52. #define DWC2_EP0_STATE_OUTSTATUS 4
  53. static inline int dwc2_reset(struct usbh_bus *bus)
  54. {
  55. volatile uint32_t count = 0U;
  56. /* Wait for AHB master IDLE state. */
  57. do {
  58. if (++count > 200000U) {
  59. return -1;
  60. }
  61. } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
  62. /* Core Soft Reset */
  63. count = 0U;
  64. USB_OTG_GLB->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
  65. do {
  66. if (++count > 200000U) {
  67. return -1;
  68. }
  69. } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
  70. return 0;
  71. }
  72. static inline int dwc2_core_init(struct usbh_bus *bus)
  73. {
  74. int ret;
  75. #if defined(CONFIG_USB_HS)
  76. /* Init The ULPI Interface */
  77. USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
  78. /* Select vbus source */
  79. USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
  80. //USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
  81. /* Reset after a PHY select */
  82. ret = dwc2_reset(bus);
  83. #else
  84. /* Select FS Embedded PHY */
  85. USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
  86. /* Reset after a PHY select */
  87. ret = dwc2_reset(bus);
  88. #endif
  89. return ret;
  90. }
  91. static inline void dwc2_set_mode(struct usbh_bus *bus, uint8_t mode)
  92. {
  93. USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
  94. if (mode == USB_OTG_MODE_HOST) {
  95. USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
  96. } else if (mode == USB_OTG_MODE_DEVICE) {
  97. USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
  98. }
  99. usb_osal_msleep(50);
  100. }
  101. static inline int dwc2_flush_rxfifo(struct usbh_bus *bus)
  102. {
  103. volatile uint32_t count = 0U;
  104. /* Wait for AHB master IDLE state. */
  105. do {
  106. if (++count > 200000U) {
  107. return -1;
  108. }
  109. } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
  110. count = 0;
  111. USB_OTG_GLB->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
  112. do {
  113. if (++count > 200000U) {
  114. return -1;
  115. }
  116. } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
  117. return 0;
  118. }
  119. static inline int dwc2_flush_txfifo(struct usbh_bus *bus, uint32_t num)
  120. {
  121. volatile uint32_t count = 0U;
  122. /* Wait for AHB master IDLE state. */
  123. do {
  124. if (++count > 200000U) {
  125. return -1;
  126. }
  127. } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
  128. count = 0;
  129. USB_OTG_GLB->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
  130. do {
  131. if (++count > 200000U) {
  132. return -1;
  133. }
  134. } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
  135. return 0;
  136. }
  137. static inline void dwc2_drivebus(struct usbh_bus *bus, uint8_t state)
  138. {
  139. __IO uint32_t hprt0 = 0U;
  140. hprt0 = USB_OTG_HPRT;
  141. hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
  142. USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
  143. if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U)) {
  144. USB_OTG_HPRT = (USB_OTG_HPRT_PPWR | hprt0);
  145. }
  146. if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U)) {
  147. USB_OTG_HPRT = ((~USB_OTG_HPRT_PPWR) & hprt0);
  148. }
  149. }
  150. static inline uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
  151. {
  152. __IO uint32_t hprt0 = 0U;
  153. uint8_t speed;
  154. hprt0 = USB_OTG_HPRT;
  155. speed = (hprt0 & USB_OTG_HPRT_PSPD) >> 17;
  156. if (speed == HPRT0_PRTSPD_HIGH_SPEED) {
  157. return USB_SPEED_HIGH;
  158. } else if (speed == HPRT0_PRTSPD_FULL_SPEED) {
  159. return USB_SPEED_FULL;
  160. } else if (speed == HPRT0_PRTSPD_LOW_SPEED) {
  161. return USB_SPEED_LOW;
  162. } else {
  163. return USB_SPEED_UNKNOWN;
  164. }
  165. }
  166. static inline void dwc2_chan_char_init(struct usbh_bus *bus, uint8_t ch_num, uint8_t devaddr, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps, uint8_t speed)
  167. {
  168. uint32_t regval;
  169. /* Program the HCCHAR register */
  170. regval = (((uint32_t)ep_mps << USB_OTG_HCCHAR_MPSIZ_Pos) & USB_OTG_HCCHAR_MPSIZ) |
  171. ((((uint32_t)ep_addr & 0x7FU) << USB_OTG_HCCHAR_EPNUM_Pos) & USB_OTG_HCCHAR_EPNUM) |
  172. (((uint32_t)ep_type << USB_OTG_HCCHAR_EPTYP_Pos) & USB_OTG_HCCHAR_EPTYP) |
  173. (((uint32_t)devaddr << USB_OTG_HCCHAR_DAD_Pos) & USB_OTG_HCCHAR_DAD);
  174. if ((ep_addr & 0x80U) == 0x80U) {
  175. regval |= USB_OTG_HCCHAR_EPDIR;
  176. }
  177. /* LS device plugged to HUB */
  178. if ((speed == USB_SPEED_LOW) && (usbh_get_port_speed(bus, 0) != USB_SPEED_LOW)) {
  179. regval |= USB_OTG_HCCHAR_LSDEV;
  180. }
  181. if (ep_type == USB_ENDPOINT_TYPE_INTERRUPT) {
  182. regval |= USB_OTG_HCCHAR_ODDFRM;
  183. }
  184. USB_OTG_HC((uint32_t)ch_num)->HCCHAR = regval;
  185. }
  186. static void dwc2_chan_init(struct usbh_bus *bus, uint8_t ch_num, uint8_t devaddr, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps, uint8_t speed)
  187. {
  188. uint32_t regval;
  189. /* Clear old interrupt conditions for this host channel. */
  190. USB_OTG_HC((uint32_t)ch_num)->HCINT = 0xFFFFFFFFU;
  191. /* Enable channel interrupts required for this transfer. */
  192. regval = USB_OTG_HCINTMSK_CHHM;
  193. if (ep_type == USB_ENDPOINT_TYPE_INTERRUPT) {
  194. regval |= USB_OTG_HCINTMSK_NAKM;
  195. }
  196. USB_OTG_HC((uint32_t)ch_num)->HCINTMSK = regval;
  197. /* Enable the top level host channel interrupt. */
  198. USB_OTG_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
  199. dwc2_chan_char_init(bus, ch_num, devaddr, ep_addr, ep_type, ep_mps, speed);
  200. }
  201. /* For IN channel HCTSIZ.XferSize is expected to be an integer multiple of ep_mps size.*/
  202. static inline void dwc2_chan_transfer(struct usbh_bus *bus, uint8_t ch_num, uint8_t ep_addr, uint32_t *buf, uint32_t size, uint8_t num_packets, uint8_t pid)
  203. {
  204. __IO uint32_t tmpreg;
  205. uint8_t is_oddframe;
  206. /* Initialize the HCTSIZn register */
  207. USB_OTG_HC(ch_num)->HCTSIZ = (size & USB_OTG_HCTSIZ_XFRSIZ) |
  208. (((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
  209. (((uint32_t)pid << 29) & USB_OTG_HCTSIZ_DPID);
  210. /* xfer_buff MUST be 32-bits aligned */
  211. USB_OTG_HC(ch_num)->HCDMA = (uint32_t)buf;
  212. is_oddframe = (((uint32_t)USB_OTG_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U;
  213. USB_OTG_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
  214. USB_OTG_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29;
  215. /* Set host channel enable */
  216. tmpreg = USB_OTG_HC(ch_num)->HCCHAR;
  217. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  218. tmpreg |= USB_OTG_HCCHAR_CHENA;
  219. USB_OTG_HC(ch_num)->HCCHAR = tmpreg;
  220. }
  221. static void dwc2_halt(struct usbh_bus *bus, uint8_t ch_num)
  222. {
  223. volatile uint32_t ChannelEna = (USB_OTG_HC(ch_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31;
  224. volatile uint32_t count = 0U;
  225. __IO uint32_t value;
  226. if (((USB_OTG_GLB->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == USB_OTG_GAHBCFG_DMAEN) &&
  227. (ChannelEna == 0U)) {
  228. return;
  229. }
  230. USB_OTG_HC(ch_num)->HCINTMSK = 0;
  231. value = USB_OTG_HC(ch_num)->HCCHAR;
  232. value |= USB_OTG_HCCHAR_CHDIS;
  233. value &= ~USB_OTG_HCCHAR_CHENA;
  234. value &= ~USB_OTG_HCCHAR_EPDIR;
  235. USB_OTG_HC(ch_num)->HCCHAR = value;
  236. do {
  237. if (++count > 200000U) {
  238. break;
  239. }
  240. } while (USB_OTG_HC(ch_num)->HCCHAR & USB_OTG_HCCHAR_CHENA);
  241. USB_OTG_HC(ch_num)->HCINT = USB_OTG_HC(ch_num)->HCINT;
  242. }
  243. static int usbh_reset_port(struct usbh_bus *bus, const uint8_t port)
  244. {
  245. __IO uint32_t hprt0 = 0U;
  246. hprt0 = USB_OTG_HPRT;
  247. hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
  248. USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
  249. USB_OTG_HPRT = (USB_OTG_HPRT_PRST | hprt0);
  250. usb_osal_msleep(100U); /* See Note #1 */
  251. USB_OTG_HPRT = ((~USB_OTG_HPRT_PRST) & hprt0);
  252. usb_osal_msleep(10U);
  253. while (!(USB_OTG_HPRT & USB_OTG_HPRT_PENA)) {
  254. usb_osal_msleep(10U);
  255. }
  256. return 0;
  257. }
  258. /**
  259. * @brief dwc2_get_glb_intstatus: return the global USB interrupt status
  260. * @retval status
  261. */
  262. static inline uint32_t dwc2_get_glb_intstatus(struct usbh_bus *bus)
  263. {
  264. uint32_t tmpreg;
  265. tmpreg = USB_OTG_GLB->GINTSTS;
  266. tmpreg &= USB_OTG_GLB->GINTMSK;
  267. return tmpreg;
  268. }
  269. static int dwc2_chan_alloc(struct usbh_bus *bus)
  270. {
  271. size_t flags;
  272. int chidx;
  273. flags = usb_osal_enter_critical_section();
  274. for (chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
  275. if (!g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].inuse) {
  276. g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].inuse = true;
  277. usb_osal_leave_critical_section(flags);
  278. return chidx;
  279. }
  280. }
  281. usb_osal_leave_critical_section(flags);
  282. return -1;
  283. }
  284. static void dwc2_chan_free(struct dwc2_chan *chan)
  285. {
  286. size_t flags;
  287. flags = usb_osal_enter_critical_section();
  288. chan->inuse = false;
  289. usb_osal_leave_critical_section(flags);
  290. }
  291. static uint8_t dwc2_calculate_packet_num(uint32_t input_size, uint8_t ep_addr, uint16_t ep_mps, uint32_t *output_size)
  292. {
  293. uint16_t num_packets;
  294. num_packets = (uint16_t)((input_size + ep_mps - 1U) / ep_mps);
  295. if (num_packets > 256) {
  296. num_packets = 256;
  297. }
  298. if (input_size == 0) {
  299. num_packets = 1;
  300. }
  301. if (ep_addr & 0x80) {
  302. input_size = num_packets * ep_mps;
  303. } else {
  304. }
  305. *output_size = input_size;
  306. return num_packets;
  307. }
  308. static void dwc2_control_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb, struct usb_setup_packet *setup, uint8_t *buffer, uint32_t buflen)
  309. {
  310. struct dwc2_chan *chan;
  311. chan = &g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx];
  312. if (chan->ep0_state == DWC2_EP0_STATE_SETUP) /* fill setup */
  313. {
  314. chan->num_packets = dwc2_calculate_packet_num(8, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
  315. dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
  316. dwc2_chan_transfer(bus, chidx, 0x00, (uint32_t *)setup, chan->xferlen, chan->num_packets, HC_PID_SETUP);
  317. } else if (chan->ep0_state == DWC2_EP0_STATE_INDATA) /* fill in data */
  318. {
  319. chan->num_packets = dwc2_calculate_packet_num(setup->wLength, 0x80, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
  320. dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
  321. dwc2_chan_transfer(bus, chidx, 0x80, (uint32_t *)buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
  322. } else if (chan->ep0_state == DWC2_EP0_STATE_OUTDATA) /* fill out data */
  323. {
  324. chan->num_packets = dwc2_calculate_packet_num(setup->wLength, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
  325. dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
  326. dwc2_chan_transfer(bus, chidx, 0x00, (uint32_t *)buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
  327. } else if (chan->ep0_state == DWC2_EP0_STATE_INSTATUS) /* fill in status */
  328. {
  329. chan->num_packets = dwc2_calculate_packet_num(0, 0x80, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
  330. dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
  331. dwc2_chan_transfer(bus, chidx, 0x80, NULL, chan->xferlen, chan->num_packets, HC_PID_DATA1);
  332. } else if (chan->ep0_state == DWC2_EP0_STATE_OUTSTATUS) /* fill out status */
  333. {
  334. chan->num_packets = dwc2_calculate_packet_num(0, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
  335. dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
  336. dwc2_chan_transfer(bus, chidx, 0x00, NULL, chan->xferlen, chan->num_packets, HC_PID_DATA1);
  337. }
  338. }
  339. static void dwc2_bulk_intr_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
  340. {
  341. struct dwc2_chan *chan;
  342. chan = &g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx];
  343. chan->num_packets = dwc2_calculate_packet_num(buflen, urb->ep->bEndpointAddress, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
  344. dwc2_chan_init(bus, chidx, urb->hport->dev_addr, urb->ep->bEndpointAddress, USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes), USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
  345. dwc2_chan_transfer(bus, chidx, urb->ep->bEndpointAddress, (uint32_t *)buffer, chan->xferlen, chan->num_packets, urb->data_toggle == 0 ? HC_PID_DATA0 : HC_PID_DATA1);
  346. }
  347. static void dwc2_iso_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb, struct usbh_iso_frame_packet *iso_packet)
  348. {
  349. struct dwc2_chan *chan;
  350. chan = &g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx];
  351. chan->num_packets = dwc2_calculate_packet_num(iso_packet->transfer_buffer_length, urb->ep->bEndpointAddress, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
  352. dwc2_chan_init(bus, chidx, urb->hport->dev_addr, urb->ep->bEndpointAddress, USB_ENDPOINT_TYPE_ISOCHRONOUS, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
  353. dwc2_chan_transfer(bus, chidx, urb->ep->bEndpointAddress, (uint32_t *)iso_packet->transfer_buffer, chan->xferlen, chan->num_packets, HC_PID_DATA0);
  354. }
  355. __WEAK void usb_hc_low_level_init(struct usbh_bus *bus)
  356. {
  357. (void)bus;
  358. }
  359. __WEAK void usb_hc_low_level_deinit(struct usbh_bus *bus)
  360. {
  361. (void)bus;
  362. }
  363. int usb_hc_init(struct usbh_bus *bus)
  364. {
  365. int ret;
  366. memset(&g_dwc2_hcd[bus->hcd.hcd_id], 0, sizeof(struct dwc2_hcd));
  367. for (uint8_t chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
  368. g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].waitsem = usb_osal_sem_create(0);
  369. }
  370. usb_hc_low_level_init(bus);
  371. USB_LOG_INFO("========== dwc2 hcd params ==========\r\n");
  372. USB_LOG_INFO("CID:%08x\r\n", USB_OTG_GLB->CID);
  373. USB_LOG_INFO("GSNPSID:%08x\r\n", USB_OTG_GLB->GSNPSID);
  374. USB_LOG_INFO("GHWCFG1:%08x\r\n", USB_OTG_GLB->GHWCFG1);
  375. USB_LOG_INFO("GHWCFG2:%08x\r\n", USB_OTG_GLB->GHWCFG2);
  376. USB_LOG_INFO("GHWCFG3:%08x\r\n", USB_OTG_GLB->GHWCFG3);
  377. USB_LOG_INFO("GHWCFG4:%08x\r\n", USB_OTG_GLB->GHWCFG4);
  378. USB_LOG_INFO("dwc2 has %d channels and dfifo depth(32-bit words) is %d\r\n", ((USB_OTG_GLB->GHWCFG2 & (0x0f << 14)) >> 14) + 1, (USB_OTG_GLB->GHWCFG3 >> 16));
  379. if (((USB_OTG_GLB->GHWCFG2 & (0x3U << 3)) >> 3) != 2) {
  380. USB_LOG_ERR("This dwc2 version does not support dma mode, so stop working\r\n");
  381. while (1) {
  382. }
  383. }
  384. if ((CONFIG_USB_DWC2_RX_FIFO_SIZE + CONFIG_USB_DWC2_NPTX_FIFO_SIZE + CONFIG_USB_DWC2_PTX_FIFO_SIZE) > (USB_OTG_GLB->GHWCFG3 >> 16)) {
  385. USB_LOG_ERR("Your fifo config is overflow, please check\r\n");
  386. while (1) {
  387. }
  388. }
  389. USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
  390. /* This is vendor register */
  391. USB_OTG_GLB->GCCFG = usbh_get_dwc2_gccfg_conf(bus->hcd.reg_base);
  392. ret = dwc2_core_init(bus);
  393. /* Force Host Mode*/
  394. dwc2_set_mode(bus, USB_OTG_MODE_HOST);
  395. usb_osal_msleep(50);
  396. /* Restart the Phy Clock */
  397. USB_OTG_PCGCCTL = 0U;
  398. dwc2_drivebus(bus, 1);
  399. usb_osal_msleep(200);
  400. /* Set default Max speed support */
  401. USB_OTG_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
  402. /* Clear all pending HC Interrupts */
  403. for (uint8_t i = 0U; i < CONFIG_USBHOST_PIPE_NUM; i++) {
  404. USB_OTG_HC(i)->HCINT = 0xFFFFFFFFU;
  405. USB_OTG_HC(i)->HCINTMSK = 0U;
  406. }
  407. /* Disable all interrupts. */
  408. USB_OTG_GLB->GINTMSK = 0U;
  409. /* Clear any pending interrupts */
  410. USB_OTG_GLB->GINTSTS = 0xFFFFFFFFU;
  411. /* set Rx FIFO size */
  412. USB_OTG_GLB->GRXFSIZ = CONFIG_USB_DWC2_RX_FIFO_SIZE;
  413. USB_OTG_GLB->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((CONFIG_USB_DWC2_NPTX_FIFO_SIZE << 16) & USB_OTG_NPTXFD) | CONFIG_USB_DWC2_RX_FIFO_SIZE);
  414. USB_OTG_GLB->HPTXFSIZ = (uint32_t)(((CONFIG_USB_DWC2_PTX_FIFO_SIZE << 16) & USB_OTG_HPTXFSIZ_PTXFD) | (CONFIG_USB_DWC2_RX_FIFO_SIZE + CONFIG_USB_DWC2_NPTX_FIFO_SIZE));
  415. ret = dwc2_flush_txfifo(bus, 0x10U);
  416. ret = dwc2_flush_rxfifo(bus);
  417. USB_OTG_GLB->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_4;
  418. USB_OTG_GLB->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
  419. /* Enable interrupts matching to the Host mode ONLY */
  420. USB_OTG_GLB->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM |
  421. USB_OTG_GINTSTS_DISCINT);
  422. USB_OTG_GLB->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
  423. return ret;
  424. }
  425. int usb_hc_deinit(struct usbh_bus *bus)
  426. {
  427. volatile uint32_t count = 0U;
  428. uint32_t value;
  429. USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
  430. dwc2_flush_txfifo(bus, 0x10U);
  431. dwc2_flush_rxfifo(bus);
  432. /* Flush out any leftover queued requests. */
  433. for (uint32_t i = 0U; i <= 15U; i++) {
  434. value = USB_OTG_HC(i)->HCCHAR;
  435. value |= USB_OTG_HCCHAR_CHDIS;
  436. value &= ~USB_OTG_HCCHAR_CHENA;
  437. value &= ~USB_OTG_HCCHAR_EPDIR;
  438. USB_OTG_HC(i)->HCCHAR = value;
  439. }
  440. /* Halt all channels to put them into a known state. */
  441. for (uint32_t i = 0U; i <= 15U; i++) {
  442. value = USB_OTG_HC(i)->HCCHAR;
  443. value |= USB_OTG_HCCHAR_CHDIS;
  444. value |= USB_OTG_HCCHAR_CHENA;
  445. value &= ~USB_OTG_HCCHAR_EPDIR;
  446. USB_OTG_HC(i)->HCCHAR = value;
  447. do {
  448. if (++count > 1000U) {
  449. return -USB_ERR_TIMEOUT;
  450. }
  451. } while ((USB_OTG_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
  452. }
  453. /* Disable all interrupts. */
  454. USB_OTG_GLB->GINTMSK = 0U;
  455. /* Clear any pending Host interrupts */
  456. USB_OTG_HOST->HAINT = 0xFFFFFFFFU;
  457. USB_OTG_GLB->GINTSTS = 0xFFFFFFFFU;
  458. dwc2_drivebus(bus, 0);
  459. usb_osal_msleep(200);
  460. for (uint8_t chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
  461. usb_osal_sem_delete(g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].waitsem);
  462. }
  463. usb_hc_low_level_deinit(bus);
  464. return 0;
  465. }
  466. uint16_t usbh_get_frame_number(struct usbh_bus *bus)
  467. {
  468. return (USB_OTG_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
  469. }
  470. int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, uint8_t *buf)
  471. {
  472. __IO uint32_t hprt0;
  473. uint8_t nports;
  474. uint8_t port;
  475. uint32_t status;
  476. nports = CONFIG_USBHOST_MAX_RHPORTS;
  477. port = setup->wIndex;
  478. if (setup->bmRequestType & USB_REQUEST_RECIPIENT_DEVICE) {
  479. switch (setup->bRequest) {
  480. case HUB_REQUEST_CLEAR_FEATURE:
  481. switch (setup->wValue) {
  482. case HUB_FEATURE_HUB_C_LOCALPOWER:
  483. break;
  484. case HUB_FEATURE_HUB_C_OVERCURRENT:
  485. break;
  486. default:
  487. return -USB_ERR_NOTSUPP;
  488. }
  489. break;
  490. case HUB_REQUEST_SET_FEATURE:
  491. switch (setup->wValue) {
  492. case HUB_FEATURE_HUB_C_LOCALPOWER:
  493. break;
  494. case HUB_FEATURE_HUB_C_OVERCURRENT:
  495. break;
  496. default:
  497. return -USB_ERR_NOTSUPP;
  498. }
  499. break;
  500. case HUB_REQUEST_GET_DESCRIPTOR:
  501. break;
  502. case HUB_REQUEST_GET_STATUS:
  503. memset(buf, 0, 4);
  504. break;
  505. default:
  506. break;
  507. }
  508. } else if (setup->bmRequestType & USB_REQUEST_RECIPIENT_OTHER) {
  509. switch (setup->bRequest) {
  510. case HUB_REQUEST_CLEAR_FEATURE:
  511. if (!port || port > nports) {
  512. return -USB_ERR_INVAL;
  513. }
  514. switch (setup->wValue) {
  515. case HUB_PORT_FEATURE_ENABLE:
  516. USB_OTG_HPRT &= ~USB_OTG_HPRT_PENA;
  517. break;
  518. case HUB_PORT_FEATURE_SUSPEND:
  519. case HUB_PORT_FEATURE_C_SUSPEND:
  520. break;
  521. case HUB_PORT_FEATURE_POWER:
  522. dwc2_drivebus(bus, 0);
  523. break;
  524. case HUB_PORT_FEATURE_C_CONNECTION:
  525. g_dwc2_hcd[bus->hcd.hcd_id].port_csc = 0;
  526. break;
  527. case HUB_PORT_FEATURE_C_ENABLE:
  528. g_dwc2_hcd[bus->hcd.hcd_id].port_pec = 0;
  529. break;
  530. case HUB_PORT_FEATURE_C_OVER_CURREN:
  531. g_dwc2_hcd[bus->hcd.hcd_id].port_occ = 0;
  532. break;
  533. case HUB_PORT_FEATURE_C_RESET:
  534. break;
  535. default:
  536. return -USB_ERR_NOTSUPP;
  537. }
  538. break;
  539. case HUB_REQUEST_SET_FEATURE:
  540. if (!port || port > nports) {
  541. return -USB_ERR_INVAL;
  542. }
  543. switch (setup->wValue) {
  544. case HUB_PORT_FEATURE_SUSPEND:
  545. break;
  546. case HUB_PORT_FEATURE_POWER:
  547. dwc2_drivebus(bus, 1);
  548. break;
  549. case HUB_PORT_FEATURE_RESET:
  550. usbh_reset_port(bus, port);
  551. break;
  552. default:
  553. return -USB_ERR_NOTSUPP;
  554. }
  555. break;
  556. case HUB_REQUEST_GET_STATUS:
  557. if (!port || port > nports) {
  558. return -USB_ERR_INVAL;
  559. }
  560. hprt0 = USB_OTG_HPRT;
  561. status = 0;
  562. if (g_dwc2_hcd[bus->hcd.hcd_id].port_csc) {
  563. status |= (1 << HUB_PORT_FEATURE_C_CONNECTION);
  564. }
  565. if (g_dwc2_hcd[bus->hcd.hcd_id].port_pec) {
  566. status |= (1 << HUB_PORT_FEATURE_C_ENABLE);
  567. }
  568. if (g_dwc2_hcd[bus->hcd.hcd_id].port_occ) {
  569. status |= (1 << HUB_PORT_FEATURE_C_OVER_CURREN);
  570. }
  571. if (hprt0 & USB_OTG_HPRT_PCSTS) {
  572. status |= (1 << HUB_PORT_FEATURE_CONNECTION);
  573. }
  574. if (hprt0 & USB_OTG_HPRT_PENA) {
  575. status |= (1 << HUB_PORT_FEATURE_ENABLE);
  576. if (usbh_get_port_speed(bus, port) == USB_SPEED_LOW) {
  577. status |= (1 << HUB_PORT_FEATURE_LOWSPEED);
  578. } else if (usbh_get_port_speed(bus, port) == USB_SPEED_HIGH) {
  579. status |= (1 << HUB_PORT_FEATURE_HIGHSPEED);
  580. }
  581. }
  582. if (hprt0 & USB_OTG_HPRT_POCA) {
  583. status |= (1 << HUB_PORT_FEATURE_OVERCURRENT);
  584. }
  585. if (hprt0 & USB_OTG_HPRT_PRST) {
  586. status |= (1 << HUB_PORT_FEATURE_RESET);
  587. }
  588. if (hprt0 & USB_OTG_HPRT_PPWR) {
  589. status |= (1 << HUB_PORT_FEATURE_POWER);
  590. }
  591. memcpy(buf, &status, 4);
  592. break;
  593. default:
  594. break;
  595. }
  596. }
  597. return 0;
  598. }
  599. int usbh_submit_urb(struct usbh_urb *urb)
  600. {
  601. struct dwc2_chan *chan;
  602. struct usbh_bus *bus;
  603. size_t flags;
  604. int ret = 0;
  605. int chidx;
  606. if (!urb || !urb->hport || !urb->ep || !urb->hport->bus) {
  607. return -USB_ERR_INVAL;
  608. }
  609. /* dma addr must be aligned 4 bytes */
  610. if ((((uint32_t)urb->setup) & 0x03) || (((uint32_t)urb->transfer_buffer) & 0x03)) {
  611. return -USB_ERR_INVAL;
  612. }
  613. bus = urb->hport->bus;
  614. if (!(USB_OTG_HPRT & USB_OTG_HPRT_PCSTS) || !urb->hport->connected) {
  615. return -USB_ERR_NOTCONN;
  616. }
  617. if (urb->errorcode == -USB_ERR_BUSY) {
  618. return -USB_ERR_BUSY;
  619. }
  620. chidx = dwc2_chan_alloc(bus);
  621. if (chidx == -1) {
  622. return -USB_ERR_NOMEM;
  623. }
  624. if (urb->ep->bEndpointAddress & 0x80) {
  625. /* Check if pipe rx fifo is overflow */
  626. if (USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) > (CONFIG_USB_DWC2_RX_FIFO_SIZE * 4)) {
  627. return -USB_ERR_RANGE;
  628. }
  629. } else {
  630. /* Check if intr and iso pipe tx fifo is overflow */
  631. if (((USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) == USB_ENDPOINT_TYPE_ISOCHRONOUS) ||
  632. (USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) == USB_ENDPOINT_TYPE_INTERRUPT)) &&
  633. USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) > (CONFIG_USB_DWC2_PTX_FIFO_SIZE * 4)) {
  634. return -USB_ERR_RANGE;
  635. } else {
  636. /* Check if control and bulk pipe tx fifo is overflow */
  637. if (USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) > (CONFIG_USB_DWC2_NPTX_FIFO_SIZE * 4)) {
  638. return -USB_ERR_RANGE;
  639. }
  640. }
  641. }
  642. flags = usb_osal_enter_critical_section();
  643. chan = &g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx];
  644. chan->chidx = chidx;
  645. chan->urb = urb;
  646. urb->hcpriv = chan;
  647. urb->errorcode = -USB_ERR_BUSY;
  648. urb->actual_length = 0;
  649. usb_osal_leave_critical_section(flags);
  650. switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) {
  651. case USB_ENDPOINT_TYPE_CONTROL:
  652. chan->ep0_state = DWC2_EP0_STATE_SETUP;
  653. dwc2_control_urb_init(bus, chidx, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
  654. break;
  655. case USB_ENDPOINT_TYPE_BULK:
  656. case USB_ENDPOINT_TYPE_INTERRUPT:
  657. dwc2_bulk_intr_urb_init(bus, chidx, urb, urb->transfer_buffer, urb->transfer_buffer_length);
  658. break;
  659. case USB_ENDPOINT_TYPE_ISOCHRONOUS:
  660. break;
  661. default:
  662. break;
  663. }
  664. if (urb->timeout > 0) {
  665. /* wait until timeout or sem give */
  666. ret = usb_osal_sem_take(chan->waitsem, urb->timeout);
  667. if (ret < 0) {
  668. goto errout_timeout;
  669. }
  670. urb->timeout = 0;
  671. ret = urb->errorcode;
  672. /* we can free chan when waitsem is done */
  673. dwc2_chan_free(chan);
  674. }
  675. return ret;
  676. errout_timeout:
  677. urb->timeout = 0;
  678. usbh_kill_urb(urb);
  679. return ret;
  680. }
  681. int usbh_kill_urb(struct usbh_urb *urb)
  682. {
  683. struct dwc2_chan *chan;
  684. struct usbh_bus *bus;
  685. size_t flags;
  686. if (!urb || !urb->hcpriv || !urb->hport->bus) {
  687. return -USB_ERR_INVAL;
  688. }
  689. bus = urb->hport->bus;
  690. flags = usb_osal_enter_critical_section();
  691. chan = (struct dwc2_chan *)urb->hcpriv;
  692. dwc2_halt(bus, chan->chidx);
  693. chan->urb = NULL;
  694. urb->hcpriv = NULL;
  695. urb->errorcode = -USB_ERR_SHUTDOWN;
  696. if (urb->timeout) {
  697. usb_osal_sem_give(chan->waitsem);
  698. } else {
  699. dwc2_chan_free(chan);
  700. }
  701. usb_osal_leave_critical_section(flags);
  702. return 0;
  703. }
  704. static inline void dwc2_urb_waitup(struct usbh_urb *urb)
  705. {
  706. struct dwc2_chan *chan;
  707. chan = (struct dwc2_chan *)urb->hcpriv;
  708. chan->urb = NULL;
  709. urb->hcpriv = NULL;
  710. if (urb->timeout) {
  711. usb_osal_sem_give(chan->waitsem);
  712. } else {
  713. dwc2_chan_free(chan);
  714. }
  715. if (urb->complete) {
  716. if (urb->errorcode < 0) {
  717. urb->complete(urb->arg, urb->errorcode);
  718. } else {
  719. urb->complete(urb->arg, urb->actual_length);
  720. }
  721. }
  722. }
  723. static void dwc2_inchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
  724. {
  725. uint32_t chan_intstatus;
  726. struct dwc2_chan *chan;
  727. struct usbh_urb *urb;
  728. chan_intstatus = USB_OTG_HC(ch_num)->HCINT;
  729. chan = &g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[ch_num];
  730. urb = chan->urb;
  731. //printf("s1:%08x\r\n", chan_intstatus);
  732. if (chan_intstatus & USB_OTG_HCINT_CHH) {
  733. if (chan_intstatus & USB_OTG_HCINT_XFRC) {
  734. urb->errorcode = 0;
  735. uint32_t count = chan->xferlen - (USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ); /* how many size has received */
  736. uint32_t has_used_packets = chan->num_packets - ((USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19); /* how many packets have used */
  737. urb->actual_length += count;
  738. uint8_t data_toggle = ((USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_DPID) >> USB_OTG_HCTSIZ_DPID_Pos);
  739. if (data_toggle == HC_PID_DATA0) {
  740. urb->data_toggle = 0;
  741. } else {
  742. urb->data_toggle = 1;
  743. }
  744. if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_CONTROL) {
  745. if (chan->ep0_state == DWC2_EP0_STATE_INDATA) {
  746. chan->ep0_state = DWC2_EP0_STATE_OUTSTATUS;
  747. dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
  748. } else if (chan->ep0_state == DWC2_EP0_STATE_INSTATUS) {
  749. chan->ep0_state = DWC2_EP0_STATE_SETUP;
  750. dwc2_urb_waitup(urb);
  751. }
  752. } else if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
  753. } else {
  754. dwc2_urb_waitup(urb);
  755. }
  756. } else if (chan_intstatus & USB_OTG_HCINT_AHBERR) {
  757. urb->errorcode = -USB_ERR_IO;
  758. dwc2_urb_waitup(urb);
  759. } else if (chan_intstatus & USB_OTG_HCINT_STALL) {
  760. urb->errorcode = -USB_ERR_STALL;
  761. dwc2_urb_waitup(urb);
  762. } else if (chan_intstatus & USB_OTG_HCINT_NAK) {
  763. urb->errorcode = -USB_ERR_NAK;
  764. dwc2_urb_waitup(urb);
  765. } else if (chan_intstatus & USB_OTG_HCINT_NYET) {
  766. urb->errorcode = -USB_ERR_NAK;
  767. dwc2_urb_waitup(urb);
  768. } else if (chan_intstatus & USB_OTG_HCINT_TXERR) {
  769. urb->errorcode = -USB_ERR_IO;
  770. dwc2_urb_waitup(urb);
  771. } else if (chan_intstatus & USB_OTG_HCINT_BBERR) {
  772. urb->errorcode = -USB_ERR_BABBLE;
  773. dwc2_urb_waitup(urb);
  774. } else if (chan_intstatus & USB_OTG_HCINT_DTERR) {
  775. urb->errorcode = -USB_ERR_DT;
  776. dwc2_urb_waitup(urb);
  777. } else if (chan_intstatus & USB_OTG_HCINT_FRMOR) {
  778. urb->errorcode = -USB_ERR_IO;
  779. dwc2_urb_waitup(urb);
  780. }
  781. USB_OTG_HC(ch_num)->HCINT = chan_intstatus;
  782. }
  783. }
  784. static void dwc2_outchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
  785. {
  786. uint32_t chan_intstatus;
  787. struct dwc2_chan *chan;
  788. struct usbh_urb *urb;
  789. chan_intstatus = USB_OTG_HC(ch_num)->HCINT;
  790. chan = &g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[ch_num];
  791. urb = chan->urb;
  792. //printf("s2:%08x\r\n", chan_intstatus);
  793. if (chan_intstatus & USB_OTG_HCINT_CHH) {
  794. if (chan_intstatus & USB_OTG_HCINT_XFRC) {
  795. urb->errorcode = 0;
  796. uint32_t count = USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ; /* last packet size */
  797. uint32_t has_used_packets = chan->num_packets - ((USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19); /* how many packets have used */
  798. urb->actual_length += (has_used_packets - 1) * USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) + count; //the same with urb->actual_length += chan->xferlen;
  799. uint8_t data_toggle = ((USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_DPID) >> USB_OTG_HCTSIZ_DPID_Pos);
  800. if (data_toggle == HC_PID_DATA0) {
  801. urb->data_toggle = 0;
  802. } else {
  803. urb->data_toggle = 1;
  804. }
  805. if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_CONTROL) {
  806. if (chan->ep0_state == DWC2_EP0_STATE_SETUP) {
  807. if (urb->setup->wLength) {
  808. if (urb->setup->bmRequestType & 0x80) {
  809. chan->ep0_state = DWC2_EP0_STATE_INDATA;
  810. } else {
  811. chan->ep0_state = DWC2_EP0_STATE_OUTDATA;
  812. }
  813. } else {
  814. chan->ep0_state = DWC2_EP0_STATE_INSTATUS;
  815. }
  816. dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
  817. } else if (chan->ep0_state == DWC2_EP0_STATE_OUTDATA) {
  818. chan->ep0_state = DWC2_EP0_STATE_INSTATUS;
  819. dwc2_control_urb_init(bus, ch_num, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
  820. } else if (chan->ep0_state == DWC2_EP0_STATE_OUTSTATUS) {
  821. chan->ep0_state = DWC2_EP0_STATE_SETUP;
  822. dwc2_urb_waitup(urb);
  823. }
  824. } else if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
  825. } else {
  826. dwc2_urb_waitup(urb);
  827. }
  828. } else if (chan_intstatus & USB_OTG_HCINT_AHBERR) {
  829. urb->errorcode = -USB_ERR_IO;
  830. dwc2_urb_waitup(urb);
  831. } else if (chan_intstatus & USB_OTG_HCINT_STALL) {
  832. urb->errorcode = -USB_ERR_STALL;
  833. dwc2_urb_waitup(urb);
  834. } else if (chan_intstatus & USB_OTG_HCINT_NAK) {
  835. urb->errorcode = -USB_ERR_NAK;
  836. dwc2_urb_waitup(urb);
  837. } else if (chan_intstatus & USB_OTG_HCINT_NYET) {
  838. urb->errorcode = -USB_ERR_NAK;
  839. dwc2_urb_waitup(urb);
  840. } else if (chan_intstatus & USB_OTG_HCINT_TXERR) {
  841. urb->errorcode = -USB_ERR_IO;
  842. dwc2_urb_waitup(urb);
  843. } else if (chan_intstatus & USB_OTG_HCINT_BBERR) {
  844. urb->errorcode = -USB_ERR_BABBLE;
  845. dwc2_urb_waitup(urb);
  846. } else if (chan_intstatus & USB_OTG_HCINT_DTERR) {
  847. urb->errorcode = -USB_ERR_DT;
  848. dwc2_urb_waitup(urb);
  849. } else if (chan_intstatus & USB_OTG_HCINT_FRMOR) {
  850. urb->errorcode = -USB_ERR_IO;
  851. dwc2_urb_waitup(urb);
  852. }
  853. USB_OTG_HC(ch_num)->HCINT = chan_intstatus;
  854. }
  855. }
  856. static void dwc2_port_irq_handler(struct usbh_bus *bus)
  857. {
  858. __IO uint32_t hprt0, hprt0_dup, regval;
  859. /* Handle Host Port Interrupts */
  860. hprt0 = USB_OTG_HPRT;
  861. hprt0_dup = USB_OTG_HPRT;
  862. hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
  863. USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
  864. /* Check whether Port Connect detected */
  865. if ((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET) {
  866. if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS) {
  867. bus->hcd.roothub.int_buffer[0] = (1 << 1);
  868. usbh_hub_thread_wakeup(&bus->hcd.roothub);
  869. }
  870. hprt0_dup |= USB_OTG_HPRT_PCDET;
  871. g_dwc2_hcd[bus->hcd.hcd_id].port_csc = 1;
  872. }
  873. /* Check whether Port Enable Changed */
  874. if ((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG) {
  875. hprt0_dup |= USB_OTG_HPRT_PENCHNG;
  876. g_dwc2_hcd[bus->hcd.hcd_id].port_pec = 1;
  877. if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA) {
  878. #if defined(CONFIG_USB_HS)
  879. #else
  880. if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17)) {
  881. USB_OTG_HOST->HFIR = 6000U;
  882. if ((USB_OTG_HOST->HCFG & USB_OTG_HCFG_FSLSPCS) != USB_OTG_HCFG_FSLSPCS_1) {
  883. regval = USB_OTG_HOST->HCFG;
  884. regval &= ~USB_OTG_HCFG_FSLSPCS;
  885. regval |= USB_OTG_HCFG_FSLSPCS_1;
  886. USB_OTG_HOST->HCFG = regval;
  887. }
  888. } else {
  889. USB_OTG_HOST->HFIR = 48000U;
  890. if ((USB_OTG_HOST->HCFG & USB_OTG_HCFG_FSLSPCS) != USB_OTG_HCFG_FSLSPCS_0) {
  891. regval = USB_OTG_HOST->HCFG;
  892. regval &= ~USB_OTG_HCFG_FSLSPCS;
  893. regval |= USB_OTG_HCFG_FSLSPCS_0;
  894. USB_OTG_HOST->HCFG = regval;
  895. }
  896. }
  897. #endif
  898. } else {
  899. }
  900. }
  901. /* Check for an overcurrent */
  902. if ((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG) {
  903. hprt0_dup |= USB_OTG_HPRT_POCCHNG;
  904. g_dwc2_hcd[bus->hcd.hcd_id].port_occ = 1;
  905. }
  906. /* Clear Port Interrupts */
  907. USB_OTG_HPRT = hprt0_dup;
  908. }
  909. void USBH_IRQHandler(uint8_t busid)
  910. {
  911. uint32_t gint_status, chan_int;
  912. struct usbh_bus *bus;
  913. bus = &g_usbhost_bus[busid];
  914. gint_status = dwc2_get_glb_intstatus(bus);
  915. if ((USB_OTG_GLB->GINTSTS & 0x1U) == USB_OTG_MODE_HOST) {
  916. /* Avoid spurious interrupt */
  917. if (gint_status == 0) {
  918. return;
  919. }
  920. if (gint_status & USB_OTG_GINTSTS_HPRTINT) {
  921. dwc2_port_irq_handler(bus);
  922. }
  923. if (gint_status & USB_OTG_GINTSTS_DISCINT) {
  924. g_dwc2_hcd[bus->hcd.hcd_id].port_csc = 1;
  925. bus->hcd.roothub.int_buffer[0] = (1 << 1);
  926. usbh_hub_thread_wakeup(&bus->hcd.roothub);
  927. USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_DISCINT;
  928. }
  929. if (gint_status & USB_OTG_GINTSTS_HCINT) {
  930. chan_int = (USB_OTG_HOST->HAINT & USB_OTG_HOST->HAINTMSK) & 0xFFFFU;
  931. for (uint8_t i = 0U; i < CONFIG_USBHOST_PIPE_NUM; i++) {
  932. if ((chan_int & (1UL << (i & 0xFU))) != 0U) {
  933. if ((USB_OTG_HC(i)->HCCHAR & USB_OTG_HCCHAR_EPDIR) == USB_OTG_HCCHAR_EPDIR) {
  934. dwc2_inchan_irq_handler(bus, i);
  935. } else {
  936. dwc2_outchan_irq_handler(bus, i);
  937. }
  938. }
  939. }
  940. USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_HCINT;
  941. }
  942. }
  943. }