cdc_acm_hid_msc_template.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. /*
  2. * Copyright (c) 2024, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "usbd_core.h"
  7. #include "usbd_msc.h"
  8. #include "usbd_cdc_acm.h"
  9. #include "usbd_hid.h"
  10. /*!< endpoint address */
  11. #define CDC_IN_EP 0x81
  12. #define CDC_OUT_EP 0x02
  13. #define CDC_INT_EP 0x83
  14. #define MSC_IN_EP 0x84
  15. #define MSC_OUT_EP 0x05
  16. /*!< endpoint address */
  17. #define HID_INT_EP 0x86
  18. #define HID_INT_EP_SIZE 4
  19. #define HID_INT_EP_INTERVAL 10
  20. #define USBD_VID 0xFFFF
  21. #define USBD_PID 0xFFFF
  22. #define USBD_MAX_POWER 100
  23. #define USBD_LANGID_STRING 1033
  24. /*!< report descriptor size */
  25. #define HID_MOUSE_REPORT_DESC_SIZE 74
  26. #define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN + MSC_DESCRIPTOR_LEN + 25)
  27. #ifdef CONFIG_USB_HS
  28. #define CDC_MAX_MPS 512
  29. #else
  30. #define CDC_MAX_MPS 64
  31. #endif
  32. #ifdef CONFIG_USB_HS
  33. #define MSC_MAX_MPS 512
  34. #else
  35. #define MSC_MAX_MPS 64
  36. #endif
  37. #ifdef CONFIG_USBDEV_ADVANCE_DESC
  38. static const uint8_t device_descriptor[] = {
  39. USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01)
  40. };
  41. static const uint8_t config_descriptor[] = {
  42. USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x04, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
  43. CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
  44. MSC_DESCRIPTOR_INIT(0x02, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02),
  45. /************** Descriptor of Joystick Mouse interface ****************/
  46. /* 09 */
  47. 0x09, /* bLength: Interface Descriptor size */
  48. USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
  49. 0x03, /* bInterfaceNumber: Number of Interface */
  50. 0x00, /* bAlternateSetting: Alternate setting */
  51. 0x01, /* bNumEndpoints */
  52. 0x03, /* bInterfaceClass: HID */
  53. 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
  54. 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
  55. 0, /* iInterface: Index of string descriptor */
  56. /******************** Descriptor of Joystick Mouse HID ********************/
  57. /* 18 */
  58. 0x09, /* bLength: HID Descriptor size */
  59. HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
  60. 0x11, /* bcdHID: HID Class Spec release number */
  61. 0x01,
  62. 0x00, /* bCountryCode: Hardware target country */
  63. 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
  64. 0x22, /* bDescriptorType */
  65. HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
  66. 0x00,
  67. /******************** Descriptor of Mouse endpoint ********************/
  68. /* 27 */
  69. 0x07, /* bLength: Endpoint Descriptor size */
  70. USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
  71. HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
  72. 0x03, /* bmAttributes: Interrupt endpoint */
  73. HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
  74. 0x00,
  75. HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
  76. };
  77. static const uint8_t device_quality_descriptor[] = {
  78. ///////////////////////////////////////
  79. /// device qualifier descriptor
  80. ///////////////////////////////////////
  81. 0x0a,
  82. USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
  83. 0x00,
  84. 0x02,
  85. 0x00,
  86. 0x00,
  87. 0x00,
  88. 0x40,
  89. 0x00,
  90. 0x00,
  91. };
  92. static const char *string_descriptors[] = {
  93. (const char[]){ 0x09, 0x04 }, /* Langid */
  94. "CherryUSB", /* Manufacturer */
  95. "CherryUSB CDC MSC HID DEMO", /* Product */
  96. "2022123456", /* Serial Number */
  97. };
  98. static const uint8_t *device_descriptor_callback(uint8_t speed)
  99. {
  100. return device_descriptor;
  101. }
  102. static const uint8_t *config_descriptor_callback(uint8_t speed)
  103. {
  104. return config_descriptor;
  105. }
  106. static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
  107. {
  108. return device_quality_descriptor;
  109. }
  110. static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
  111. {
  112. if (index > 3) {
  113. return NULL;
  114. }
  115. return string_descriptors[index];
  116. }
  117. const struct usb_descriptor cdc_acm_hid_msc_descriptor = {
  118. .device_descriptor_callback = device_descriptor_callback,
  119. .config_descriptor_callback = config_descriptor_callback,
  120. .device_quality_descriptor_callback = device_quality_descriptor_callback,
  121. .string_descriptor_callback = string_descriptor_callback
  122. };
  123. #else
  124. const uint8_t cdc_acm_hid_msc_descriptor[] = {
  125. USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
  126. USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x04, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
  127. CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
  128. MSC_DESCRIPTOR_INIT(0x02, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02),
  129. /************** Descriptor of Joystick Mouse interface ****************/
  130. /* 09 */
  131. 0x09, /* bLength: Interface Descriptor size */
  132. USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
  133. 0x03, /* bInterfaceNumber: Number of Interface */
  134. 0x00, /* bAlternateSetting: Alternate setting */
  135. 0x01, /* bNumEndpoints */
  136. 0x03, /* bInterfaceClass: HID */
  137. 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
  138. 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
  139. 0, /* iInterface: Index of string descriptor */
  140. /******************** Descriptor of Joystick Mouse HID ********************/
  141. /* 18 */
  142. 0x09, /* bLength: HID Descriptor size */
  143. HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
  144. 0x11, /* bcdHID: HID Class Spec release number */
  145. 0x01,
  146. 0x00, /* bCountryCode: Hardware target country */
  147. 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
  148. 0x22, /* bDescriptorType */
  149. HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
  150. 0x00,
  151. /******************** Descriptor of Mouse endpoint ********************/
  152. /* 27 */
  153. 0x07, /* bLength: Endpoint Descriptor size */
  154. USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
  155. HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
  156. 0x03, /* bmAttributes: Interrupt endpoint */
  157. HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
  158. 0x00,
  159. HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
  160. ///////////////////////////////////////
  161. /// string0 descriptor
  162. ///////////////////////////////////////
  163. USB_LANGID_INIT(USBD_LANGID_STRING),
  164. ///////////////////////////////////////
  165. /// string1 descriptor
  166. ///////////////////////////////////////
  167. 0x14, /* bLength */
  168. USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
  169. 'C', 0x00, /* wcChar0 */
  170. 'h', 0x00, /* wcChar1 */
  171. 'e', 0x00, /* wcChar2 */
  172. 'r', 0x00, /* wcChar3 */
  173. 'r', 0x00, /* wcChar4 */
  174. 'y', 0x00, /* wcChar5 */
  175. 'U', 0x00, /* wcChar6 */
  176. 'S', 0x00, /* wcChar7 */
  177. 'B', 0x00, /* wcChar8 */
  178. ///////////////////////////////////////
  179. /// string2 descriptor
  180. ///////////////////////////////////////
  181. 0x26, /* bLength */
  182. USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
  183. 'C', 0x00, /* wcChar0 */
  184. 'h', 0x00, /* wcChar1 */
  185. 'e', 0x00, /* wcChar2 */
  186. 'r', 0x00, /* wcChar3 */
  187. 'r', 0x00, /* wcChar4 */
  188. 'y', 0x00, /* wcChar5 */
  189. 'U', 0x00, /* wcChar6 */
  190. 'S', 0x00, /* wcChar7 */
  191. 'B', 0x00, /* wcChar8 */
  192. ' ', 0x00, /* wcChar9 */
  193. 'C', 0x00, /* wcChar10 */
  194. 'M', 0x00, /* wcChar11 */
  195. 'H', 0x00, /* wcChar12 */
  196. ' ', 0x00, /* wcChar13 */
  197. 'D', 0x00, /* wcChar14 */
  198. 'E', 0x00, /* wcChar15 */
  199. 'M', 0x00, /* wcChar16 */
  200. 'O', 0x00, /* wcChar17 */
  201. ///////////////////////////////////////
  202. /// string3 descriptor
  203. ///////////////////////////////////////
  204. 0x16, /* bLength */
  205. USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
  206. '2', 0x00, /* wcChar0 */
  207. '0', 0x00, /* wcChar1 */
  208. '2', 0x00, /* wcChar2 */
  209. '2', 0x00, /* wcChar3 */
  210. '1', 0x00, /* wcChar4 */
  211. '2', 0x00, /* wcChar5 */
  212. '3', 0x00, /* wcChar6 */
  213. '4', 0x00, /* wcChar7 */
  214. '5', 0x00, /* wcChar8 */
  215. '6', 0x00, /* wcChar9 */
  216. #ifdef CONFIG_USB_HS
  217. ///////////////////////////////////////
  218. /// device qualifier descriptor
  219. ///////////////////////////////////////
  220. 0x0a,
  221. USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
  222. 0x00,
  223. 0x02,
  224. 0x00,
  225. 0x00,
  226. 0x00,
  227. 0x40,
  228. 0x00,
  229. 0x00,
  230. #endif
  231. 0x00
  232. };
  233. #endif
  234. /*!< hid mouse report descriptor */
  235. static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
  236. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  237. 0x09, 0x02, // USAGE (Mouse)
  238. 0xA1, 0x01, // COLLECTION (Application)
  239. 0x09, 0x01, // USAGE (Pointer)
  240. 0xA1, 0x00, // COLLECTION (Physical)
  241. 0x05, 0x09, // USAGE_PAGE (Button)
  242. 0x19, 0x01, // USAGE_MINIMUM (Button 1)
  243. 0x29, 0x03, // USAGE_MAXIMUM (Button 3)
  244. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  245. 0x25, 0x01, // LOGICAL_MAXIMUM (1)
  246. 0x95, 0x03, // REPORT_COUNT (3)
  247. 0x75, 0x01, // REPORT_SIZE (1)
  248. 0x81, 0x02, // INPUT (Data,Var,Abs)
  249. 0x95, 0x01, // REPORT_COUNT (1)
  250. 0x75, 0x05, // REPORT_SIZE (5)
  251. 0x81, 0x01, // INPUT (Cnst,Var,Abs)
  252. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  253. 0x09, 0x30, // USAGE (X)
  254. 0x09, 0x31, // USAGE (Y)
  255. 0x09, 0x38,
  256. 0x15, 0x81, // LOGICAL_MINIMUM (-127)
  257. 0x25, 0x7F, // LOGICAL_MAXIMUM (127)
  258. 0x75, 0x08, // REPORT_SIZE (8)
  259. 0x95, 0x03, // REPORT_COUNT (2)
  260. 0x81, 0x06, // INPUT (Data,Var,Rel)
  261. 0xC0, 0x09,
  262. 0x3c, 0x05,
  263. 0xff, 0x09,
  264. 0x01, 0x15,
  265. 0x00, 0x25,
  266. 0x01, 0x75,
  267. 0x01, 0x95,
  268. 0x02, 0xb1,
  269. 0x22, 0x75,
  270. 0x06, 0x95,
  271. 0x01, 0xb1,
  272. 0x01, 0xc0 // END_COLLECTION
  273. };
  274. /*!< mouse report struct */
  275. struct hid_mouse {
  276. uint8_t buttons;
  277. int8_t x;
  278. int8_t y;
  279. int8_t wheel;
  280. };
  281. /*!< mouse report */
  282. static struct hid_mouse mouse_cfg;
  283. #define HID_STATE_IDLE 0
  284. #define HID_STATE_BUSY 1
  285. /*!< hid state ! Data can be sent only when state is idle */
  286. static volatile uint8_t hid_state = HID_STATE_IDLE;
  287. /* function ------------------------------------------------------------------*/
  288. static void usbd_hid_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
  289. {
  290. hid_state = HID_STATE_IDLE;
  291. }
  292. /*!< endpoint call back */
  293. static struct usbd_endpoint hid_in_ep = {
  294. .ep_cb = usbd_hid_int_callback,
  295. .ep_addr = HID_INT_EP
  296. };
  297. USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048];
  298. USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
  299. volatile bool ep_tx_busy_flag = false;
  300. static void usbd_event_handler(uint8_t busid, uint8_t event)
  301. {
  302. switch (event) {
  303. case USBD_EVENT_RESET:
  304. break;
  305. case USBD_EVENT_CONNECTED:
  306. break;
  307. case USBD_EVENT_DISCONNECTED:
  308. break;
  309. case USBD_EVENT_RESUME:
  310. break;
  311. case USBD_EVENT_SUSPEND:
  312. break;
  313. case USBD_EVENT_CONFIGURED:
  314. ep_tx_busy_flag = false;
  315. hid_state = HID_STATE_IDLE;
  316. /* setup first out ep read transfer */
  317. usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048);
  318. break;
  319. case USBD_EVENT_SET_REMOTE_WAKEUP:
  320. break;
  321. case USBD_EVENT_CLR_REMOTE_WAKEUP:
  322. break;
  323. default:
  324. break;
  325. }
  326. }
  327. void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
  328. {
  329. USB_LOG_RAW("actual out len:%d\r\n", nbytes);
  330. /* setup next out ep read transfer */
  331. usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048);
  332. }
  333. void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
  334. {
  335. USB_LOG_RAW("actual in len:%d\r\n", nbytes);
  336. if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
  337. /* send zlp */
  338. usbd_ep_start_write(busid, CDC_IN_EP, NULL, 0);
  339. } else {
  340. ep_tx_busy_flag = false;
  341. }
  342. }
  343. /*!< endpoint call back */
  344. struct usbd_endpoint cdc_out_ep = {
  345. .ep_addr = CDC_OUT_EP,
  346. .ep_cb = usbd_cdc_acm_bulk_out
  347. };
  348. struct usbd_endpoint cdc_in_ep = {
  349. .ep_addr = CDC_IN_EP,
  350. .ep_cb = usbd_cdc_acm_bulk_in
  351. };
  352. struct usbd_interface intf0;
  353. struct usbd_interface intf1;
  354. struct usbd_interface intf2;
  355. struct usbd_interface intf3;
  356. void cdc_acm_hid_msc_descriptor_init(uint8_t busid, uintptr_t reg_base)
  357. {
  358. #ifdef CONFIG_USBDEV_ADVANCE_DESC
  359. usbd_desc_register(busid, &cdc_acm_hid_msc_descriptor);
  360. #else
  361. usbd_desc_register(busid, cdc_acm_hid_msc_descriptor);
  362. #endif
  363. usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0));
  364. usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1));
  365. usbd_add_endpoint(busid, &cdc_out_ep);
  366. usbd_add_endpoint(busid, &cdc_in_ep);
  367. usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf2, MSC_OUT_EP, MSC_IN_EP));
  368. usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf3, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE));
  369. usbd_add_endpoint(busid, &hid_in_ep);
  370. /*!< init mouse report data */
  371. mouse_cfg.buttons = 0;
  372. mouse_cfg.wheel = 0;
  373. mouse_cfg.x = 0;
  374. mouse_cfg.y = 0;
  375. usbd_initialize(busid, reg_base, usbd_event_handler);
  376. }
  377. /**
  378. * @brief hid mouse test
  379. * @pre none
  380. * @param[in] none
  381. * @retval none
  382. */
  383. void hid_mouse_test(uint8_t busid)
  384. {
  385. if(usb_device_is_configured(busid) == false) {
  386. return;
  387. }
  388. /*!< move mouse pointer */
  389. mouse_cfg.x += 10;
  390. mouse_cfg.y = 0;
  391. hid_state = HID_STATE_BUSY;
  392. usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
  393. while (hid_state == HID_STATE_BUSY) {
  394. }
  395. }
  396. volatile uint8_t dtr_enable = 0;
  397. void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr)
  398. {
  399. if (dtr) {
  400. dtr_enable = 1;
  401. } else {
  402. dtr_enable = 0;
  403. }
  404. }
  405. void cdc_acm_data_send_with_dtr_test(uint8_t busid)
  406. {
  407. if (dtr_enable) {
  408. memset(&write_buffer[10], 'a', 2038);
  409. ep_tx_busy_flag = true;
  410. usbd_ep_start_write(busid, CDC_IN_EP, write_buffer, 2048);
  411. while (ep_tx_busy_flag) {
  412. }
  413. }
  414. }
  415. #define BLOCK_SIZE 512
  416. #define BLOCK_COUNT 10
  417. typedef struct
  418. {
  419. uint8_t BlockSpace[BLOCK_SIZE];
  420. } BLOCK_TYPE;
  421. BLOCK_TYPE mass_block[BLOCK_COUNT];
  422. void usbd_msc_get_cap(uint8_t busid, uint8_t lun, uint32_t *block_num, uint32_t *block_size)
  423. {
  424. *block_num = 1000; //Pretend having so many buffer,not has actually.
  425. *block_size = BLOCK_SIZE;
  426. }
  427. int usbd_msc_sector_read(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
  428. {
  429. if (sector < 10)
  430. memcpy(buffer, mass_block[sector].BlockSpace, length);
  431. return 0;
  432. }
  433. int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
  434. {
  435. if (sector < 10)
  436. memcpy(mass_block[sector].BlockSpace, buffer, length);
  437. return 0;
  438. }