Author Topic: Problem with VB USB HID example with Microchip PIC18F4550 - AsyncCallback fails  (Read 20108 times)

dewey1

  • Member
  • ***
  • Posts: 6
Hi

I have been trying to use Jan's example HID code for VB.Net (both the ReadFile/WriteFile and Filestreams versions) with a Microchip Picdem FSUSB board.  This board features a Microchip PIC18F4550 with an integrated USB SIE.  I am running firmware on it written by Microchip called their "HID - Simple Custom Demo", included in the "Microchip Solutions" free USB stack, v 2.2.

I have been focusing on the Filestream version (although I get the same error with both), and keep getting timeout errors when trying to exchange input and output reports with Jan's code, specifically when attempting to get the input report.  The software gets the output report okay, but then times out waiting for the input report from the chip.  The exchange of reports is initiated in VB by a call to the .NET filestream function BeginRead, which includes in it a call to Jan's GetInputReportData function, using the AsyncCallback delegate to wait for the asynchronous file read thread to complete.  I saw a thread here where somebody had the same problem and Jan proposed a solution of creating a local variable to store the result of the AsyncCallback (a variable of the form IAsyncResult), then comparing that to the variable inputReportBuffer, which, at that time, should have a value of Nothing.  I tried that method, using her modified code in the Filestreams version of the VB code, but I keep getting the same problem.

I'm not terribly well-versed in the USB spec, although I'm learning.  Would this possibly be the result of an input report descriptor made with some erroneous values in the Microchip code?  Incidentally, Microchip includes a C++ interface example for Windows in their code that works well for interfacing the chip when running the same "simple example" HID firmware (written by Microchip)...problem for me though in that I don't know C++ well enough to modify it for my needs.  

Can anyone help?  Here is the code in question:

Code: [Select]

Private Sub ExchangeInputAndOutputReports()
                Try

                        currentAsyncResult = fileStreamdevicedata.BeginRead(inputReportBuffer, _
                        0, inputReportBuffer.Length, _
                        New AsyncCallback(AddressOf GetInputReportData), inputReportBuffer)

        ...


Private Sub GetInputReportData(ByVal ar As IAsyncResult)

Dim byteValue As String
Dim count As Int32
Dim inputReportBuffer As Byte() = Nothing

Try
                   inputReportBuffer = CType(ar.AsyncState, Byte())


                   If (ar Is currentAsyncResult) Then
                       fileStreamdevicedata.EndRead(ar)

                       tmrReadTimeout.Stop()

                       ' Display the received report data in the form's list box.

        ...

Private Sub OnReadTimeout(ByVal source As Object, ByVal e As ElapsedEventArgs)

MyMarshalToForm("AddItemToListBox", "The attempt to read a report timed out.")

                ' This timeout method is eventually called


Thanks for any assistance!
« Last Edit: February 14, 2012, 08:49:01 pm by dewey1 »

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Is the device sending a report whose size matches the size defined in the report descriptor? The PC software will time out if the device isn't sending a report, so that's the first place to look.

My example HID firmware waits for an Output report and then sends an Input report. Have you tried that example?

http://www.lvr.com/hidpage.htm#MyExampleCode

Jan

dewey1

  • Member
  • ***
  • Posts: 6
Hi Jan!

Thanks for responding to this yourself.  I wasn't sure if I'd get to talk with you directly.

Yes, the code I'm referring to is that very same HID example code of yours.  So I might have misunderstood...I thought the output report was the one being sent from the PC and the input report was recieved from the remote peripheral.  It looks like my understanding was backwards.  I thought since the function in question was beginRead, that the PC was reading "in" the data from the input report.

So if that's the case, and my remote device isn't getting the input report from your software, a likely culprit might be a mis-specified input report descriptor?  I'm not too good at deciphering them, but here's the way my device's report descriptor reads.  Are there any obvious mismatches you can see, or do you know of any good software tools I can use to understand descriptors better?


Code: [Select]
/* Report Descriptor */

0x06, 0x00, 0xFF,      // Usage Page = 0xFF (Vendor Defined)
0x09, 0x01,               // Usage
0xA1, 0x01,               // Collection (Application, probably not important because vendor defined usage)
0x19, 0x01,               // Usage Minimum (Vendor usage = 0) (minimum bytes the device should send is 0)

// Input Definition

0x29, 0x40,               // Usage Maximum (Vendor usage = 64)  (maximum bytes the device should send is 64)
0x15, 0x00,               // Logical Minimum (Vendor usage = 0)
0x26, 0xFF, 0x00,      // Logical Maximum (Vendor usage = 255)
0x75, 0x08,               // Report size 8 bits (one full byte) for each report
0x95, 0x40,               // Report Count 64 bytes in a full report
0x81, 0x02,               // Input (Data, Var, Abs)

// Output Definition

0x19, 0x01,               // Usage Minimum (Vendor usage = 0)
0x29, 0x40,               // Usage Maximum (Vendor Usage = 64)
0x91, 0x02,               // Output (Data, Var, Abs)
0xC0


Something that stands out to me as strange is the line in the Input Report definition that says 64 bytes in a full report.  When your software idetifies my device (the Find My Device button), in populates the Input Report Buffer Size textbox with 32.  Wouldn't that hint that the input report buffer size is way too small for the size of report the device is expecting?

Thank you for the help!
-Josh

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
IN = device to host
OUT = host to device

The PIC firmware waits for an Output report and sends an Input report.

The PC software sends an Output report and waits for an Input report.

You said your device was receiving the Output report but the PC software wasn't seeing the Input report. So I advised checking to see if the device was sending an Input report.

The report descriptor you posted isn't the descriptor from my example PIC firmware, which I suggested you could try.

The ReadFile buffer has to be at least as large as the Input report + 1 byte.

The best sources I know for learning about report descriptors are my USB Complete:

http://www.lvr.com/usbc.htm

and the HID spec from usb.org.

Jan


dewey1

  • Member
  • ***
  • Posts: 6
Hi again Jan

I didn't even see that you have provided PIC18F4550 code of your own on your HID page!  I was using Microchip's example firmware.  I'm headed over there right now to check it out.

Thanks for pointing me in that direction and for clarifying reports a little more.

-Josh

dewey1

  • Member
  • ***
  • Posts: 6
Hi again Jan

I found your HID code specifically written for the PIC18F4550, and I got a newer copy of your book.  (I had started to read an older revision a while ago, but never got to the chapters covering HID-specific implementations).

I was able to compile your code for the PIC using the same Microchip Solutions USB stack, version 2.6a, with the C18 compiler.  The code compiled on the 1st try, and I was ready to test out the VB application you wrote to interface with it, but Windows XP's device manager is giving me an error, code 10, saying the device failed to start (the device is a Microchip Picdem FSUSB dev board).  I know without reports from any USB analyzer tools it may be impossible to say, but do you have any idea if there are any common things that might be causing this error?

Thanks again for your help with this!
-Josh
« Last Edit: February 20, 2012, 04:02:37 am by dewey1 »

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Does MPLAB show the code running?

View the setupapi log file. (Do a web search for more info.)

Jan

dewey1

  • Member
  • ***
  • Posts: 6
MPLAB does show the code running when I run it in the simulator.  I have not tried it in debug mode with the debugger though - I just loaded it straight to the board.

In examining my setupapi.log file, I see the following line covering the error message:

#-166 Device install function: DIF_INSTALLDEVICE.
#I123 Doing full install of "USB\VID_0925&PID_7001\6&4DD5342&0&3".
#I163 Device not started: Device has problem: 0x0a: CM_PROB_FAILED_START.
#I121 Device install of "USB\VID_0925&PID_7001\6&4DD5342&0&3" finished successfully.

As I understand, CM_PROB_FAILED_START means the driver loaded, passed through DriverEntry, passed through AddDevice, and then failed during IRP_MN_START_DEVICE.

On the board, the LEDs are blinking very fast, at the same time (indicating failure or suspend...I'm not sure yet).  I'm trying to dig into the code, and I found where the LEDs are set when things go right, but haven't figured out where they're set when things go wrong (the fast blink).  I'm hoping that will lead me to some cases I can look for that pinpoint why my device is failing.

Something else I noticed that was different between your code and the original Microchip code was in the descriptor.  Using the USB.org descriptor tool, it said the first Vendor Defined Usage Page would have a code 0x06, 0x00, 0xFF.  I notice your code uses 0x06, 0xA0, 0xFF.  Even when I change it, I get the same fail-to-start error, but I was just curious if there was something there.

« Last Edit: February 22, 2012, 08:18:03 pm by dewey1 »

dewey1

  • Member
  • ***
  • Posts: 6
I found something else.  When I changed the logging level in setupapi.log to the highest level, I see the following:

#-166 Device install function: DIF_INSTALLINTERFACES.
@ 16:06:17.830 #V005 Opened the PNF file of "c:\windows\inf\input.inf" (Language = 0409).
#-011 Installing section [HID_Inst.NT.Interfaces] from "c:\windows\inf\input.inf".
#I054 Interfaces installed.
#-166 Device install function: DIF_INSTALLDEVICE.
#I123 Doing full install of "USB\VID_0925&PID_7001\8&FD60E89&0&4".
@ 16:06:17.846 #V005 Opened the PNF file of "c:\windows\inf\input.inf" (Language = 0409).
#-086 Deleting registry value "HKR\SelectiveSuspendEnabled"
@ 16:06:17.846 #V033 Error 2: The system cannot find the file specified.
#I163 Device not started: Device has problem: 0x0a: CM_PROB_FAILED_START.
#I121 Device install of "USB\VID_0925&PID_7001\8&FD60E89&0&4" finished successfully.

Which file is the system referring to?  Could that be related to my failure to start condition?

-Josh


Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Either Usage page will work.

Try it in the debugger and see where it stops.

It's a little annoying that the error message says "the file specified" without specifying a file!

Jan