usb_hc_dwc2.c 39 KB

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