Ports and Interfaces > USB

USB Host Software using VB.Net 2010

(1/4) > >>

Geoff:
Hi,

Although I am relatively new to USB interface development, I have learned quite a lot from my copy of USB Complete 4th Edition.  Thanks to Jan Axelson.

However, I have been unsuccessful in performing interrupt-driven communications with Host software written using Visual Basic 2010 (includes .NET Framework V4.0) - on an XP (SP3) based PC.

Can anyone please assist me ?

------------

The custom peripheral device has been successfully enumerated.  This has been verified using a GraphicUSB sniffer from MQP Electronics, and recognized correctly by the Device Manager.

The peripheral has been created to support an input Report (12 bytes), an output Report (7 bytes) and a feature report (6 bytes).
The peripheral has also been created to support:
*** Configuration 1
 ** Interface 0 (alt 0) HID
    - Class Descriptor
    * Endpoint 2-IN INTERRUPT
    * Endpoint 1-OUT INTERRUPT

Using VB, I can successfully find the peripheral device, and I can send data to the peripheral device using the command:
              success = HidD_SetFeature(hidHandle, outFeatureReportBuffer, outFeatureReportBuffer.Length)

However after many,many attempts I have been unable to send data to the peripheral device using the command:
              success = HidD_SetOutputReport(hidHandle, outputReportBuffer, outputReportBuffer.Length)

Of course, using the HidD_SetFeature command uses Endpoint 0 (command endpoint) whereas I wish to use Endpoint 1 (the output endpoint) using the HidD_SetOutputReport command.

Jan Axelson's "GenericHid.vb" example host software was built using Visual Studio 2008 Standard Edition with the .NET Framework V2.0.    I have rebuilt this example using VS 2010 with .NET 4.0 .   After setting the VendorID and ProductID, the peripheral device is successfully detected, with the message:

"Device detected:  VendorID=B6A  ProductID = ABE1  The device is a system .  Windows 2000 and Windows XP obtain exclusive access to Input and Output reports for this devices.  Applications can access Feature reports only. "

Does this mean that XP can never send output reports to Endpoint 1 ?

I hope that someone can assist me.

Jan Axelson:
If the descriptors identify the device as a system mouse or keyboard, Windows takes exclusive access to Input and Output reports.

For other HIDs, to use interrrupt transfers, use ReadFile and WriteFile, not HidD_ functions.

Jan

Geoff:
Hi Jan,

Thank you for your response comments.

The descriptors for the HID device define it to be "user defined" - and not a system mouse or keyboard.   I have tried many times to get ReadFile and WriteFile to work, however they always fail.   Currently the only method by which I am able to transfer data to/from the peripheral device is via HidD_SetFeature and HidD_GetFeature VB commands.

(a) The device is successfully detected, and registered for device notifications.
(b) The writeHandle is created using VB command:
        writeHandle = CreateFile(CapturedDevicePathName, GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
(c) The writeHandle is confirmed OK since writeHandle.IsInvalid = False
(d) The output report buffer is initialized with some data.
(e) The output report buffer is sent to the peripheral device using VB command:
        WriteFile(writeHandle, OutputReportBuffer, OutputReportBuffer.Length, NumberOfBytesWritten, IntPtr.Zero)
(f) The number of bytes written to the peripheral device is zero (ie. NumberofBytesWritten=0) and the Last Error Code (Err.LastDllError) is "1" (ie. "incorrect function").
(g) The readHandle is attempted to be created using VB command:
        readHandle = CreateFile(CapturedDevicePathName, GENERIC_READ, FILE_SHARE_READ Or FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0)
(h) The readHandle failed since readHandle.IsInvalid = True   with the Last Error Code (Err.LastDllError) = "0".

The peripheral device is defined as:
  1. Configuration Descriptor: 9 bytes, Type=2, TotalLength=0041 bytes, NumInterfaces=1, ConfigValue=1, Configuration=0, Attributes=self-powered + RWU supported, Max Power=2mA
  2. Interface Descriptor: 9 bytes, Type=4, Interface=0, No alternate, 2 endpoints, InterfaceClass=HID, SubClass=0, Protocol=0, Interface=0
  3. HID Descriptor: 9 bytes, Type=33=HID, HID Rev 1.1, country code = 0, 1 report descriptor, DescriptorType=34=Report, Report Descriptor Length=47
  4. EndPoint Descriptor: 7 bytes, Type=5=EndPoint, EndPointAddress=82=EP2-IN Attributes=interrupt(03), MaxPacketSize=0064, Poll Interval=10msec
  5. EndPoint Descriptor: 7 bytes, Type=5=EndPoint, EndPointAddress=01=EP1-OUT Attributes=control(03), MaxPacketSize=0064, Poll Interval=10msec

This has been verified (using USB Analyzer) as:

Device Descriptor:
        bLength = 18
        bDescriptorType = 1  (device)
        bcdUSB = 0x0110      (Rev 1.1)
        bDeviceClass = 0x00
        bDeviceSubClass = 0x00
        bDeviceProtocol = 0x00
        bMaxPacketSize0 = 64
        idVendor = 0x0B6A
        idProduct = 0xABE1
        bcdDEvice = 0x0100
        iManufacturer = 1
        iProduct = 2
        iSerialNumber = 3
        bNumCOnfigurations = 1

Configuration Descriptor:
        bLength = 9
        bDescriptorType = 2 (configuration)
        wTotalLength = 41
        bNumInterfaces = 1
        bConfigurationValue = 1
        iConfiguration = 0
        bmAttributes = 1 (self-powered)
        bmAttributes = 1 (remote wakeup)
        bMaxPower = 2 mA

Interface Descriptor:
        bLength = 9
        bDescriptorType = 4 (interface)
        bInterfaceNumber = 0
        bAlternateSetting = 0
        bNumEndpoint = 2
        bInterfaceClass = 0x03    (HID)
        bInterfaceSubClass = 0x00
        bInterfaceProtocol = 0x00
        iInterface = 0

HID Descriptor:
        bLength = 9
        bDescriptorType = 0x21  (HID)
        bcdHID = 0x0110
        bCountryCode = 0
        bNumDescriptors = 1
        bDescriptorType = REPORT   (type 34)
        wDescriptorLength = 47

EndPoint Descriptor:
        bLength = 7
        bDescriptorType = 5 (Endpoint)
        bEndpointAddress = 0x82   (Endpoint 2 - IN)
        bmAttributes = 0x03  (interrupt)
        wMaxPacketSoze = 0x0040  (64)
        bInterval = 0x0A  (10ms)

EndPoint Descriptor:
        bLength = 7
        bDescriptorType = 5 (Endpoint)
        bEndpointAddress = 0x01   (Endpoint 1 - OUT)
        bmAttributes = 0x03  (interrupt)
        wMaxPacketSoze = 0x0040  (64)
        bInterval = 0x01  (1ms)

Report Descriptor: VENDOR-DEFINED Device (Input Report of 12 bytes, Output Report of 7 bytes, Feature Report of 8 bytes)

   0x06,0xFFA0,       // Usage Page (vendor defined)
   0x09,0x01,          // Usage (vendor defined)
   0xA1,0x01,          // Collection
  
   0x09,0x01,          //   Usage (vendor defined)
   0x15,0x00,          //   Logical Minimum = 0
   0x26,0x00FF        //   Logical Maximum = 255
   0x95,0x0C,          //   Report Count = 12
   0x75,0x08,          //   Report Size = 8
   0x81,0x02,          //  Input(Data,Variable,Absolute)

   0x09,0x05,          //   Usage (vendor defined)
   0x15,0x00,          //   Logical Minimum = 0
   0x26,0x00FF        //   Logical Maximum = 255
   0x95,0x06,          //   Report Count = 6
   0x75,0x08,          //   Report Size = 8
   0xB1,0x02,          //  Feature(Data,Variable,Absolute)

   0x09,0x04,          //   Usage (vendor defined)
   0x15,0x00,          //   Logical Minimum = 0
   0x26,0x00FF        //   Logical Maximum = 255
   0x95,0x07,          //   Report Count = 7
   0x75,0x08,          //   Report Size = 8
   0x91,0x02,          //  Output(Data,Variable,Absolute)
  
   0xC0                  // End Collection  


I hope that this information will assist in resolving the faulty operation of the VB interface communicating with the peripheral device.  However, I don't know whether this is the result of faulty specification of the peripheral device or faulty VB commands trying to access the report structures.

Thank you.

Jan Axelson:
Do the Usages and report lengths that HidP_GetCaps returns in HidD_Caps match what's in the report descriptor?

Is the WriteFile buffer at least 8 bytes with the first byte =0?

Jan

Geoff:
Hi Jan,

The short answer: is "yes" and "yes".

The long answer is:  please see my VB code, and the results from execution of this code.

Thank you for your assistance and patience.

-----------

The following is the VB code used to perform a WriteFile (following the successful finding of the matching PID/VID).  Is there something incorrect in this sequence ?


    Private writeHandle As SafeFileHandle
    Dim success As Boolean
    Dim preparsedData As IntPtr
    Dim Capabilities As HIDP_CAPS
    Dim result As Int32
    Dim vcSize As Int32 = Capabilities.NumberInputValueCaps
    Dim valueCaps(vcSize - 1) As Byte
    Dim CapturedDevicePathName As String

    writeHandle = CreateFile(CapturedDevicePathName, GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
    If Not (writeHandle.IsInvalid) Then
        success = HidD_GetPreparsedData(writeHandle, preparsedData)
        result = HidP_GetCaps(preparsedData, Capabilities)
        If (result <> 0) Then
            result = HidP_GetValueCaps(HidP_Input, valueCaps, vcSize, preparsedData)
            Array.Resize(OutputReportBuffer, Capabilities.OutputReportByteLength)

            OutputReportBuffer(0) = CByte("0")
            OutputReportBuffer(1) = CByte("1")
            OutputReportBuffer(2) = CByte("2")
            OutputReportBuffer(3) = CByte("3")
            OutputReportBuffer(4) = CByte("4")
            OutputReportBuffer(5) = CByte("5")
            OutputReportBuffer(6) = CByte("6")
            OutputReportBuffer(7) = CByte("7")

            WriteFile(writeHandle, OutputReportBuffer, OutputReportBuffer.Length, NumberOfBytesWritten, IntPtr.Zero)

            lstResults.Items.Add("Last Error Code = " & Err.LastDllError)
            lstResults.Items.Add("NumberOfBytesWritten=" & NumberOfBytesWritten)

            lstResults.Items.Add("  Usage: " & Hex(Capabilities.Usage))
            lstResults.Items.Add("  Usage Page: " & Hex(Capabilities.UsagePage))
            lstResults.Items.Add("  Input Report Byte Length: " & Capabilities.InputReportByteLength)
            lstResults.Items.Add("  Feature Report Byte Length: " & Capabilities.FeatureReportByteLength)
            lstResults.Items.Add("  Output Report Byte Length: " & Capabilities.OutputReportByteLength)
        End If
    End If


The result of executing this code is:
  "Last Error Code = 1"
  "NumberOfBytesWritten=0"
  "  Usage: 1"
  "  Usage Page: FFA0"
  "  Input Report Byte Length: 13"
  "  Feature Report Byte Length: 7"
  "  Output Report Byte Length: 8"

This is completely consistent with the Report Descriptor which includes:

   0x95,0x0C,          //   Report Count = 12
   0x75,0x08,          //   Report Size = 8
   0x81,0x02,          //  Input(Data,Variable,Absolute)

   0x95,0x06,          //   Report Count = 6
   0x75,0x08,          //   Report Size = 8
   0xB1,0x02,          //  Feature(Data,Variable,Absolute)

   0x95,0x07,          //   Report Count = 7
   0x75,0x08,          //   Report Size = 8
   0x91,0x02,          //  Output(Data,Variable,Absolute)

ie. the Output Report Buffer has a size of 7 bytes, hence the OutputReportBuffer has elements 0 through 7, where element 0 contains "0".

Can you see something incorrect in the above sequence ?

Navigation

[0] Message Index

[#] Next page

Go to full version