@ Dat - Did you see the GetDescriptor for index = 238 request? What did the device show up like in the Device Manager?
Here is my Main:
public static void Main()
{
Debug.Print("G400-D start USB init");
//This "creates" your USB device and VS will not be able to see the device after this executes (if you debug via USB).
USB.Init();
Debug.Print("G400-D USB init complete");
Thread.Sleep(Timeout.Infinite);
}
My USB.cs file with a stream read and write to echo messages back. This essentially the code from the codeshare project, with my fixes and extra descriptors for MS OS Descriptors. This still missing the descriptor for DeviceInterfaceGUID, and assigning WinUSB as the driver may not be correctly formated. So a working solution for me would be to check Device Manager and see that the WinUSB driver has been assigned to the G400. (No code necessary on the USB host system to confirm this.)
I try to do some more testing my self, like I mentioned I did see the setting bcdUSB = 2.10 work a could of times, but now it always fails.
Thank you for your support this far.
using System;
using Microsoft.SPOT;
using System.Threading;
using Microsoft.SPOT.Hardware.UsbClient;
namespace USBDevice
{
class USB
{
public static string SerialNumber = "FFFFFFFFFFF";
private const int WRITE_EP = 1;
private const int READ_EP = 2;
// Microsoft OS Descriptors
private const int OS_DESCRIPTOR_EX_VERSION = 0x0100;
private const int OS_DESCRIPTOR_STRING = 0xEE;
private const int OS_DESCRIPTOR_STRING_VENDOR_CODE = 0xA5;
private const int USB_RESUEST_TYPE_IN = 0x80;
private const int USB_REQUEST_TYPE_VENDOR = 0x40;
private const int USB_RESUEST_TYPE_INTERFACE = 0x01;
private const int USB_XCOMPATIBLE_OS_REQUEST = 0x04;
private const int USB_XPROPERTY_OS_REQUEST = 0x05;
private const int USB_GENERIC_DISCRIPTOR_HEADER_SIZE = 16;
private const int USB_XCOMPATIBLE_OS_SIZE = 24;
static UsbStream usbStream = null;
/**
* Simply echos back whatever is sent.
*/
public static void HandleRequests()
{
byte[] readData = new byte[512];
int bytesRead;
while (true)
{
bytesRead = usbStream.Read(readData, 0, readData.Length);
if (bytesRead > 0)
{
usbStream.Write(readData, 0, bytesRead);
}
}
}
private static bool ConfigureUSBController(UsbController usbController)
{
bool bRet = false;
// Create the device descriptor
Configuration.DeviceDescriptor device = new Configuration.DeviceDescriptor(0xDEAD, 0xF00C, 0x0200);
device.bcdUSB = 0x210;
device.bDeviceClass = 0xFF; // Vendor defined class
device.bDeviceSubClass = 0xFF; // Vendor defined subclass
device.bDeviceProtocol = 0;
device.bMaxPacketSize0 = 64; // Maximum packet size of EP0
device.iManufacturer = 1; // String #1 is manufacturer name (see string descriptors below)
device.iProduct = 2; // String #2 is product name
device.iSerialNumber = 3; // String #3 is the serial number
// Create the endpoints
Configuration.Endpoint writeEP = new Configuration.Endpoint(WRITE_EP, Configuration.Endpoint.ATTRIB_Write | Configuration.Endpoint.ATTRIB_Bulk | Configuration.Endpoint.ATTRIB_Synchronous);//Configuration.Endpoint.ATTRIB_Bulk | Configuration.Endpoint.ATTRIB_Write);
writeEP.wMaxPacketSize = 64;
writeEP.bInterval = 0;
Configuration.Endpoint readEP = new Configuration.Endpoint(READ_EP, Configuration.Endpoint.ATTRIB_Read | Configuration.Endpoint.ATTRIB_Bulk | Configuration.Endpoint.ATTRIB_Synchronous);// Configuration.Endpoint.ATTRIB_Bulk | Configuration.Endpoint.ATTRIB_Read);
readEP.wMaxPacketSize = 64;
readEP.bInterval = 0;
Configuration.Endpoint[] usbEndpoints = new Configuration.Endpoint[] { writeEP, readEP };
// Set up the USB interface
Configuration.UsbInterface usbInterface = new Configuration.UsbInterface(0, usbEndpoints);
usbInterface.bInterfaceClass = 0xFF; // Vendor defined class
usbInterface.bInterfaceSubClass = 0xFF; // Vendor defined subclass
usbInterface.bInterfaceProtocol = 0;
// Create array of USB interfaces
Configuration.UsbInterface[] usbInterfaces = new Configuration.UsbInterface[] { usbInterface };
// Create configuration descriptor
Configuration.ConfigurationDescriptor config = new Configuration.ConfigurationDescriptor(200, usbInterfaces);
// Create the string descriptors
Configuration.StringDescriptor manufacturerName = new Configuration.StringDescriptor(1, "YourName");
Configuration.StringDescriptor productName = new Configuration.StringDescriptor(2, "G400 Proto HDW");
Configuration.StringDescriptor serialNumber = new Configuration.StringDescriptor(3, "0000-0" + USB.SerialNumber.Substring(0, 3) + "-" + USB.SerialNumber.Substring(3, 4) + "-" + USB.SerialNumber.Substring(7, 4));
Configuration.StringDescriptor displayName = new Configuration.StringDescriptor(4, "YourDisplayName");
Configuration.StringDescriptor friendlyName = new Configuration.StringDescriptor(5, "YourFriendlyName");
// Create the OS String Descriptor - See Microsoft OS Descriptor Overview Page 6 for details.
// append the two bytes 0xA5 and 0x00 to "MSFT100" string with \ua500 syntax
// The bMS_VendorCode is set to 0xA5 (OS_DESCRIPTOR_STRING_VENDOR_CODE) but this can be set by the IHV.
Configuration.StringDescriptor osName = new Configuration.StringDescriptor(OS_DESCRIPTOR_STRING, "MSFT100" + "\uA500");
// Create the OS Feature Descriptor for WinUSB - See Extended Compat ID OS Feature Descriptor Spec. Page 10
byte[] osExtComp = new byte[] { 0x00, 0x00, 0x00, USB_GENERIC_DISCRIPTOR_HEADER_SIZE + USB_XCOMPATIBLE_OS_SIZE
, (OS_DESCRIPTOR_EX_VERSION >> 8), (OS_DESCRIPTOR_EX_VERSION & 0xFF)
, 0x00, 0x04 // Extended Comp ID Descriptor
, 0x01 // Count of custom properties
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Reserved
// OS Extended Compatible ID for WinUSB
, 0x00 // Interface Number
, 0x01 // Reserved
, 0x57, 0x49, 0x4e, 0x55, 0x53, 0x42, 0x00, 0x00 // WINUSB
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Sub Compatible ID
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Reserved
Configuration.GenericDescriptor osExtendedCompatible = new Configuration.GenericDescriptor(USB_RESUEST_TYPE_IN | USB_REQUEST_TYPE_VENDOR, 0, osExtComp);
osExtendedCompatible.bRequest = OS_DESCRIPTOR_STRING_VENDOR_CODE;
osExtendedCompatible.wIndex = USB_XCOMPATIBLE_OS_REQUEST;
// Create the final configuration
Configuration configuration = new Configuration();
configuration.descriptors = new Configuration.Descriptor[] {
device,
config,
manufacturerName,
productName,
serialNumber,
displayName,
friendlyName
, osName
, osExtendedCompatible
};
try
{
// Set the configuration
usbController.Configuration = configuration;
if (UsbController.ConfigError.ConfigOK != usbController.ConfigurationError)
{
throw new ArgumentException();
}
// If all ok, start the USB controller.
bRet = usbController.Start();
}
catch (ArgumentException)
{
Debug.Print("Can't configure USB controller, error " + usbController.ConfigurationError.ToString());
}
return bRet;
}
public static void Init()
{
// See if the hardware supports USB
UsbController[] controllers = UsbController.GetControllers();
// Bail out if USB is not supported on this hardware!
if (0 == controllers.Length)
{
Debug.Print("USB is not supported on this hardware!");
return;
}
foreach (UsbController controller in controllers)
{
if (controller.Status != UsbController.PortState.Stopped)
{
controller.Stop();
Thread.Sleep(1000);
}
}
// Find a free USB controller
UsbController usbController = null;
foreach (UsbController controller in controllers)
{
if (controller.Status == UsbController.PortState.Stopped)
{
usbController = controller;
break;
}
}
// If no free USB controller
if (null == usbController)
{
Debug.Print("All available USB controllers already in use. Set the device to use Ethernet or Serial debugging.");
return;
}
try
{ // Configure the USB controller
if (ConfigureUSBController(usbController))
{
usbStream = usbController.CreateUsbStream(WRITE_EP, READ_EP);
if (usbStream.CanTimeout)
{
usbStream.ReadTimeout = 60000;
usbStream.WriteTimeout = 60000;
}
}
else
{
throw new Exception();
}
}
catch (Exception)
{
Debug.Print("USB stream could not be created, error " + usbController.ConfigurationError.ToString());
return;
}
}
}
}