usb_hc_dwc2.c 38 KB

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