cdc_acm_template.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /*
  2. * Copyright (c) 2024, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "usbd_core.h"
  7. #include "usbd_cdc_acm.h"
  8. /*!< endpoint address */
  9. #define CDC_IN_EP 0x81
  10. #define CDC_OUT_EP 0x02
  11. #define CDC_INT_EP 0x83
  12. #define USBD_VID 0xFFFF
  13. #define USBD_PID 0xFFFF
  14. #define USBD_MAX_POWER 100
  15. #define USBD_LANGID_STRING 1033
  16. /*!< config descriptor size */
  17. #define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN)
  18. #ifdef CONFIG_USB_HS
  19. #define CDC_MAX_MPS 512
  20. #else
  21. #define CDC_MAX_MPS 64
  22. #endif
  23. /*!< global descriptor */
  24. static const uint8_t cdc_descriptor[] = {
  25. USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
  26. USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
  27. CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
  28. ///////////////////////////////////////
  29. /// string0 descriptor
  30. ///////////////////////////////////////
  31. USB_LANGID_INIT(USBD_LANGID_STRING),
  32. ///////////////////////////////////////
  33. /// string1 descriptor
  34. ///////////////////////////////////////
  35. 0x14, /* bLength */
  36. USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
  37. 'C', 0x00, /* wcChar0 */
  38. 'h', 0x00, /* wcChar1 */
  39. 'e', 0x00, /* wcChar2 */
  40. 'r', 0x00, /* wcChar3 */
  41. 'r', 0x00, /* wcChar4 */
  42. 'y', 0x00, /* wcChar5 */
  43. 'U', 0x00, /* wcChar6 */
  44. 'S', 0x00, /* wcChar7 */
  45. 'B', 0x00, /* wcChar8 */
  46. ///////////////////////////////////////
  47. /// string2 descriptor
  48. ///////////////////////////////////////
  49. 0x26, /* bLength */
  50. USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
  51. 'C', 0x00, /* wcChar0 */
  52. 'h', 0x00, /* wcChar1 */
  53. 'e', 0x00, /* wcChar2 */
  54. 'r', 0x00, /* wcChar3 */
  55. 'r', 0x00, /* wcChar4 */
  56. 'y', 0x00, /* wcChar5 */
  57. 'U', 0x00, /* wcChar6 */
  58. 'S', 0x00, /* wcChar7 */
  59. 'B', 0x00, /* wcChar8 */
  60. ' ', 0x00, /* wcChar9 */
  61. 'C', 0x00, /* wcChar10 */
  62. 'D', 0x00, /* wcChar11 */
  63. 'C', 0x00, /* wcChar12 */
  64. ' ', 0x00, /* wcChar13 */
  65. 'D', 0x00, /* wcChar14 */
  66. 'E', 0x00, /* wcChar15 */
  67. 'M', 0x00, /* wcChar16 */
  68. 'O', 0x00, /* wcChar17 */
  69. ///////////////////////////////////////
  70. /// string3 descriptor
  71. ///////////////////////////////////////
  72. 0x16, /* bLength */
  73. USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
  74. '2', 0x00, /* wcChar0 */
  75. '0', 0x00, /* wcChar1 */
  76. '2', 0x00, /* wcChar2 */
  77. '2', 0x00, /* wcChar3 */
  78. '1', 0x00, /* wcChar4 */
  79. '2', 0x00, /* wcChar5 */
  80. '3', 0x00, /* wcChar6 */
  81. '4', 0x00, /* wcChar7 */
  82. '5', 0x00, /* wcChar8 */
  83. '6', 0x00, /* wcChar9 */
  84. #ifdef CONFIG_USB_HS
  85. ///////////////////////////////////////
  86. /// device qualifier descriptor
  87. ///////////////////////////////////////
  88. 0x0a,
  89. USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
  90. 0x00,
  91. 0x02,
  92. 0x02,
  93. 0x02,
  94. 0x01,
  95. 0x40,
  96. 0x00,
  97. 0x00,
  98. #endif
  99. 0x00
  100. };
  101. USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048]; /* 2048 is only for test speed , please use CDC_MAX_MPS for common*/
  102. USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
  103. volatile bool ep_tx_busy_flag = false;
  104. static void usbd_event_handler(uint8_t busid, uint8_t event)
  105. {
  106. switch (event) {
  107. case USBD_EVENT_RESET:
  108. break;
  109. case USBD_EVENT_CONNECTED:
  110. break;
  111. case USBD_EVENT_DISCONNECTED:
  112. break;
  113. case USBD_EVENT_RESUME:
  114. break;
  115. case USBD_EVENT_SUSPEND:
  116. break;
  117. case USBD_EVENT_CONFIGURED:
  118. ep_tx_busy_flag = false;
  119. /* setup first out ep read transfer */
  120. usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048);
  121. break;
  122. case USBD_EVENT_SET_REMOTE_WAKEUP:
  123. break;
  124. case USBD_EVENT_CLR_REMOTE_WAKEUP:
  125. break;
  126. default:
  127. break;
  128. }
  129. }
  130. void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
  131. {
  132. USB_LOG_RAW("actual out len:%d\r\n", nbytes);
  133. // for (int i = 0; i < 100; i++) {
  134. // printf("%02x ", read_buffer[i]);
  135. // }
  136. // printf("\r\n");
  137. /* setup next out ep read transfer */
  138. usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048);
  139. }
  140. void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
  141. {
  142. USB_LOG_RAW("actual in len:%d\r\n", nbytes);
  143. if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
  144. /* send zlp */
  145. usbd_ep_start_write(busid, CDC_IN_EP, NULL, 0);
  146. } else {
  147. ep_tx_busy_flag = false;
  148. }
  149. }
  150. /*!< endpoint call back */
  151. struct usbd_endpoint cdc_out_ep = {
  152. .ep_addr = CDC_OUT_EP,
  153. .ep_cb = usbd_cdc_acm_bulk_out
  154. };
  155. struct usbd_endpoint cdc_in_ep = {
  156. .ep_addr = CDC_IN_EP,
  157. .ep_cb = usbd_cdc_acm_bulk_in
  158. };
  159. static struct usbd_interface intf0;
  160. static struct usbd_interface intf1;
  161. void cdc_acm_init(uint8_t busid, uintptr_t reg_base)
  162. {
  163. const uint8_t data[10] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30 };
  164. memcpy(&write_buffer[0], data, 10);
  165. memset(&write_buffer[10], 'a', 2038);
  166. usbd_desc_register(busid, cdc_descriptor);
  167. usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0));
  168. usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1));
  169. usbd_add_endpoint(busid, &cdc_out_ep);
  170. usbd_add_endpoint(busid, &cdc_in_ep);
  171. usbd_initialize(busid, reg_base, usbd_event_handler);
  172. }
  173. volatile uint8_t dtr_enable = 0;
  174. void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr)
  175. {
  176. if (dtr) {
  177. dtr_enable = 1;
  178. } else {
  179. dtr_enable = 0;
  180. }
  181. }
  182. void cdc_acm_data_send_with_dtr_test(uint8_t busid)
  183. {
  184. if (dtr_enable) {
  185. ep_tx_busy_flag = true;
  186. usbd_ep_start_write(busid, CDC_IN_EP, write_buffer, 2048);
  187. while (ep_tx_busy_flag) {
  188. }
  189. }
  190. }