Author Topic: My first question: Using WinUsb_cs  (Read 21931 times)

goodnewsjim

  • Frequent Contributor
  • ****
  • Posts: 52
My first question: Using WinUsb_cs
« on: November 22, 2013, 12:30:48 pm »
Hello,

I found where I set the GUID, and set it.
I ran the application, clicked "find my device"
It says:Device Detected:
Then I clicked send on interrupt transfers, and the line in WinUsbDevice.cs doesn't return true:

success = WinUsb_WritePipe
               (myDevInfo.winUsbHandle,
               myDevInfo.interruptOutPipe,
               buffer,
               bytesToWrite,
               ref bytesWritten,
               IntPtr.Zero);


Any suggestions or guesses on how I can fix this are welcome.  I'm at a brick wall.

I am using:
winusb_cs for Visual C# .NET. Created with Visual Studio 2008 for the .NET Framework V2.0 or later. Updated 2/11/09.

Thank you for your time,
Jim

goodnewsjim

  • Frequent Contributor
  • ****
  • Posts: 52
Re: My first question: Using WinUsb_cs
« Reply #1 on: November 22, 2013, 12:58:50 pm »
One thing I find odd:  I don't know where to set Vendor Id, and Product Id.

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: My first question: Using WinUsb_cs
« Reply #2 on: November 22, 2013, 05:50:16 pm »
Use GetLastError to get the error message.

http://blogs.msdn.com/b/adam_nathan/archive/2003/04/25/56643.aspx

Use a protocol analyzer or whatever other debugging tools you have to find out how the device responded to the interrupt transactions.

The device-specific GUID ties the device to the application. If using a device-specific INF file, the GUID and Vendor ID and Product ID are in the INF file. If using the system-provided winusb.inf, these values are in the descriptors returned by the device during enumeration.

Also note that I have updated versions of the application:

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

goodnewsjim

  • Frequent Contributor
  • ****
  • Posts: 52
Re: My first question: Using WinUsb_cs
« Reply #3 on: November 25, 2013, 01:42:33 pm »
Thank you for your help Jan.

Okay, found the error is that it couldn't read an interrupt.(Because the microcontroller didn't get one to reply to is my guess)  I commented out: //ReadDataViaInterruptTransfer(); and the error never happens.

What is going on is this:
I click send on Interrupt Transfers, and in the message box is: "Interrupt OUT transfer failed"

The send button is greyed out after that.
When I close the window, I get this:
An unhandled exception of type 'System.AccessViolationException' occurred in WinUsbDemo.exe
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Any help is welcome.  The microcontroller works fine with winusb for c/c++, but the system I'm integrating to is C#.

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: My first question: Using WinUsb_cs
« Reply #4 on: November 25, 2013, 01:55:56 pm »
For the interrupt OUT error, use whatever debugging tools you have to find out if the data is going out on the bus and if so, how the device is responding - NAK, ACK, no response?

For the read operation (interrupt IN), find out how the device is responding to the IN token packets.

Compare the working C code you have to the C# code (since both use the WinUSB API).


goodnewsjim

  • Frequent Contributor
  • ****
  • Posts: 52
Re: My first question: Using WinUsb_cs
« Reply #5 on: November 25, 2013, 04:58:20 pm »
Thank you for continuing to step me through this.  I'm very much at a brick wall for days.  I'll try and give you all the information I can.

Here is the C# code when it is supposed to send data out:

if (myDeviceDetected)
            {
               success = myWinUsbDevice.SendViaInterruptTransfer
                  (ref dataBuffer,
                  bytesToSend);

               if (success)
               {
                  formText = "Data sent via interrupt transfer.";
               }
               else
               {
                  formText = "Interrupt OUT transfer failed.";
               }

Success ends up being false.
My microcontroller reads no data packet.  Since no packet comes in, obviously it isn't going to reply...







EXTRA DATA:


Here is the myWinUsbDevice.SendViaInterruptTransfer inspected deeper:

internal Boolean SendViaInterruptTransfer(ref Byte[] buffer, UInt32 bytesToWrite)
      {
         UInt32 bytesWritten = 0;
         Boolean success;

         try
         {
      
            success = WinUsb_WritePipe
               (myDevInfo.winUsbHandle,
               myDevInfo.interruptOutPipe,
               buffer,
               bytesToWrite,
               ref bytesWritten,
               IntPtr.Zero);

            if (!(success))
            {
               CloseDeviceHandle();
            }

            return success;
         }
         catch (Exception ex)
         {
            throw;
         }
      }


HERE IS THE Writepipe deeper:

[DllImport("winusb.dll", SetLastError = true)]
      internal static extern Boolean WinUsb_WritePipe(IntPtr InterfaceHandle, Byte PipeID, Byte[] Buffer, UInt32 BufferLength, ref UInt32 LengthTransferred, IntPtr Overlapped);



Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research

goodnewsjim

  • Frequent Contributor
  • ****
  • Posts: 52
Re: My first question: Using WinUsb_cs
« Reply #7 on: November 26, 2013, 12:31:20 pm »
Jan, 

Thank you for sticking with me on this. I appreciate it.

I spent about a half hour trying to get GetLastError to work in C#.
I asked someone who codes in C# to look at my code and do it.
He says GetLastError is a C++ function call and I can't use it.
He says something about WinUsb_WritePipe being called by a Com interrupt too, but I'm not sure what that means.

The syntax should be simple for what you want me to do, but alas I do not know it.
Any help on that?  Is there a C# call to get a last error?  I couldn't google for it.

Thanks again,
Jim


goodnewsjim

  • Frequent Contributor
  • ****
  • Posts: 52
Re: My first question: Using WinUsb_cs
« Reply #9 on: November 26, 2013, 12:48:54 pm »
the error is 1008

I called it with:
  int error = Marshal.GetLastWin32Error();

after the failed attempt at sending an interrupt transfer:
   success = myWinUsbDevice.SendViaInterruptTransfer
                  (ref dataBuffer,
                  bytesToSend);

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: My first question: Using WinUsb_cs
« Reply #10 on: November 26, 2013, 01:10:53 pm »
Well that is error no token:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms681383%28v=vs.85%29.aspx

which is not helpful. So I'll return to my earlier question:

How does the C# code differ from the C code that is working?

Set a breakpoint and examine the parameters for Winusb_WritePipe.


goodnewsjim

  • Frequent Contributor
  • ****
  • Posts: 52
Re: My first question: Using WinUsb_cs
« Reply #11 on: November 26, 2013, 01:33:30 pm »
Jan,

I'll play with it some and see what I get.  I didn't realize the two functions in C# and C++ are similar.  Let me play with this some and I'll get back to you.

I'm impressed with how quickly you have responded.
Thank you once again,
Jim

goodnewsjim

  • Frequent Contributor
  • ****
  • Posts: 52
Re: My first question: Using WinUsb_cs
« Reply #12 on: November 26, 2013, 02:21:58 pm »
Jan,

Again, a whole host of thank yous for stepping me through this.

I was able to send a packet of 0x80 to my micro controller  :)

I might have more problems in the future and make a completely new post, but this thread is done: Jan won it.

,Jim

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: My first question: Using WinUsb_cs
« Reply #13 on: November 26, 2013, 03:27:30 pm »
I should add the GetLastError code to the example.

Would you like to tell us how you got it working?

goodnewsjim

  • Frequent Contributor
  • ****
  • Posts: 52
Re: My first question: Using WinUsb_cs
« Reply #14 on: December 03, 2013, 04:07:17 pm »
OH yes.  I'll post how I got it working.

In SendViaInterruptTransfer, I changed the writepipe

Here is mine:
WinUsb_WritePipe(myDevInfo.winUsbHandle, 0x01, OUTBuffer, len, ref bytesWritten, IntPtr.Zero);

It is different from the C# code you had in there.
and my readpipe is this:
WinUsb_ReadPipe(myDevInfo.winUsbHandle, 0x81, INBuffer, 64, ref bytesWritten, IntPtr.Zero);
which I put in GetViaInterruptTransfer(bool a)


I'm actually surprised it worked because I lifted code from Visual C++, modified a few fields, and it worked in C#
I'm very happy you stepped me through this Jan A.  I wouldn't be able to do it on my own.