1 /*
2 * Copyright (c) 2025, sakumisu
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include "usbd_core.h"
7 #include "usbd_cdc_acm.h"
8
9 /*!< endpoint address */
10 #define CDC_IN_EP 0x81
11 #define CDC_OUT_EP 0x02
12 #define CDC_INT_EP 0x83
13
14 #define USBD_VID 0xFFFF
15 #define USBD_PID 0xFFFF
16 #define USBD_MAX_POWER 100
17 #define USBD_LANGID_STRING 1033
18
19 /*!< config descriptor size */
20 #define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN)
21
22 #ifdef CONFIG_USB_HS
23 #define CDC_MAX_MPS 512
24 #else
25 #define CDC_MAX_MPS 64
26 #endif
27
28 #ifdef CONFIG_USBDEV_ADVANCE_DESC
29 static const uint8_t device_descriptor[] = {
30 USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
31 };
32
33 static const uint8_t config_descriptor[] = {
34 USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
35 CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02)
36 };
37
38 static const uint8_t device_quality_descriptor[] = {
39 ///////////////////////////////////////
40 /// device qualifier descriptor
41 ///////////////////////////////////////
42 0x0a,
43 USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
44 0x00,
45 0x02,
46 0x00,
47 0x00,
48 0x00,
49 0x40,
50 0x00,
51 0x00,
52 };
53
54 static const char *string_descriptors[] = {
55 (const char[]){ 0x09, 0x04 }, /* Langid */
56 "CherryUSB", /* Manufacturer */
57 "CherryUSB CDC DEMO", /* Product */
58 "2022123456", /* Serial Number */
59 };
60
device_descriptor_callback(uint8_t speed)61 static const uint8_t *device_descriptor_callback(uint8_t speed)
62 {
63 return device_descriptor;
64 }
65
config_descriptor_callback(uint8_t speed)66 static const uint8_t *config_descriptor_callback(uint8_t speed)
67 {
68 return config_descriptor;
69 }
70
device_quality_descriptor_callback(uint8_t speed)71 static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
72 {
73 return device_quality_descriptor;
74 }
75
string_descriptor_callback(uint8_t speed,uint8_t index)76 static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
77 {
78 if (index > 3) {
79 return NULL;
80 }
81 return string_descriptors[index];
82 }
83
84 const struct usb_descriptor cdc_descriptor = {
85 .device_descriptor_callback = device_descriptor_callback,
86 .config_descriptor_callback = config_descriptor_callback,
87 .device_quality_descriptor_callback = device_quality_descriptor_callback,
88 .string_descriptor_callback = string_descriptor_callback
89 };
90 #else
91 /*!< global descriptor */
92 static const uint8_t cdc_descriptor[] = {
93 USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
94 USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
95 CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
96 ///////////////////////////////////////
97 /// string0 descriptor
98 ///////////////////////////////////////
99 USB_LANGID_INIT(USBD_LANGID_STRING),
100 ///////////////////////////////////////
101 /// string1 descriptor
102 ///////////////////////////////////////
103 0x14, /* bLength */
104 USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
105 'C', 0x00, /* wcChar0 */
106 'h', 0x00, /* wcChar1 */
107 'e', 0x00, /* wcChar2 */
108 'r', 0x00, /* wcChar3 */
109 'r', 0x00, /* wcChar4 */
110 'y', 0x00, /* wcChar5 */
111 'U', 0x00, /* wcChar6 */
112 'S', 0x00, /* wcChar7 */
113 'B', 0x00, /* wcChar8 */
114 ///////////////////////////////////////
115 /// string2 descriptor
116 ///////////////////////////////////////
117 0x26, /* bLength */
118 USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
119 'C', 0x00, /* wcChar0 */
120 'h', 0x00, /* wcChar1 */
121 'e', 0x00, /* wcChar2 */
122 'r', 0x00, /* wcChar3 */
123 'r', 0x00, /* wcChar4 */
124 'y', 0x00, /* wcChar5 */
125 'U', 0x00, /* wcChar6 */
126 'S', 0x00, /* wcChar7 */
127 'B', 0x00, /* wcChar8 */
128 ' ', 0x00, /* wcChar9 */
129 'C', 0x00, /* wcChar10 */
130 'D', 0x00, /* wcChar11 */
131 'C', 0x00, /* wcChar12 */
132 ' ', 0x00, /* wcChar13 */
133 'D', 0x00, /* wcChar14 */
134 'E', 0x00, /* wcChar15 */
135 'M', 0x00, /* wcChar16 */
136 'O', 0x00, /* wcChar17 */
137 ///////////////////////////////////////
138 /// string3 descriptor
139 ///////////////////////////////////////
140 0x16, /* bLength */
141 USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
142 '2', 0x00, /* wcChar0 */
143 '0', 0x00, /* wcChar1 */
144 '2', 0x00, /* wcChar2 */
145 '2', 0x00, /* wcChar3 */
146 '1', 0x00, /* wcChar4 */
147 '2', 0x00, /* wcChar5 */
148 '3', 0x00, /* wcChar6 */
149 '4', 0x00, /* wcChar7 */
150 '5', 0x00, /* wcChar8 */
151 '6', 0x00, /* wcChar9 */
152 #ifdef CONFIG_USB_HS
153 ///////////////////////////////////////
154 /// device qualifier descriptor
155 ///////////////////////////////////////
156 0x0a,
157 USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
158 0x00,
159 0x02,
160 0x00,
161 0x00,
162 0x00,
163 0x40,
164 0x00,
165 0x00,
166 #endif
167 0x00
168 };
169 #endif
170
usbd_event_handler(uint8_t busid,uint8_t event)171 static void usbd_event_handler(uint8_t busid, uint8_t event)
172 {
173 switch (event) {
174 case USBD_EVENT_RESET:
175 break;
176 case USBD_EVENT_CONNECTED:
177 break;
178 case USBD_EVENT_DISCONNECTED:
179 break;
180 case USBD_EVENT_RESUME:
181 break;
182 case USBD_EVENT_SUSPEND:
183 break;
184 case USBD_EVENT_CONFIGURED:
185
186 break;
187 case USBD_EVENT_SET_REMOTE_WAKEUP:
188 break;
189 case USBD_EVENT_CLR_REMOTE_WAKEUP:
190 break;
191
192 default:
193 break;
194 }
195 }
196
197 extern void usbd_cdc_acm_serial_init(uint8_t busid, uint8_t in_ep, uint8_t out_ep);
198
cdc_acm_chardev_init(uint8_t busid,uintptr_t reg_base)199 void cdc_acm_chardev_init(uint8_t busid, uintptr_t reg_base)
200 {
201 #ifdef CONFIG_USBDEV_ADVANCE_DESC
202 usbd_desc_register(busid, &cdc_descriptor);
203 #else
204 usbd_desc_register(busid, cdc_descriptor);
205 #endif
206 usbd_cdc_acm_serial_init(busid, CDC_IN_EP, CDC_OUT_EP);
207 usbd_initialize(busid, reg_base, usbd_event_handler);
208 }