usb_hc_dwc2.c 39 KB

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