On Apr 23, 2010, at 1:17 AM, Gary Briggs wrote:

On Tue, Apr 20, 2010 at 07:49:50AM -0400, Charles Lepple wrote:
I've written some code [mainly copied outright from the libhid test
example], here:
http://icculus.org/~chunky/stuff/dcdcusb/main.c

The output from that program is:
http://icculus.org/~chunky/stuff/dcdcusb/ set_output_report_output.txt

The only thing to note is that there is a bug in the printing routine,
and if you see a "0x00000000" path element, it is just the 2nd or
later element of a range. The parser knows what to do internally,
though.

I'm still just having a hard time understanding the overall "how to get a
path out, given a lsusb listing".

You're not the first :-)

Based on a quick read of the Windows source code, I don't know if the paths will really matter. Note that the hid_interrupt_read() and hid_interrupt_write() calls do not worry about paths - they just take an endpoint number, and require you to figure out the packet size yourself.

But for completeness, here's how the first element in the dump is computed.

parse tree of HIDInterface 003/015[0]:
  path: 0x00010080.0x00010081; type: 0x80

The first part of the report descriptor:

          Report Descriptor: (length is 200)
            Item(Global): Usage Page, data= [ 0x01 ] 1
                            Generic Desktop Controls
            Item(Local ): Usage, data= [ 0x80 ] 128
                            System Control

"Usage Page...= 0x01" is shorthand, and gets translated to "0x0001 << 16", or 0x00010000. "Usage...=0x80" gets OR'd with that, to produce "0x00010080". That full 32-bit Usage is the first element of the path ("root directory", if you will).

The next element in the report descriptor is a collection:

            Item(Main  ): Collection, data= [ 0x01 ] 1
                            Application

The notion of a collection is similar to a directory on a filesystem; hence, the full Usage calculated above will be the first elements of all the paths until the collection ends.

            Item(Global): Report ID, data= [ 0x01 ] 1

Report IDs are sort of another dimension to the data - they allow the information to be broken up into chunks that can be requested separately (keyed by the Report ID). They are "sticky" until the next Report ID.

            Item(Local ): Usage, data= [ 0x81 ] 129
                            System Power Down

This Usage ID is inside the collection, and it inherits the last Usage Page which was set (0x0001 => 0x00010000). So its full 32-bit Usage is (0x0001 << 16) | 0x0081, or 0x00010081, which is the second element of the path (shown in the first line of the dump).

            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0x01 ] 1
            Item(Global): Report Size, data= [ 0x01 ] 1
            Item(Global): Report Count, data= [ 0x01 ] 1
            Item(Main  ): Input, data= [ 0x06 ] 6
                            Data Variable Relative No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield

This portion from the lsusb listing basically says that the path represents one bit of input data. The "0x80" at the end of the libhid dump is the internal libhid direction flag (Input, which is Device-to- Host).

            Item(Global): Report Count, data= [ 0x07 ] 7
            Item(Main  ): Input, data= [ 0x01 ] 1
                            Constant Array Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile Bitfield

The single bit of data is padded out with 7 bits of "don't care" (the Constant/Absolute flags above).

If we look up the Usage in that Usage Page (which lsusb has done for us), it appears as though the PSU is synthesizing a "System Power Down" keypress.

After that, the collection is closed, which is sort of like "cd ..":

            Item(Main  ): End Collection, data=none


So the next Usage Page and Usage pair will specify the first element in the path.

I started reading this:
http://www.networkupstools.org/doc/2.2.0/hid-subdrivers.html
Is this actually relevant to me? It seems that if someone else has done
most of the work for HID power supplies, I'll have more luck beginning
with that?

Unfortunately, that particular driver is looking for the standard HID Power Device Class (PDC) Usage numbers (0x0084 and 0x0085).

Here's a sample libhid dump from the kind of UPS that NUT works with out-of-the-box:

http://boxster.ghz.cc/projects/libhid/browser/trunk/ref/test_libhid_output/MGE_Pulsar_Evolution_500

Overall, I'm just confused as to what's going on or how to progress
and
make this work. If anyone has any suggestions as to what I should do
from here, I'd greatly appreciate it.

What are your goals? Shutting down the power supply? Monitoring
certain parameters? If possible, I would start with something
innocuous like changing the state of an LED, but if you can power the
test machine from another power source, that would be best.

At least to start, I just want to read the current state of the PSU.
Saliently, at least to start, I just want to be able to figure out
whether the ignition is connected or not, and if not, how long until it
actually shuts the whole system down.

You may be in luck if it's rainy this weekend - I'll have more time to look into the Windows code.

I figure that once I see *something* everything else is in the realm of
figuring out the device-specific hoojimajiggery. I'm still just at the
point where I want to see *something*.

Thank-you so much for your time and explanations, they've really been
helping me.

You're welcome. You have evidently spent a lot of time researching this, so I figure it's the least I can do.

Oh, OK - I admit it - I think this device would be cool to support in Network UPS Tools :-)

_______________________________________________
libhid-discuss mailing list
libhid-discuss@lists.alioth.debian.org
http://lists.alioth.debian.org/mailman/listinfo/libhid-discuss
http://libhid.alioth.debian.org/

Reply via email to