ch585_usbhs_dc.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. #include "usbd_core.h"
  2. #include "ch585_usbhs_reg.h"
  3. /**
  4. * @brief Related register macro
  5. */
  6. #define USB_BASE 0x40009000u
  7. #define CH585_USBHS_DEV ((USBHSD_TypeDef *)USB_BASE)
  8. #ifndef USBD_IRQHandler
  9. #define USBD_IRQHandler USB2_DEVICE_IRQHandler //use actual usb irq name instead
  10. #endif
  11. #define R16_PIN_CONFIG (*((PUINT16V)0x4000101A))
  12. #define R32_PIN_CONFIG (*((PUINT32V)0x40001018)) // RW, I/O pin configuration
  13. #define RB_PIN_USB2_EN 0x20
  14. #define USB_SET_RX_DMA(ep_idx, addr) (*(volatile uint32_t *)((uint32_t)(&CH585_USBHS_DEV->UEP1_RX_DMA) + 4 * (ep_idx - 1)) = addr)
  15. #define USB_SET_TX_DMA(ep_idx, addr) (*(volatile uint32_t *)((uint32_t)(&CH585_USBHS_DEV->UEP1_TX_DMA) + 4 * (ep_idx - 1)) = addr)
  16. #define USB_SET_MAX_LEN(ep_idx, len) (*(volatile uint16_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_MAX_LEN) + 4 * ep_idx) = len)
  17. #define USB_SET_TX_LEN(ep_idx, len) (*(volatile uint16_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_TX_LEN) + 4 * ep_idx) = len)
  18. #define USB_GET_TX_LEN(ep_idx) (*(volatile uint16_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_TX_LEN) + 4 * ep_idx))
  19. #define USB_SET_TX_CTRL(ep_idx, val) (*(volatile uint8_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_TX_CTRL) + 4 * ep_idx) = val)
  20. #define USB_GET_TX_CTRL(ep_idx) (*(volatile uint8_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_TX_CTRL) + 4 * ep_idx))
  21. #define USB_SET_RX_CTRL(ep_idx, val) (*(volatile uint8_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_RX_CTRL) + 4 * ep_idx) = val)
  22. #define USB_GET_RX_CTRL(ep_idx) (*(volatile uint8_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_RX_CTRL) + 4 * ep_idx))
  23. #define EPn_SET_TX_NAK(ep_idx) USB_SET_TX_CTRL(ep_idx, (USB_GET_TX_CTRL(ep_idx) & ~USBHS_UEP_T_RES_MASK) | USBHS_UEP_T_RES_NAK)
  24. #define EPn_SET_TX_VALID(ep_idx) USB_SET_TX_CTRL(ep_idx, (USB_GET_TX_CTRL(ep_idx) & ~USBHS_UEP_T_RES_MASK) | USBHS_UEP_T_RES_ACK)
  25. #define EPn_SET_RX_NAK(ep_idx) USB_SET_RX_CTRL(ep_idx, (USB_GET_RX_CTRL(ep_idx) & ~USBHS_UEP_R_RES_MASK) | USBHS_UEP_R_RES_NAK)
  26. #define EPn_SET_RX_VALID(ep_idx) USB_SET_RX_CTRL(ep_idx, (USB_GET_RX_CTRL(ep_idx) & ~USBHS_UEP_R_RES_MASK) | USBHS_UEP_R_RES_ACK)
  27. #define EPn_GET_RX_LEN(ep_idx) (*(volatile uint16_t *)((uint32_t)(&CH585_USBHS_DEV->USB_EP0_RX_LEN) + 4 * ep_idx))
  28. #define EPn_SET_TX_LEN(ep_idx, len) (*(volatile uint16_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_TX_LEN) + 4 * ep_idx) = len)
  29. #define EPn_CLEAR_TX_DONE(ep_idx) USB_SET_TX_CTRL(ep_idx, USB_GET_TX_CTRL(ep_idx) & ~USBHS_UEP_T_DONE)
  30. #define EPn_CLEAR_RX_DONE(ep_idx) USB_SET_RX_CTRL(ep_idx, USB_GET_RX_CTRL(ep_idx) & ~USBHS_UEP_R_DONE)
  31. #define EPn_SET_TX_ISO_VALID(ep_idx)
  32. #define EPn_SET_RX_ISO_VALID(ep_idx)
  33. /* ep nums */
  34. #ifndef CONFIG_USBDEV_EP_NUM
  35. #define CONFIG_USBDEV_EP_NUM 8
  36. #endif
  37. /**
  38. * @brief Endpoint information structure
  39. */
  40. typedef struct _usbd_ep_info {
  41. uint8_t mps; /* Maximum packet length of endpoint */
  42. uint8_t eptype; /* Endpoint Type */
  43. uint8_t ep_enable; /* Endpoint enable */
  44. uint8_t *xfer_buf;
  45. uint32_t xfer_len;
  46. uint32_t actual_xfer_len;
  47. } usbd_ep_info;
  48. /* ch58x usb */
  49. static struct _ch58x_core_prvi {
  50. uint8_t address; /* Address */
  51. usbd_ep_info ep_in[CONFIG_USBDEV_EP_NUM];
  52. usbd_ep_info ep_out[CONFIG_USBDEV_EP_NUM];
  53. struct usb_setup_packet setup;
  54. } usb_dc_cfg;
  55. __WEAK void usb_dc_low_level_init(void)
  56. {
  57. }
  58. __WEAK void usb_dc_low_level_deinit(void)
  59. {
  60. }
  61. /**
  62. * @brief USB initialization
  63. * @pre None
  64. * @param[in] None
  65. * @retval >=0 success otherwise failure
  66. */
  67. int usb_dc_init(uint8_t busid)
  68. {
  69. R8_USBHS_PLL_CTRL = USBHS_PLL_EN;
  70. R16_PIN_CONFIG |= RB_PIN_USB2_EN;
  71. CH585_USBHS_DEV->CONTROL = USBHS_UD_RST_LINK | USBHS_UD_PHY_SUSPENDM;
  72. CH585_USBHS_DEV->INT_EN = USBHS_UDIE_BUS_RST | USBHS_UDIE_SUSPEND | USBHS_UDIE_BUS_SLEEP | USBHS_UDIE_LPM_ACT | USBHS_UDIE_TRANSFER | USBHS_UDIE_LINK_RDY;
  73. /* Enable all end points */
  74. CH585_USBHS_DEV->UEP_TX_EN = 0xffff;
  75. CH585_USBHS_DEV->UEP_RX_EN = 0xffff;
  76. CH585_USBHS_DEV->BASE_MODE = USBHS_UD_SPEED_HIGH;
  77. CH585_USBHS_DEV->CONTROL = USBHS_UD_DEV_EN | USBHS_UD_DMA_EN | USBHS_UD_LPM_EN | USBHS_UD_PHY_SUSPENDM;
  78. CH585_USBHS_DEV->UEP_T_TOG_AUTO = 0xfe;
  79. CH585_USBHS_DEV->UEP_R_TOG_AUTO = 0xfe;
  80. usb_dc_low_level_init();
  81. return 0;
  82. }
  83. int usb_dc_deinit(uint8_t busid)
  84. {
  85. R8_USBHS_PLL_CTRL &= ~USBHS_PLL_EN;
  86. R32_PIN_CONFIG &= ~RB_PIN_USB2_EN;
  87. CH585_USBHS_DEV->CONTROL |= USBHS_UD_RST_SIE;
  88. CH585_USBHS_DEV->CONTROL &= ~USBHS_UD_RST_SIE;
  89. usb_dc_low_level_deinit();
  90. return 0;
  91. }
  92. /**
  93. * @brief Set address
  94. * @pre None
  95. * @param[in] address :8-bit valid address
  96. * @retval >=0 success otherwise failure
  97. */
  98. int usbd_set_address(uint8_t busid, const uint8_t address)
  99. {
  100. if (address == 0) {
  101. CH585_USBHS_DEV->DEV_AD = (CH585_USBHS_DEV->DEV_AD & 0x80) | address;
  102. }
  103. usb_dc_cfg.address = address;
  104. return 0;
  105. }
  106. int usbd_set_remote_wakeup(uint8_t busid)
  107. {
  108. return -1;
  109. }
  110. uint8_t usbd_get_port_speed(uint8_t busid)
  111. {
  112. return USB_SPEED_HIGH;
  113. }
  114. /**
  115. * @brief Open endpoint
  116. * @pre None
  117. * @param[in] ep_cfg : Endpoint configuration structure pointer
  118. * @retval >=0 success otherwise failure
  119. */
  120. int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
  121. {
  122. uint8_t epid = USB_EP_GET_IDX(ep->bEndpointAddress);
  123. if (epid > (CONFIG_USBDEV_EP_NUM - 1)) {
  124. /**
  125. * If you use ch58x, you can change the CONFIG_USBDEV_EP_NUM set to 8
  126. */
  127. USB_LOG_ERR("Ep addr %02x overflow\r\n", ep->bEndpointAddress);
  128. return -1;
  129. }
  130. uint8_t mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
  131. USB_SET_MAX_LEN(epid, mps);
  132. if (USB_EP_DIR_IS_IN(ep->bEndpointAddress)) {
  133. usb_dc_cfg.ep_in[epid].ep_enable = true;
  134. usb_dc_cfg.ep_in[epid].mps = mps;
  135. usb_dc_cfg.ep_in[epid].eptype = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
  136. USB_SET_TX_CTRL(epid, USBHS_UEP_T_RES_NAK);
  137. EPn_CLEAR_TX_DONE(epid);
  138. } else if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
  139. usb_dc_cfg.ep_out[epid].ep_enable = true;
  140. usb_dc_cfg.ep_out[epid].mps = mps;
  141. usb_dc_cfg.ep_out[epid].eptype = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
  142. USB_SET_RX_CTRL(epid, USBHS_UEP_R_RES_NAK);
  143. }
  144. return 0;
  145. }
  146. /**
  147. * @brief Close endpoint
  148. * @pre None
  149. * @param[in] ep : Endpoint address
  150. * @retval >=0 success otherwise failure
  151. */
  152. int usbd_ep_close(uint8_t busid, const uint8_t ep)
  153. {
  154. uint8_t epid = USB_EP_GET_IDX(ep);
  155. if (USB_EP_DIR_IS_IN(ep)) {
  156. usb_dc_cfg.ep_in[epid].ep_enable = false;
  157. } else if (USB_EP_DIR_IS_OUT(ep)) {
  158. usb_dc_cfg.ep_out[epid].ep_enable = false;
  159. }
  160. return 0;
  161. }
  162. /**
  163. * @brief Endpoint setting stall
  164. * @pre None
  165. * @param[in] ep : Endpoint address
  166. * @retval >=0 success otherwise failure
  167. */
  168. int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
  169. {
  170. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  171. if (USB_EP_DIR_IS_OUT(ep)) {
  172. if (ep_idx == 0) {
  173. CH585_USBHS_DEV->UEP0_RX_CTRL = USBHS_UEP_R_RES_STALL;
  174. } else {
  175. USB_SET_RX_CTRL(ep_idx, (USB_GET_RX_CTRL(ep_idx) & ~USBHS_UEP_R_RES_MASK) | USBHS_UEP_R_RES_STALL);
  176. }
  177. } else {
  178. if (ep_idx == 0) {
  179. CH585_USBHS_DEV->UEP0_TX_CTRL = USBHS_UEP_T_RES_STALL;
  180. } else {
  181. USB_SET_TX_CTRL(ep_idx, (USB_GET_TX_CTRL(ep_idx) & ~USBHS_UEP_T_RES_MASK) | USBHS_UEP_T_RES_STALL);
  182. }
  183. }
  184. return 0;
  185. }
  186. /**
  187. * @brief Endpoint clear stall
  188. * @pre None
  189. * @param[in] ep : Endpoint address
  190. * @retval >=0 success otherwise failure
  191. */
  192. int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
  193. {
  194. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  195. if (USB_EP_DIR_IS_OUT(ep)) {
  196. USB_SET_RX_CTRL(ep_idx, USBHS_UEP_R_RES_ACK | USBHS_UEP_R_TOG_DATA0);
  197. } else {
  198. USB_SET_TX_CTRL(ep_idx, USBHS_UEP_T_RES_NAK | USBHS_UEP_T_TOG_DATA0);
  199. }
  200. return 0;
  201. }
  202. /**
  203. * @brief Check endpoint status
  204. * @pre None
  205. * @param[in] ep : Endpoint address
  206. * @param[out] stalled : Outgoing endpoint status
  207. * @retval >=0 success otherwise failure
  208. */
  209. int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
  210. {
  211. if (USB_EP_DIR_IS_OUT(ep)) {
  212. } else {
  213. }
  214. return 0;
  215. }
  216. /**
  217. * @brief Setup in ep transfer setting and start transfer.
  218. *
  219. * This function is asynchronous.
  220. * This function is similar to uart with tx dma.
  221. *
  222. * This function is called to write data to the specified endpoint. The
  223. * supplied usbd_endpoint_callback function will be called when data is transmitted
  224. * out.
  225. *
  226. * @param[in] ep Endpoint address corresponding to the one
  227. * listed in the device configuration table
  228. * @param[in] data Pointer to data to write
  229. * @param[in] data_len Length of the data requested to write. This may
  230. * be zero for a zero length status packet.
  231. * @return 0 on success, negative errno code on fail.
  232. */
  233. int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
  234. {
  235. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  236. if (!data && data_len) {
  237. return -1;
  238. }
  239. if (!usb_dc_cfg.ep_in[ep_idx].ep_enable) {
  240. return -2;
  241. }
  242. if ((uint32_t)data & 0x03) {
  243. return -3;
  244. }
  245. usb_dc_cfg.ep_in[ep_idx].xfer_buf = (uint8_t *)data;
  246. usb_dc_cfg.ep_in[ep_idx].xfer_len = data_len;
  247. usb_dc_cfg.ep_in[ep_idx].actual_xfer_len = 0;
  248. if (ep_idx == 0) {
  249. if (data_len == 0) {
  250. USB_SET_TX_LEN(ep_idx, 0);
  251. } else {
  252. data_len = MIN(data_len, usb_dc_cfg.ep_in[ep_idx].mps);
  253. USB_SET_TX_LEN(ep_idx, data_len);
  254. CH585_USBHS_DEV->UEP0_DMA = (uint32_t)data;
  255. }
  256. } else {
  257. if (data_len == 0) {
  258. USB_SET_TX_LEN(ep_idx, 0);
  259. } else {
  260. data_len = MIN(data_len, usb_dc_cfg.ep_in[ep_idx].mps);
  261. USB_SET_TX_LEN(ep_idx, data_len);
  262. USB_SET_TX_DMA(ep_idx, (uint32_t)data);
  263. }
  264. }
  265. EPn_SET_TX_VALID(ep_idx);
  266. return 0;
  267. }
  268. /**
  269. * @brief Setup out ep transfer setting and start transfer.
  270. *
  271. * This function is asynchronous.
  272. * This function is similar to uart with rx dma.
  273. *
  274. * This function is called to read data to the specified endpoint. The
  275. * supplied usbd_endpoint_callback function will be called when data is received
  276. * in.
  277. *
  278. * @param[in] ep Endpoint address corresponding to the one
  279. * listed in the device configuration table
  280. * @param[in] data Pointer to data to read
  281. * @param[in] data_len Max length of the data requested to read.
  282. *
  283. * @return 0 on success, negative errno code on fail.
  284. */
  285. int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
  286. {
  287. uint8_t ep_idx = USB_EP_GET_IDX(ep);
  288. if (!data && data_len) {
  289. return -1;
  290. }
  291. if (!usb_dc_cfg.ep_out[ep_idx].ep_enable) {
  292. return -2;
  293. }
  294. if ((uint32_t)data & 0x03) {
  295. return -3;
  296. }
  297. usb_dc_cfg.ep_out[ep_idx].xfer_buf = (uint8_t *)data;
  298. usb_dc_cfg.ep_out[ep_idx].xfer_len = data_len;
  299. usb_dc_cfg.ep_out[ep_idx].actual_xfer_len = 0;
  300. if (ep_idx == 0) {
  301. if (data_len == 0) {
  302. } else {
  303. CH585_USBHS_DEV->UEP0_DMA = (uint32_t)data;
  304. }
  305. } else {
  306. USB_SET_RX_DMA(ep_idx, (uint32_t)data);
  307. }
  308. EPn_SET_RX_VALID(ep_idx);
  309. return 0;
  310. }
  311. static inline void handle_ep0_in(void)
  312. {
  313. switch (usb_dc_cfg.setup.bmRequestType >> USB_REQUEST_DIR_SHIFT) {
  314. case 1:
  315. CH585_USBHS_DEV->UEP0_TX_CTRL ^= USBHS_UEP_T_TOG_DATA1;
  316. EPn_SET_TX_NAK(0);
  317. if (usb_dc_cfg.ep_in[0].xfer_len > usb_dc_cfg.ep_in[0].mps) {
  318. usb_dc_cfg.ep_in[0].xfer_len -= usb_dc_cfg.ep_in[0].mps;
  319. usb_dc_cfg.ep_in[0].actual_xfer_len += usb_dc_cfg.ep_in[0].mps;
  320. usbd_event_ep_in_complete_handler(0, 0 | 0x80, usb_dc_cfg.ep_in[0].actual_xfer_len);
  321. } else {
  322. usb_dc_cfg.ep_in[0].actual_xfer_len += usb_dc_cfg.ep_in[0].xfer_len;
  323. usb_dc_cfg.ep_in[0].xfer_len = 0;
  324. usbd_event_ep_in_complete_handler(0, 0 | 0x80, usb_dc_cfg.ep_in[0].actual_xfer_len);
  325. }
  326. break;
  327. case 0:
  328. /* Set */
  329. switch (usb_dc_cfg.setup.bRequest) {
  330. case USB_REQUEST_SET_ADDRESS:
  331. /* Fill in the equipment address */
  332. CH585_USBHS_DEV->DEV_AD = usb_dc_cfg.address;
  333. CH585_USBHS_DEV->UEP0_DMA = (uint32_t)&usb_dc_cfg.setup;
  334. EPn_SET_TX_NAK(0);
  335. EPn_SET_RX_VALID(0);
  336. break;
  337. default:
  338. /* Normal out state phase */
  339. CH585_USBHS_DEV->UEP0_DMA = (uint32_t)&usb_dc_cfg.setup;
  340. EPn_SET_TX_NAK(0);
  341. EPn_SET_RX_VALID(0);
  342. break;
  343. }
  344. break;
  345. }
  346. }
  347. static inline void handle_non_ep0_in(uint8_t epid)
  348. {
  349. EPn_SET_TX_NAK(epid);
  350. if (usb_dc_cfg.ep_in[epid].xfer_len > usb_dc_cfg.ep_in[epid].mps) {
  351. /* Need start in again */
  352. usb_dc_cfg.ep_in[epid].xfer_buf += usb_dc_cfg.ep_in[epid].mps;
  353. usb_dc_cfg.ep_in[epid].xfer_len -= usb_dc_cfg.ep_in[epid].mps;
  354. usb_dc_cfg.ep_in[epid].actual_xfer_len += usb_dc_cfg.ep_in[epid].mps;
  355. uint32_t write_count = MIN(usb_dc_cfg.ep_in[epid].xfer_len, usb_dc_cfg.ep_in[epid].mps);
  356. USB_SET_TX_LEN(epid, write_count);
  357. USB_SET_TX_DMA(epid, (uint32_t)usb_dc_cfg.ep_in[epid].xfer_buf);
  358. if (usb_dc_cfg.ep_in[epid].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
  359. EPn_SET_TX_VALID(epid);
  360. } else {
  361. EPn_SET_TX_ISO_VALID(epid);
  362. }
  363. } else {
  364. usb_dc_cfg.ep_in[epid].actual_xfer_len += usb_dc_cfg.ep_in[epid].xfer_len;
  365. usb_dc_cfg.ep_in[epid].xfer_len = 0;
  366. usbd_event_ep_in_complete_handler(0, epid | 0x80, usb_dc_cfg.ep_in[epid].actual_xfer_len);
  367. }
  368. }
  369. static inline void usb_process_ep_in(uint8_t epid)
  370. {
  371. if (epid == 0) {
  372. handle_ep0_in();
  373. } else {
  374. handle_non_ep0_in(epid);
  375. }
  376. EPn_CLEAR_TX_DONE(epid);
  377. }
  378. static inline void usb_process_ep_out(uint8_t epid)
  379. {
  380. EPn_SET_RX_NAK(epid);
  381. if (epid == 0) {
  382. if (CH585_USBHS_DEV->UEP0_RX_CTRL & USBHS_UEP_R_SETUP_IS) {
  383. CH585_USBHS_DEV->UEP0_RX_CTRL |= USBHS_UEP_R_TOG_DATA1;
  384. CH585_USBHS_DEV->UEP0_TX_CTRL |= USBHS_UEP_T_TOG_DATA1;
  385. if (usb_dc_cfg.setup.bmRequestType >> USB_REQUEST_DIR_SHIFT == 0) {
  386. /**
  387. * Ep0 The next in must be the status stage.
  388. * The device must reply to the host data 0 length packet.
  389. * Here, set the transmission length to 0 and the transmission status to ACK,
  390. * and wait for the host to send the in token to retrieve
  391. */
  392. EPn_SET_TX_LEN(0, 0);
  393. EPn_SET_TX_VALID(0);
  394. }
  395. usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&usb_dc_cfg.setup);
  396. } else {
  397. CH585_USBHS_DEV->UEP0_RX_CTRL ^= USBHS_UEP_R_TOG_DATA1;
  398. uint32_t read_count = EPn_GET_RX_LEN(0);
  399. usb_dc_cfg.ep_out[0].actual_xfer_len += read_count;
  400. usb_dc_cfg.ep_out[0].xfer_len -= read_count;
  401. usbd_event_ep_out_complete_handler(0, 0x00, usb_dc_cfg.ep_out[0].actual_xfer_len);
  402. if (read_count == 0) {
  403. /* Out status, start reading setup */
  404. CH585_USBHS_DEV->UEP0_DMA = (uint32_t)&usb_dc_cfg.setup;
  405. EPn_SET_RX_VALID(0);
  406. }
  407. }
  408. } else {
  409. if (USB_GET_RX_CTRL(epid) & USBHS_UEP_R_TOG_MATCH) {
  410. uint32_t read_count = EPn_GET_RX_LEN(epid);
  411. usb_dc_cfg.ep_out[epid].xfer_buf += read_count;
  412. usb_dc_cfg.ep_out[epid].actual_xfer_len += read_count;
  413. usb_dc_cfg.ep_out[epid].xfer_len -= read_count;
  414. if ((read_count < usb_dc_cfg.ep_out[epid].mps) || (usb_dc_cfg.ep_out[epid].xfer_len == 0)) {
  415. usbd_event_ep_out_complete_handler(0, ((epid) & 0x7f), usb_dc_cfg.ep_out[epid].actual_xfer_len);
  416. } else {
  417. USB_SET_RX_DMA(epid, (uint32_t)usb_dc_cfg.ep_out[epid].xfer_buf);
  418. if (usb_dc_cfg.ep_out[epid].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
  419. EPn_SET_RX_VALID(epid);
  420. } else {
  421. EPn_SET_RX_ISO_VALID(epid);
  422. }
  423. }
  424. }
  425. }
  426. EPn_CLEAR_RX_DONE(epid);
  427. }
  428. static inline void usb_trans_end_process(void)
  429. {
  430. uint8_t epid = (CH585_USBHS_DEV->INT_ST & USBHS_UDIS_EP_ID_MASK);
  431. switch (CH585_USBHS_DEV->INT_ST & USBHS_UDIS_EP_DIR) {
  432. case USBHS_UDIS_EP_DIR: /* in */
  433. usb_process_ep_in(epid);
  434. break;
  435. case 0: /* setup or out */
  436. usb_process_ep_out(epid);
  437. break;
  438. default:
  439. break;
  440. }
  441. }
  442. /**
  443. * @brief USB interrupt processing function
  444. * @pre None
  445. * @param[in] None
  446. * @retval None
  447. */
  448. __attribute__((interrupt("WCH-Interrupt-fast")))
  449. __attribute__((section(".highcode"))) void
  450. USBD_IRQHandler(void)
  451. {
  452. volatile uint8_t intflag = 0;
  453. intflag = CH585_USBHS_DEV->INT_FG;
  454. if (intflag & USBHS_UDIF_TRANSFER) {
  455. usb_trans_end_process();
  456. } else if (intflag & USBHS_UDIF_BUS_RST) {
  457. /* Reset */
  458. CH585_USBHS_DEV->DEV_AD = 0;
  459. usbd_event_reset_handler(0);
  460. /* Set ep0 rx vaild to start receive setup packet */
  461. CH585_USBHS_DEV->UEP0_DMA = (uint32_t)&usb_dc_cfg.setup;
  462. // EPn_SET_RX_VALID(0);
  463. R8_U2EP0_TX_CTRL = USBHS_UEP_T_RES_NAK;
  464. R8_U2EP0_RX_CTRL = USBHS_UEP_R_RES_ACK;
  465. CH585_USBHS_DEV->INT_FG = USBHS_UDIF_BUS_RST;
  466. } else if (intflag & USBHS_UDIF_SUSPEND) {
  467. if (CH585_USBHS_DEV->MIS_ST & 0x04) {
  468. /* Suspend */
  469. } else {
  470. /* Wake up */
  471. }
  472. CH585_USBHS_DEV->INT_FG = USBHS_UDIF_SUSPEND;
  473. } else {
  474. CH585_USBHS_DEV->INT_FG = intflag;
  475. }
  476. }