@@ -88,6 +88,9 @@ Adafruit_USBD_Device::Adafruit_USBD_Device(void)
8888 _desc_cfglen = sizeof (tusb_desc_configuration_t );
8989 _itf_count = 0 ;
9090 _epin_count = _epout_count = 1 ;
91+
92+ _manufacturer = USB_MANUFACTURER;
93+ _product = USB_PRODUCT;
9194}
9295
9396// Add interface descriptor
@@ -138,6 +141,16 @@ void Adafruit_USBD_Device::setVersion(uint16_t bcd)
138141 _desc_device.bcdUSB = bcd;
139142}
140143
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+
141154bool Adafruit_USBD_Device::begin (void )
142155{
143156 return true ;
@@ -161,6 +174,85 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
161174 return USBDevice._desc_cfg ;
162175}
163176
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+
164256// up to 32 unicode characters (header make it 33)
165257static uint16_t _desc_str[33 ];
166258
@@ -178,20 +270,12 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index)
178270 chr_count = 1 ;
179271 break ;
180272
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 ;
189276
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 );
195279 break ;
196280
197281 case 3 :
0 commit comments