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