Skip to content

Commit c4f3490

Browse files
authored
Merge pull request arduino#172 from kaysievers/usb-names-override
tinyusb: Allow to set the USB manufacturer/product identifiers
2 parents 04eb7d1 + 9417d79 commit c4f3490

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
@@ -89,6 +89,9 @@ Adafruit_USBD_Device::Adafruit_USBD_Device(void)
8989
_desc_cfglen = sizeof(tusb_desc_configuration_t);
9090
_itf_count = 0;
9191
_epin_count = _epout_count = 1;
92+
93+
_manufacturer = USB_MANUFACTURER;
94+
_product = USB_PRODUCT;
9295
}
9396

9497
// Add interface descriptor
@@ -149,6 +152,16 @@ void Adafruit_USBD_Device::setVersion(uint16_t bcd)
149152
_desc_device.bcdUSB = bcd;
150153
}
151154

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+
152165
bool Adafruit_USBD_Device::begin(void)
153166
{
154167
return true;
@@ -172,6 +185,85 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
172185
return USBDevice._desc_cfg;
173186
}
174187

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+
175267
// up to 32 unicode characters (header make it 33)
176268
static uint16_t _desc_str[33];
177269

@@ -189,20 +281,12 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index)
189281
chr_count = 1;
190282
break;
191283

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;
200287

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);
206290
break;
207291

208292
case 3:

cores/arduino/Adafruit_TinyUSB_Core/Adafruit_USBD_Device.h

+9
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ class Adafruit_USBD_Device
4848
uint8_t _epin_count;
4949
uint8_t _epout_count;
5050

51+
const char *_manufacturer;
52+
const char *_product;
53+
5154
public:
5255
Adafruit_USBD_Device(void);
5356

@@ -56,6 +59,12 @@ class Adafruit_USBD_Device
5659

5760
void setID(uint16_t vid, uint16_t pid);
5861
void setVersion(uint16_t bcd);
62+
63+
const char *getManufacturer(void) { return _manufacturer; }
64+
void setManufacturer(const char *s);
65+
const char *getProduct(void) { return _product; }
66+
void setProduct(const char *s);
67+
5968
bool begin(void);
6069

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

0 commit comments

Comments
 (0)