usb_dc_chipidea.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. /*
  2. * Copyright (c) 2021-2024 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. /*
  8. * Copyright (c) 2024, sakumisu
  9. *
  10. * SPDX-License-Identifier: Apache-2.0
  11. */
  12. #include "usbd_core.h"
  13. #include "usb_chipidea_reg.h"
  14. #define USB_OTG_DEV ((CHIPIDEA_TypeDef *)g_usbdev_bus[busid].reg_base)
  15. #define CHIPIDEA_BITSMASK(val, offset) ((uint32_t)(val) << (offset))
  16. #define QTD_COUNT_EACH_ENDPOINT (8U)
  17. #ifndef CONFIG_USBDEV_EP_NUM
  18. #define CONFIG_USBDEV_EP_NUM 8
  19. #endif
  20. /* ENDPTCTRL */
  21. enum {
  22. ENDPTCTRL_STALL = CHIPIDEA_BITSMASK(1, 0),
  23. ENDPTCTRL_TYPE = CHIPIDEA_BITSMASK(3, 2),
  24. ENDPTCTRL_TOGGLE_INHIBIT = CHIPIDEA_BITSMASK(1, 5),
  25. ENDPTCTRL_TOGGLE_RESET = CHIPIDEA_BITSMASK(1, 6),
  26. ENDPTCTRL_ENABLE = CHIPIDEA_BITSMASK(1, 7),
  27. };
  28. /* USBSTS, USBINTR */
  29. enum {
  30. intr_usb = CHIPIDEA_BITSMASK(1, 0),
  31. intr_error = CHIPIDEA_BITSMASK(1, 1),
  32. intr_port_change = CHIPIDEA_BITSMASK(1, 2),
  33. intr_reset = CHIPIDEA_BITSMASK(1, 6),
  34. intr_sof = CHIPIDEA_BITSMASK(1, 7),
  35. intr_suspend = CHIPIDEA_BITSMASK(1, 8),
  36. intr_nak = CHIPIDEA_BITSMASK(1, 16)
  37. };
  38. /* Queue Transfer Descriptor */
  39. typedef struct {
  40. /* Word 0: Next QTD Pointer */
  41. volatile uint32_t next; /* Next link pointer This field contains the physical memory address of the next dTD to be processed */
  42. /* Word 1: qTQ Token */
  43. volatile uint32_t : 3;
  44. volatile uint32_t xact_err : 1;
  45. volatile uint32_t : 1;
  46. volatile uint32_t buffer_err : 1;
  47. volatile uint32_t halted : 1;
  48. volatile uint32_t active : 1;
  49. volatile uint32_t : 2;
  50. volatile uint32_t iso_mult_override : 2; /* This field can be used for transmit ISOs to override the MULT field in the dQH. This field must be zero for all packet types that are not transmit-ISO. */
  51. volatile uint32_t : 3;
  52. volatile uint32_t int_on_complete : 1;
  53. volatile uint32_t total_bytes : 15;
  54. volatile uint32_t : 0;
  55. /* Word 2-6: Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page */
  56. volatile uint32_t buffer[5];
  57. /*------------- DCD Area -------------*/
  58. volatile uint16_t expected_bytes;
  59. volatile uint8_t reserved[2];
  60. } dcd_qtd_t;
  61. /* Queue Head */
  62. typedef struct {
  63. /* Word 0: Capabilities and Characteristics */
  64. volatile uint32_t : 15; /* Number of packets executed per transaction descriptor 00 - Execute N transactions as demonstrated by the USB variable length protocol where N is computed using Max_packet_length and the Total_bytes field in the dTD. 01 - Execute one transaction 10 - Execute two transactions 11 - Execute three transactions Remark: Non-isochronous endpoints must set MULT = 00. Remark: Isochronous endpoints must set MULT = 01, 10, or 11 as needed. */
  65. volatile uint32_t int_on_setup : 1; /* Interrupt on setup This bit is used on control type endpoints to indicate if USBINT is set in response to a setup being received. */
  66. volatile uint32_t max_packet_size : 11; /* This directly corresponds to the maximum packet size of the associated endpoint (wMaxPacketSize) */
  67. volatile uint32_t : 2;
  68. volatile uint32_t zero_length_termination : 1; /* This bit is used for non-isochronous endpoints to indicate when a zero-length packet is received to terminate transfers in case the total transfer length is “multiple”. 0 - Enable zero-length packet to terminate transfers equal to a multiple of Max_packet_length (default). 1 - Disable zero-length packet on transfers that are equal in length to a multiple Max_packet_length. */
  69. volatile uint32_t iso_mult : 2;
  70. volatile uint32_t : 0;
  71. /* Word 1: Current qTD Pointer */
  72. volatile uint32_t qtd_addr;
  73. /* Word 2-9: Transfer Overlay */
  74. volatile dcd_qtd_t qtd_overlay;
  75. /* Word 10-11: Setup request (control OUT only) */
  76. volatile struct usb_setup_packet setup_request;
  77. /*--------------------------------------------------------------------
  78. * Due to the fact QHD is 64 bytes aligned but occupies only 48 bytes
  79. * thus there are 16 bytes padding free that we can make use of.
  80. *--------------------------------------------------------------------
  81. */
  82. volatile uint8_t reserved[16];
  83. } dcd_qhd_t;
  84. typedef struct {
  85. dcd_qhd_t qhd[CONFIG_USBDEV_EP_NUM * 2];
  86. dcd_qtd_t qtd[CONFIG_USBDEV_EP_NUM * 2 * QTD_COUNT_EACH_ENDPOINT];
  87. } dcd_data_t;
  88. /* Endpoint state */
  89. struct chipidea_ep_state {
  90. uint16_t ep_mps; /* Endpoint max packet size */
  91. uint8_t ep_type; /* Endpoint type */
  92. uint8_t ep_stalled; /* Endpoint stall flag */
  93. uint8_t ep_enable; /* Endpoint enable */
  94. uint8_t *xfer_buf;
  95. uint32_t xfer_len;
  96. uint32_t actual_xfer_len;
  97. };
  98. /* Driver state */
  99. struct chipidea_udc {
  100. dcd_data_t *dcd_data;
  101. bool is_suspend;
  102. struct chipidea_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/
  103. struct chipidea_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */
  104. } g_chipidea_udc[CONFIG_USBDEV_MAX_BUS];
  105. static USB_NOCACHE_RAM_SECTION __attribute__((aligned(2048))) dcd_data_t _dcd_data0;
  106. #if CONFIG_USBDEV_MAX_BUS == 2
  107. static USB_NOCACHE_RAM_SECTION __attribute__((aligned(2048))) dcd_data_t _dcd_data1;
  108. #endif
  109. static dcd_data_t *g_dcd_data[CONFIG_USBDEV_MAX_BUS] = {
  110. &_dcd_data0,
  111. #if CONFIG_USBDEV_MAX_BUS == 2
  112. &_dcd_data1
  113. #endif
  114. };
  115. /* Index to bit position in register */
  116. static inline uint8_t ep_idx2bit(uint8_t ep_idx)
  117. {
  118. return ep_idx / 2 + ((ep_idx % 2) ? 16 : 0);
  119. }
  120. static void __chipidea_bus_reset(CHIPIDEA_TypeDef *ptr)
  121. {
  122. /* The reset value for all endpoint types is the control endpoint. If one endpoint
  123. * direction is enabled and the paired endpoint of opposite direction is disabled, then the
  124. * endpoint type of the unused direction must be changed from the control type to any other
  125. * type (e.g. bulk). Leaving an un-configured endpoint control will cause undefined behavior
  126. * for the data PID tracking on the active endpoint.
  127. */
  128. for (uint32_t i = 1; i < CONFIG_USBDEV_EP_NUM; i++) {
  129. ptr->ENDPTCTRL[i] = USB_ENDPTCTRL_TXT_SET(USB_ENDPOINT_TYPE_BULK) | USB_ENDPTCTRL_RXT_SET(USB_ENDPOINT_TYPE_BULK);
  130. }
  131. /* Clear All Registers */
  132. ptr->ENDPTNAK = ptr->ENDPTNAK;
  133. ptr->ENDPTNAKEN = 0;
  134. ptr->USBSTS = ptr->USBSTS;
  135. ptr->ENDPTSETUPSTAT = ptr->ENDPTSETUPSTAT;
  136. ptr->ENDPTCOMPLETE = ptr->ENDPTCOMPLETE;
  137. while (ptr->ENDPTPRIME) {
  138. }
  139. ptr->ENDPTFLUSH = 0xFFFFFFFF;
  140. while (ptr->ENDPTFLUSH) {
  141. }
  142. }
  143. static void chipidea_init(CHIPIDEA_TypeDef *ptr)
  144. {
  145. /* Reset controller */
  146. ptr->USBCMD |= USB_USBCMD_RST_MASK;
  147. while (USB_USBCMD_RST_GET(ptr->USBCMD)) {
  148. }
  149. /* Set mode to device, must be set immediately after reset */
  150. ptr->USBMODE &= ~USB_USBMODE_CM_MASK;
  151. ptr->USBMODE |= USB_USBMODE_CM_SET(2);
  152. /* Disable setup lockout, please refer to "Control Endpoint Operation" section in RM. */
  153. ptr->USBMODE &= ~USB_USBMODE_SLOM_MASK;
  154. /* Set the endian */
  155. ptr->USBMODE &= ~USB_USBMODE_ES_MASK;
  156. /* Set parallel interface signal */
  157. ptr->PORTSC1 &= ~USB_PORTSC1_STS_MASK;
  158. /* Set parallel transceiver width */
  159. ptr->PORTSC1 &= ~USB_PORTSC1_PTW_MASK;
  160. /* Set usb forced to full speed mode */
  161. //ptr->PORTSC1 |= USB_PORTSC1_PFSC_MASK;
  162. /* Not use interrupt threshold. */
  163. ptr->USBCMD &= ~USB_USBCMD_ITC_MASK;
  164. /* Enable VBUS discharge */
  165. ptr->OTGSC |= USB_OTGSC_VD_MASK;
  166. }
  167. static void chipidea_deinit(CHIPIDEA_TypeDef *ptr)
  168. {
  169. /* Stop */
  170. ptr->USBCMD &= ~USB_USBCMD_RS_MASK;
  171. /* Reset controller */
  172. ptr->USBCMD |= USB_USBCMD_RST_MASK;
  173. while (USB_USBCMD_RST_GET(ptr->USBCMD)) {
  174. }
  175. /* Reset endpoint list address register */
  176. ptr->ENDPTLISTADDR = 0;
  177. /* Reset status register */
  178. ptr->USBSTS = ptr->USBSTS;
  179. /* Reset interrupt enable register */
  180. ptr->USBINTR = 0;
  181. }
  182. /*---------------------------------------------------------------------
  183. * Endpoint API
  184. *---------------------------------------------------------------------
  185. */
  186. static void __chipidea_edpt_open(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr, uint8_t ep_type)
  187. {
  188. uint8_t const epnum = ep_addr & 0x0f;
  189. uint8_t const dir = (ep_addr & 0x80) >> 7;
  190. /* Enable EP Control */
  191. uint32_t temp = ptr->ENDPTCTRL[epnum];
  192. temp &= ~((0x03 << 2) << (dir ? 16 : 0));
  193. temp |= ((ep_type << 2) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET) << (dir ? 16 : 0);
  194. ptr->ENDPTCTRL[epnum] = temp;
  195. }
  196. static void chipidea_edpt_xfer(CHIPIDEA_TypeDef *ptr, uint8_t ep_idx)
  197. {
  198. uint32_t offset = ep_idx / 2 + ((ep_idx % 2) ? 16 : 0);
  199. /* Start transfer */
  200. ptr->ENDPTPRIME = 1 << offset;
  201. }
  202. static void chipidea_edpt_stall(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr)
  203. {
  204. uint8_t const epnum = ep_addr & 0x0f;
  205. uint8_t const dir = (ep_addr & 0x80) >> 7;
  206. ptr->ENDPTCTRL[epnum] |= ENDPTCTRL_STALL << (dir ? 16 : 0);
  207. }
  208. static void chipidea_edpt_clear_stall(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr)
  209. {
  210. uint8_t const epnum = ep_addr & 0x0f;
  211. uint8_t const dir = (ep_addr & 0x80) >> 7;
  212. /* data toggle also need to be reset */
  213. ptr->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << (dir ? 16 : 0);
  214. ptr->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << (dir ? 16 : 0));
  215. }
  216. static bool chipidea_edpt_check_stall(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr)
  217. {
  218. uint8_t const epnum = ep_addr & 0x0f;
  219. uint8_t const dir = (ep_addr & 0x80) >> 7;
  220. return (ptr->ENDPTCTRL[epnum] & (ENDPTCTRL_STALL << (dir ? 16 : 0))) ? true : false;
  221. }
  222. static void chipidea_edpt_close(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr)
  223. {
  224. uint8_t const epnum = ep_addr & 0x0f;
  225. uint8_t const dir = (ep_addr & 0x80) >> 7;
  226. uint32_t primebit = CHIPIDEA_BITSMASK(1, epnum) << (dir ? 16 : 0);
  227. /* Flush the endpoint to stop a transfer. */
  228. do {
  229. /* Set the corresponding bit(s) in the ENDPTFLUSH register */
  230. ptr->ENDPTFLUSH |= primebit;
  231. /* Wait until all bits in the ENDPTFLUSH register are cleared. */
  232. while (0U != (ptr->ENDPTFLUSH & primebit)) {
  233. }
  234. /*
  235. * Read the ENDPTSTAT register to ensure that for all endpoints
  236. * commanded to be flushed, that the corresponding bits
  237. * are now cleared.
  238. */
  239. } while (0U != (ptr->ENDPTSTAT & primebit));
  240. /* Disable the endpoint */
  241. ptr->ENDPTCTRL[epnum] &= ~((ENDPTCTRL_TYPE | ENDPTCTRL_ENABLE | ENDPTCTRL_STALL) << (dir ? 16 : 0));
  242. ptr->ENDPTCTRL[epnum] |= (USB_ENDPOINT_TYPE_BULK << 2) << (dir ? 16 : 0);
  243. }
  244. /* Initialize qtd */
  245. static void usb_qtd_init(dcd_qtd_t *p_qtd, void *data_ptr, uint16_t total_bytes)
  246. {
  247. memset(p_qtd, 0, sizeof(dcd_qtd_t));
  248. p_qtd->next = 1;
  249. p_qtd->active = 1;
  250. p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes;
  251. if (data_ptr != NULL) {
  252. p_qtd->buffer[0] = (uint32_t)data_ptr;
  253. for (uint8_t i = 1; i < 5; i++) {
  254. p_qtd->buffer[i] = ((p_qtd->buffer[i - 1]) & 0xFFFFF000UL) + 4096U;
  255. }
  256. }
  257. }
  258. static dcd_qhd_t *chipidea_qhd_get(uint8_t busid, uint8_t ep_idx)
  259. {
  260. dcd_data_t *dcd_data;
  261. dcd_data = g_chipidea_udc[busid].dcd_data;
  262. return &dcd_data->qhd[ep_idx];
  263. }
  264. static dcd_qtd_t *chipidea_qtd_get(uint8_t busid, uint8_t ep_idx)
  265. {
  266. dcd_data_t *dcd_data;
  267. dcd_data = g_chipidea_udc[busid].dcd_data;
  268. return &dcd_data->qtd[ep_idx * QTD_COUNT_EACH_ENDPOINT];
  269. }
  270. static void chipidea_bus_reset(uint8_t busid, uint16_t ep0_max_packet_size)
  271. {
  272. dcd_data_t *dcd_data;
  273. dcd_data = g_chipidea_udc[busid].dcd_data;
  274. __chipidea_bus_reset(USB_OTG_DEV);
  275. /* Queue Head & Queue TD */
  276. memset(dcd_data, 0, sizeof(dcd_data_t));
  277. /* Set up Control Endpoints (0 OUT, 1 IN) */
  278. dcd_data->qhd[0].zero_length_termination = dcd_data->qhd[1].zero_length_termination = 1;
  279. dcd_data->qhd[0].max_packet_size = dcd_data->qhd[1].max_packet_size = ep0_max_packet_size;
  280. dcd_data->qhd[0].qtd_overlay.next = dcd_data->qhd[1].qtd_overlay.next = 1;
  281. /* OUT only */
  282. dcd_data->qhd[0].int_on_setup = 1;
  283. }
  284. static void chipidea_edpt_open(uint8_t busid, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps)
  285. {
  286. uint8_t const epnum = ep_addr & 0x0f;
  287. uint8_t const dir = (ep_addr & 0x80) >> 7;
  288. uint8_t const ep_idx = 2 * epnum + dir;
  289. dcd_data_t *dcd_data;
  290. dcd_qhd_t *p_qhd;
  291. /* Prepare Queue Head */
  292. dcd_data = g_chipidea_udc[busid].dcd_data;
  293. p_qhd = &dcd_data->qhd[ep_idx];
  294. memset(p_qhd, 0, sizeof(dcd_qhd_t));
  295. p_qhd->zero_length_termination = 1;
  296. p_qhd->max_packet_size = ep_mps & 0x7FFu;
  297. p_qhd->qtd_overlay.next = 1;
  298. if (ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
  299. p_qhd->iso_mult = ((ep_mps >> 11u) & 0x3u) + 1u;
  300. }
  301. __chipidea_edpt_open(USB_OTG_DEV, ep_addr, ep_type);
  302. }
  303. static bool chipidea_start_xfer(uint8_t busid, uint8_t ep_addr, uint8_t *buffer, uint32_t total_bytes)
  304. {
  305. uint8_t const epnum = ep_addr & 0x0f;
  306. uint8_t const dir = (ep_addr & 0x80) >> 7;
  307. uint8_t const ep_idx = 2 * epnum + dir;
  308. uint8_t qtd_num;
  309. uint8_t i;
  310. uint32_t xfer_len;
  311. dcd_qhd_t *p_qhd;
  312. dcd_qtd_t *p_qtd;
  313. dcd_qtd_t *first_p_qtd = NULL;
  314. dcd_qtd_t *prev_p_qtd = NULL;
  315. dcd_data_t *dcd_data;
  316. dcd_data = g_chipidea_udc[busid].dcd_data;
  317. if (epnum == 0) {
  318. /* follows UM Setup packet handling using setup lockout mechanism
  319. * wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out
  320. */
  321. while (USB_OTG_DEV->ENDPTSETUPSTAT & CHIPIDEA_BITSMASK(1, 0)) {
  322. }
  323. }
  324. qtd_num = (total_bytes + 0x3fff) / 0x4000;
  325. if (qtd_num > QTD_COUNT_EACH_ENDPOINT) {
  326. return false;
  327. }
  328. if (buffer != NULL) {
  329. buffer = (uint8_t *)buffer;
  330. }
  331. p_qhd = &dcd_data->qhd[ep_idx];
  332. i = 0;
  333. do {
  334. p_qtd = &dcd_data->qtd[ep_idx * QTD_COUNT_EACH_ENDPOINT + i];
  335. i++;
  336. if (total_bytes > 0x4000) {
  337. xfer_len = 0x4000;
  338. total_bytes -= 0x4000;
  339. } else {
  340. xfer_len = total_bytes;
  341. total_bytes = 0;
  342. }
  343. usb_qtd_init(p_qtd, (void *)buffer, xfer_len);
  344. if (total_bytes == 0) {
  345. p_qtd->int_on_complete = true;
  346. }
  347. buffer += xfer_len;
  348. if (prev_p_qtd) {
  349. prev_p_qtd->next = (uint32_t)p_qtd;
  350. } else {
  351. first_p_qtd = p_qtd;
  352. }
  353. prev_p_qtd = p_qtd;
  354. } while (total_bytes > 0);
  355. p_qhd->qtd_overlay.next = (uint32_t)first_p_qtd; /* link qtd to qhd */
  356. chipidea_edpt_xfer(USB_OTG_DEV, ep_idx);
  357. return true;
  358. }
  359. __WEAK void usb_dc_low_level_init(uint8_t busid)
  360. {
  361. }
  362. __WEAK void usb_dc_low_level_deinit(uint8_t busid)
  363. {
  364. }
  365. int usb_dc_init(uint8_t busid)
  366. {
  367. uint32_t int_mask;
  368. int_mask = (USB_USBINTR_UE_MASK | USB_USBINTR_UEE_MASK | USB_USBINTR_SLE_MASK |
  369. USB_USBINTR_PCE_MASK | USB_USBINTR_URE_MASK);
  370. usb_dc_low_level_init(busid);
  371. memset(&g_chipidea_udc[busid], 0, sizeof(struct chipidea_udc));
  372. g_chipidea_udc[busid].dcd_data = g_dcd_data[busid];
  373. memset(g_chipidea_udc[busid].dcd_data, 0, sizeof(dcd_data_t));
  374. chipidea_init(USB_OTG_DEV);
  375. /* Set endpoint list address */
  376. USB_OTG_DEV->ENDPTLISTADDR = ((uint32_t)g_chipidea_udc[busid].dcd_data->qhd) & USB_ENDPTLISTADDR_EPBASE_MASK;
  377. /* Clear status */
  378. USB_OTG_DEV->USBSTS = USB_OTG_DEV->USBSTS;
  379. #ifdef CONFIG_USBDEV_SOF_ENABLE
  380. int_mask |= USB_USBINTR_SRE_MASK;
  381. #endif
  382. /* Enable interrupt mask */
  383. USB_OTG_DEV->USBINTR |= int_mask;
  384. /* Connect by enabling internal pull-up resistor on D+/D- */
  385. USB_OTG_DEV->USBCMD |= USB_USBCMD_RS_MASK;
  386. return 0;
  387. }
  388. int usb_dc_deinit(uint8_t busid)
  389. {
  390. chipidea_deinit(USB_OTG_DEV);
  391. for (uint32_t i = 0; i < CONFIG_USBDEV_EP_NUM; i++) {
  392. chipidea_edpt_close(USB_OTG_DEV, (i | 0x80));
  393. chipidea_edpt_close(USB_OTG_DEV, (i | 0x00));
  394. }
  395. usb_dc_low_level_deinit(busid);
  396. return 0;
  397. }
  398. int usbd_set_address(uint8_t busid, const uint8_t addr)
  399. {
  400. USB_OTG_DEV->DEVICEADDR = USB_DEVICEADDR_USBADR_SET(addr) | USB_DEVICEADDR_USBADRA_MASK;
  401. return 0;
  402. }
  403. int usbd_set_remote_wakeup(uint8_t busid)
  404. {
  405. if (!USB_PORTSC1_SUSP_GET(USB_OTG_DEV->PORTSC1)) {
  406. return -1;
  407. }
  408. USB_OTG_DEV->PORTSC1 |= USB_PORTSC1_FPR_MASK;
  409. while (USB_OTG_DEV->PORTSC1 & USB_PORTSC1_FPR_MASK) {
  410. }
  411. return 0;
  412. }
  413. uint8_t usbd_get_port_speed(uint8_t busid)
  414. {
  415. uint8_t speed;
  416. speed = USB_PORTSC1_PSPD_GET(USB_OTG_DEV->PORTSC1);
  417. if (speed == 0x00) {
  418. return USB_SPEED_FULL;
  419. }
  420. if (speed == 0x01) {
  421. return USB_SPEED_LOW;
  422. }
  423. if (speed == 0x02) {
  424. return USB_SPEED_HIGH;
  425. }
  426. return 0;
  427. }
  428. int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
  429. {
  430. uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress);
  431. USB_ASSERT_MSG(ep_idx < CONFIG_USBDEV_EP_NUM, "Ep addr %02x overflow", ep->bEndpointAddress);
  432. chipidea_edpt_open(busid, ep->bEndpointAddress, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), ep->wMaxPacketSize);
  433. if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
  434. g_chipidea_udc[busid].out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
  435. g_chipidea_udc[busid].out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
  436. g_chipidea_udc[busid].out_ep[ep_idx].ep_enable = true;
  437. } else {
  438. g_chipidea_udc[busid].in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
  439. g_chipidea_udc[busid].in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
  440. g_chipidea_udc[busid].in_ep[ep_idx].ep_enable = true;
  441. }
  442. return 0;
  443. }
  444. int usbd_ep_close(uint8_t busid, const uint8_t ep)
  445. {
  446. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  447. if (USB_EP_DIR_IS_OUT(ep)) {
  448. g_chipidea_udc[busid].out_ep[ep_idx].ep_enable = false;
  449. } else {
  450. g_chipidea_udc[busid].in_ep[ep_idx].ep_enable = false;
  451. }
  452. chipidea_edpt_close(USB_OTG_DEV, ep);
  453. return 0;
  454. }
  455. int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
  456. {
  457. chipidea_edpt_stall(USB_OTG_DEV, ep);
  458. return 0;
  459. }
  460. int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
  461. {
  462. chipidea_edpt_clear_stall(USB_OTG_DEV, ep);
  463. return 0;
  464. }
  465. int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
  466. {
  467. *stalled = chipidea_edpt_check_stall(USB_OTG_DEV, ep);
  468. return 0;
  469. }
  470. int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
  471. {
  472. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  473. if (!data && data_len) {
  474. return -1;
  475. }
  476. if (!g_chipidea_udc[busid].in_ep[ep_idx].ep_enable) {
  477. return -2;
  478. }
  479. g_chipidea_udc[busid].in_ep[ep_idx].xfer_buf = (uint8_t *)data;
  480. g_chipidea_udc[busid].in_ep[ep_idx].xfer_len = data_len;
  481. g_chipidea_udc[busid].in_ep[ep_idx].actual_xfer_len = 0;
  482. chipidea_start_xfer(busid, ep, (uint8_t *)data, data_len);
  483. return 0;
  484. }
  485. int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
  486. {
  487. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  488. if (!data && data_len) {
  489. return -1;
  490. }
  491. if (!g_chipidea_udc[busid].out_ep[ep_idx].ep_enable) {
  492. return -2;
  493. }
  494. g_chipidea_udc[busid].out_ep[ep_idx].xfer_buf = (uint8_t *)data;
  495. g_chipidea_udc[busid].out_ep[ep_idx].xfer_len = data_len;
  496. g_chipidea_udc[busid].out_ep[ep_idx].actual_xfer_len = 0;
  497. chipidea_start_xfer(busid, ep, data, data_len);
  498. return 0;
  499. }
  500. void USBD_IRQHandler(uint8_t busid)
  501. {
  502. uint32_t int_status;
  503. uint32_t transfer_len;
  504. bool ep_cb_req;
  505. /* Acknowledge handled interrupt */
  506. int_status = USB_OTG_DEV->USBSTS;
  507. int_status &= USB_OTG_DEV->USBINTR;
  508. USB_OTG_DEV->USBSTS = int_status;
  509. if (int_status & intr_error) {
  510. USB_LOG_ERR("usbd intr error!\r\n");
  511. }
  512. #ifdef CONFIG_USBDEV_SOF_ENABLE
  513. if (int_status & intr_sof) {
  514. usbd_event_sof_handler(busid);
  515. }
  516. #endif
  517. if (int_status & intr_reset) {
  518. g_chipidea_udc[busid].is_suspend = false;
  519. memset(g_chipidea_udc[busid].in_ep, 0, sizeof(struct chipidea_ep_state) * CONFIG_USBDEV_EP_NUM);
  520. memset(g_chipidea_udc[busid].out_ep, 0, sizeof(struct chipidea_ep_state) * CONFIG_USBDEV_EP_NUM);
  521. usbd_event_reset_handler(busid);
  522. chipidea_bus_reset(busid, 64);
  523. }
  524. if (int_status & intr_suspend) {
  525. if (USB_PORTSC1_SUSP_GET(USB_OTG_DEV->PORTSC1)) {
  526. /* Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. */
  527. if (USB_DEVICEADDR_USBADR_GET(USB_OTG_DEV->DEVICEADDR)) {
  528. g_chipidea_udc[busid].is_suspend = true;
  529. usbd_event_suspend_handler(busid);
  530. }
  531. } else {
  532. }
  533. }
  534. if (int_status & intr_port_change) {
  535. if (!USB_PORTSC1_CCS_GET(USB_OTG_DEV->PORTSC1)) {
  536. usbd_event_disconnect_handler(busid);
  537. } else {
  538. if (g_chipidea_udc[busid].is_suspend) {
  539. g_chipidea_udc[busid].is_suspend = false;
  540. usbd_event_resume_handler(busid);
  541. }
  542. usbd_event_connect_handler(busid);
  543. }
  544. }
  545. if (int_status & intr_usb) {
  546. uint32_t const edpt_complete = USB_OTG_DEV->ENDPTCOMPLETE;
  547. uint32_t edpt_setup_status = USB_OTG_DEV->ENDPTSETUPSTAT;
  548. if (edpt_complete) {
  549. USB_OTG_DEV->ENDPTCOMPLETE = edpt_complete;
  550. for (uint8_t ep_idx = 0; ep_idx < (CONFIG_USBDEV_EP_NUM * 2); ep_idx++) {
  551. if (edpt_complete & (1 << ep_idx2bit(ep_idx))) {
  552. transfer_len = 0;
  553. ep_cb_req = true;
  554. /* Failed QTD also get ENDPTCOMPLETE set */
  555. dcd_qtd_t *p_qtd = chipidea_qtd_get(busid, ep_idx);
  556. while (1) {
  557. if (p_qtd->halted || p_qtd->xact_err || p_qtd->buffer_err) {
  558. USB_LOG_ERR("usbd transfer error!\r\n");
  559. ep_cb_req = false;
  560. break;
  561. } else if (p_qtd->active) {
  562. ep_cb_req = false;
  563. break;
  564. } else {
  565. transfer_len += p_qtd->expected_bytes - p_qtd->total_bytes;
  566. }
  567. if (p_qtd->next == 1) {
  568. break;
  569. } else {
  570. p_qtd = (dcd_qtd_t *)p_qtd->next;
  571. }
  572. }
  573. if (ep_cb_req) {
  574. uint8_t const ep_addr = (ep_idx / 2) | ((ep_idx & 0x01) ? 0x80 : 0);
  575. if (ep_addr & 0x80) {
  576. usbd_event_ep_in_complete_handler(busid, ep_addr, transfer_len);
  577. } else {
  578. usbd_event_ep_out_complete_handler(busid, ep_addr, transfer_len);
  579. }
  580. }
  581. }
  582. }
  583. }
  584. if (edpt_setup_status) {
  585. /*------------- Set up Received -------------*/
  586. USB_OTG_DEV->ENDPTSETUPSTAT = edpt_setup_status;
  587. dcd_qhd_t *qhd0 = chipidea_qhd_get(busid, 0);
  588. usbd_event_ep0_setup_complete_handler(busid, (uint8_t *)&qhd0->setup_request);
  589. }
  590. }
  591. }