3434 #define USB_PRODUCT " Unknown"
3535#endif
3636
37+ #ifndef USB_LANGUAGE
38+ #define USB_LANGUAGE 0x0409 // default is English
39+ #endif
40+
41+ #ifndef USB_CONFIG_POWER
42+ #define USB_CONFIG_POWER 100
43+ #endif
44+
3745extern uint8_t load_serial_number (uint16_t * serial_str);
3846
3947Adafruit_USBD_Device USBDevice;
@@ -76,23 +84,29 @@ Adafruit_USBD_Device::Adafruit_USBD_Device(void)
7684 .bConfigurationValue = 1 ,
7785 .iConfiguration = 0x00 ,
7886 .bmAttributes = TU_BIT (7 ) | TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP,
79- .bMaxPower = TUSB_DESC_CONFIG_POWER_MA (100 )
87+ .bMaxPower = TUSB_DESC_CONFIG_POWER_MA (USB_CONFIG_POWER )
8088 };
8189
82- memcpy (_desc_cfg, &dev_cfg, sizeof (tusb_desc_configuration_t ));
90+ memcpy (_desc_cfg_buffer, &dev_cfg, sizeof (tusb_desc_configuration_t ));
91+ _desc_cfg = _desc_cfg_buffer;
92+ _desc_cfg_maxlen = sizeof (_desc_cfg_buffer);
93+ _desc_cfg_len = sizeof (tusb_desc_configuration_t );
94+
95+ _itf_count = 0 ;
96+ _epin_count = _epout_count = 1 ;
8397
84- _desc_cfglen = sizeof ( tusb_desc_configuration_t ) ;
85- _itf_count = 0 ;
86- _epin_count = _epout_count = 1 ;
98+ _language_id = USB_LANGUAGE ;
99+ _manufacturer = USB_MANUFACTURER ;
100+ _product = USB_PRODUCT ;
87101}
88102
89103// Add interface descriptor
90104// - Interface number will be updated to match current count
91105// - Endpoint number is updated to be unique
92106bool Adafruit_USBD_Device::addInterface (Adafruit_USBD_Interface& itf)
93107{
94- uint8_t * desc = _desc_cfg+_desc_cfglen ;
95- uint16_t const len = itf.getDescriptor (_itf_count, desc, sizeof (_desc_cfg)-_desc_cfglen );
108+ uint8_t * desc = _desc_cfg+_desc_cfg_len ;
109+ uint16_t const len = itf.getDescriptor (_itf_count, desc, _desc_cfg_maxlen-_desc_cfg_len );
96110 uint8_t * desc_end = desc+len;
97111
98112 if ( !len ) return false ;
@@ -113,19 +127,29 @@ bool Adafruit_USBD_Device::addInterface(Adafruit_USBD_Interface& itf)
113127 desc += desc[0 ]; // next
114128 }
115129
116- _desc_cfglen += len;
130+ _desc_cfg_len += len;
117131
118132 // Update configuration descriptor
119133 tusb_desc_configuration_t * config = (tusb_desc_configuration_t *)_desc_cfg;
120- config->wTotalLength = _desc_cfglen ;
134+ config->wTotalLength = _desc_cfg_len ;
121135 config->bNumInterfaces = _itf_count;
122136
123137 return true ;
124138}
125139
140+ void Adafruit_USBD_Device::setDescriptorBuffer (uint8_t * buf, uint32_t buflen)
141+ {
142+ if (buflen < _desc_cfg_maxlen)
143+ return ;
144+
145+ memcpy (buf, _desc_cfg, _desc_cfg_len);
146+ _desc_cfg = buf;
147+ _desc_cfg_maxlen = buflen;
148+ }
149+
126150void Adafruit_USBD_Device::setID (uint16_t vid, uint16_t pid)
127151{
128- _desc_device.idVendor = vid;
152+ _desc_device.idVendor = vid;
129153 _desc_device.idProduct = pid;
130154}
131155
@@ -134,6 +158,22 @@ void Adafruit_USBD_Device::setVersion(uint16_t bcd)
134158 _desc_device.bcdUSB = bcd;
135159}
136160
161+
162+ void Adafruit_USBD_Device::setLanguageDescriptor (uint16_t language_id)
163+ {
164+ _language_id = language_id;
165+ }
166+
167+ void Adafruit_USBD_Device::setManufacturerDescriptor (const char *s)
168+ {
169+ _manufacturer = s;
170+ }
171+
172+ void Adafruit_USBD_Device::setProductDescriptor (const char *s)
173+ {
174+ _product = s;
175+ }
176+
137177bool Adafruit_USBD_Device::begin (void )
138178{
139179 return true ;
@@ -157,6 +197,84 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
157197 return USBDevice._desc_cfg ;
158198}
159199
200+ static int utf8_to_unichar (const char *str8, int *unicharp)
201+ {
202+ int unichar;
203+ int len;
204+
205+ if (str8[0 ] < 0x80 )
206+ len = 1 ;
207+ else if ((str8[0 ] & 0xe0 ) == 0xc0 )
208+ len = 2 ;
209+ else if ((str8[0 ] & 0xf0 ) == 0xe0 )
210+ len = 3 ;
211+ else if ((str8[0 ] & 0xf8 ) == 0xf0 )
212+ len = 4 ;
213+ else if ((str8[0 ] & 0xfc ) == 0xf8 )
214+ len = 5 ;
215+ else if ((str8[0 ] & 0xfe ) == 0xfc )
216+ len = 6 ;
217+ else
218+ return -1 ;
219+
220+ switch (len) {
221+ case 1 :
222+ unichar = str8[0 ];
223+ break ;
224+ case 2 :
225+ unichar = str8[0 ] & 0x1f ;
226+ break ;
227+ case 3 :
228+ unichar = str8[0 ] & 0x0f ;
229+ break ;
230+ case 4 :
231+ unichar = str8[0 ] & 0x07 ;
232+ break ;
233+ case 5 :
234+ unichar = str8[0 ] & 0x03 ;
235+ break ;
236+ case 6 :
237+ unichar = str8[0 ] & 0x01 ;
238+ break ;
239+ }
240+
241+ for (int i = 1 ; i < len; i++) {
242+ if ((str8[i] & 0xc0 ) != 0x80 )
243+ return -1 ;
244+ unichar <<= 6 ;
245+ unichar |= str8[i] & 0x3f ;
246+ }
247+
248+ *unicharp = unichar;
249+ return len;
250+ }
251+
252+ // Simple UCS-2/16-bit coversion, which handles the Basic Multilingual Plane
253+ static int strcpy_uni16 (const char *s, uint16_t *buf, int bufsize) {
254+ int i = 0 ;
255+ int buflen = 0 ;
256+
257+ while (i < bufsize) {
258+ int unichar;
259+ int utf8len = utf8_to_unichar (s + i, &unichar);
260+
261+ if (utf8len < 0 ) {
262+ // Invalid utf8 sequence, skip it
263+ i++;
264+ continue ;
265+ }
266+
267+ i += utf8len;
268+
269+ // If the codepoint is larger than 16 bit, skip it
270+ if (unichar <= 0xffff )
271+ buf[buflen++] = unichar;
272+ }
273+
274+ buf[buflen] = ' \0 ' ;
275+ return buflen;
276+ }
277+
160278// up to 32 unicode characters (header make it 33)
161279static uint16_t _desc_str[33 ];
162280
@@ -169,25 +287,16 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index)
169287 switch (index)
170288 {
171289 case 0 :
172- // language = English
173- _desc_str[1 ] = 0x0409 ;
290+ _desc_str[1 ] = USBDevice.getLanguageDescriptor ();
174291 chr_count = 1 ;
175292 break ;
176293
177- case 1 : // Manufacturer
178- case 2 : // Product
179- {
180- char const * str = (index == 1 ) ? USB_MANUFACTURER : USB_PRODUCT;
181-
182- // cap at max char
183- chr_count = strlen (str);
184- if ( chr_count > 32 ) chr_count = 32 ;
294+ case 1 :
295+ chr_count = strcpy_uni16 (USBDevice.getManufacturerDescriptor (), _desc_str + 1 , 32 );
296+ break ;
185297
186- for (uint8_t i=0 ; i<chr_count; i++)
187- {
188- _desc_str[1 +i] = str[i];
189- }
190- }
298+ case 2 :
299+ chr_count = strcpy_uni16 (USBDevice.getProductDescriptor (), _desc_str + 1 , 32 );
191300 break ;
192301
193302 case 3 :
@@ -198,8 +307,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index)
198307 default : return NULL ;
199308 }
200309
201- // first byte is len , second byte is string type
202- _desc_str[0 ] = TUD_DESC_STR_HEADER ( chr_count);
310+ // first byte is length (including header) , second byte is string type
311+ _desc_str[0 ] = (TUSB_DESC_STRING << 8 ) | ( 2 * chr_count + 2 );
203312
204313 return _desc_str;
205314}
0 commit comments