usb_dc_chipidea.c 23 KB

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