dap_main.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. /*
  2. * Copyright (c) 2023 ~ 2025, sakumisu
  3. * Copyright (c) 2023 ~ 2025, HalfSweet
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. */
  7. #include "dap_main.h"
  8. #define CMSIS_DAP_INTERFACE_SIZE (9 + 7 + 7)
  9. #define CUSTOM_HID_LEN (9 + 9 + 7 + 7)
  10. #define HIDRAW_INTERVAL 4
  11. #define HID_CUSTOM_REPORT_DESC_SIZE 53
  12. #define USBD_WINUSB_VENDOR_CODE 0x20
  13. #define USBD_WEBUSB_VENDOR_CODE 0x21
  14. #define USBD_WEBUSB_ENABLE 1
  15. #define USBD_BULK_ENABLE 1
  16. #define USBD_WINUSB_ENABLE 1
  17. /* WinUSB Microsoft OS 2.0 descriptor sizes */
  18. #define WINUSB_DESCRIPTOR_SET_HEADER_SIZE 10
  19. #define WINUSB_FUNCTION_SUBSET_HEADER_SIZE 8
  20. #define WINUSB_FEATURE_COMPATIBLE_ID_SIZE 20
  21. #define FUNCTION_SUBSET_LEN 160
  22. #define DEVICE_INTERFACE_GUIDS_FEATURE_LEN 132
  23. #define USBD_WINUSB_DESC_SET_LEN (WINUSB_DESCRIPTOR_SET_HEADER_SIZE + USBD_WEBUSB_ENABLE * FUNCTION_SUBSET_LEN + USBD_BULK_ENABLE * FUNCTION_SUBSET_LEN)
  24. #define USBD_NUM_DEV_CAPABILITIES (USBD_WEBUSB_ENABLE + USBD_WINUSB_ENABLE)
  25. #define USBD_WEBUSB_DESC_LEN 24
  26. #define USBD_WINUSB_DESC_LEN 28
  27. #define USBD_BOS_WTOTALLENGTH (0x05 + \
  28. USBD_WEBUSB_DESC_LEN * USBD_WEBUSB_ENABLE + \
  29. USBD_WINUSB_DESC_LEN * USBD_WINUSB_ENABLE)
  30. #define USB_CONFIG_SIZE (9 + CMSIS_DAP_INTERFACE_SIZE + CDC_ACM_DESCRIPTOR_LEN + \
  31. CONFIG_CHERRYDAP_USE_CUSTOM_HID * CUSTOM_HID_LEN + \
  32. CONFIG_CHERRYDAP_USE_MSC * MSC_DESCRIPTOR_LEN + USBD_WEBUSB_ENABLE * 9)
  33. #define INTF_NUM (1 + 2 + CONFIG_CHERRYDAP_USE_CUSTOM_HID + CONFIG_CHERRYDAP_USE_MSC + USBD_WEBUSB_ENABLE)
  34. #define MSC_INTF_NUM (3 + CONFIG_CHERRYDAP_USE_CUSTOM_HID)
  35. #define WEBUSB_INTF_NUM (3 + CONFIG_CHERRYDAP_USE_CUSTOM_HID + CONFIG_CHERRYDAP_USE_MSC)
  36. #define WEBUSB_URL_STRINGS \
  37. 'c', 'h', 'e', 'r', 'r', 'y', 'd', 'a', 'p', '.', 'c', 'h', 'e', 'r', 'r', 'y', '-', 'e', 'm', 'b', 'e', 'd', 'd', 'e', 'd', '.', 'o', 'r', 'g',
  38. __ALIGN_BEGIN const uint8_t USBD_WinUSBDescriptorSetDescriptor[] = {
  39. WBVAL(WINUSB_DESCRIPTOR_SET_HEADER_SIZE), /* wLength */
  40. WBVAL(WINUSB_SET_HEADER_DESCRIPTOR_TYPE), /* wDescriptorType */
  41. 0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/
  42. WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */
  43. #if (USBD_WEBUSB_ENABLE)
  44. WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), // wLength
  45. WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), // wDescriptorType
  46. WEBUSB_INTF_NUM, // bFirstInterface USBD_WINUSB_IF_NUM
  47. 0, // bReserved
  48. WBVAL(FUNCTION_SUBSET_LEN), // wSubsetLength
  49. WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), // wLength
  50. WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), // wDescriptorType
  51. 'W', 'I', 'N', 'U', 'S', 'B', 0, 0, // CompatibleId
  52. 0, 0, 0, 0, 0, 0, 0, 0, // SubCompatibleId
  53. WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), // wLength
  54. WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), // wDescriptorType
  55. WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), // wPropertyDataType
  56. WBVAL(42), // wPropertyNameLength
  57. 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
  58. 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
  59. 'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
  60. WBVAL(80), // wPropertyDataLength
  61. '{', 0,
  62. '9', 0, '2', 0, 'C', 0, 'E', 0, '6', 0, '4', 0, '6', 0, '2', 0, '-', 0,
  63. '9', 0, 'C', 0, '7', 0, '7', 0, '-', 0,
  64. '4', 0, '6', 0, 'F', 0, 'E', 0, '-', 0,
  65. '9', 0, '3', 0, '3', 0, 'B', 0, '-',
  66. 0, '3', 0, '1', 0, 'C', 0, 'B', 0, '9', 0, 'C', 0, '5', 0, 'A', 0, 'A', 0, '3', 0, 'B', 0, '9', 0,
  67. '}', 0, 0, 0, 0, 0,
  68. #endif
  69. #if USBD_BULK_ENABLE
  70. WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), /* wLength */
  71. WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), /* wDescriptorType */
  72. 0, /* bFirstInterface USBD_BULK_IF_NUM*/
  73. 0, /* bReserved */
  74. WBVAL(FUNCTION_SUBSET_LEN), /* wSubsetLength */
  75. WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), /* wLength */
  76. WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), /* wDescriptorType */
  77. 'W', 'I', 'N', 'U', 'S', 'B', 0, 0, /* CompatibleId*/
  78. 0, 0, 0, 0, 0, 0, 0, 0, /* SubCompatibleId*/
  79. WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), /* wLength */
  80. WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), /* wDescriptorType */
  81. WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), /* wPropertyDataType */
  82. WBVAL(42), /* wPropertyNameLength */
  83. 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
  84. 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
  85. 'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
  86. WBVAL(80), /* wPropertyDataLength */
  87. '{', 0,
  88. 'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0,
  89. '2', 0, '9', 0, '3', 0, 'B', 0, '-', 0,
  90. '4', 0, '6', 0, '6', 0, '3', 0, '-', 0,
  91. 'A', 0, 'A', 0, '3', 0, '6', 0, '-',
  92. 0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0,
  93. '}', 0, 0, 0, 0, 0
  94. #endif
  95. };
  96. __ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
  97. 0x05, /* bLength */
  98. 0x0f, /* bDescriptorType */
  99. WBVAL(USBD_BOS_WTOTALLENGTH), /* wTotalLength */
  100. USBD_NUM_DEV_CAPABILITIES, /* bNumDeviceCaps */
  101. #if (USBD_WEBUSB_ENABLE)
  102. USBD_WEBUSB_DESC_LEN, /* bLength */
  103. 0x10, /* bDescriptorType */
  104. USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
  105. 0x00, /* bReserved */
  106. 0x38, 0xB6, 0x08, 0x34, /* PlatformCapabilityUUID */
  107. 0xA9, 0x09, 0xA0, 0x47,
  108. 0x8B, 0xFD, 0xA0, 0x76,
  109. 0x88, 0x15, 0xB6, 0x65,
  110. WBVAL(0x0100), /* 1.00 */ /* bcdVersion */
  111. USBD_WEBUSB_VENDOR_CODE, /* bVendorCode */
  112. 1, /* iLandingPage */
  113. #endif
  114. #if (USBD_WINUSB_ENABLE)
  115. USBD_WINUSB_DESC_LEN, /* bLength */
  116. 0x10, /* bDescriptorType */
  117. USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
  118. 0x00, /* bReserved */
  119. 0xDF, 0x60, 0xDD, 0xD8, /* PlatformCapabilityUUID */
  120. 0x89, 0x45, 0xC7, 0x4C,
  121. 0x9C, 0xD2, 0x65, 0x9D,
  122. 0x9E, 0x64, 0x8A, 0x9F,
  123. 0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/
  124. WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */
  125. USBD_WINUSB_VENDOR_CODE, /* bVendorCode */
  126. 0, /* bAltEnumCode */
  127. #endif
  128. };
  129. #define URL_DESCRIPTOR_LENGTH (3 + 29)
  130. const uint8_t USBD_WebUSBURLDescriptor[URL_DESCRIPTOR_LENGTH] = {
  131. URL_DESCRIPTOR_LENGTH,
  132. WEBUSB_URL_TYPE,
  133. WEBUSB_URL_SCHEME_HTTPS,
  134. WEBUSB_URL_STRINGS
  135. };
  136. // clang-format off
  137. #define HID_DESC() \
  138. /************** Descriptor of Custom interface *****************/ \
  139. 0x09, /* bLength: Interface Descriptor size */ \
  140. USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ \
  141. 0X03, /* bInterfaceNumber: Number of Interface */ \
  142. 0x00, /* bAlternateSetting: Alternate setting */ \
  143. 0x02, /* bNumEndpoints */ \
  144. 0x03, /* bInterfaceClass: HID */ \
  145. 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ \
  146. 0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ \
  147. 0, /* iInterface: Index of string descriptor */ /******************** Descriptor of Custom HID ********************/ \
  148. 0x09, /* bLength: HID Descriptor size */ \
  149. HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ \
  150. 0x11, /* bcdHID: HID Class Spec release number */ \
  151. 0x01, \
  152. 0x00, /* bCountryCode: Hardware target country */ \
  153. 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ \
  154. 0x22, /* bDescriptorType */ \
  155. HID_CUSTOM_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ \
  156. 0x00, /******************** Descriptor of Custom in endpoint ********************/ \
  157. 0x07, /* bLength: Endpoint Descriptor size */ \
  158. USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \
  159. HID_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */ \
  160. 0x03, /* bmAttributes: Interrupt endpoint */ \
  161. WBVAL(HID_PACKET_SIZE), /* wMaxPacketSize: 4 Byte max */ \
  162. HIDRAW_INTERVAL, /* bInterval: Polling Interval */ /******************** Descriptor of Custom out endpoint ********************/ \
  163. 0x07, /* bLength: Endpoint Descriptor size */ \
  164. USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \
  165. HID_OUT_EP, /* bEndpointAddress: Endpoint Address (IN) */ \
  166. 0x03, /* bmAttributes: Interrupt endpoint */ \
  167. WBVAL(HID_PACKET_SIZE), /* wMaxPacketSize: 4 Byte max */ \
  168. HIDRAW_INTERVAL /* bInterval: Polling Interval */
  169. // clang-format on
  170. static const uint8_t device_descriptor[] = {
  171. USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
  172. };
  173. static const uint8_t config_descriptor[] = {
  174. USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
  175. /* Interface 0 */
  176. USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02),
  177. /* Endpoint OUT 2 */
  178. USB_ENDPOINT_DESCRIPTOR_INIT(DAP_OUT_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00),
  179. /* Endpoint IN 1 */
  180. USB_ENDPOINT_DESCRIPTOR_INIT(DAP_IN_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00),
  181. CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, DAP_PACKET_SIZE, 0x00),
  182. #if CONFIG_CHERRYDAP_USE_CUSTOM_HID
  183. HID_DESC(),
  184. #endif
  185. #if CONFIG_CHERRYDAP_USE_MSC
  186. MSC_DESCRIPTOR_INIT(MSC_INTF_NUM, MSC_OUT_EP, MSC_IN_EP, DAP_PACKET_SIZE, 0x00),
  187. #endif
  188. #if USBD_WEBUSB_ENABLE
  189. USB_INTERFACE_DESCRIPTOR_INIT(WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x04),
  190. #endif
  191. };
  192. static const uint8_t other_speed_config_descriptor[] = {
  193. USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
  194. /* Interface 0 */
  195. USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02),
  196. /* Endpoint OUT 2 */
  197. USB_ENDPOINT_DESCRIPTOR_INIT(DAP_OUT_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00),
  198. /* Endpoint IN 1 */
  199. USB_ENDPOINT_DESCRIPTOR_INIT(DAP_IN_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00),
  200. CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, DAP_PACKET_SIZE, 0x00),
  201. #if CONFIG_CHERRYDAP_USE_CUSTOM_HID
  202. HID_DESC(),
  203. #endif
  204. #if CONFIG_CHERRYDAP_USE_MSC
  205. MSC_DESCRIPTOR_INIT(0x04, MSC_OUT_EP, MSC_IN_EP, DAP_PACKET_SIZE, 0x00),
  206. #endif
  207. #if USBD_WEBUSB_ENABLE
  208. USB_INTERFACE_DESCRIPTOR_INIT(WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x04),
  209. #endif
  210. };
  211. /*!< custom hid report descriptor */
  212. const uint8_t hid_custom_report_desc[HID_CUSTOM_REPORT_DESC_SIZE] = {
  213. /* USER CODE BEGIN 0 */
  214. 0x06, 0x00, 0xff, /* USAGE_PAGE (Vendor Defined Page 1) */
  215. 0x09, 0x01, /* USAGE (Vendor Usage 1) */
  216. 0xa1, 0x01, /* COLLECTION (Application) */
  217. 0x85, 0x02, /* REPORT ID (0x02) */
  218. 0x09, 0x02, /* USAGE (Vendor Usage 1) */
  219. 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
  220. 0x25, 0xff, /*LOGICAL_MAXIMUM (255) */
  221. 0x75, 0x08, /* REPORT_SIZE (8) */
  222. 0x96, 0xff, 0x03, /* REPORT_COUNT (1023) */
  223. 0x81, 0x02, /* INPUT (Data,Var,Abs) */
  224. /* <___________________________________________________> */
  225. 0x85, 0x01, /* REPORT ID (0x01) */
  226. 0x09, 0x03, /* USAGE (Vendor Usage 1) */
  227. 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
  228. 0x25, 0xff, /* LOGICAL_MAXIMUM (255) */
  229. 0x75, 0x08, /* REPORT_SIZE (8) */
  230. 0x96, 0xff, 0x03, /* REPORT_COUNT (1023) */
  231. 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */
  232. /* <___________________________________________________> */
  233. 0x85, 0x03, /* REPORT ID (0x03) */
  234. 0x09, 0x04, /* USAGE (Vendor Usage 1) */
  235. 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
  236. 0x25, 0xff, /* LOGICAL_MAXIMUM (255) */
  237. 0x75, 0x08, /* REPORT_SIZE (8) */
  238. 0x96, 0xff, 0x03, /* REPORT_COUNT (1023) */
  239. 0xb1, 0x02, /* FEATURE (Data,Var,Abs) */
  240. /* USER CODE END 0 */
  241. 0xC0 /* END_COLLECTION */
  242. };
  243. char serial_number_dynamic[36] = "00000000000000000123456789ABCDEF"; // Dynamic serial number
  244. char *string_descriptors[] = {
  245. (char[]){ 0x09, 0x04 }, /* Langid */
  246. "CherryUSB", /* Manufacturer */
  247. "CherryUSB CMSIS-DAP", /* Product */
  248. "00000000000000000123456789ABCDEF", /* Serial Number */
  249. "CherryUSB WebUSB",
  250. };
  251. static const uint8_t device_quality_descriptor[] = {
  252. USB_DEVICE_QUALIFIER_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, 0x01),
  253. };
  254. __WEAK const uint8_t *device_descriptor_callback(uint8_t speed)
  255. {
  256. (void)speed;
  257. return device_descriptor;
  258. }
  259. __WEAK const uint8_t *config_descriptor_callback(uint8_t speed)
  260. {
  261. (void)speed;
  262. return config_descriptor;
  263. }
  264. __WEAK const uint8_t *device_quality_descriptor_callback(uint8_t speed)
  265. {
  266. (void)speed;
  267. return device_quality_descriptor;
  268. }
  269. __WEAK const uint8_t *other_speed_config_descriptor_callback(uint8_t speed)
  270. {
  271. (void)speed;
  272. return other_speed_config_descriptor;
  273. }
  274. __WEAK const char *string_descriptor_callback(uint8_t speed, uint8_t index)
  275. {
  276. (void)speed;
  277. if (index == 3) {
  278. return serial_number_dynamic;
  279. }
  280. if (index >= (sizeof(string_descriptors) / sizeof(char *))) {
  281. return NULL;
  282. }
  283. return string_descriptors[index];
  284. }
  285. static volatile uint16_t USB_RequestIndexI = 0; // Request Index In
  286. static volatile uint16_t USB_RequestIndexO = 0; // Request Index Out
  287. static volatile uint16_t USB_RequestCountI = 0; // Request Count In
  288. static volatile uint16_t USB_RequestCountO = 0; // Request Count Out
  289. static volatile uint8_t USB_RequestIdle = 1; // Request Idle Flag
  290. static volatile uint16_t USB_ResponseIndexI = 0; // Response Index In
  291. static volatile uint16_t USB_ResponseIndexO = 0; // Response Index Out
  292. static volatile uint16_t USB_ResponseCountI = 0; // Response Count In
  293. static volatile uint16_t USB_ResponseCountO = 0; // Response Count Out
  294. static volatile uint8_t USB_ResponseIdle = 1; // Response Idle Flag
  295. static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t USB_Request[DAP_PACKET_COUNT][DAP_PACKET_SIZE]; // Request Buffer
  296. static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE]; // Response Buffer
  297. static uint16_t USB_RespSize[DAP_PACKET_COUNT]; // Response Size
  298. volatile struct cdc_line_coding g_cdc_lincoding;
  299. volatile uint8_t config_uart = 0;
  300. volatile uint8_t config_uart_transfer = 0;
  301. USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t uartrx_ringbuffer[CONFIG_UARTRX_RINGBUF_SIZE];
  302. USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t usbrx_ringbuffer[CONFIG_USBRX_RINGBUF_SIZE];
  303. USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t usb_tmpbuffer[DAP_PACKET_SIZE];
  304. static volatile uint8_t usbrx_idle_flag = 0;
  305. static volatile uint8_t usbtx_idle_flag = 0;
  306. static volatile uint8_t uarttx_idle_flag = 0;
  307. USB_NOCACHE_RAM_SECTION chry_ringbuffer_t g_uartrx;
  308. USB_NOCACHE_RAM_SECTION chry_ringbuffer_t g_usbrx;
  309. void usbd_event_handler(uint8_t busid, uint8_t event)
  310. {
  311. (void)busid;
  312. switch (event) {
  313. case USBD_EVENT_RESET:
  314. usbrx_idle_flag = 0;
  315. usbtx_idle_flag = 0;
  316. uarttx_idle_flag = 0;
  317. config_uart_transfer = 0;
  318. break;
  319. case USBD_EVENT_CONNECTED:
  320. break;
  321. case USBD_EVENT_DISCONNECTED:
  322. break;
  323. case USBD_EVENT_RESUME:
  324. break;
  325. case USBD_EVENT_SUSPEND:
  326. break;
  327. case USBD_EVENT_CONFIGURED:
  328. /* setup first out ep read transfer */
  329. USB_RequestIdle = 0U;
  330. usbd_ep_start_read(0, DAP_OUT_EP, USB_Request[0], DAP_PACKET_SIZE);
  331. usbd_ep_start_read(0, CDC_OUT_EP, usb_tmpbuffer, DAP_PACKET_SIZE);
  332. break;
  333. case USBD_EVENT_SET_REMOTE_WAKEUP:
  334. break;
  335. case USBD_EVENT_CLR_REMOTE_WAKEUP:
  336. break;
  337. default:
  338. break;
  339. }
  340. }
  341. void dap_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
  342. {
  343. (void)busid;
  344. if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {
  345. DAP_TransferAbort = 1U;
  346. } else {
  347. USB_RequestIndexI++;
  348. if (USB_RequestIndexI == DAP_PACKET_COUNT) {
  349. USB_RequestIndexI = 0U;
  350. }
  351. USB_RequestCountI++;
  352. }
  353. // Start reception of next request packet
  354. if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
  355. usbd_ep_start_read(0, DAP_OUT_EP, USB_Request[USB_RequestIndexI], DAP_PACKET_SIZE);
  356. } else {
  357. USB_RequestIdle = 1U;
  358. }
  359. }
  360. void dap_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
  361. {
  362. (void)busid;
  363. if (USB_ResponseCountI != USB_ResponseCountO) {
  364. // Load data from response buffer to be sent back
  365. usbd_ep_start_write(0, DAP_IN_EP, USB_Response[USB_ResponseIndexO], USB_RespSize[USB_ResponseIndexO]);
  366. USB_ResponseIndexO++;
  367. if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
  368. USB_ResponseIndexO = 0U;
  369. }
  370. USB_ResponseCountO++;
  371. } else {
  372. USB_ResponseIdle = 1U;
  373. }
  374. }
  375. void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
  376. {
  377. (void)busid;
  378. chry_ringbuffer_write(&g_usbrx, usb_tmpbuffer, nbytes);
  379. if (chry_ringbuffer_get_free(&g_usbrx) >= DAP_PACKET_SIZE) {
  380. usbd_ep_start_read(0, CDC_OUT_EP, usb_tmpbuffer, DAP_PACKET_SIZE);
  381. } else {
  382. usbrx_idle_flag = 1;
  383. }
  384. }
  385. void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
  386. {
  387. (void)busid;
  388. uint32_t size;
  389. uint8_t *buffer;
  390. chry_ringbuffer_linear_read_done(&g_uartrx, nbytes);
  391. if ((nbytes % DAP_PACKET_SIZE) == 0 && nbytes) {
  392. /* send zlp */
  393. usbd_ep_start_write(0, CDC_IN_EP, NULL, 0);
  394. } else {
  395. if (chry_ringbuffer_get_used(&g_uartrx)) {
  396. buffer = chry_ringbuffer_linear_read_setup(&g_uartrx, &size);
  397. usbd_ep_start_write(0, CDC_IN_EP, buffer, size);
  398. } else {
  399. usbtx_idle_flag = 1;
  400. }
  401. }
  402. }
  403. struct usbd_endpoint dap_out_ep = {
  404. .ep_addr = DAP_OUT_EP,
  405. .ep_cb = dap_out_callback
  406. };
  407. struct usbd_endpoint dap_in_ep = {
  408. .ep_addr = DAP_IN_EP,
  409. .ep_cb = dap_in_callback
  410. };
  411. struct usbd_endpoint cdc_out_ep = {
  412. .ep_addr = CDC_OUT_EP,
  413. .ep_cb = usbd_cdc_acm_bulk_out
  414. };
  415. struct usbd_endpoint cdc_in_ep = {
  416. .ep_addr = CDC_IN_EP,
  417. .ep_cb = usbd_cdc_acm_bulk_in
  418. };
  419. #if CONFIG_CHERRYDAP_USE_CUSTOM_HID
  420. struct usbd_endpoint hid_custom_in_ep = {
  421. .ep_addr = HID_IN_EP,
  422. .ep_cb = usbd_hid_custom_in_callback,
  423. };
  424. struct usbd_endpoint hid_custom_out_ep = {
  425. .ep_addr = HID_OUT_EP,
  426. .ep_cb = usbd_hid_custom_out_callback,
  427. };
  428. #endif
  429. struct usbd_interface dap_intf;
  430. struct usbd_interface intf1;
  431. struct usbd_interface intf2;
  432. #if CONFIG_CHERRYDAP_USE_CUSTOM_HID
  433. struct usbd_interface hid_intf;
  434. #endif
  435. #if CONFIG_CHERRYDAP_USE_MSC
  436. struct usbd_interface intf3;
  437. #endif
  438. struct usb_msosv2_descriptor msosv2_desc = {
  439. .vendor_code = USBD_WINUSB_VENDOR_CODE,
  440. .compat_id = USBD_WinUSBDescriptorSetDescriptor,
  441. .compat_id_len = USBD_WINUSB_DESC_SET_LEN,
  442. };
  443. struct usb_bos_descriptor bos_desc = {
  444. .string = USBD_BinaryObjectStoreDescriptor,
  445. .string_len = USBD_BOS_WTOTALLENGTH
  446. };
  447. struct usb_webusb_descriptor webusb_url_desc = {
  448. .vendor_code = USBD_WEBUSB_VENDOR_CODE,
  449. .string = USBD_WebUSBURLDescriptor,
  450. .string_len = URL_DESCRIPTOR_LENGTH
  451. };
  452. const struct usb_descriptor cmsisdap_descriptor = {
  453. .device_descriptor_callback = device_descriptor_callback,
  454. .config_descriptor_callback = config_descriptor_callback,
  455. .device_quality_descriptor_callback = device_quality_descriptor_callback,
  456. .other_speed_descriptor_callback = other_speed_config_descriptor_callback,
  457. .string_descriptor_callback = string_descriptor_callback,
  458. .bos_descriptor = &bos_desc,
  459. .msosv2_descriptor = &msosv2_desc,
  460. .webusb_url_descriptor = &webusb_url_desc
  461. };
  462. void chry_dap_init(uint8_t busid, uint32_t reg_base)
  463. {
  464. chry_ringbuffer_init(&g_uartrx, uartrx_ringbuffer, CONFIG_UARTRX_RINGBUF_SIZE);
  465. chry_ringbuffer_init(&g_usbrx, usbrx_ringbuffer, CONFIG_USBRX_RINGBUF_SIZE);
  466. DAP_Setup();
  467. usbd_desc_register(0, &cmsisdap_descriptor);
  468. /*!< winusb */
  469. usbd_add_interface(0, &dap_intf);
  470. usbd_add_endpoint(0, &dap_out_ep);
  471. usbd_add_endpoint(0, &dap_in_ep);
  472. /*!< cdc acm */
  473. usbd_add_interface(0, usbd_cdc_acm_init_intf(0, &intf1));
  474. usbd_add_interface(0, usbd_cdc_acm_init_intf(0, &intf2));
  475. usbd_add_endpoint(0, &cdc_out_ep);
  476. usbd_add_endpoint(0, &cdc_in_ep);
  477. #if CONFIG_CHERRYDAP_USE_CUSTOM_HID
  478. /*!< hid */
  479. usbd_add_interface(0, usbd_hid_init_intf(0, &hid_intf, hid_custom_report_desc, HID_CUSTOM_REPORT_DESC_SIZE));
  480. hid_intf.notify_handler = hid_custom_notify_handler;
  481. usbd_add_endpoint(0, &hid_custom_in_ep);
  482. usbd_add_endpoint(0, &hid_custom_out_ep);
  483. #endif
  484. #if CONFIG_CHERRYDAP_USE_MSC
  485. usbd_add_interface(0, usbd_msc_init_intf(0, &intf3, MSC_OUT_EP, MSC_IN_EP));
  486. #endif
  487. usbd_initialize(busid, reg_base, usbd_event_handler);
  488. }
  489. void chry_dap_handle(void)
  490. {
  491. uint32_t n;
  492. // Process pending requests
  493. while (USB_RequestCountI != USB_RequestCountO) {
  494. // Handle Queue Commands
  495. n = USB_RequestIndexO;
  496. while (USB_Request[n][0] == ID_DAP_QueueCommands) {
  497. USB_Request[n][0] = ID_DAP_ExecuteCommands;
  498. n++;
  499. if (n == DAP_PACKET_COUNT) {
  500. n = 0U;
  501. }
  502. if (n == USB_RequestIndexI) {
  503. // flags = osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);
  504. // if (flags & 0x80U) {
  505. // break;
  506. // }
  507. }
  508. }
  509. // Execute DAP Command (process request and prepare response)
  510. USB_RespSize[USB_ResponseIndexI] =
  511. (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);
  512. // Update Request Index and Count
  513. USB_RequestIndexO++;
  514. if (USB_RequestIndexO == DAP_PACKET_COUNT) {
  515. USB_RequestIndexO = 0U;
  516. }
  517. USB_RequestCountO++;
  518. if (USB_RequestIdle) {
  519. if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
  520. USB_RequestIdle = 0U;
  521. usbd_ep_start_read(0, DAP_OUT_EP, USB_Request[USB_RequestIndexI], DAP_PACKET_SIZE);
  522. }
  523. }
  524. // Update Response Index and Count
  525. USB_ResponseIndexI++;
  526. if (USB_ResponseIndexI == DAP_PACKET_COUNT) {
  527. USB_ResponseIndexI = 0U;
  528. }
  529. USB_ResponseCountI++;
  530. if (USB_ResponseIdle) {
  531. if (USB_ResponseCountI != USB_ResponseCountO) {
  532. // Load data from response buffer to be sent back
  533. n = USB_ResponseIndexO++;
  534. if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
  535. USB_ResponseIndexO = 0U;
  536. }
  537. USB_ResponseCountO++;
  538. USB_ResponseIdle = 0U;
  539. usbd_ep_start_write(0, DAP_IN_EP, USB_Response[n], USB_RespSize[n]);
  540. }
  541. }
  542. }
  543. }
  544. void usbd_cdc_acm_set_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding)
  545. {
  546. (void)busid;
  547. if (memcmp(line_coding, (uint8_t *)&g_cdc_lincoding, sizeof(struct cdc_line_coding)) != 0) {
  548. memcpy((uint8_t *)&g_cdc_lincoding, line_coding, sizeof(struct cdc_line_coding));
  549. config_uart = 1;
  550. config_uart_transfer = 0;
  551. }
  552. }
  553. void usbd_cdc_acm_get_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding)
  554. {
  555. (void)busid;
  556. memcpy(line_coding, (uint8_t *)&g_cdc_lincoding, sizeof(struct cdc_line_coding));
  557. }
  558. void chry_dap_usb2uart_handle(void)
  559. {
  560. uint32_t size;
  561. uint8_t *buffer;
  562. if (config_uart) {
  563. /* disable irq here */
  564. config_uart = 0;
  565. /* config uart here */
  566. chry_dap_usb2uart_uart_config_callback((struct cdc_line_coding *)&g_cdc_lincoding);
  567. usbtx_idle_flag = 1;
  568. uarttx_idle_flag = 1;
  569. config_uart_transfer = 1;
  570. //chry_ringbuffer_reset_read(&g_uartrx);
  571. /* enable irq here */
  572. }
  573. if (config_uart_transfer == 0) {
  574. return;
  575. }
  576. /* why we use chry_ringbuffer_linear_read_setup?
  577. * becase we use dma and we do not want to use temp buffer to memcpy from ringbuffer
  578. *
  579. */
  580. /* uartrx to usb tx */
  581. if (usbtx_idle_flag) {
  582. if (chry_ringbuffer_get_used(&g_uartrx)) {
  583. usbtx_idle_flag = 0;
  584. /* start first transfer */
  585. buffer = chry_ringbuffer_linear_read_setup(&g_uartrx, &size);
  586. usbd_ep_start_write(0, CDC_IN_EP, buffer, size);
  587. }
  588. }
  589. /* usbrx to uart tx */
  590. if (uarttx_idle_flag) {
  591. if (chry_ringbuffer_get_used(&g_usbrx)) {
  592. uarttx_idle_flag = 0;
  593. /* start first transfer */
  594. buffer = chry_ringbuffer_linear_read_setup(&g_usbrx, &size);
  595. chry_dap_usb2uart_uart_send_bydma(buffer, size);
  596. }
  597. }
  598. /* check whether usb rx ringbuffer have space to store */
  599. if (usbrx_idle_flag) {
  600. if (chry_ringbuffer_get_free(&g_usbrx) >= DAP_PACKET_SIZE) {
  601. usbrx_idle_flag = 0;
  602. usbd_ep_start_read(0, CDC_OUT_EP, usb_tmpbuffer, DAP_PACKET_SIZE);
  603. }
  604. }
  605. }
  606. /* implment by user */
  607. __WEAK void chry_dap_usb2uart_uart_config_callback(struct cdc_line_coding *line_coding)
  608. {
  609. }
  610. /* called by user */
  611. void chry_dap_usb2uart_uart_send_complete(uint32_t size)
  612. {
  613. uint8_t *buffer;
  614. chry_ringbuffer_linear_read_done(&g_usbrx, size);
  615. if (chry_ringbuffer_get_used(&g_usbrx)) {
  616. buffer = chry_ringbuffer_linear_read_setup(&g_usbrx, &size);
  617. chry_dap_usb2uart_uart_send_bydma(buffer, size);
  618. } else {
  619. uarttx_idle_flag = 1;
  620. }
  621. }
  622. /* implment by user */
  623. __WEAK void chry_dap_usb2uart_uart_send_bydma(uint8_t *data, uint16_t len)
  624. {
  625. }
  626. #if CONFIG_CHERRYDAP_USE_MSC
  627. #define BLOCK_SIZE 512
  628. #define BLOCK_COUNT 10
  629. typedef struct
  630. {
  631. uint8_t BlockSpace[BLOCK_SIZE];
  632. } BLOCK_TYPE;
  633. BLOCK_TYPE mass_block[BLOCK_COUNT];
  634. void usbd_msc_get_cap(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
  635. {
  636. *block_num = 1000; //Pretend having so many buffer,not has actually.
  637. *block_size = BLOCK_SIZE;
  638. }
  639. int usbd_msc_sector_read(uint32_t sector, uint8_t *buffer, uint32_t length)
  640. {
  641. if (sector < 10)
  642. memcpy(buffer, mass_block[sector].BlockSpace, length);
  643. return 0;
  644. }
  645. int usbd_msc_sector_write(uint32_t sector, uint8_t *buffer, uint32_t length)
  646. {
  647. if (sector < 10)
  648. memcpy(mass_block[sector].BlockSpace, buffer, length);
  649. return 0;
  650. }
  651. #endif