&GXKEGKTOYCTG A WinUSB device has an interface descriptor with bInterfaceClass = FFh to indicate a vendor-specific class.. Following the interface descriptor are endpoint descriptors for
Trang 1The host:
• Is Windows XP SP2 or later.
• Needs no more than one open handle to the device at once.
• Has an INF file that contains the device’s Vendor ID and Product ID and a vendor-defined device interface GUID
• Has the WinUSB driver and installation files For Windows XP, the device vendor can provide the files, which are a free, redistributable download from Microsoft Windows Vista systems include the files.
• Has a vendor-provided application to communicate with the device Pro-gramming languages for the application can include Visual Basic, Visual C#, and other languages that can call Windows API functions.
&GXKEG(KTOYCTG
A WinUSB device has an interface descriptor with bInterfaceClass = FFh to indicate a vendor-specific class Listing 14-1 shows descriptors for an example WinUSB device Following the interface descriptor are endpoint descriptors for interrupt IN, interrupt OUT, bulk IN, and bulk OUT endpoints as needed A device can also use vendor-specific control transfers Unlike HID data, WinUSB data doesn’t have to be in defined-length reports.
Device firmware can respond to vendor-specific requests in control transfers Firmware handles these transfers in much the same way as the HID Get Report and Set Report requests The Setup packet can use any values for the wValue, wIndex, and wLength fields In the bmRequestType field, bits 6 5 equal 10 to indicate a vendor-defined request The bRequest field is a vendor-defined request number.
For all of the transfer types, the host application and device firmware must agree on the data format For example, for a data-acquisition device, firmware might define a vendor-specific control request with bRequest = 01h to identify the request, wIndex indicating which sensor reading to return, and wLength equal to the number of bytes the device should return with the requested data.
Or the firmware might send sensor data in a defined format on an interrupt or bulk endpoint In a similar way, a host application can send data to a device using control, bulk, or interrupt transfers.
Trang 2Device Descriptor
12 bLength Descriptor size in bytes
01 bDescriptorType Descriptor type (Device)
0200 bcdUSB USB Specification release number (BCD) (2.00)
00 bDeviceClass Class Code
00 bDeviceSubClass Subclass code
00 bDeviceProtocol Protocol code
08 bMaxPacketSize0 Endpoint 0 maximum packet size
0925 idVendor Vendor ID (Lakeview Research)
1456 idProduct Product ID
0100 bcdDevice Device release number (BCD)
00 iManufacturer Manufacturer string index
00 iProduct Product string index
00 iSerialNumber Device serial number string index
01 bNumConfigurations Number of configurations
Configuration Descriptor
09 bLength Descriptor size in bytes
02 bDescriptorType Descriptor type (Configuration)
002E wTotalLength Total length of this and subordinate descriptors
01 bNumInterfaces Number of interfaces in this configuration
01 bConfigurationValue Index of this configuration
00 iConfiguration Configuration string index
E0 bmAttributes Attributes (self powered, remote wakeup supported)
32 bMaxPower Maximum power consumption (100 mA)
Interface Descriptor
09 bLength Descriptor size in bytes
04 bDescriptorType Descriptor type (Interface)
00 bInterfaceNumber Interface number
00 bAlternateSetting Alternate setting number
04 bNumEndpoints Number of endpoints in this interface
FF bInterfaceClass Interface class (vendor specific)
00 bInterfaceSubclass Interface subclass
00 bInterfaceProtocol Interface protocol
00 iInterface Interface string index
Trang 3Interrupt IN Endpoint Descriptor
07 bLength Descriptor size in bytes
05 bDescriptorType Descriptor type (Endpoint)
81 bEndpointAddress Endpoint number and direction (1 IN)
03 bmAttributes Transfer type (interrupt)
0008 wMaxPacketSize Maximum packet size
0A bInterval polling interval (milliseconds)
Interrupt OUT Endpoint Descriptor
07 bLength Descriptor size in bytes
05 bDescriptorType Descriptor type (Endpoint)
01 bEndpointAddress Endpoint number and direction (1 OUT)
03 bmAttributes Transfer type (interrupt)
0008 wMaxPacketSize Maximum packet size
0A bInterval polling interval (milliseconds)
Bulk IN Endpoint Descriptor
07 bLength Descriptor size in bytes
05 bDescriptorType Descriptor type (Endpoint)
82 bEndpointAddress Endpoint number and direction (2 IN)
02 bmAttributes Transfer type (bulk)
0040 wMaxPacketSize Maximum packet size
00 bInterval polling interval (ignored)
Bulk OUT Endpoint Descriptor
07 bLength Descriptor size in bytes
05 bDescriptorType Descriptor type (Endpoint)
02 bEndpointAddress Endpoint number and direction (2 OUT)
02 bmAttributes Transfer type (bulk)
0040 wMaxPacketSize Maximum packet size
00 bInterval polling interval (ignored)
Listing 14-1: Example descriptors for a WinUSB device All values are in hexadecimal (Part 2 of 2)
Trang 42$2 For PICBASIC PRO firmware for WinUSB, visit my website (www.Lvr.com).
% The Microchip USB Framework provides WinUSB firmware for the
PIC18F4550 and other Microchip microcontrollers The code supports send-ing and receivsend-ing data ussend-ing bulk and interrupt transfers For code that also
supports control transfers, visit www.Lvr.com.
#UUKIPKPIVJG9KP75$&TKXGT
Installing a USB device that uses the WinUSB driver requires an INF file that identifies the device Chapter 9 showed an INF file for a WinUSB device Win-dows XP installations also require a free, redistributable coinstaller files from the WDK.
The WinUSB coinstaller file is:
WinUsbCoinstaller.dll
located in:
<winddk_home>\<build_number>\redist\winusb\<arch>
where <winddk_home> and <build_number> are the home directory and subdi-rectory of the WDK and <arch> indicates a PC architecture such as x86 for
32-bit systems, amd64 for AMD 64-bit systems, or ia64 for Itanium 64-bit sys-tems For example, a 32-bit file for WDK build 6001 might be stored here:
c:\winddk\6001\redist\winusb\x86
The coinstaller contains the winusb.sys driver so you don’t need to provide this
file separately The coinstaller installs the driver
The other needed WDK files are:
WdfCoInstallerxxx.dll
WUDFUpdate_xxx.dll
where xxx represents the edition of the file.
For WDK build 6001, the file names are:
WdfCoinstaller01007.dll
WudfUpdate_01007.dll
For other WDK builds, the file editions and file names may differ Check the directories for the correct file names for your WDK.
The files are located here:
Trang 5The value of KmdfLibraryVersion in the INF file must correspond to the
ver-sion numbers of WdfCoInstaller01xxx.dll and WUDFUpdate_01xxx.dll For
W D K b u i l d 6 0 0 1 , w h i c h c o n t a i n s Wd f C o In s t a l l e r 0 1 0 0 7 d l l a n d WUDFUpdate_01007.dll, set KmdfLibraryVersion=1.7.
If using WDK build 6000, make these changes to the example INF file: the
WudfUpdate and WdfCoinstaller file names are WudfUpdate_01005.dll and WdfCoinstaller01005.dll, and KmdfLibraryVersion=1.5 Later WDK editions
may require similar changes to these items.
#EEGUUKPIVJG&GXKEG
Accessing a WinUSB device requires finding the device, initializing communi-cations, and exchanging data using bulk, interrupt, and control transfers as
needed The WinUSB driver provides Winusb.dll, which exposes
WinUSB-spe-cific functions that applications can call to obtain access to devices and to con-figure, and exchange data with them
The code examples in this chapter assume the following Imports and using state-ments:
8$ Imports Microsoft.Win32.SafeHandles
Imports System.Runtime.InteropServices
8% using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
1DVCKPKPIC9KP75$*CPFNG
Before exchanging data with a WinUSB device, an application obtains a device pathname using SetupDi_ functions and the device interface GUID from the device’s INF file The application can then use CreateFile to obtain a handle In the call to CreateFile, the dwFlagsandAttributes parameter must be set to FILE_FLAG_OVERLAPPED.
Chapter 8 discussed how to generate a GUID Chapter 10 showed how to obtain a handle with CreateFile and use the handle to detect when a device is attached and removed.
After calling CreateFile to obtain a handle, the application calls WinUsb_Initialize to obtain a WinUSB interface handle The application uses this handle for all communications with the interface.
Trang 68$ Definitions
Friend Structure devInfo
Friend deviceHandle As SafeFileHandle
Friend winUsbHandle As IntPtr
Friend bulkInPipe As Byte
Friend bulkOutPipe As Byte
Friend interruptInPipe As Byte
Friend interruptOutPipe As Byte
Friend devicespeed As UInt32
End Structure
<DllImport("winusb.dll", SetLastError:=True)> Friend Shared Function WinUsb_Initialize _ (ByVal DeviceHandle As SafeFileHandle, _
ByRef InterfaceHandle As IntPtr) _
As Boolean
End Function
Use
Dim success As Boolean
Friend myDevInfo As New devInfo
success = WinUsb_Initialize _
(myDevInfo.deviceHandle, _
myDevInfo.winUsbHandle)
8% Definitions
internal struct devInfo
{
internal SafeFileHandle deviceHandle;
internal InPtr winUsbHandle;
internal Byte bulkInPipe;
internal Byte bulkOutPipe;
internal Byte interruptInPipe;
internal Byte interruptOutPipe;
internal UInt32 devicespeed;
[DllImport("winusb.dll", SetLastError = true)]
internal static extern Boolean WinUsb_Initialize
Trang 7Boolean success;
internal devInfo myDevInfo = new devInfo();
success = WinUsb_Initialize
(myDevInfo.deviceHandle,
ref myDevInfo.winUsbHandle);
&GVCKNU
The application can create a devInfo structure to hold information about a device and its endpoints The myDevInfo.deviceHandle parameter is the han-dle returned by CreateFile On success, the function returns True and myDevInfo.winUsbHandle is a pointer to a WinUSB handle that the applica-tion can use to access the device.
4GSWGUVKPICP+PVGTHCEG&GUETKRVQT
The WinUsb_QueryInterfaceSettings function returns a structure with infor-mation about a WinUSB interface.
8$ Definitions
Friend Structure USB_INTERFACE_DESCRIPTOR
Friend bLength As Byte
Friend bDescriptorType As Byte
Friend bInterfaceNumber As Byte
Friend bAlternateSetting As Byte
Friend bNumEndpoints As Byte
Friend bInterfaceClass As Byte
Friend bInterfaceSubClass As Byte
Friend bInterfaceProtocol As Byte
Friend iInterface As Byte
End Structure
<DllImport("winusb.dll", SetLastError:=True)> _
Friend Shared Function WinUsb_QueryInterfaceSettings _
(ByVal InterfaceHandle As IntPtr, _
ByVal AlternateInterfaceNumber As Byte, _
ByRef UsbAltInterfaceDescriptor As USB_INTERFACE_DESCRIPTOR) _
As Boolean
End Function
Trang 8Dim ifaceDescriptor As USB_INTERFACE_DESCRIPTOR
Dim success As Boolean
success = WinUsb_QueryInterfaceSettings _
(myDevInfo.winUsbHandle, _
0, _
ifaceDescriptor)
8% Definitions
internal struct USB_INTERFACE_DESCRIPTOR
{
internal Byte bLength;
internal Byte bDescriptorType;
internal Byte bInterfaceNumber;
internal Byte bAlternateSetting;
internal Byte bNumEndpoints;
internal Byte bInterfaceClass;
internal Byte bInterfaceSubClass;
internal Byte bInterfaceProtocol;
internal Byte iInterface;
}
[DllImport("winusb.dll", SetLastError = true)]
internal static extern Boolean WinUsb_QueryInterfaceSettings
(IntPtr InterfaceHandle,
Byte AlternateInterfaceNumber,
ref USB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor);
Use
USB_INTERFACE_DESCRIPTOR ifaceDescriptor;
Boolean success;
success = WinUsb_QueryInterfaceSettings
(myDevInfo.winUsbHandle,
0,
ref ifaceDescriptor);
&GVCKNU
Trang 9quer y On success, the function returns Tr ue and a pointer to a USB_INTERFACE_DESCRIPTOR structure containing information from the requested interface descriptor.
+FGPVKH[KPIVJG'PFRQKPVU
For each endpoint in the interface descriptor, an application can call WinUsb_QueryPipe to learn the endpoint’s transfer type and direction The myDevInfo structure can store the information.
8$ Definitions
Friend Enum USBD_PIPE_TYPE
UsbdPipeTypeControl
UsbdPipeTypeIsochronous
UsbdPipeTypeBulk
UsbdPipeTypeInterrupt
End Enum
Friend Structure WINUSB_PIPE_INFORMATION
Friend PipeType As USBD_PIPE_TYPE
Friend PipeId As Byte
Friend MaximumPacketSize As UShort
Friend Interval As Byte
End Structure
<DllImport("winusb.dll", SetLastError:=True)> _
Friend Shared Function WinUsb_QueryPipe _
(ByVal InterfaceHandle As IntPtr, _
ByVal AlternateInterfaceNumber As Byte, _
ByVal PipeIndex As Byte, _
ByRef PipeInformation As WINUSB_PIPE_INFORMATION) _
As Boolean
End Function
Trang 10The UsbEndpointDirectionIn and UsbEndpointDirectionOut functions enable querying the direction of an endpoint:
Private Function UsbEndpointDirectionIn(ByVal addr As Int32) As Boolean
If ((addr And &H80) = &H80) Then
UsbEndpointDirectionIn = True
Else
UsbEndpointDirectionIn = False
End If
End Function
Private Function UsbEndpointDirectionOut(ByVal addr As Int32) As Boolean
If ((addr And &H80) = 0) Then
UsbEndpointDirectionOut = True
Else
UsbEndpointDirectionOut = False
End If
End Function