1 /*
2  * Copyright (c) 2024, sakumisu
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include "usbd_core.h"
7 #include "usbd_dfu.h"
8 
9 #define USBD_VID           0x0483
10 #define USBD_PID           0xDF11
11 #define USBD_MAX_POWER     100
12 #define USBD_LANGID_STRING 1033
13 
14 #define FLASH_DESC_STR "@Internal Flash   /0x08000000/16*001Ka,112*01Kg"
15 
16 #define USB_CONFIG_SIZE (9 + 9 + 9)
17 
18 #ifdef CONFIG_USBDEV_ADVANCE_DESC
19 static const uint8_t device_descriptor[] = {
20     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01)
21 };
22 
23 static const uint8_t config_descriptor[] = {
24     USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
25     DFU_DESCRIPTOR_INIT()
26 };
27 
28 static const uint8_t device_quality_descriptor[] = {
29     ///////////////////////////////////////
30     /// device qualifier descriptor
31     ///////////////////////////////////////
32     0x0a,
33     USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
34     0x00,
35     0x02,
36     0x00,
37     0x00,
38     0x00,
39     0x40,
40     0x00,
41     0x00,
42 };
43 
44 static const char *string_descriptors[] = {
45     (const char[]){ 0x09, 0x04 }, /* Langid */
46     "CherryUSB",                  /* Manufacturer */
47     "CherryUSB DFU DEMO",         /* Product */
48     "2022123456",                 /* Serial Number */
49 };
50 
device_descriptor_callback(uint8_t speed)51 static const uint8_t *device_descriptor_callback(uint8_t speed)
52 {
53     return device_descriptor;
54 }
55 
config_descriptor_callback(uint8_t speed)56 static const uint8_t *config_descriptor_callback(uint8_t speed)
57 {
58     return config_descriptor;
59 }
60 
device_quality_descriptor_callback(uint8_t speed)61 static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
62 {
63     return device_quality_descriptor;
64 }
65 
string_descriptor_callback(uint8_t speed,uint8_t index)66 static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
67 {
68     if (index > 3) {
69         return NULL;
70     }
71     return string_descriptors[index];
72 }
73 
74 const struct usb_descriptor dfu_flash_descriptor = {
75     .device_descriptor_callback = device_descriptor_callback,
76     .config_descriptor_callback = config_descriptor_callback,
77     .device_quality_descriptor_callback = device_quality_descriptor_callback,
78     .string_descriptor_callback = string_descriptor_callback
79 };
80 #else
81 const uint8_t dfu_flash_descriptor[] = {
82     USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
83     USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
84     DFU_DESCRIPTOR_INIT(),
85     ///////////////////////////////////////
86     /// string0 descriptor
87     ///////////////////////////////////////
88     USB_LANGID_INIT(USBD_LANGID_STRING),
89     ///////////////////////////////////////
90     /// string1 descriptor
91     ///////////////////////////////////////
92     0x14,                       /* bLength */
93     USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
94     'C', 0x00,                  /* wcChar0 */
95     'h', 0x00,                  /* wcChar1 */
96     'e', 0x00,                  /* wcChar2 */
97     'r', 0x00,                  /* wcChar3 */
98     'r', 0x00,                  /* wcChar4 */
99     'y', 0x00,                  /* wcChar5 */
100     'U', 0x00,                  /* wcChar6 */
101     'S', 0x00,                  /* wcChar7 */
102     'B', 0x00,                  /* wcChar8 */
103     ///////////////////////////////////////
104     /// string2 descriptor
105     ///////////////////////////////////////
106     0x1e,                       /* bLength */
107     USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
108     'D', 0x00,                  /* wcChar0 */
109     'F', 0x00,                  /* wcChar1 */
110     'U', 0x00,                  /* wcChar2 */
111     'W', 0x00,                  /* wcChar3 */
112     'i', 0x00,                  /* wcChar4 */
113     't', 0x00,                  /* wcChar5 */
114     'h', 0x00,                  /* wcChar6 */
115     's', 0x00,                  /* wcChar7 */
116     't', 0x00,                  /* wcChar8 */
117     ' ', 0x00,                  /* wcChar9 */
118     't', 0x00,                  /* wcChar10 */
119     'o', 0x00,                  /* wcChar11 */
120     'o', 0x00,                  /* wcChar12 */
121     'l', 0x00,                  /* wcChar13 */
122     ///////////////////////////////////////
123     /// string3 descriptor
124     ///////////////////////////////////////
125     0x16,                       /* bLength */
126     USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
127     '2', 0x00,                  /* wcChar0 */
128     '0', 0x00,                  /* wcChar1 */
129     '2', 0x00,                  /* wcChar2 */
130     '2', 0x00,                  /* wcChar3 */
131     '1', 0x00,                  /* wcChar4 */
132     '2', 0x00,                  /* wcChar5 */
133     '3', 0x00,                  /* wcChar6 */
134     '4', 0x00,                  /* wcChar7 */
135     '5', 0x00,                  /* wcChar8 */
136     '6', 0x00,                  /* wcChar9 */
137     ///////////////////////////////////////
138     /// string4 descriptor
139     ///////////////////////////////////////
140     0x60,                       /* bLength */
141     USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
142     '@', 0x00,                  /* wcChar0 */
143     'I', 0x00,                  /* wcChar1 */
144     'n', 0x00,                  /* wcChar2 */
145     't', 0x00,                  /* wcChar3 */
146     'e', 0x00,                  /* wcChar4 */
147     'r', 0x00,                  /* wcChar5 */
148     'n', 0x00,                  /* wcChar6 */
149     'a', 0x00,                  /* wcChar7 */
150     'l', 0x00,                  /* wcChar8 */
151     ' ', 0x00,                  /* wcChar9 */
152     'F', 0x00,                  /* wcChar10 */
153     'l', 0x00,                  /* wcChar11*/
154     'a', 0x00,                  /* wcChar12 */
155     's', 0x00,                  /* wcChar13 */
156     'h', 0x00,                  /* wcChar14 */
157     ' ', 0x00,                  /* wcChar15 */
158     ' ', 0x00,                  /* wcChar16 */
159     ' ', 0x00,                  /* wcChar17 */
160     '/', 0x00,                  /* wcChar18 */
161     '0', 0x00,                  /* wcChar19 */
162     'x', 0x00,                  /* wcChar20 */
163     '0', 0x00,                  /* wcChar21*/
164     '8', 0x00,                  /* wcChar22 */
165     '0', 0x00,                  /* wcChar23 */
166     '0', 0x00,                  /* wcChar24 */
167     '0', 0x00,                  /* wcChar25 */
168     '0', 0x00,                  /* wcChar26 */
169     '0', 0x00,                  /* wcChar27 */
170     '0', 0x00,                  /* wcChar28 */
171     '/', 0x00,                  /* wcChar29 */
172     '1', 0x00,                  /* wcChar30 */
173     '6', 0x00,                  /* wcChar31*/
174     '*', 0x00,                  /* wcChar32 */
175     '0', 0x00,                  /* wcChar33 */
176     '0', 0x00,                  /* wcChar34 */
177     '1', 0x00,                  /* wcChar35 */
178     'K', 0x00,                  /* wcChar36 */
179     'a', 0x00,                  /* wcChar37 */
180     ',', 0x00,                  /* wcChar38 */
181     '1', 0x00,                  /* wcChar39 */
182     '1', 0x00,                  /* wcChar40 */
183     '2', 0x00,                  /* wcChar41*/
184     '*', 0x00,                  /* wcChar42 */
185     '0', 0x00,                  /* wcChar43 */
186     '1', 0x00,                  /* wcChar44 */
187     'K', 0x00,                  /* wcChar45 */
188     'g', 0x00,                  /* wcChar46 */
189 
190 #ifdef CONFIG_USB_HS
191     ///////////////////////////////////////
192     /// device qualifier descriptor
193     ///////////////////////////////////////
194     0x0a,
195     USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
196     0x00,
197     0x02,
198     0x00,
199     0x00,
200     0x00,
201     0x40,
202     0x00,
203     0x00,
204 #endif
205     0x00
206 };
207 #endif
208 
usbd_event_handler(uint8_t busid,uint8_t event)209 static void usbd_event_handler(uint8_t busid, uint8_t event)
210 {
211     switch (event) {
212         case USBD_EVENT_RESET:
213             break;
214         case USBD_EVENT_CONNECTED:
215             break;
216         case USBD_EVENT_DISCONNECTED:
217             break;
218         case USBD_EVENT_RESUME:
219             break;
220         case USBD_EVENT_SUSPEND:
221             break;
222         case USBD_EVENT_CONFIGURED:
223             break;
224         case USBD_EVENT_SET_REMOTE_WAKEUP:
225             break;
226         case USBD_EVENT_CLR_REMOTE_WAKEUP:
227             break;
228 
229         default:
230             break;
231     }
232 }
233 
234 struct usbd_interface intf0;
235 
dfu_flash_init(uint8_t busid,uintptr_t reg_base)236 void dfu_flash_init(uint8_t busid, uintptr_t reg_base)
237 {
238 #ifdef CONFIG_USBDEV_ADVANCE_DESC
239     usbd_desc_register(busid, &dfu_flash_descriptor);
240 #else
241     usbd_desc_register(busid, dfu_flash_descriptor);
242 #endif
243     usbd_add_interface(busid, usbd_dfu_init_intf(&intf0));
244     usbd_initialize(busid, reg_base, usbd_event_handler);
245 }
246