Closed marvk closed 3 years ago
And by the way, trying to set the display in Java using usb4java-javax
:
final byte[] d = new byte[20];
Arrays.fill(d, (byte) ('9' - '0'));
// 0x21
final byte bmRequestType = (UsbConst.ENDPOINT_DIRECTION_OUT | UsbConst.REQUESTTYPE_TYPE_CLASS | UsbConst.REQUESTTYPE_RECIPIENT_INTERFACE);
// 0x09
final byte bRequest = UsbConst.REQUEST_SET_CONFIGURATION;
final UsbControlIrp irp = usbDevice.createUsbControlIrp(
bmRequestType,
bRequest,
(short) 0x03,
(short) 0x00
);
irp.setData(d);
usbDevice.syncSubmit(irp);
I am getting the following exception which sounds pretty much like what I'm getting in your golang library.
Exception in thread "main" javax.usb.UsbPlatformException: USB error 2: Unable to submit control message: Invalid parameter
at org.usb4java.javax.ExceptionUtils.createPlatformException(ExceptionUtils.java:39)
at org.usb4java.javax.AbstractIrpQueue.processControlIrp(AbstractIrpQueue.java:229)
at org.usb4java.javax.ControlIrpQueue.processIrp(ControlIrpQueue.java:41)
at org.usb4java.javax.ControlIrpQueue.processIrp(ControlIrpQueue.java:18)
at org.usb4java.javax.AbstractIrpQueue.process(AbstractIrpQueue.java:104)
at org.usb4java.javax.AbstractIrpQueue$1.run(AbstractIrpQueue.java:73)
at java.base/java.lang.Thread.run(Thread.java:832)
Hi. Everything in my code worked for me the last time I used it, which is quite some time ago. For example, the radiotest program which displays all kinds of strings on the displays, worked without issues. It doesn't work for you? If not, does it give any errors?
Are you running on Linux, Windows or Mac? I've just tested it on Linux on a couple of distros.
Make sure you have right permissions. If on Linux, are you running as root?
Does your device have the same USB vendor and product ID?
For example, the radiotest program which displays all kinds of strings on the displays, worked without issues. It doesn't work for you? If not, does it give any errors?
radiotest.go
is what I am running and besides displaying anything, it is working fine. That is, it outputs selector, rotary encoder and button inputs to the console.
There are no errors out of the box, because you are not logging any errors in your RadioPanel.refreshDisplay
method, as mentioned in my initial post. If I add error logging there, as I said, I get libusb: invalid param [code -2]
.
Are you running on Linux, Windows or Mac? I've just tested it on Linux on a couple of distros.
This is on Windows. Running as administrator unfortunately changed nothing.
Does your device have the same USB vendor and product ID?
Yes: Bus 002 Device 003: ID 06a3:0d05
It could be some difference between Windows and Linux then. I've never tested on Windows. On Linux the panel displayed the output fine the last time I tested.
I added error checking, and on Linux don't receive any error in the location you mention, and it returns the expected number of bytes written (20). I'll commit error checking to the code after I figure out how I want to do it. I don't want to use logging inside a library, and I'm not sure I want to exit because the error could be transient. Maybe I'll have to create a channel to return errors from the thread that is refreshing the display.
Yeah I figured it might be a OS issue. Do you have an opportunity to test on Windows?
I can test on Windows, but I'm unfortunately not very motivated to do it. Sorry. I'm currently not using this library myself anymore at all, not even on Linux. But I still might have a look at it on Windows at some point.
Edit: What I say below is wrong. 0x20 is REQUEST_TYPE_CLASS, which is defined in the gousb library as gousb.ControlClass
.
My original comment with the wrong information follows:
It could be that I'm using the go libusb library wrong, because I send Control(0x21,...)
which is ENDPONT_OUT (0x00) | CLASS_STANDARD (0x20) | RECEPIENT_INTERCACE (0x01)
. However, when I just now was replacing these with constants instead of the magic number 0x21, I noticed from the go libusb documentation that constant 0x20 (Standard) is not defined:
// "Standard" is explicitly omitted, as functionality of standard requests
// is exposed through higher level operations of gousb.
So, I should maybe replace this Control()
with some "higher level operation", whatever that is.
It's been some time I fiddled with the USB protocol, so it might take some time for me to figure this out.
Well, I was looking through some other libraries and I found DCSFlightpanels, which is written in C# and uses HIDSkeletonBase.HIDWriteDevice?.WriteFeatureData(array);
, which seems a bit higher level, see here.
I unfortunately know very little about the USB protocol and am just trying to figure things out as I go along right now, looking at examples such as your library and DCSFlightpanels.
By the way, I think it isn't an issue with the first byte (bmRequestType
). I have tried sending every possible byte and it was the same error every time.
I was able to reproduce the issue on Windows. Don't know what is causing it. I'll happily accept fixing patches ;-)
Sometimes the display lights up with all zeros.
Does DCSFlightpanels work for you @marvk?
I'd love to be able to tell you, but I don't usually play DCS and I think that software needs some payware to function since the free planes don't have configurations included. So yeah, I can't really tell you at present time unfortunately. But I tried with a HID-Library in Java and also couldn't get that to work either. It's really strange. The Panel itself works fine with the MSFS2020 drivers that Logitech released, but I would like to make some modifications. Quite unfortunate.
The other panels, the switch and multifunction, have the same issue. Output to the panels gives the error, but switches work.
I play DCS, so maybe I can test DCSFlightpanels some time.
I would appreciate it. I'd love to get to the bottom of this, my goal is to basically emulate the standard FS2020 drivers, but with the radio display ditching the first 1 and displaying three decimal places so you can display 8.33kHz banded frequencies correctly.
It's not possible to test any output with DCSFlightpanels without using DCS? Just wondering, if you don't want to wait until I possibly test.
I don't think it is. I even downloaded DCS, but I couldn't get it to work with it. I think I might be missing the right planes.
I tested with Logitech's Flight Panels Test Software and did a USB dump (which I originally also used to reverse engineer it in the first place) . The output to me looks the same as to what I try to do:
The only difference being that Logitech's software sends 22 bytes, and I send 20. I tried with 22 bytes, and it didn't help. I'm starting to suspect that the error is in libusb. When sending with my software nothing is seen in the USB capture, so it is probably being blocked by Windows.
I compiled libusb with debug logging enabled and made a Go implementation that is as simple as possible (about 5 lines of code, nothing from this fpanels library) to just output to the display, and got the following output:
[ 0.014260] [00001154] libusb: debug [libusb_open] open 2.17
[ 0.076927] [00001154] libusb: debug [hid_open] set maximum input buffer size to 512
[ 0.076945] [00001154] libusb: debug [hid_open] 0 HID input report value(s) found
[ 0.076946] [00001154] libusb: debug [hid_open] 0 HID output report value(s) found
[ 0.076946] [00001154] libusb: debug [hid_open] 1 HID feature report value(s) found
[ 0.076947] [00001154] libusb: debug [hid_open] Report ID: 0x00
[ 0.081734] [00001154] libusb: debug [libusb_alloc_transfer] transfer 00000177b241c588
[ 0.081737] [00001154] libusb: debug [libusb_submit_transfer] transfer 00000177b241c588
[ 0.081740] [00001154] libusb: debug [libusb_claim_interface] interface 0
[ 0.081740] [00001154] libusb: debug [hid_claim_interface] claimed interface 0
[ 0.081743] [00001154] libusb: debug [windows_assign_endpoints] (re)assigned endpoint 81 to interface 0
[ 0.081744] [00001154] libusb: debug [auto_claim] auto-claimed interface 0 for control request
[ 0.081744] [00001154] libusb: debug [hid_submit_control_transfer] will use interface 0
[ 0.081744] [00001154] libusb: warning [_hid_set_report] unknown HID report type 0
[ 0.081745] [00001154] libusb: debug [libusb_release_i2021/02/22 22:54:32 libusb: invalid param [code -2]
Looking at the libusb code, the issue seems to be "unknown HID report type 0", when it should be HID_REPORT_TYPE_FEATURE
, which is a parameter to _hid_set_report()
. Now I need to backtrace from where this parameter originates and this will be fixed. ;-)
I got past that problem, but now I got new ones.
I changed
panel.device.Control(0x21, 0x09, 0x03, 0x00, panel.displayState[:])
to
panel.device.Control(0x21, 0x09, 0x0300, 0x00, panel.displayState[:])
By looking at the libusb code, the high byte in 0x0300
is HID_REPORT_TYPE_FEATURE
, and the low byte is the report ID.
Looking at the USB dump above, this is wValue
, which actually is 0x0300
(and not 0x0003
, like I have).
This is fixed now with the latest commit. :-) Thanks for the report!
In your Java code just change 0x03 to 0x0300 and make sure you use a buffer length of 22 bytes (not 20) for the display contents.
There is still some issue with the multi panel on Windows, that I'm still looking in to, but the radio panel works now.
Yup, confirmed working! Thanks for letting me know how it's done! :-)
https://user-images.githubusercontent.com/6569856/108795955-d6389800-7587-11eb-845a-482da655d15a.mp4
Hey there,
I'm trying to interface with the Logitech Radio Panel in Java, and while trying to set the display contents, I was getting an error.
Since I'm using your lib as a reference anyways, I tried using it to set the display contents and ran into the same error.
I've added an error printout to this line:
https://github.com/bjanders/fpanels/blob/d7b94033586d73b3d820ba89a00605099bebcd65/radiopanel.go#L218
and I'm getting the following error:
Was this working for you and do you have any idea for a fix?
My device M/N is
J-U0010
.edit: I should add that the go API is returning inputs just fine. It's just not able to display anything.