usb_dc_chipidea.c 23 KB

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