@@ -89,6 +89,9 @@ Adafruit_USBD_Device::Adafruit_USBD_Device(void)
89
89
_desc_cfglen = sizeof (tusb_desc_configuration_t );
90
90
_itf_count = 0 ;
91
91
_epin_count = _epout_count = 1 ;
92
+
93
+ _manufacturer = USB_MANUFACTURER;
94
+ _product = USB_PRODUCT;
92
95
}
93
96
94
97
// Add interface descriptor
@@ -149,6 +152,16 @@ void Adafruit_USBD_Device::setVersion(uint16_t bcd)
149
152
_desc_device.bcdUSB = bcd;
150
153
}
151
154
155
+ void Adafruit_USBD_Device::setManufacturer (const char *s)
156
+ {
157
+ _manufacturer = s;
158
+ }
159
+
160
+ void Adafruit_USBD_Device::setProduct (const char *s)
161
+ {
162
+ _product = s;
163
+ }
164
+
152
165
bool Adafruit_USBD_Device::begin (void )
153
166
{
154
167
return true ;
@@ -172,6 +185,85 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
172
185
return USBDevice._desc_cfg ;
173
186
}
174
187
188
+
189
+ static int utf8_to_unichar (const char *str8, int *unicharp)
190
+ {
191
+ int unichar;
192
+ int len;
193
+
194
+ if (str8[0 ] < 0x80 )
195
+ len = 1 ;
196
+ else if ((str8[0 ] & 0xe0 ) == 0xc0 )
197
+ len = 2 ;
198
+ else if ((str8[0 ] & 0xf0 ) == 0xe0 )
199
+ len = 3 ;
200
+ else if ((str8[0 ] & 0xf8 ) == 0xf0 )
201
+ len = 4 ;
202
+ else if ((str8[0 ] & 0xfc ) == 0xf8 )
203
+ len = 5 ;
204
+ else if ((str8[0 ] & 0xfe ) == 0xfc )
205
+ len = 6 ;
206
+ else
207
+ return -1 ;
208
+
209
+ switch (len) {
210
+ case 1 :
211
+ unichar = str8[0 ];
212
+ break ;
213
+ case 2 :
214
+ unichar = str8[0 ] & 0x1f ;
215
+ break ;
216
+ case 3 :
217
+ unichar = str8[0 ] & 0x0f ;
218
+ break ;
219
+ case 4 :
220
+ unichar = str8[0 ] & 0x07 ;
221
+ break ;
222
+ case 5 :
223
+ unichar = str8[0 ] & 0x03 ;
224
+ break ;
225
+ case 6 :
226
+ unichar = str8[0 ] & 0x01 ;
227
+ break ;
228
+ }
229
+
230
+ for (int i = 1 ; i < len; i++) {
231
+ if ((str8[i] & 0xc0 ) != 0x80 )
232
+ return -1 ;
233
+ unichar <<= 6 ;
234
+ unichar |= str8[i] & 0x3f ;
235
+ }
236
+
237
+ *unicharp = unichar;
238
+ return len;
239
+ }
240
+
241
+ // Simple UCS-2/16-bit coversion, which handles the Basic Multilingual Plane
242
+ static int strcpy_uni16 (const char *s, uint16_t *buf, int bufsize) {
243
+ int i = 0 ;
244
+ int buflen = 0 ;
245
+
246
+ while (i < bufsize) {
247
+ int unichar;
248
+ int utf8len = utf8_to_unichar (s + i, &unichar);
249
+
250
+ if (utf8len < 0 ) {
251
+ // Invalid utf8 sequence, skip it
252
+ i++;
253
+ continue ;
254
+ }
255
+
256
+ i += utf8len;
257
+
258
+ // If the codepoint is larger than 16 bit, skip it
259
+ if (unichar <= 0xffff )
260
+ buf[buflen++] = unichar;
261
+ }
262
+
263
+ buf[buflen] = ' \0 ' ;
264
+ return buflen;
265
+ }
266
+
175
267
// up to 32 unicode characters (header make it 33)
176
268
static uint16_t _desc_str[33 ];
177
269
@@ -189,20 +281,12 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index)
189
281
chr_count = 1 ;
190
282
break ;
191
283
192
- case 1 : // Manufacturer
193
- case 2 : // Product
194
- {
195
- char const * str = (index == 1 ) ? USB_MANUFACTURER : USB_PRODUCT;
196
-
197
- // cap at max char
198
- chr_count = strlen (str);
199
- if ( chr_count > 32 ) chr_count = 32 ;
284
+ case 1 :
285
+ chr_count = strcpy_uni16 (USBDevice.getManufacturer (), _desc_str + 1 , 32 );
286
+ break ;
200
287
201
- for (uint8_t i=0 ; i<chr_count; i++)
202
- {
203
- _desc_str[1 +i] = str[i];
204
- }
205
- }
288
+ case 2 :
289
+ chr_count = strcpy_uni16 (USBDevice.getProduct (), _desc_str + 1 , 32 );
206
290
break ;
207
291
208
292
case 3 :
0 commit comments