|
I am coming up to speed on getting a USB working with an Atmel application I built (HID).
Searching through multiple packages on the internet, this .NET package was the best by far. Clean and solid... at least while I was testing it using my Windows 8.1 pc.
When I moved it to the target machine which has Window 7, SendMessage does not work. Everything else is fine.
It's coming down to "Kernel32.WriteFile" in DeviceCommunication.
I am looking into using HidD_SetOutputReport in place of WriteFile.
Ironically, Microsoft knowledge base suggests using WriteFile instead of HidD_SetOutputReport.
If anyone else has a suggestion, please let us know.
Thanks
|
|
|
|
|
Hi.
Please check post by Vivchun posted on 25-Jun-13 22:13 which describes how to overcome the problem.
Thanks.
|
|
|
|
|
Thank You for your reply.
I had already seen Vivchun's comment concerning "int" versus "IntPtr". Changing that didn't help.
Note, the Windows 8.1 I am using is x64. The Windows 7 target is 32bit. This would seem to be the opposite situation to what Vivchun was addressing.
I am presuming my problem involves report length and buffer sizes.
(EDIT - I am getting a 1784 error from WriteFile)
The USB caps indicate the report length is 8. Which, if I understand correctly, means the buffer size for the WriteFile should be 9. I have varied the buffer size and tested them. Buffer size changes never make Windows 8.1 fail, even for buffers sizes of 5 or 11. The Windows 7 system doesn't work for any buffer size I tried.
My working presumption is that Windows 8.1 somehow automatically deals with buffer size incompatibilities in a way the Windows 7 does not.
I will be exploring this further.
Again, thank you for your reply, it is helpful to be talking with someone who can understand what I am dealing with.
Regards,
David Petticord
modified 25-May-14 12:25pm.
|
|
|
|
|
From the file CommandMessage.cs
private byte[] GetMessageData()
{
var result = new byte[65];
result[0] = 0;
result[1] = Command;
if (Parameters != null)
{
Array.Copy(Parameters, 0 ,result, 2, Parameters.Length);
}
return result;
}
Change To...
private byte[] GetMessageData()
{
var result = new byte[2+Parameters.Length];
result[0] = 0;
result[1] = Command;
if (Parameters != null)
{
Array.Copy(Parameters, 0 ,result, 2, Parameters.Length);
}
return result;
}
With the original code, result.length is always 65.
Thanks for the UsbHid. Even though I had to spend more time than I wanted to, I now understand USB and this code a lot better. Frankly, I have to admit using USB Hid was a lot harder than I had expected and UsbHid was a lot easier to understand than the other packages I looked at.
When things settle down for me, and if you don't mind, I would like to duplicate your hardware/software example using an Atmel XMega microprocessor.
Regards,
David Petticord
|
|
|
|
|
Hi,
Yes Indeed as I mentioned in the article, this component assumes that the data length is 64 bytes.
I'm glad you managed to tweak it so that it fits for your needs.
By all means please feel free to use this code for your article, the merrier the better.
Thanks.
|
|
|
|
|
I'm a bit confused on the syntax to send data to a device from the host on either the control EP (0) or on an OUT EP. I have a device with an IN endpoint, OUT endpoint, and of course the control endpoint. I am able to use the library to get data from my device via the IN endpoint, that is working great. I am able to send data on the OUT EP or down EP 0 using a program called BUSHOUND, and the data is getting to my device in that way.
I'd like to understand the syntax to do the following:
1. Send data down an OUT EP from C# to my device
2. Send a SET_REPORT to my device to provide a few bytes of data on EP0
Let me know if there is some sample code to get me started.
Thanks,
Corey
|
|
|
|
|
Hi.
I can't give a definitive answer at the moment. The USB stack used in this example is an old implementation of the only fairly simple and open source stack I could find at the time. Since then I have improved it so that it now works on IRQs rather than by polling and supports multiple endpoints. In fact I have managed to build a composite device that presents itself as a HID, Keyboard, Mouse and two gamepads based in this stack but there are still some flaws that I need to recap on and polish up so that it will be easy to configure the device to become whatever you need it to be. However I am doing it in my spare time of which I don't have much, so the only thing I can ask you for at this stage is patience, as the update is coming.
Thanks.
|
|
|
|
|
OK, let's just keep it simple. I assume that the following code:
private void Button1Click(object sender, EventArgs e)
{
if (!Device.IsDeviceConnected) return;
var command = new CommandMessage(0x86, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 });
Device.SendMessage(command);
...is used to send data down an OUT endpoint to supply data to the device into the Output usages in the HID report descriptor. I have defined 2 EP's in my software (CYpress PSOC1), have Input and Output usages in my HID Report descriptor, I'm enumerating properly, and I can use BusHound to send data down my OUT endpoint and the PSOC gets the data just fine.
So I simply need to understand the syntax of the CommandMessage.
1. Is SendMessage used to send data to the HID OUT endpoint?
2. What does the 0x86 represent?
Let me know!
Thanks.
Corey
|
|
|
|
|
Hi Corey,
Well the 0x86 means absolutely nothing. it could be any value you want. When you sending a 64 byte message to the device you are in fact sending 65 bytes where the first byte is zero and by message I mean a bunch of 65 bytes. Command message is only a prototype, like a wrapper around those 65 bytes you are about to send. After you send it you'll end up with the latter 64 bytes in the buffer on the device which then you can parse and process in any way you want, all thou this example does not really parse anything, just blindly replaces four bytes before sending the same message back.
The Command message prototype is really an example of implementation of the sent bytes treating the first one as a directive about what the rest of the bytes are about. so if the first one is in example 0x81 then the rest will turn on or off latches on port A, but if it is 0x82 then we are talking about port B, but if the first one is 0x80 then the rest is irrelevant because I just want the device to send me current state of all ports, and so on. Of course thee values do not have to start with 0x80 but in all examples so far I have seen, this as a kind of a trend that I have decided to follow in my projects, but feel free to send whatever you want, and in whatever you want order.
In terms of what exactly those bytes mean, determination is really the purpose of the device and then the imagination is the only limit on how it is implemented.
I hope this helps.
Thanks.
|
|
|
|
|
I cannot send data from VC# to PIC4550-Board with this code:
private void Button1Click(object sender, EventArgs e)
{
if (!Device.IsDeviceConnected) return;
var command = new CommandMessage(0x86, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 });
Device.SendMessage(command);
}
Please show me the reason, or give me the solution.
PS: My PIC4550-Board are OK when I use VB.NET to transmit and receive data.
|
|
|
|
|
I have the same problem with Windows 7 and Windows 8 systems. But it works fine with Windows 8.1 systems.
Does anyone have an idea about the problem and how to modify the code so it can work with Windows 7 and 8?
|
|
|
|
|
In Windows 8.1, you can write data from C# to PIC4550-Board?
|
|
|
|
|
Nobody help me this
|
|
|
|
|
Hi
I cannot send data from VC# to PIC4550-Board is a bit to wide in terms of description of a problem. It sounds a bit like "Can you fix my internet ?"
Could you be more specific ? At which point exactly there is a failure ? What is the state of "Device.IsDeviceConnected" ? Is it connected ? Does the VID and PID match ?
Too many questions ...
Please be more specific and we'll see what we can do.
Thanks.
|
|
|
|
|
Well, the CONNECTION is OK, the PIC4550-Board send data to VC# is OK, but on the contrary, VC# cannot send data to PIC with this code:
private void Button1Click(object sender, EventArgs e)
{
if (!Device.IsDeviceConnected) return;
var command = new CommandMessage(0x86, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 });
Device.SendMessage(command);
}
I use the Example "USB2550HidTest.zip" downloaded from this thread!
|
|
|
|
|
What do you mean by cannot send data ?
What happens when you try ?
|
|
|
|
|
Well, when I try to send data by this:
private void Button1Click(object sender, EventArgs e)
{
if (!Device.IsDeviceConnected) return;
var command = new CommandMessage(0x86, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 });
Device.SendMessage(command);
}
then my PIC4550-Board do not receive anything (Note that PIC4550-Board receive data when I use VB.NET to test, that means PIC4550-Board is OK.).
So, my problem is: that code (above) did not work
|
|
|
|
|
Has anyone ever tested this code to send data from C# to MicroController?
|
|
|
|
|
Hello my friend.
Yes it has been tested and worked for many. Have a look at the post below by Vivchun called "Problem with win 7 64 bit machine [modified]" and see if that helps.
Thanks.
|
|
|
|
|
Yes I have tested the code with Cypress PSoC1. There is no problem sending data to the PSoC controller if using Windows 8.1 system but no data received by the controller if using Windows 7 or Windows 8
|
|
|
|
|
I can Run the demo program on my win7 64bit os and can read the data successful ,but i can't write any thing . i use getlasterror get the error code : 1784 .
i spend lots of time but can't fixed .
i tried ,increase the size of the array ,or make it to be special length ,like 32, 33 , 64, 65 , but ,it does't work !
i also tried to change the type of param of kernel.writefile from byte[] to Intptr ,but it does'nt work as well.
would you please help me . thanks . .
Yang
|
|
|
|
|
Hi
WriteFile error return 1784 usually means ERROR_INVALID_USER_BUFFER.
As I have written in the article the hid buffer of this example is fixed to 64 bytes which means that in effect indeed you need to send 65.
Since I had it working for over a year in various setups on several machines and had a lot of positive replies from other people, it suggests that you have made some modification in either host or device software for the mismatch to take place.
without analysing your code I won't be able to detect where the problem is, but what I would like to suggest is please try to run the code unmodified as is and see if you can get that working and if you can, then I think that would be a very good start-up point for debugging your version.
Hope this helps.
|
|
|
|
|
Good explanations and code.
Thanks
|
|
|
|
|
Glad you like it
|
|
|
|
|
Exactly what I needed Thanks!
PS: I can confirm that vivichun's fix is required for 64bit systems/compilations and works perfectly.
|
|
|
|
|