8$ Definitions Friend Enum POLICY_TYPE As UInt32 SHORT_PACKET_TERMINATE = 1 AUTO_CLEAR_STALL PIPE_TRANSFER_TIMEOUT IGNORE_SHORT_PACKETS ALLOW_PARTIAL_READS AUTO_FLUSH RAW_IO End Enum ' U
Trang 1The application can request and store information about each of the interface’s endpoints in turn.
For i As Int32 = 0 To ifaceDescriptor.bNumEndpoints - 1
WinUsb_QueryPipe _
(myDevInfo.winUsbHandle, _
0, _ Convert.ToByte(i), _ pipeInfo)
If ((pipeInfo.PipeType = _
USBD_PIPE_TYPE.UsbdPipeTypeBulk) And _ UsbEndpointDirectionIn(pipeInfo.PipeId)) Then myDevInfo.bulkInPipe = pipeInfo.PipeId ElseIf ((pipeInfo.PipeType = _
USBD_PIPE_TYPE.UsbdPipeTypeBulk) And _ UsbEndpointDirectionOut(pipeInfo.PipeId)) Then myDevInfo.bulkOutPipe = pipeInfo.PipeId ElseIf (pipeInfo.PipeType = _
USBD_PIPE_TYPE.UsbdPipeTypeInterrupt) And _ UsbEndpointDirectionIn(pipeInfo.PipeId) Then myDevInfo.interruptInPipe = pipeInfo.PipeId ElseIf (pipeInfo.PipeType = _
USBD_PIPE_TYPE.UsbdPipeTypeInterrupt) And _ UsbEndpointDirectionOut(pipeInfo.PipeId) Then myDevInfo.interruptOutPipe = pipeInfo.PipeId End If
Next i
8% Definitions
internal enum USBD_PIPE_TYPE
{
UsbdPipeTypeControl,
UsbdPipeTypeIsochronous,
UsbdPipeTypeBulk,
UsbdPipeTypeInterrupt,
}
Trang 2internal struct WINUSB_PIPE_INFORMATION
{
internal USBD_PIPE_TYPE PipeType;
internal Byte PipeId;
internal ushort MaximumPacketSize;
internal Byte Interval;
}
[DllImport("winusb.dll", SetLastError = true)]
internal static extern Boolean WinUsb_QueryPipe
(IntPtr InterfaceHandle,
Byte AlternateInterfaceNumber,
Byte PipeIndex,
ref WINUSB_PIPE_INFORMATION PipeInformation);
Use
The UsbEndpointDirectionIn and UsbEndpointDirectionOut functions enable querying the direction of an endpoint:
private Boolean UsbEndpointDirectionIn(Int32 addr)
{
Boolean directionIn;
if (((addr & 0X80) == 0X80))
{ directionIn = true; }
else
{ directionIn = false; }
}
return directionIn;
}
private Boolean UsbEndpointDirectionOut(Int32 addr)
{
Boolean directionOut;
if (((addr & 0X80) == 0))
{ directionOut = true; }
else
{ directionOut = false; }
return directionOut;
}
Trang 3The application can request and store information about each of the interface’s endpoints in turn
for ( Int32 i=0; i <= ifaceDescriptor.bNumEndpoints - 1; i++ )
{
WinUsb_QueryPipe
(myDevInfo.winUsbHandle,
0, Convert.ToByte(i), ref pipeInfo);
if (((pipeInfo.PipeType ==
USBD_PIPE_TYPE.UsbdPipeTypeBulk) &&
UsbEndpointDirectionIn(pipeInfo.PipeId))) {
myDevInfo.bulkInPipe = pipeInfo.PipeId;
}
else if (((pipeInfo.PipeType ==
USBD_PIPE_TYPE.UsbdPipeTypeBulk) &&
UsbEndpointDirectionOut(pipeInfo.PipeId))) {
myDevInfo.bulkOutPipe = pipeInfo.PipeId;
}
else if ((pipeInfo.PipeType ==
USBD_PIPE_TYPE.UsbdPipeTypeInterrupt) &&
UsbEndpointDirectionIn(pipeInfo.PipeId)) {
myDevInfo.interruptInPipe = pipeInfo.PipeId;
}
else if ((pipeInfo.PipeType ==
USBD_PIPE_TYPE.UsbdPipeTypeInterrupt) &&
UsbEndpointDirectionOut(pipeInfo.PipeId)) {
myDevInfo.interruptOutPipe = pipeInfo.PipeId;
}
}
&GVCKNU
The PipeId value equals bEndpointAddress in the endpoint descriptor A valid endpoint has a PipeId greater than zero The USBD_PIPE_TYPE enumerator includes an entry for isochronous pipes, but the WinUSB driver doesn’t sup-port isochronous transfers.
Trang 4After identifying an endpoint, an application can set vendor-specific policies for transfers at the endpoint Table 14-1 shows the policies.
8$ Definitions
Friend Enum POLICY_TYPE As UInt32
SHORT_PACKET_TERMINATE = 1
AUTO_CLEAR_STALL
PIPE_TRANSFER_TIMEOUT
IGNORE_SHORT_PACKETS
ALLOW_PARTIAL_READS
AUTO_FLUSH
RAW_IO
End Enum
' Use this definition when the returned Value parameter is a Byte
' (all except PIPE_TRANSFER_TIMEOUT):
<DllImport("winusb.dll", SetLastError:=True)> _
Friend Shared Function WinUsb_SetPipePolicy _
(ByVal InterfaceHandle As IntPtr, _
ByVal PipeID As Byte, _
ByVal PolicyType As UInt32, _
ByVal ValueLength As UInt32, _
ByRef Value As Byte) _
As Boolean
End Function
' Use this alias when the returned Value parameter
' is a UInt32 (PIPE_TRANSFER_TIMEOUT only):
<DllImport("winusb.dll", EntryPoint:="WinUsb_SetPipePolicy", SetLastError:=True)> _ Friend Shared Function WinUsb_SetPipePolicy1 _
(ByVal InterfaceHandle As IntPtr, _
ByVal PipeID As Byte, _
ByVal PolicyType As UInt32, _
ByVal ValueLength As UInt32, _
ByRef Value As UInt32) _
As Boolean
End Function
Trang 5Table 14-1: The WinUsb_SetPipePolicy function can specify how the driver responds to various conditions when performing a transfer and whether data bypasses WinUSB’s queuing and error handling
SHORT_PACKET_TERMINATE 01h False If True, terminate a write transfer
that is a multiple of wMaxPacketSize with a ZLP
AUTO_CLEAR_STALL 02h False If True, clear a stall condition
automatically
PIPE_TRANSFER_TIMEOUT 03h Zero Set a transfer timeout interval in
milliseconds Zero = never time out IGNORE_SHORT_PACKETS 04h False If True, complete a read operation
only on receiving the specified number of bytes If False, complete a read operation on receiving the specified number of bytes or a short packet
ALLOW_PARTIAL_READS 05h True Sets the policy if the endpoint
returns more data than requested If True, complete the read operation and save or discard the extra data as specified by AUTO_FLUSH If False, fail the read request
ALLOW_PARTIAL_READS is also True, discard extra data If False and ALLOW_PARTIAL_READS is True, save extra data and return it in the next read operation If
ALLOW_PARTIAL_READS is False, ignore
WinUsb_ReadPipe bypasses WinUSB's queuing and error handling, If True, calls pass directly
to the USB stack, and the read buffer must be a multiple of
wMaxPacketSize and less than the host controller’s maximum per transfer If False, calls don’t pass directly to the USB stack, and the buffers don’t have the size restrictions
Trang 6With these overloaded functions, you can call SetPipePolicy to set a policy with
a Byte or UINT32 value as needed.
Private Function SetPipePolicy _
(ByVal pipeId As Byte, ByVal policyType As UInt32, ByVal value As Byte) _
As Boolean
Dim success As Boolean = WinUsb_SetPipePolicy _
(myDevInfo.winUsbHandle, _
pipeId, _
policyType, _
1, _
value)
Return success
End Function
Private Function SetPipePolicy _
(ByVal pipeId As Byte, ByVal policyType As UInt32, ByVal value As UInt32) _
As Boolean
Dim success As Boolean = WinUsb_SetPipePolicy1 _
(myDevInfo.winUsbHandle, _
pipeId, _
policyType, _
4, _
value)
Return success
End Function
Call the functions to set policies for an endpoint:
Dim success As Boolean
SetPipePolicy _
(myDevInfo.bulkInPipe, _
POLICY_TYPE.IGNORE_SHORT_PACKETS, _
Convert.ToByte(False))
Dim pipeTimeout As UInt32 = 2000
Trang 7success = SetPipePolicy _
(myDevInfo.bulkInPipe, _
POLICY_TYPE.PIPE_TRANSFER_TIMEOUT, _
pipeTimeout)
8% Definitions
internal enum POLICY_TYPE
{
SHORT_PACKET_TERMINATE = 1,
AUTO_CLEAR_STALL,
PIPE_TRANSFER_TIMEOUT,
IGNORE_SHORT_PACKETS,
ALLOW_PARTIAL_READS,
AUTO_FLUSH,
RAW_IO,
}
// Use this definition when the returned Value parameter is a Byte
// (all except PIPE_TRANSFER_TIMEOUT):
[DllImport("winusb.dll", SetLastError = true)]
internal static extern Boolean WinUsb_SetPipePolicy
(IntPtr InterfaceHandle,
Byte PipeID,
UInt32 PolicyType,
UInt32 ValueLength,
ref Byte Value);
// Use this alias when the returned Value parameter is a UInt32
// (PIPE_TRANSFER_TIMEOUT only):
[DllImport("winusb.dll", SetLastError = true, EntryPoint = "WinUsb_SetPipePolicy")] internal static extern Boolean WinUsb_SetPipePolicy1
(IntPtr InterfaceHandle,
Byte PipeID,
UInt32 PolicyType,
UInt32 ValueLength,
ref UInt32 Value);
Trang 8With these overloaded functions, you can call SetPipePolicy to set a policy with
a Byte or UINT32 value as needed.
private Boolean SetPipePolicy( Byte pipeId, UInt32 policyType, Byte value )
{
Boolean success = WinUsb_SetPipePolicy
( myDevInfo.winUsbHandle,
pipeId,
policyType,
1,
ref value ;
return success;
}
private Boolean SetPipePolicy( Byte pipeId, UInt32 policyType, UInt32 value )
{
Boolean success = WinUsb_SetPipePolicy1
( myDevInfo.winUsbHandle,
pipeId,
policyType,
4,
ref value );
return success;
}
Call the functions to set policies for an endpoint:
Boolean success;
success = SetPipePolicy
( myDevInfo.bulkInPipe,
Convert.ToUInt32(POLICY_TYPE.IGNORE_SHORT_PACKETS),
Convert.ToByte(false));
UInt32 pipeTimeout = 2000;
success = SetPipePolicy
(myDevInfo.bulkInPipe,
Convert.ToUInt32(POLICY_TYPE.PIPE_TRANSFER_TIMEOUT),
pipeTimeout);
Trang 9The WinUsb_SetPipePolicy function accepts a Byte for the value parameter for all policies except PIPE_TRANSFER_TIMEOUT, which requires a UINT32.
To handle both types, the code provides a definition that accepts a Byte value and an alias that accepts a UINT32 Two overloaded SetPipePolicy functions accept different value parameter types and pass the parameter to WinUsb_SetPipePolicy
The Byte parameters have true/false meanings, so for readability, the Set-PipePolicy function accepts a Boolean value, and the Convert.ToByte method converts to a Byte for passing to WinUsb_SetPipePolicy.
The example sets two policies for the bulk IN endpoint In a similar way, you can set policies for all of the interface’s endpoints A companion function for reading pipe policies is WinUsb_GetPipePolicy.
9TKVKPI&CVCXKC$WNMCPF+PVGTTWRV6TCPUHGTU
The WinUsb_WritePipe function can write data using bulk or interrupt trans-fers.
8$ Definitions
<DllImport("winusb.dll", SetLastError:=True)> _
Friend Shared Function WinUsb_WritePipe _
(ByVal InterfaceHandle As IntPtr, _
ByVal PipeID As Byte, _
ByVal Buffer() As Byte, _
ByVal BufferLength As UInt32, _
ByRef LengthTransferred As UInt32, _
ByVal Overlapped As IntPtr) _
As Boolean
End Function
Use
Dim buffer(1) As Byte
Dim bytesToWrite As UInt32 = 2
Dim bytesWritten As UInt32
Dim success As Boolean
Trang 10' Place data in the buffer to send Example:
buffer(0) = 72
buffer(1) = 105
bytesToWrite = Convert.ToUInt32(buffer.Length)
success = WinUsb_WritePipe _
(myDevInfo.winUsbHandle, _
myDevInfo.bulkOutPipe, _
buffer, _
bytesToWrite, _
bytesWritten, _
IntPtr.Zero)
8% Definitions
[DllImport("winusb.dll", SetLastError = true)]
internal static extern Boolean WinUsb_WritePipe
(IntPtr InterfaceHandle,
Byte PipeID,
Byte[] Buffer,
UInt32 BufferLength,
ref UInt32 LengthTransferred,
IntPtr Overlapped);
Use
Byte[] buffer = new Byte[2];
UInt32 bytesToWrite = 2;
UInt32 bytesWritten = 0;
Boolean success;
// Place data in the buffer to send Example:
buffer[0] = 72;
buffer[1] = 105;
bytesToWrite = Convert.ToUInt32( buffer.Length);
success = WinUsb_WritePipe
(myDevInfo.winUsbHandle,
myDevInfo.bulkOutPipe,
buffer,
bytesToWrite,
ref bytesWritten,
IntPtr.Zero);