cdc_acm_msc_template.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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. #include "usbd_msc.h"
  9. /*!< endpoint address */
  10. #define CDC_IN_EP 0x81
  11. #define CDC_OUT_EP 0x02
  12. #define CDC_INT_EP 0x83
  13. #define MSC_IN_EP 0x84
  14. #define MSC_OUT_EP 0x05
  15. #define USBD_VID 0xFFFF
  16. #define USBD_PID 0xFFFF
  17. #define USBD_MAX_POWER 100
  18. #define USBD_LANGID_STRING 1033
  19. /*!< config descriptor size */
  20. #define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN + MSC_DESCRIPTOR_LEN)
  21. #ifdef CONFIG_USB_HS
  22. #define CDC_MAX_MPS 512
  23. #else
  24. #define CDC_MAX_MPS 64
  25. #endif
  26. #ifdef CONFIG_USB_HS
  27. #define MSC_MAX_MPS 512
  28. #else
  29. #define MSC_MAX_MPS 64
  30. #endif
  31. static const uint8_t device_descriptor[] = {
  32. USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
  33. };
  34. static const uint8_t config_descriptor[] = {
  35. USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
  36. CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
  37. MSC_DESCRIPTOR_INIT(0x02, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x00)
  38. };
  39. static const uint8_t device_quality_descriptor[] = {
  40. ///////////////////////////////////////
  41. /// device qualifier descriptor
  42. ///////////////////////////////////////
  43. 0x0a,
  44. USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
  45. 0x00,
  46. 0x02,
  47. 0x00,
  48. 0x00,
  49. 0x00,
  50. 0x40,
  51. 0x00,
  52. 0x00,
  53. };
  54. static const char *string_descriptors[] = {
  55. (const char[]){ 0x09, 0x04 }, /* Langid */
  56. "CherryUSB", /* Manufacturer */
  57. "CherryUSB CDC MSC DEMO", /* Product */
  58. "2022123456", /* Serial Number */
  59. };
  60. static const uint8_t *device_descriptor_callback(uint8_t speed)
  61. {
  62. return device_descriptor;
  63. }
  64. static const uint8_t *config_descriptor_callback(uint8_t speed)
  65. {
  66. return config_descriptor;
  67. }
  68. static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
  69. {
  70. return device_quality_descriptor;
  71. }
  72. static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
  73. {
  74. if (index > 3) {
  75. return NULL;
  76. }
  77. return string_descriptors[index];
  78. }
  79. const struct usb_descriptor cdc_msc_descriptor = {
  80. .device_descriptor_callback = device_descriptor_callback,
  81. .config_descriptor_callback = config_descriptor_callback,
  82. .device_quality_descriptor_callback = device_quality_descriptor_callback,
  83. .string_descriptor_callback = string_descriptor_callback
  84. };
  85. 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*/
  86. USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
  87. volatile bool ep_tx_busy_flag = false;
  88. static void usbd_event_handler(uint8_t busid, uint8_t event)
  89. {
  90. switch (event) {
  91. case USBD_EVENT_RESET:
  92. break;
  93. case USBD_EVENT_CONNECTED:
  94. break;
  95. case USBD_EVENT_DISCONNECTED:
  96. break;
  97. case USBD_EVENT_RESUME:
  98. break;
  99. case USBD_EVENT_SUSPEND:
  100. break;
  101. case USBD_EVENT_CONFIGURED:
  102. ep_tx_busy_flag = false;
  103. /* setup first out ep read transfer */
  104. usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048);
  105. break;
  106. case USBD_EVENT_SET_REMOTE_WAKEUP:
  107. break;
  108. case USBD_EVENT_CLR_REMOTE_WAKEUP:
  109. break;
  110. default:
  111. break;
  112. }
  113. }
  114. void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
  115. {
  116. USB_LOG_RAW("actual out len:%d\r\n", (unsigned int)nbytes);
  117. /* setup next out ep read transfer */
  118. usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048);
  119. }
  120. void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
  121. {
  122. USB_LOG_RAW("actual in len:%d\r\n", (unsigned int)nbytes);
  123. if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
  124. /* send zlp */
  125. usbd_ep_start_write(busid, CDC_IN_EP, NULL, 0);
  126. } else {
  127. ep_tx_busy_flag = false;
  128. }
  129. }
  130. /*!< endpoint call back */
  131. struct usbd_endpoint cdc_out_ep = {
  132. .ep_addr = CDC_OUT_EP,
  133. .ep_cb = usbd_cdc_acm_bulk_out
  134. };
  135. struct usbd_endpoint cdc_in_ep = {
  136. .ep_addr = CDC_IN_EP,
  137. .ep_cb = usbd_cdc_acm_bulk_in
  138. };
  139. struct usbd_interface intf0;
  140. struct usbd_interface intf1;
  141. struct usbd_interface intf2;
  142. void cdc_acm_msc_init(uint8_t busid, uintptr_t reg_base)
  143. {
  144. usbd_desc_register(busid, &cdc_msc_descriptor);
  145. usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0));
  146. usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1));
  147. usbd_add_endpoint(busid, &cdc_out_ep);
  148. usbd_add_endpoint(busid, &cdc_in_ep);
  149. usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf2, MSC_OUT_EP, MSC_IN_EP));
  150. usbd_initialize(busid, reg_base, usbd_event_handler);
  151. }
  152. volatile uint8_t dtr_enable = 0;
  153. void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr)
  154. {
  155. if (dtr) {
  156. dtr_enable = 1;
  157. } else {
  158. dtr_enable = 0;
  159. }
  160. }
  161. void cdc_acm_data_send_with_dtr_test(uint8_t busid)
  162. {
  163. if (dtr_enable) {
  164. memset(&write_buffer[10], 'a', 2038);
  165. ep_tx_busy_flag = true;
  166. usbd_ep_start_write(busid, CDC_IN_EP, write_buffer, 2048);
  167. while (ep_tx_busy_flag) {
  168. }
  169. }
  170. }
  171. #define BLOCK_SIZE 512
  172. #define BLOCK_COUNT 10
  173. typedef struct
  174. {
  175. uint8_t BlockSpace[BLOCK_SIZE];
  176. } BLOCK_TYPE;
  177. BLOCK_TYPE mass_block[BLOCK_COUNT];
  178. void usbd_msc_get_cap(uint8_t busid, uint8_t lun, uint32_t *block_num, uint32_t *block_size)
  179. {
  180. *block_num = 1000; //Pretend having so many buffer,not has actually.
  181. *block_size = BLOCK_SIZE;
  182. }
  183. int usbd_msc_sector_read(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
  184. {
  185. if (sector < 10)
  186. memcpy(buffer, mass_block[sector].BlockSpace, length);
  187. return 0;
  188. }
  189. int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
  190. {
  191. if (sector < 10)
  192. memcpy(mass_block[sector].BlockSpace, buffer, length);
  193. return 0;
  194. }