Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't get it working with a CP2112 from SiLabs #33

Closed
micjoc00 opened this issue Mar 31, 2016 · 4 comments
Closed

Can't get it working with a CP2112 from SiLabs #33

micjoc00 opened this issue Mar 31, 2016 · 4 comments

Comments

@micjoc00
Copy link

I'm trying to get the CP2112 (I2C and GPIO interface chip) from SiLabs working. The HID interface is documented here: http://www.silabs.com/Support%20Documents/TechnicalDocs/AN495.pdf Here is the output of the show_hids.py example: show_hids.txt My environment is Win7(64-bit) and python 3.4.4 (32-bit).
I already got the LEDs on the board blinking, but I'm running into problems when the HidP_GetUsageValueArray function is called in getting a report:

Traceback (most recent call last):
  File "C:/work/usb_hid_test_cp2112/cp2112_test.py", line 148, in <module>
    print(cp.get_version())
  File "C:/work/usb_hid_test_cp2112/cp2112_test.py", line 114, in get_version
    val = report.get()
  File "C:\Anaconda3\lib\site-packages\pywinusb\hid\core.py", line 1522, in get
    self.set_raw_data(raw_data)
  File "C:\Anaconda3\lib\site-packages\pywinusb\hid\core.py", line 1375, in set_raw_data
    byref(self.__raw_data), len(self.__raw_data)) )
  File "C:\Anaconda3\lib\site-packages\pywinusb\hid\winapi.py", line 395, in __init__
    raise helpers.HIDError("hidP error: %s" % self.error_message_dict[error_code])
pywinusb.hid.helpers.HIDError: hidP error: not value array

The interesting thing is that it is working for report_id 0x03, but not for report_id 0x05. If I comment out the section where HidP_GetUsageValueArray is called, it works.

Here is the code I'm using:

from time import sleep
import struct
import ctypes
from ctypes import c_ubyte
import pywinusb.hid as hid

USB_VID=0x10c4
USB_PID=0xea90
USB_VENDOR="OMICRON"
USB_PRODCT="SWT1LOAD"

class CP2112(object):
        def __init__(self, usb_device):
            """Initialize a cp2112 device class.
            The pywinusb device object must exist and needs to be open
            """
            self.dev = usb_device
            self.__feature_reports = dict()
            for r in self.dev.find_feature_reports():
                self.__feature_reports[r.report_id] = r

        def set_gpio_configuration(self, direction=0x00, push_pull=0x00, special=0x00, clk_divider=0x00):
            device.send_feature_report( (c_ubyte * 5)(0x02, direction, push_pull, special, clk_divider) )

        def get_gpio(self):
            report = self.__feature_reports[0x03]
            return report.get()[1]

        def set_gpio(self, value=0, mask=0xff):
            device.send_feature_report( (c_ubyte * 3)(0x04, value, mask) )

        def get_version(self):
            report = self.__feature_reports[0x05]
            val = report.get()
            return (val[1], val[2])

if __name__ == '__main__':
    devices = hid.HidDeviceFilter(vendor_id = USB_VID, product_id = USB_PID,
                                  vendor_name=USB_VENDOR, product=USB_PRODCT).get_devices()
    device = devices[0]
    device.open()
    cp=CP2112(device)
    cp.set_gpio_configuration(0xff, 0)
    print(cp.get_gpio())
    print(cp.get_version())
    # blink leds
    for k in range(10):
        cp.set_gpio()
        cp.get_gpio()
        sleep(0.1)
        cp.set_gpio(0xff)
        cp.get_gpio()
        sleep(0.1)
@rene-aguirre
Copy link
Owner

@micjoc00, your device HID descriptor has non consistent usage ids, the Windows HID descriptor parser is kind of picky about value arrays, and looks like the Silicon Labs took a shortcut trying to simplify the descriptor.

Anyway... by default, .get() tries to parse the retrieved device data using the device supplied HID descriptors.

Actually here, everything is usage id '1', even for some items that are not value arrays, like you mentioned as in feature report 3 (report_count=1), which doesn't even follow the AN495 specification that states that there are actually 2 bytes on it, is likely windows matches the wrong capabilities due the id/page match but different report count field: result, the usage in report 3 is not a value array as reported in report 5.

If this is about something you can provide technical feedback, try suggesting using consistent (separate values, specially dedicated ones for different fields not actually only for full reports) usage IDs.

This would avoid the "byte and offset" specification at all, the HID descriptor would provide the right schema for how to access and find specific fields. This is the purpose of having standard usage pages, and that's why your USB HID button controls for volume just work, regardless of the report id a device would use or the actual byte and bit offset for button toggles.

Anyway, just use raw reports to avoid the broken device descriptor Windows can't cope with.

Try calling report.get(do_process_raw_report = False) or just report.get(False), this will skip any attempt to decode the usages based on the device HID report.

@micjoc00
Copy link
Author

micjoc00 commented Apr 1, 2016

I suspected that the device is the cause of this, but i don't have enough knowledge about the HID descriptors. I will try to give feedback to SiLabs for future devices. Sadly the firmware is programmed by the vendor and cannot be changed by the user. I will have to live with it.

I already tried to specify the do_process_raw_report=False, but the parsing happens in the set_raw_data method. The argument do_process_raw_report is checked one line after calling that method. Thanks for the fast response and help so far!

rene-aguirre pushed a commit that referenced this issue May 2, 2016
Fixing do_process_raw_reports parameter, this allows to read
reports in a totally transparent way.
@rene-aguirre
Copy link
Owner

Hello @micjoc00, sorry for the late reply, please take a look to this change: 721cf63

Please let me know if this is good enough for you.

@micjoc00
Copy link
Author

micjoc00 commented May 3, 2016

Hi @rene-aguirre, it's working perfectly now. Thank you!

@micjoc00 micjoc00 closed this as completed May 3, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants