static bool ConfigurePinger(UsbController port)
        {
            UsbController.PortState portState = port.Status;

            if (portState != UsbController.PortState.Stopped)
            {
                Debug.Print("The controller has already been initialized and is in state " + portState.ToString() + ".");
                // return false;
            }

            // Create the device descriptor
            Configuration.DeviceDescriptor device = new Configuration.DeviceDescriptor(0x15A2, 0x0026, 0x0100);
            device.iManufacturer = 1;      // String 1 is the manufacturer name
            device.iProduct      = 2;      // String 2 is the product name
            device.bcdUSB        = 0x0200; // USB version 2.00

            // Create the simple configuration descriptor
            Configuration.Endpoint endpoint1 = new Configuration.Endpoint(1, Configuration.Endpoint.ATTRIB_Bulk | Configuration.Endpoint.ATTRIB_Write);
            Configuration.Endpoint endpoint2 = new Configuration.Endpoint(2, Configuration.Endpoint.ATTRIB_Bulk | Configuration.Endpoint.ATTRIB_Read);
            endpoint1.wMaxPacketSize = 64;
            endpoint2.wMaxPacketSize = 64;      // Pinger endpoints use the maximum allowable buffer
            Configuration.Endpoint[] endpoints = new Configuration.Endpoint[2] {
                endpoint1, endpoint2
            };
            // Assign the endpoints to the interface and set up the interface fields
            Configuration.UsbInterface UsbInterface0 = new Configuration.UsbInterface(0, endpoints);
            UsbInterface0.bInterfaceClass    = 0xFF; // Vendor class
            UsbInterface0.bInterfaceSubClass = 1;
            UsbInterface0.bInterfaceProtocol = 1;
            // Finish by assigning the interfaces to the configuration descriptor
            Configuration.UsbInterface[] UsbInterfaces = new Configuration.UsbInterface[1] {
                UsbInterface0
            };
            Configuration.ConfigurationDescriptor config = new Configuration.ConfigurationDescriptor(280, UsbInterfaces);

            // Create the standard strings needed for the iMXS board Pinger
            Configuration.StringDescriptor manufacturerName = new Configuration.StringDescriptor(1, "Freescale");
            Configuration.StringDescriptor productName      = new Configuration.StringDescriptor(2, "Micro Framework MXS Reference ");
            Configuration.StringDescriptor displayName      = new Configuration.StringDescriptor(4, "iMXS");
            Configuration.StringDescriptor friendlyName     = new Configuration.StringDescriptor(5, "a7e70ea2");

            // Create the Sideshow OS String descriptor as if it were a standard string descriptor
            Configuration.StringDescriptor OS_StringDescriptor = new Configuration.StringDescriptor(0xEE, "MSFT100\xA5");

            // Create the Sideshow OS Extended Compatible ID Descriptor as a Generic
            byte[] compatibleIdPayload = new byte[]
            {
                40, 0, 0, 0,                                                                    // Size of the payload
                00, 1,                                                                          // Version 1.00
                04, 0,                                                                          // OS Compatible ID request
                1,                                                                              // Interface count
                0, 0, 0, 0, 0, 0, 0,                                                            // padding (7 zeros)

                0,                                                                              // Interface number
                1,                                                                              // reserved
                (byte)'S', (byte)'I', (byte)'D', (byte)'E', (byte)'S', (byte)'H', (byte)'W', 0, // Compatible ID
                (byte)'E', (byte)'N', (byte)'H', (byte)'V', (byte)'1', 0, 0, 0,                 // Sub-compatible ID
                0, 0, 0, 0, 0, 0                                                                // padding (6 zeros)
            };
            // Assign the payload to the generic and fill in the generic descriptor fields
            const byte RequestType          = Configuration.GenericDescriptor.REQUEST_IN | Configuration.GenericDescriptor.REQUEST_Vendor;
            const byte RequestCommand       = 0xA5;
            const byte XCompatibleOsRequest = 4;

            Configuration.GenericDescriptor XCompatibleOsDescriptor = new Configuration.GenericDescriptor(RequestType, 0, compatibleIdPayload);
            XCompatibleOsDescriptor.bRequest = RequestCommand;
            XCompatibleOsDescriptor.wIndex   = XCompatibleOsRequest;

            // Now assemble all of these descriptors into the final configuration
            Configuration simpleConfig = new Configuration();

            simpleConfig.descriptors = new Configuration.Descriptor[]
            {
                device,
                config,
                manufacturerName,
                productName,
                displayName,
                friendlyName,
                OS_StringDescriptor,
                XCompatibleOsDescriptor,
            };

            try
            {
                // Set the configuration to the USB Controller
                port.Configuration = simpleConfig;

                if (port.ConfigurationError != UsbController.ConfigError.ConfigOK)
                {
                    Debug.Print("Simple configuration reported an error " + port.ConfigurationError.ToString());
                    return(false);
                }

                // Kick the USB Controller into action
                if (!port.Start())
                {
                    Debug.Print("Simple USB could not be started.");
                    return(false);
                }
            }
            catch (ArgumentException)
            {
                Debug.Print("Couldn't configure Simple USB due to error " + port.ConfigurationError.ToString());
                return(false);
            }

            const int MaxTenths = 20;       // Wait up to two seconds for controller to finish handshake
            int       tenths;

            for (tenths = 0; tenths < MaxTenths; tenths++)
            {
                if (port.Status == UsbController.PortState.Running)     // If host has finished with handshake
                {
                    break;
                }
                System.Threading.Thread.Sleep(100);
            }
            if (tenths < MaxTenths)
            {
                return(true);
            }

            Debug.Print("After " + MaxTenths.ToString() + " tenths of a second, Simple USB still had status of " + port.Status.ToString());
            return(false);
        }
        static bool ConfigureMouseAndPinger(UsbController port)
        {
            UsbController.PortState portState = port.Status;

            if (portState != UsbController.PortState.Stopped)
            {
                Debug.Print("The controller has already been initialized and is in state " + portState.ToString() + ".");
                // return false;
            }

            // Create the device descriptor
            Configuration.DeviceDescriptor device = new Configuration.DeviceDescriptor(0x15A2, 0x0026, 0x0100);
            device.iManufacturer = 1;     // String 1 is the manufacturer name
            device.iProduct      = 2;     // String 2 is the product name
            device.bcdUSB        = 0x200; // USB version 2.00

            // Create the compound configuration descriptor
            Configuration.Endpoint endpoint1 = new Configuration.Endpoint(1, Configuration.Endpoint.ATTRIB_Bulk | Configuration.Endpoint.ATTRIB_Write);
            Configuration.Endpoint endpoint2 = new Configuration.Endpoint(2, Configuration.Endpoint.ATTRIB_Bulk | Configuration.Endpoint.ATTRIB_Read);
            Configuration.Endpoint endpoint3 = new Configuration.Endpoint(3, Configuration.Endpoint.ATTRIB_Interrupt | Configuration.Endpoint.ATTRIB_Write);
            endpoint1.wMaxPacketSize = 64;
            endpoint2.wMaxPacketSize = 64; // Pinger endpoints use the maximum allowable buffer
            endpoint3.wMaxPacketSize = 8;  // Mouse data requires only eight bytes
            endpoint3.bInterval      = 10; // Host should request data from mouse every 10 mS
            Configuration.Endpoint[] pingerEndpoints = new Configuration.Endpoint[2] {
                endpoint1, endpoint2
            };
            Configuration.Endpoint[] mouseEndpoints = new Configuration.Endpoint[1] {
                endpoint3
            };
            // Set up the Pinger interface
            Configuration.UsbInterface UsbInterface0 = new Configuration.UsbInterface(0, pingerEndpoints);
            UsbInterface0.bInterfaceClass    = 0xFF; // Vendor class
            UsbInterface0.bInterfaceSubClass = 1;
            UsbInterface0.bInterfaceProtocol = 1;
            // Set up the Mouse interface
            Configuration.UsbInterface UsbInterface1 = new Configuration.UsbInterface(1, mouseEndpoints);
            UsbInterface1.bInterfaceClass    = 3; // HID interface
            UsbInterface1.bInterfaceSubClass = 1; // Boot device
            UsbInterface1.bInterfaceProtocol = 2; // Standard mouse protocol
            // Assemble the HID class descriptor
            byte[] HidPayload = new byte[]
            {
                0x01, 0x01,     // bcdHID = HID version 1.01
                0x00,           // bCountryCode (unimportant)
                0x01,           // bNumDescriptors = number of descriptors available for this device
                0x22,           // bDescriptorType = Report descriptor
                0x32, 0x00      // Total size of Report descriptor (50)
            };
            UsbInterface1.classDescriptors    = new Configuration.ClassDescriptor[1];
            UsbInterface1.classDescriptors[0] = new Configuration.ClassDescriptor(0x21, HidPayload);
            Configuration.UsbInterface[] UsbInterfaces = new Configuration.UsbInterface[2] {
                UsbInterface0, UsbInterface1
            };
            Configuration.ConfigurationDescriptor config = new Configuration.ConfigurationDescriptor(280, UsbInterfaces);

            // Create the report descriptor as a Generic
            // This data was created using
            byte[] BootMouseReportPayload = new byte[]
            {
                0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
                0x09, 0x02,                    // USAGE (Mouse)
                0xa1, 0x01,                    // COLLECTION (Application)
                0x09, 0x01,                    //   USAGE (Pointer)
                0xa1, 0x00,                    //   COLLECTION (Physical)
                0x05, 0x09,                    //     USAGE_PAGE (Button)
                0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
                0x29, 0x03,                    //     USAGE_MAXIMUM (Button 3)
                0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
                0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
                0x95, 0x03,                    //     REPORT_COUNT (3)
                0x75, 0x01,                    //     REPORT_SIZE (1)
                0x81, 0x02,                    //     INPUT (Data,Var,Abs)
                0x95, 0x01,                    //     REPORT_COUNT (1)
                0x75, 0x05,                    //     REPORT_SIZE (5)
                0x81, 0x01,                    //     INPUT (Cnst,Ary,Abs)
                0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
                0x09, 0x30,                    //     USAGE (X)
                0x09, 0x31,                    //     USAGE (Y)
                0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
                0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
                0x75, 0x08,                    //     REPORT_SIZE (8)
                0x95, 0x02,                    //     REPORT_COUNT (2)
                0x81, 0x06,                    //     INPUT (Data,Var,Rel)
                0xc0,                          //     END_COLLECTION
                0xc0                           // END_COLLECTION
            };
            const byte   DescriptorRequest = 0x81;
            const byte   ReportDescriptor  = 0x22;
            const byte   GetDescriptor     = 0x06;
            const ushort Report_wValue     = (ushort)ReportDescriptor << 8;

            Configuration.GenericDescriptor mouseReportDescriptor = new Configuration.GenericDescriptor(DescriptorRequest, Report_wValue, BootMouseReportPayload);
            mouseReportDescriptor.bRequest = GetDescriptor;
            mouseReportDescriptor.wIndex   = 1;      // The interface number

            // Create the standard strings needed for the iMXS board Pinger
            Configuration.StringDescriptor manufacturerName = new Configuration.StringDescriptor(1, "Freescale");
            Configuration.StringDescriptor productName      = new Configuration.StringDescriptor(2, "Micro Framework MXS Reference ");
            Configuration.StringDescriptor displayName      = new Configuration.StringDescriptor(4, "iMXS");
            Configuration.StringDescriptor friendlyName     = new Configuration.StringDescriptor(5, "a7e70ea2");

            // Create the Sideshow OS String descriptor as if it were a standard string descriptor
            Configuration.StringDescriptor OS_StringDescriptor = new Configuration.StringDescriptor(0xEE, "MSFT100\xA5");

            // Create the Sideshow OS Extended Compatible ID Descriptor as a Generic
            byte[] compatibleIdPayload = new byte[]
            {
                40, 0, 0, 0,                                                                    // Size of the payload
                00, 1,                                                                          // Version 1.00
                04, 0,                                                                          // OS Compatible ID request
                1,                                                                              // Interface count
                0, 0, 0, 0, 0, 0, 0,                                                            // padding (7 zeros)

                0,                                                                              // Interface number
                1,                                                                              // reserved
                (byte)'S', (byte)'I', (byte)'D', (byte)'E', (byte)'S', (byte)'H', (byte)'W', 0, // Compatible ID
                (byte)'E', (byte)'N', (byte)'H', (byte)'V', (byte)'1', 0, 0, 0,                 // Sub-compatible ID
                0, 0, 0, 0, 0, 0                                                                // padding (6 zeros)
            };
            // Create the report descriptor as a Generic
            const byte RequestType          = Configuration.GenericDescriptor.REQUEST_IN | Configuration.GenericDescriptor.REQUEST_Vendor;
            const byte RequestCommand       = 0xA5;
            const byte XCompatibleOsRequest = 4;

            Configuration.GenericDescriptor XCompatibleOsDescriptor = new Configuration.GenericDescriptor(RequestType, 0, compatibleIdPayload);
            XCompatibleOsDescriptor.bRequest = RequestCommand;
            XCompatibleOsDescriptor.wIndex   = XCompatibleOsRequest;

            // Now assemble all of these descriptors into the final configuration
            Configuration compoundConfig = new Configuration();

            compoundConfig.descriptors = new Configuration.Descriptor[]
            {
                device,
                config,
                manufacturerName,
                productName,
                displayName,
                friendlyName,
                OS_StringDescriptor,
                XCompatibleOsDescriptor,
                mouseReportDescriptor
            };

            try
            {
                // Set the configuration to the USB Controller
                port.Configuration = compoundConfig;

                if (port.ConfigurationError != UsbController.ConfigError.ConfigOK)
                {
                    Debug.Print("Compound configuration reported an error " + port.ConfigurationError.ToString());
                    return(false);
                }

                // Kick the USB Controller into action
                if (!port.Start())
                {
                    Debug.Print("Compound USB could not be started.");
                    return(false);
                }
            }
            catch (ArgumentException)
            {
                Debug.Print("Couldn't configure Compound USB due to error " + port.ConfigurationError.ToString());
                return(false);
            }

            const int MaxTenths = 20;       // Wait up to two seconds for controller to finish handshake
            int       tenths;

            for (tenths = 0; tenths < MaxTenths; tenths++)
            {
                if (port.Status == UsbController.PortState.Running)     // If host has finished with handshake
                {
                    break;
                }
                System.Threading.Thread.Sleep(100);
            }
            if (tenths < MaxTenths)
            {
                return(true);
            }

            Debug.Print("After " + MaxTenths.ToString() + " tenths of a second, Compound USB still had status of " + port.Status.ToString());
            return(false);
        }