问题
So I've been playing with the controllers for the PS2 game, Buzz. I've successfully used libusb to poll and read the buttons, and all is merry and bright.
The trouble is, I'd love to use the in-built lights to signal the folks who're using them (specifically to show them who has buzzed first). I know there's lights, I know that the PS2 was able to turn them on and off at will, and I know that someone has managed it with python. So I set out to implement their code with libusb in Ruby.
I've reproduced the SET_CONFIGURATION call they're making but I keep getting this error:
/home/ajfaraday/.rvm/gems/ruby-2.2.1/gems/libusb-0.5.0/lib/libusb/dev_handle.rb:539:in `submit_transfer':
error TRANSFER_STALL (LIBUSB::ERROR_PIPE)
I can't find any material online about what this error is, except that it's a USB pipe error which is being translated to TRANSFER_STALL by libusb.
I also wrote it out in python, with the specific line from the forum above, and I got something that looks like the same error:
usb.core.USBError: [Errno 32] Pipe error
So I'm at a loss to find out what I'm doing wrong. I've managed to make the opposite call (GET_CONFIGURATION) to a successful response (\x00
).
Here's my reproduction script (depends on the libusb gem):
require 'libusb'
usb_context = LIBUSB::Context.new
device = usb_context.devices(
idVendor: 0x054c, idProduct: 0x0002
).first
handle = device.open
puts 'get configuration:'
x = handle.control_transfer(
:bmRequestType => "10000000".to_i(2),
:bRequest => 8,
:wValue => 0,
:wIndex => 0,
:dataIn => 1
)
puts x.inspect
puts 'set configuration:'
x = handle.control_transfer(
:bmRequestType => "00000000".to_i(2),
:bRequest => 9,
:wValue => 0,
:wIndex => 0,
:dataOut => "\x00\xFF\xFF\xFF\xFF"
)
puts x.inspect
And here's it's output:
get configuration:
"\x00"
set configuration:
/home/ajfaraday/.rvm/gems/ruby-2.2.1/gems/libusb-0.5.0/lib/libusb/dev_handle.rb:539:in `submit_transfer': error TRANSFER_STALL (LIBUSB::ERROR_PIPE)
from /home/ajfaraday/.rvm/gems/ruby-2.2.1/gems/libusb-0.5.0/lib/libusb/dev_handle.rb:515:in `control_transfer'
from sketches/raw_script.rb:22:in `<main>'
It looks like the pipe error means there's something wrong with the setup or data I'm sending out, but I can't find out anywhere what it is.
I've tried:
- putting different amounts of data into the dataOut attribute, too.
- detaching the kernel driver first, also re-opening the handle
- expressing the dataOut attribute as an array
- running it on another (linux) machine
- checking the libusb source code (it's converting a USB message, nothing more)
- Using different types of message as defined in http://www.usbmadesimple.co.uk/ums_4.htm
I'd be very grateful of any assistance. This really should be possible, and I know it's been done.
回答1:
Libusb provides two functions named libusb_set_configuration
and libusb_get_configuration
. You should try to use those instead of rolling your own control transfers to do the same thing. They are documented here:
http://libusb.sourceforge.net/api-1.0/group__dev.html
You can check the source code or documentation of the Ruby libusb binding you are using to figure out how to call them from Ruby.
Also, setting a configuration is a semi-unusual thing to do to a USB device. You should make sure the drivers on your operating system do not already put the device into the correct configuration. Maybe you don't need to set the configuration.
Also, if this controller is an HID, the hidapi library might be a better fit than libusb.
来源:https://stackoverflow.com/questions/32573723/ruby-libusb-stall-error