Skip to content

Commit 9417d79

Browse files
committed
tinyusb: Allow to set the USB manufacturer/product identifiers
Set the USB descriptor strings. I accepts UTF-8 strings with codepoints up to 16 bit. void setup() { USBDevice.setManufacturer("MyManufacturer"); USBDevice.setProduct("MyProduct"); }
1 parent 52ea598 commit 9417d79

File tree

2 files changed

+106
-13
lines changed

2 files changed

+106
-13
lines changed

cores/arduino/Adafruit_TinyUSB_Core/Adafruit_USBD_Device.cpp

+97-13
Original file line numberDiff line numberDiff line change
@@ -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+
141154
bool 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)
165257
static 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:

cores/arduino/Adafruit_TinyUSB_Core/Adafruit_USBD_Device.h

+9
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,22 @@ class Adafruit_USBD_Device
4646
uint8_t _epin_count;
4747
uint8_t _epout_count;
4848

49+
const char *_manufacturer;
50+
const char *_product;
51+
4952
public:
5053
Adafruit_USBD_Device(void);
5154

5255
bool addInterface(Adafruit_USBD_Interface& itf);
5356

5457
void setID(uint16_t vid, uint16_t pid);
5558
void setVersion(uint16_t bcd);
59+
60+
const char *getManufacturer(void) { return _manufacturer; }
61+
void setManufacturer(const char *s);
62+
const char *getProduct(void) { return _product; }
63+
void setProduct(const char *s);
64+
5665
bool begin(void);
5766

5867
bool mounted (void) { return tud_mounted(); }

0 commit comments

Comments
 (0)