@@ -31,21 +31,26 @@ const char devDescriptor[] =
3131 /* Device descriptor */
3232 0x12 , // bLength
3333 0x01 , // bDescriptorType
34- 0x10 , // bcdUSBL
35- 0x01 , //
34+ 0x00 , // bcdUSB L
35+ 0x02 , // bcdUSB H
3636 0x02 , // bDeviceClass: CDC class code
3737 0x00 , // bDeviceSubclass: CDC class sub code
3838 0x00 , // bDeviceProtocol: CDC Device protocol
3939 0x40 , // bMaxPacketSize0
40- 0x41 , // idVendorL
41- 0x23 , //
42- USB_PID_LOW , // idProductL
43- USB_PID_HIGH , //
44- 0x10 , // bcdDeviceL
45- 0x01 , //
46- 0x00 , // iManufacturer // 0x01
40+ 0x41 , // idVendor L
41+ 0x23 , // idVendor H
42+ USB_PID_LOW , // idProduct L
43+ USB_PID_HIGH , // idProduct H
44+ 0x00 , // bcdDevice L, here matching SAM-BA version
45+ 0x02 , // bcdDevice H
46+ #if 0 // TODO: pending validation
47+ STRING_INDEX_MANUFACTURER , // iManufacturer
48+ STRING_INDEX_PRODUCT , // iProduct
49+ #else
50+ 0x00 , // iManufacturer
4751 0x00 , // iProduct
48- 0x00 , // SerialNumber
52+ #endif // 0
53+ 0x00 , // SerialNumber, should be based on product unique ID
4954 0x01 // bNumConfigs
5055};
5156
@@ -145,6 +150,13 @@ char cfgDescriptor[] =
145150 0x00 // bInterval
146151};
147152
153+ #ifndef STRING_MANUFACTURER
154+ # define STRING_MANUFACTURER "Arduino LLC"
155+ #endif
156+
157+ #ifndef STRING_PRODUCT
158+ # define STRING_PRODUCT "Arduino Zero"
159+ #endif
148160
149161USB_CDC sam_ba_cdc ;
150162
@@ -177,22 +189,50 @@ void sam_ba_usb_CDC_Enumerate(P_USB_CDC pCdc)
177189 switch ((bRequest << 8 ) | bmRequestType )
178190 {
179191 case STD_GET_DESCRIPTOR :
180- if (wValue == ( STD_GET_DESCRIPTOR_DEVICE << 8 ) )
192+ if (wValue >> 8 == STD_GET_DESCRIPTOR_DEVICE )
181193 {
182194 /* Return Device Descriptor */
183195 USB_Write (pCdc -> pUsb , devDescriptor , SAM_BA_MIN (sizeof (devDescriptor ), wLength ), USB_EP_CTRL );
184196 }
185197 else
186198 {
187- if (wValue == ( STD_GET_DESCRIPTOR_CONFIGURATION << 8 ) )
199+ if (wValue >> 8 == STD_GET_DESCRIPTOR_CONFIGURATION )
188200 {
189201 /* Return Configuration Descriptor */
190202 USB_Write (pCdc -> pUsb , cfgDescriptor , SAM_BA_MIN (sizeof (cfgDescriptor ), wLength ), USB_EP_CTRL );
191203 }
192204 else
193205 {
194- /* Stall the request */
195- USB_SendStall (pUsb , true);
206+ #if 0 // TODO: pending validation
207+ if (wValue >>8 == STD_GET_DESCRIPTOR_STRING )
208+ {
209+ switch ( wValue & 0xff )
210+ {
211+ case STRING_INDEX_LANGUAGES :
212+ uint16_t STRING_LANGUAGE [2 ] = { (STD_GET_DESCRIPTOR_STRING <<8 ) | 4 , 0x0409 };
213+
214+ USB_Write (pCdc -> pUsb , (const char * )STRING_LANGUAGE , SAM_BA_MIN (sizeof (STRING_LANGUAGE ), wLength ), USB_EP_CTRL );
215+ break ;
216+
217+ case STRING_INDEX_MANUFACTURER :
218+ USB_SendString (pCdc -> pUsb , STRING_MANUFACTURER , strlen (STRING_MANUFACTURER ), wLength );
219+ break ;
220+
221+ case STRING_INDEX_PRODUCT :
222+ USB_SendString (pCdc -> pUsb , STRING_PRODUCT , strlen (STRING_PRODUCT ), wLength );
223+ break ;
224+ default :
225+ /* Stall the request */
226+ USB_SendStall (pUsb , true);
227+ break ;
228+ }
229+ }
230+ else
231+ #endif // 0
232+ {
233+ /* Stall the request */
234+ USB_SendStall (pUsb , true);
235+ }
196236 }
197237 }
198238 break ;
@@ -388,3 +428,28 @@ P_USB_CDC usb_init(void)
388428
389429 return & sam_ba_cdc ;
390430}
431+
432+ #if 0 // TODO: pending validation
433+ /*----------------------------------------------------------------------------
434+ * \brief Send a USB descriptor string.
435+ *
436+ * The input string is plain ASCII but is sent out as UTF-16 with the correct 2-byte prefix.
437+ */
438+ uint32_t USB_SendString (Usb * pUsb , const char * ascii_string , uint8_t length , uint8_t maxLength )
439+ {
440+ uint8_t string_descriptor [255 ]; // Max USB-allowed string length
441+ uint16_t * unicode_string = (uint16_t * )(string_descriptor + 2 ); // point on 3 bytes of descriptor
442+
443+ int resulting_length = 1 ;
444+
445+ for ( ; * ascii_string && (length >=0 ) && (resulting_length < (maxLength >>1 )) ; ascii_string ++ , length -- , resulting_length ++ )
446+ {
447+ * unicode_string ++ = (uint16_t )(* ascii_string );
448+ }
449+
450+ string_descriptor [0 ] = (resulting_length <<1 );
451+ string_descriptor [1 ] = STD_GET_DESCRIPTOR_STRING ;
452+
453+ return USB_Write (pUsb , (const char * )unicode_string , resulting_length , USB_EP_CTRL );
454+ }
455+ #endif // 0
0 commit comments