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