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 #include "DAP_config.h"
9 #include "DAP.h"
10 
11 #define USB_CONFIG_SIZE (9 + CMSIS_DAP_INTERFACE_SIZE + CDC_ACM_DESCRIPTOR_LEN + CONFIG_MSC_DESCRIPTOR_LEN)
12 #define INTF_NUM        (2 + 1 + CONFIG_MSC_INTF_NUM)
13 
14 __ALIGN_BEGIN const uint8_t USBD_WinUSBDescriptorSetDescriptor[] = {
15         WBVAL(WINUSB_DESCRIPTOR_SET_HEADER_SIZE), /* wLength */
16         WBVAL(WINUSB_SET_HEADER_DESCRIPTOR_TYPE), /* wDescriptorType */
17         0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */  /* dwWindowsVersion*/
18         WBVAL(USBD_WINUSB_DESC_SET_LEN),          /* wDescriptorSetTotalLength */
19 #if (USBD_WEBUSB_ENABLE)
20         WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), // wLength
21         WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), // wDescriptorType
22         0,                                         // bFirstInterface USBD_WINUSB_IF_NUM
23         0,                                         // bReserved
24         WBVAL(FUNCTION_SUBSET_LEN),                // wSubsetLength
25         WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE),  // wLength
26         WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE),  // wDescriptorType
27         'W', 'I', 'N', 'U', 'S', 'B', 0, 0,        // CompatibleId
28         0, 0, 0, 0, 0, 0, 0, 0,                    // SubCompatibleId
29         WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), // wLength
30         WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE),   // wDescriptorType
31         WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), // wPropertyDataType
32         WBVAL(42),                                 // wPropertyNameLength
33         'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
34         'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
35         'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
36         WBVAL(80), // wPropertyDataLength
37         '{', 0,
38         '9', 0, '2', 0, 'C', 0, 'E', 0, '6', 0, '4', 0, '6', 0, '2', 0, '-', 0,
39         '9', 0, 'C', 0, '7', 0, '7', 0, '-', 0,
40         '4', 0, '6', 0, 'F', 0, 'E', 0, '-', 0,
41         '9', 0, '3', 0, '3', 0, 'B', 0, '-',
42         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,
43         '}', 0, 0, 0, 0, 0
44 #endif
45 #if USBD_BULK_ENABLE
46         WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), /* wLength */
47         WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), /* wDescriptorType */
48         0,                                         /* bFirstInterface USBD_BULK_IF_NUM*/
49         0,                                         /* bReserved */
50         WBVAL(FUNCTION_SUBSET_LEN),                /* wSubsetLength */
51         WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE),  /* wLength */
52         WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE),  /* wDescriptorType */
53         'W', 'I', 'N', 'U', 'S', 'B', 0, 0,        /* CompatibleId*/
54         0, 0, 0, 0, 0, 0, 0, 0,                    /* SubCompatibleId*/
55         WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), /* wLength */
56         WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE),   /* wDescriptorType */
57         WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), /* wPropertyDataType */
58         WBVAL(42),                                 /* wPropertyNameLength */
59         'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
60         'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
61         'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
62         WBVAL(80), /* wPropertyDataLength */
63         '{', 0,
64         'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0,
65         '2', 0, '9', 0, '3', 0, 'B', 0, '-', 0,
66         '4', 0, '6', 0, '6', 0, '3', 0, '-', 0,
67         'A', 0, 'A', 0, '3', 0, '6', 0, '-',
68         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,
69         '}', 0, 0, 0, 0, 0
70 #endif
71 };
72 
73 __ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
74         0x05,                         /* bLength */
75         0x0f,                         /* bDescriptorType */
76         WBVAL(USBD_BOS_WTOTALLENGTH), /* wTotalLength */
77         USBD_NUM_DEV_CAPABILITIES,    /* bNumDeviceCaps */
78 #if (USBD_WEBUSB_ENABLE)
79         USBD_WEBUSB_DESC_LEN,           /* bLength */
80         0x10,                           /* bDescriptorType */
81         USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
82         0x00,                           /* bReserved */
83         0x38, 0xB6, 0x08, 0x34,         /* PlatformCapabilityUUID */
84         0xA9, 0x09, 0xA0, 0x47,
85         0x8B, 0xFD, 0xA0, 0x76,
86         0x88, 0x15, 0xB6, 0x65,
87         WBVAL(0x0100), /* 1.00 */ /* bcdVersion */
88         USBD_WINUSB_VENDOR_CODE,  /* bVendorCode */
89         0,                        /* iLandingPage */
90 #endif
91 #if (USBD_WINUSB_ENABLE)
92         USBD_WINUSB_DESC_LEN,           /* bLength */
93         0x10,                           /* bDescriptorType */
94         USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
95         0x00,                           /* bReserved */
96         0xDF, 0x60, 0xDD, 0xD8,         /* PlatformCapabilityUUID */
97         0x89, 0x45, 0xC7, 0x4C,
98         0x9C, 0xD2, 0x65, 0x9D,
99         0x9E, 0x64, 0x8A, 0x9F,
100         0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/
101         WBVAL(USBD_WINUSB_DESC_SET_LEN),         /* wDescriptorSetTotalLength */
102         USBD_WINUSB_VENDOR_CODE,                 /* bVendorCode */
103         0,                                       /* bAltEnumCode */
104 #endif
105 };
106 
107 static const uint8_t device_descriptor[] = {
108         USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
109 };
110 
111 static const uint8_t config_descriptor[] = {
112         USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
113         /* Interface 0 */
114         USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02),
115         /* Endpoint OUT 2 */
116         USB_ENDPOINT_DESCRIPTOR_INIT(DAP_OUT_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00),
117         /* Endpoint IN 1 */
118         USB_ENDPOINT_DESCRIPTOR_INIT(DAP_IN_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00),
119         CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, DAP_PACKET_SIZE, 0x00),
120 #ifdef CONFIG_CHERRYDAP_USE_MSC
121         MSC_DESCRIPTOR_INIT(MSC_INTF_NUM, MSC_OUT_EP, MSC_IN_EP, DAP_PACKET_SIZE, 0x00),
122 #endif
123 };
124 
125 static const uint8_t other_speed_config_descriptor[] = {
126         USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
127         /* Interface 0 */
128         USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02),
129         /* Endpoint OUT 2 */
130         USB_ENDPOINT_DESCRIPTOR_INIT(DAP_OUT_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00),
131         /* Endpoint IN 1 */
132         USB_ENDPOINT_DESCRIPTOR_INIT(DAP_IN_EP, USB_ENDPOINT_TYPE_BULK, DAP_PACKET_SIZE, 0x00),
133         CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, DAP_PACKET_SIZE, 0x00),
134 #ifdef CONFIG_CHERRYDAP_USE_MSC
135         MSC_DESCRIPTOR_INIT(MSC_INTF_NUM, MSC_OUT_EP, MSC_IN_EP, DAP_PACKET_SIZE, 0x00),
136 #endif
137 };
138 
139 char *string_descriptors[] = {
140         (char[]) {0x09, 0x04},             /* Langid */
141         "CherryUSB",                        /* Manufacturer */
142         "CherryUSB CMSIS-DAP",              /* Product */
143         "00000000000000000123456789ABCDEF", /* Serial Number */
144 };
145 
146 static const uint8_t device_quality_descriptor[] = {
147         USB_DEVICE_QUALIFIER_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, 0x01),
148 };
149 
device_descriptor_callback(uint8_t speed)150 __WEAK const uint8_t *device_descriptor_callback(uint8_t speed)
151 {
152     (void) speed;
153     return device_descriptor;
154 }
155 
config_descriptor_callback(uint8_t speed)156 __WEAK const uint8_t *config_descriptor_callback(uint8_t speed)
157 {
158     (void) speed;
159     return config_descriptor;
160 }
161 
device_quality_descriptor_callback(uint8_t speed)162 __WEAK const uint8_t *device_quality_descriptor_callback(uint8_t speed)
163 {
164     (void) speed;
165     return device_quality_descriptor;
166 }
167 
other_speed_config_descriptor_callback(uint8_t speed)168 __WEAK const uint8_t *other_speed_config_descriptor_callback(uint8_t speed)
169 {
170     (void) speed;
171     return other_speed_config_descriptor;
172 }
173 
string_descriptor_callback(uint8_t speed,uint8_t index)174 __WEAK const char *string_descriptor_callback(uint8_t speed, uint8_t index)
175 {
176     (void) speed;
177 
178     if (index >= (sizeof(string_descriptors) / sizeof(char *))) {
179         return NULL;
180     }
181     return string_descriptors[index];
182 }
183 
184 static volatile uint16_t USB_RequestIndexI = 0; // Request  Index In
185 static volatile uint16_t USB_RequestIndexO = 0; // Request  Index Out
186 static volatile uint16_t USB_RequestCountI = 0; // Request  Count In
187 static volatile uint16_t USB_RequestCountO = 0; // Request  Count Out
188 static volatile uint8_t USB_RequestIdle = 1;    // Request  Idle  Flag
189 
190 static volatile uint16_t USB_ResponseIndexI = 0; // Response Index In
191 static volatile uint16_t USB_ResponseIndexO = 0; // Response Index Out
192 static volatile uint16_t USB_ResponseCountI = 0; // Response Count In
193 static volatile uint16_t USB_ResponseCountO = 0; // Response Count Out
194 static volatile uint8_t USB_ResponseIdle = 1;    // Response Idle  Flag
195 
196 static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t USB_Request[DAP_PACKET_COUNT][DAP_PACKET_SIZE];  // Request  Buffer
197 static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE]; // Response Buffer
198 static uint16_t USB_RespSize[DAP_PACKET_COUNT];                                                        // Response Size
199 
200 volatile struct cdc_line_coding g_cdc_lincoding;
201 volatile uint8_t config_uart = 0;
202 volatile uint8_t config_uart_transfer = 0;
203 
204 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t uartrx_ringbuffer[CONFIG_UARTRX_RINGBUF_SIZE];
205 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t usbrx_ringbuffer[CONFIG_USBRX_RINGBUF_SIZE];
206 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t usb_tmpbuffer[DAP_PACKET_SIZE];
207 
208 static volatile uint8_t usbrx_idle_flag = 0;
209 static volatile uint8_t usbtx_idle_flag = 0;
210 static volatile uint8_t uarttx_idle_flag = 0;
211 
212 USB_NOCACHE_RAM_SECTION chry_ringbuffer_t g_uartrx;
213 USB_NOCACHE_RAM_SECTION chry_ringbuffer_t g_usbrx;
214 
usbd_event_handler(uint8_t busid,uint8_t event)215 void usbd_event_handler(uint8_t busid, uint8_t event)
216 {
217     (void) busid;
218     switch (event) {
219         case USBD_EVENT_RESET:
220             usbrx_idle_flag = 0;
221             usbtx_idle_flag = 0;
222             uarttx_idle_flag = 0;
223             config_uart_transfer = 0;
224             break;
225         case USBD_EVENT_CONNECTED:
226             break;
227         case USBD_EVENT_DISCONNECTED:
228             break;
229         case USBD_EVENT_RESUME:
230             break;
231         case USBD_EVENT_SUSPEND:
232             break;
233         case USBD_EVENT_CONFIGURED:
234             /* setup first out ep read transfer */
235             USB_RequestIdle = 0U;
236 
237             usbd_ep_start_read(0, DAP_OUT_EP, USB_Request[0], DAP_PACKET_SIZE);
238             usbd_ep_start_read(0, CDC_OUT_EP, usb_tmpbuffer, DAP_PACKET_SIZE);
239 
240             break;
241         case USBD_EVENT_SET_REMOTE_WAKEUP:
242             break;
243         case USBD_EVENT_CLR_REMOTE_WAKEUP:
244             break;
245 
246         default:
247             break;
248     }
249 }
250 
dap_out_callback(uint8_t busid,uint8_t ep,uint32_t nbytes)251 void dap_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
252 {
253     (void) busid;
254     if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {
255         DAP_TransferAbort = 1U;
256     } else {
257         USB_RequestIndexI++;
258         if (USB_RequestIndexI == DAP_PACKET_COUNT) {
259             USB_RequestIndexI = 0U;
260         }
261         USB_RequestCountI++;
262     }
263 
264     // Start reception of next request packet
265     if ((uint16_t) (USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
266         usbd_ep_start_read(0, DAP_OUT_EP, USB_Request[USB_RequestIndexI], DAP_PACKET_SIZE);
267     } else {
268         USB_RequestIdle = 1U;
269     }
270 }
271 
dap_in_callback(uint8_t busid,uint8_t ep,uint32_t nbytes)272 void dap_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
273 {
274     (void) busid;
275     if (USB_ResponseCountI != USB_ResponseCountO) {
276         // Load data from response buffer to be sent back
277         usbd_ep_start_write(0, DAP_IN_EP, USB_Response[USB_ResponseIndexO], USB_RespSize[USB_ResponseIndexO]);
278         USB_ResponseIndexO++;
279         if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
280             USB_ResponseIndexO = 0U;
281         }
282         USB_ResponseCountO++;
283     } else {
284         USB_ResponseIdle = 1U;
285     }
286 }
287 
usbd_cdc_acm_bulk_out(uint8_t busid,uint8_t ep,uint32_t nbytes)288 void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
289 {
290     (void) busid;
291     chry_ringbuffer_write(&g_usbrx, usb_tmpbuffer, nbytes);
292     if (chry_ringbuffer_get_free(&g_usbrx) >= DAP_PACKET_SIZE) {
293         usbd_ep_start_read(0, CDC_OUT_EP, usb_tmpbuffer, DAP_PACKET_SIZE);
294     } else {
295         usbrx_idle_flag = 1;
296     }
297 }
298 
usbd_cdc_acm_bulk_in(uint8_t busid,uint8_t ep,uint32_t nbytes)299 void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
300 {
301     (void) busid;
302     uint32_t size;
303     uint8_t *buffer;
304 
305     chry_ringbuffer_linear_read_done(&g_uartrx, nbytes);
306     if ((nbytes % DAP_PACKET_SIZE) == 0 && nbytes) {
307         /* send zlp */
308         usbd_ep_start_write(0, CDC_IN_EP, NULL, 0);
309     } else {
310         if (chry_ringbuffer_get_used(&g_uartrx)) {
311             buffer = chry_ringbuffer_linear_read_setup(&g_uartrx, &size);
312             usbd_ep_start_write(0, CDC_IN_EP, buffer, size);
313         } else {
314             usbtx_idle_flag = 1;
315         }
316     }
317 }
318 
319 struct usbd_endpoint dap_out_ep = {
320         .ep_addr = DAP_OUT_EP,
321         .ep_cb = dap_out_callback
322 };
323 
324 struct usbd_endpoint dap_in_ep = {
325         .ep_addr = DAP_IN_EP,
326         .ep_cb = dap_in_callback
327 };
328 
329 struct usbd_endpoint cdc_out_ep = {
330         .ep_addr = CDC_OUT_EP,
331         .ep_cb = usbd_cdc_acm_bulk_out
332 };
333 
334 struct usbd_endpoint cdc_in_ep = {
335         .ep_addr = CDC_IN_EP,
336         .ep_cb = usbd_cdc_acm_bulk_in
337 };
338 
339 struct usbd_interface dap_intf;
340 struct usbd_interface intf1;
341 struct usbd_interface intf2;
342 struct usbd_interface intf3;
343 struct usbd_interface hid_intf;
344 
345 struct usb_msosv2_descriptor msosv2_desc = {
346         .vendor_code = USBD_WINUSB_VENDOR_CODE,
347         .compat_id = USBD_WinUSBDescriptorSetDescriptor,
348         .compat_id_len = USBD_WINUSB_DESC_SET_LEN,
349 };
350 
351 struct usb_bos_descriptor bos_desc = {
352         .string = USBD_BinaryObjectStoreDescriptor,
353         .string_len = USBD_BOS_WTOTALLENGTH
354 };
355 
356 const struct usb_descriptor cmsisdap_descriptor = {
357         .device_descriptor_callback = device_descriptor_callback,
358         .config_descriptor_callback = config_descriptor_callback,
359         .device_quality_descriptor_callback = device_quality_descriptor_callback,
360         .other_speed_descriptor_callback = other_speed_config_descriptor_callback,
361         .string_descriptor_callback = string_descriptor_callback,
362         .bos_descriptor = &bos_desc,
363         .msosv2_descriptor = &msosv2_desc,
364 };
365 
chry_dap_handle(void)366 void chry_dap_handle(void)
367 {
368     uint32_t n;
369 
370     // Process pending requests
371     while (USB_RequestCountI != USB_RequestCountO) {
372         // Handle Queue Commands
373         n = USB_RequestIndexO;
374         while (USB_Request[n][0] == ID_DAP_QueueCommands) {
375             USB_Request[n][0] = ID_DAP_ExecuteCommands;
376             n++;
377             if (n == DAP_PACKET_COUNT) {
378                 n = 0U;
379             }
380             if (n == USB_RequestIndexI) {
381                 // flags = osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);
382                 // if (flags & 0x80U) {
383                 //     break;
384                 // }
385             }
386         }
387 
388         // Execute DAP Command (process request and prepare response)
389         USB_RespSize[USB_ResponseIndexI] =
390                 (uint16_t) DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);
391 
392         // Update Request Index and Count
393         USB_RequestIndexO++;
394         if (USB_RequestIndexO == DAP_PACKET_COUNT) {
395             USB_RequestIndexO = 0U;
396         }
397         USB_RequestCountO++;
398 
399         if (USB_RequestIdle) {
400             if ((uint16_t) (USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
401                 USB_RequestIdle = 0U;
402                 usbd_ep_start_read(0, DAP_OUT_EP, USB_Request[USB_RequestIndexI], DAP_PACKET_SIZE);
403             }
404         }
405 
406         // Update Response Index and Count
407         USB_ResponseIndexI++;
408         if (USB_ResponseIndexI == DAP_PACKET_COUNT) {
409             USB_ResponseIndexI = 0U;
410         }
411         USB_ResponseCountI++;
412 
413         if (USB_ResponseIdle) {
414             if (USB_ResponseCountI != USB_ResponseCountO) {
415                 // Load data from response buffer to be sent back
416                 n = USB_ResponseIndexO++;
417                 if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
418                     USB_ResponseIndexO = 0U;
419                 }
420                 USB_ResponseCountO++;
421                 USB_ResponseIdle = 0U;
422                 usbd_ep_start_write(0, DAP_IN_EP, USB_Response[n], USB_RespSize[n]);
423             }
424         }
425     }
426 }
427 
usbd_cdc_acm_set_line_coding(uint8_t busid,uint8_t intf,struct cdc_line_coding * line_coding)428 void usbd_cdc_acm_set_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding)
429 {
430     (void) busid;
431     if (memcmp(line_coding, (uint8_t *) &g_cdc_lincoding, sizeof(struct cdc_line_coding)) != 0) {
432         memcpy((uint8_t *) &g_cdc_lincoding, line_coding, sizeof(struct cdc_line_coding));
433         config_uart = 1;
434         config_uart_transfer = 0;
435     }
436 }
437 
usbd_cdc_acm_get_line_coding(uint8_t busid,uint8_t intf,struct cdc_line_coding * line_coding)438 void usbd_cdc_acm_get_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding)
439 {
440     (void) busid;
441     memcpy(line_coding, (uint8_t *) &g_cdc_lincoding, sizeof(struct cdc_line_coding));
442 }
443 
chry_dap_usb2uart_handle(void)444 void chry_dap_usb2uart_handle(void)
445 {
446     uint32_t size;
447     uint8_t *buffer;
448 
449     if (config_uart) {
450         /* disable irq here */
451         config_uart = 0;
452         /* config uart here */
453         chry_dap_usb2uart_uart_config_callback((struct cdc_line_coding *) &g_cdc_lincoding);
454         usbtx_idle_flag = 1;
455         uarttx_idle_flag = 1;
456         config_uart_transfer = 1;
457         //chry_ringbuffer_reset_read(&g_uartrx);
458         /* enable irq here */
459     }
460 
461     if (config_uart_transfer == 0) {
462         return;
463     }
464 
465     /* why we use chry_ringbuffer_linear_read_setup?
466      * becase we use dma and we do not want to use temp buffer to memcpy from ringbuffer
467      *
468     */
469 
470     /* uartrx to usb tx */
471     if (usbtx_idle_flag) {
472         if (chry_ringbuffer_get_used(&g_uartrx)) {
473             usbtx_idle_flag = 0;
474             /* start first transfer */
475             buffer = chry_ringbuffer_linear_read_setup(&g_uartrx, &size);
476             usbd_ep_start_write(0, CDC_IN_EP, buffer, size);
477         }
478     }
479 
480     /* usbrx to uart tx */
481     if (uarttx_idle_flag) {
482         if (chry_ringbuffer_get_used(&g_usbrx)) {
483             uarttx_idle_flag = 0;
484             /* start first transfer */
485             buffer = chry_ringbuffer_linear_read_setup(&g_usbrx, &size);
486             chry_dap_usb2uart_uart_send_bydma(buffer, size);
487         }
488     }
489 
490     /* check whether usb rx ringbuffer have space to store */
491     if (usbrx_idle_flag) {
492         if (chry_ringbuffer_get_free(&g_usbrx) >= DAP_PACKET_SIZE) {
493             usbrx_idle_flag = 0;
494             usbd_ep_start_read(0, CDC_OUT_EP, usb_tmpbuffer, DAP_PACKET_SIZE);
495         }
496     }
497 }
498 
499 /* implment by user */
chry_dap_usb2uart_uart_config_callback(struct cdc_line_coding * line_coding)500 __WEAK void chry_dap_usb2uart_uart_config_callback(struct cdc_line_coding *line_coding)
501 {
502 }
503 
504 /* called by user */
chry_dap_usb2uart_uart_send_complete(uint32_t size)505 void chry_dap_usb2uart_uart_send_complete(uint32_t size)
506 {
507     uint8_t *buffer;
508 
509     chry_ringbuffer_linear_read_done(&g_usbrx, size);
510 
511     if (chry_ringbuffer_get_used(&g_usbrx)) {
512         buffer = chry_ringbuffer_linear_read_setup(&g_usbrx, &size);
513         chry_dap_usb2uart_uart_send_bydma(buffer, size);
514     } else {
515         uarttx_idle_flag = 1;
516     }
517 }
518 
519 /* implment by user */
chry_dap_usb2uart_uart_send_bydma(uint8_t * data,uint16_t len)520 __WEAK void chry_dap_usb2uart_uart_send_bydma(uint8_t *data, uint16_t len)
521 {
522 }
523 
524 #ifdef CONFIG_CHERRYDAP_USE_MSC
525 #define BLOCK_SIZE  512
526 #define BLOCK_COUNT 10
527 
528 typedef struct
529 {
530     uint8_t BlockSpace[BLOCK_SIZE];
531 } BLOCK_TYPE;
532 
533 BLOCK_TYPE mass_block[BLOCK_COUNT];
534 
usbd_msc_get_cap(uint8_t lun,uint32_t * block_num,uint16_t * block_size)535 void usbd_msc_get_cap(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
536 {
537     *block_num = 1000; //Pretend having so many buffer,not has actually.
538     *block_size = BLOCK_SIZE;
539 }
usbd_msc_sector_read(uint32_t sector,uint8_t * buffer,uint32_t length)540 int usbd_msc_sector_read(uint32_t sector, uint8_t *buffer, uint32_t length)
541 {
542     if (sector < 10)
543         memcpy(buffer, mass_block[sector].BlockSpace, length);
544     return 0;
545 }
546 
usbd_msc_sector_write(uint32_t sector,uint8_t * buffer,uint32_t length)547 int usbd_msc_sector_write(uint32_t sector, uint8_t *buffer, uint32_t length)
548 {
549     if (sector < 10)
550         memcpy(mass_block[sector].BlockSpace, buffer, length);
551     return 0;
552 }
553 #endif
554