I'm trying to create python library under windows for Flyfish FF32 USB-HID IO board (http://www.flyfish-tech.com/FF32/index.php). I'm using pywinusb library, Python 2.7, windows 7 for that.
Device itself works with provided by flyfish GUI. Also when running "show_hids" demo from pywinusb device is visible:
HID device (vID=0x04d8, pID=0xf8b9, v=0x0032); FLYFISH TECHNOLOGIES; FF32, Path: \\?\hid#vid_04d8&pid_f8b9#a&135de629&1&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
Path: \\?\hid#vid_04d8&pid_f8b9#a&135de629&1&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
Instance: HID\VID_04D8&PID_F8B9\A&135DE629&1&0000
Port (ID): 2460
Port (str):USB\VID_04D8&PID_F8B9\9&815F95E&0&3
HID device documentation report
===============================
Top Level Details
-----------------
Manufacturer String: FLYFISH TECHNOLOGIES
Product Sting: FF32
Serial Number: ?
Vendor ID: 0x04d8
Product ID: 0xf8b9
Version number: 0x0032
Device Path: \\?\hid#vid_04d8&pid_f8b9#a&135de629&1&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
Device Instance Id: HID\VID_04D8&PID_F8B9\A&135DE629&1&0000
Parent Instance Id: 2460
Top level usage: Page=0xff00, Usage=0x01
Usage identification: Unknown Page/usage
Link collections: 1 collection(s)
Reports
-------
Input Report
~~~~~~~~~~~~
Length: 65 byte(s)
Buttons: 1 button(s)
Values: 0 value(s)
Output Report
~~~~~~~~~~~~~
length: 65 byte(s)
Buttons: 1 button(s)
Values: 0 value(s)
Feature Report
~~~~~~~~~~~~~
Length: 0 byte(s)
Buttons: 0 button(s)
Values: 0 value(s)
*** Input Caps ***
Usage Range 1~64 (0x1~0x40), Page 0xff00 (Vendor-defined)
bit_field: 0
data_index_max: 63
data_index_min: 0
designator_max: 0
designator_min: 0
is_absolute: 1
is_alias: 0
is_button: True
is_designator_range: 0
is_range: 1
is_string_range: 0
is_value: False
link_collection: 0
link_usage: 1 (0x1)
link_usage_page: 65280 (0xff00)
report_id: 0
string_max: 0
string_min: 0
*** Output Caps ***
Usage Range 1~64 (0x1~0x40), Page 0xff00 (Vendor-defined)
bit_field: 0
data_index_max: 63
data_index_min: 0
designator_max: 0
designator_min: 0
is_absolute: 1
is_alias: 0
is_button: True
is_designator_range: 0
is_range: 1
is_string_range: 0
is_value: False
link_collection: 0
link_usage: 1 (0x1)
link_usage_page: 65280 (0xff00)
report_id: 0
string_max: 0
string_min: 0
But when running following, modified demo:
import pywinusb.hid as hid
from time import sleep
def sample_handler(data):
print("Raw data: {0}".format(data))
filter = hid.HidDeviceFilter(vendor_id = 0x04d8, product_id = 0xf8b9)
hid_device = filter.get_devices()
device = hid_device[0]
device.open()
target_usage = hid.get_full_usage_id(0xff00, 1)
device.set_raw_data_handler(sample_handler)
report = device.find_output_reports()
print(report[0])
buffer = [0x00]*65
buffer[0] = 0
buffer[1] = 0x13
report[0].set_raw_data(buffer)
report[0].send()
sleep(1)
device.close()
Execution output: HID report object (Output repor
t, id=0x00), 63 items included
Raw data: [0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
I'm not getting expected vendor info. I installed USB sniffing software and it turned out that no matter what I put into buffer FF32 is always getting array of 0s.
For reference. Package sniffed from GUI:
80 00 09 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 18 f1 6d 0b 80 fa ff ff
02 00 00 00 40 00 00 00 75 9f b6 0b 80 f8 ff ff
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*13* 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
And one from my script:
80 00 09 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 18 f1 6d 0b 80 fa ff ff
02 00 00 00 40 00 00 00 41 57 87 05 80 f8 ff ff
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Does anyone know what is wrong in here?
This device is strange, 65 bytes for a report is not expected as this is usually limited by the endpoint size.
Anyway, set_raw_data()
is expected to be used as a template for "all at once" HID usages settings, so it will validate you provide a valid report id and parseable information (parsing being done by Windows API).
In your case, if you want to send "anything" to your device, as long as the report id is listed in the HID descriptor (first byte), just use:
report.send(buffer) # this validate buffer[0] matches report id
device.send_output_report(buffer) # this will send anything to your device
In both cases you are bypassing the report parsing logic, these are the most efficient ways of sending data by provides the lesser validation to what you send.