Closed xchen10gh closed 2 years ago
I am sorry for the delay in replying to you -- my notifications were getting buried in a spam filter.
Does the I2C error occur immediately after a power cycle, or does it work for a while and then fail?
If it happens the first time you attempt to talk to the Hub after a power cycle, then this is like a fix for your issue:
Closing this issue as the creator seems inactive.
I get a similar error message "'Unable to perform sucessful I2C read block data" when running a loop like this
while true ; do for f in on off ; do usbhub --verbose --disable-i2c data state --port 1 --$f ; sleep 1 ; done ; done
while communicating to the host port
The device under test is self-powered, so I'm just toggling data lines.
Also - recover requires cycling power to the hub
Haven't looked at USB bus traffic yet but could with ellisys explorer 200
Will look at putting the loop into code.py
@osterwood, I think it is noteworthy, that disconning the usb cable from the host connector, connecting it to the mcu port, interrupting to the REPL, and observing the soft reset, then returning cable back to the host connection did NOT help the recovery process
cycling power brought immediate recovery
@d-c-d Thanks for brining this issue up. The I2C interface of the USB4715 is not particularly robust -- you'll notice several of closed issues in the firmware repo are related to various problems (hanging after cold start, errors trying to read EEPROM data, power, etc).
Finding the root cause of this issue has plagued me -- it seems to be related to particular units and / or the physical environment they are running in. I've been working on a "indirect" method of host control of the various I2C devices inside the Hub, so that the I2C controller of the USB4715 can just sit idle.
I'm happy to say, your report here got me to push this code over the line and it's ready for testing.
Prior to this, functions which the USB4715 could directly control (like controlling power state and reading link speed) did not touch the I2C bus, but many other functions did (like data disconnect control via a I2C GPIO expander, power measurements, and setting per-port power limits).
This new "indirect" link uses GPIO registers of the USB4715 which don't have any physical pin mapping to act as a message postbox between the Host and the MCU. This comm-link has been in place for a while, but had only been used to set configuration details on device. With these two commits it now allows for:
I've not pushed this as a new release (yet), so you'll have to install on the host-side via this command:
pip install git+https://github.com/CapableRobot/CapableRobot_USBHub_Driver --upgrade
On the firmware side, you can download that git repo, make sure the MCU drive is mounted, and then run ./usbhub_firmware.py firmware /PATH_TO_CIRCUITPY/
I'd love your feedback on these changes and let know if you run into any issues with the update (on host and on MCU).
@d-c-d Did this (unreleased) indirect method of Hub control work for you?
I just got my hub, and 100% of the time, it would give me the I2C error. I just tried installing the unreleased firmware, and now it doesn't show up as a USB hub anymore, the Host LED doesn't turn on, and usbhub
now reports that "No USB Hub was found" (yes, I updated to the pre-release of the driver too). Reverting back to the previous firmware (by checking out the previous commit, deleting the recently modified .py
files on the CIRCUITPY drive, and then re-installing the firmware) did not fix it.
What steps should I take to figure out what's going on?
Noah,
I am sorry to hear of your various troubles with the Hub. The head commit of the firmware repo should not prevent the Hub from being configured correctly and being detected by the connected host (regardless of the host-side driver version).
Can you connect a USB cable to the MCU port and enter into the CircuitPython console? There are useful debug messages there and if the firmware enters any errors, they will be reported. Once you connect, you may have to use CTRL-C and CTRL-D keystrokes to cause the firmware to reset (as messages which have already been printed are not visible to you).
Also, what version of the Hub do you have? E.g. does the MPN on the bottom end with ".1", ".2", or it is just CRZRYC?
No worries, we'll get it figured out.
I have the ".2" version. Here's the output when I delete and re-deploy the firmware using py usbhub_firmware.py firmware D:\
:
soft reboot
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Circuitpython upgrade complete
Code stopped by auto-reload.
soft reboot
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Circuitpython upgrade complete
My boot_out.txt
file says Adafruit CircuitPython 6.3.0-dirty on 2021-12-02; Capable Robot Programmable USB Hub with samd51g19
, so I think it's still running the correct version of CircuitPython (though I did mistakenly run py usbhub_firmware.py circuitpython
at one point).
Thanks for the debug output.
It looks like the firmware update process didn't complete as expected -- that output shows you are still running the "stub" firmware-update code.py (embedded in usbhub_firmware.py) -- instead of the code.py which causes the Hub to be configured.
I think all you need to do copy the real code.py from your local firmware download and over-write the code.py file on the MCU "drive".
I will look into why the firmware update process either didn't restore the original code.py file after the firmware update was complete. Does your firmware drive have a code.py.bkp file on it?
One option to manually update to the head firmware is to download from GitHub (or checkout that commit on your local download) and copy the code.py file and the "lib" folder onto the MCU drive. That is all the "update_firmware.py" script does.
It is important that the code.py file revision match the revision of the lib folder. E.g. both should be the JAN 25 commit or both the previous commit -- mismatching would likely introduce errors.
I do have a code.py.bkp file.
Part of the issue may have been that I was forgetting to delete the code.py
file before running the update_firmware script, and it was getting skipped as a result. Deleting it and re-running the script made the hub boot up correctly.
Unfortunately, I'm still getting the original error with the pre-release firmware and driver. However, I just noticed that there's a different error that occurs first:
> usbhub id
Traceback (most recent call last):
File "c:\python38\lib\site-packages\capablerobot_usbhub\i2c.py", line 164, in read_i2c_block_data
length = self.hub.handle.ctrl_transfer(REQ_OUT+1, self.CMD_I2C_WRITE, cmd, 0, [register], timeout=self.timeout)
File "c:\python38\lib\site-packages\usb\core.py", line 1071, in ctrl_transfer
self._ctx.managed_open()
File "c:\python38\lib\site-packages\usb\core.py", line 113, in wrapper
return f(self, *args, **kwargs)
File "c:\python38\lib\site-packages\usb\core.py", line 131, in managed_open
self.handle = self.backend.open_device(self.dev)
File "c:\python38\lib\site-packages\usb\backend\libusb1.py", line 804, in open_device
return _DeviceHandle(dev)
File "c:\python38\lib\site-packages\usb\backend\libusb1.py", line 652, in __init__
_check(_lib.libusb_open(self.devid, byref(self.handle)))
File "c:\python38\lib\site-packages\usb\backend\libusb1.py", line 604, in _check
raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 2] Entity not found
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "c:\python38\lib\runpy.py", line 193, in _run_module_as_main
return _run_code(code, main_globals, None,
File "c:\python38\lib\runpy.py", line 86, in _run_code
exec(code, run_globals)
File "C:\Python38\Scripts\usbhub.exe\__main__.py", line 7, in <module>
File "c:\python38\lib\site-packages\capablerobot_usbhub\console.py", line 239, in main
cli()
File "c:\python38\lib\site-packages\click\core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "c:\python38\lib\site-packages\click\core.py", line 782, in main
rv = self.invoke(ctx)
File "c:\python38\lib\site-packages\click\core.py", line 1256, in invoke
Command.invoke(self, ctx)
File "c:\python38\lib\site-packages\click\core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "c:\python38\lib\site-packages\click\core.py", line 610, in invoke
return callback(*args, **kwargs)
File "c:\python38\lib\site-packages\capablerobot_usbhub\console.py", line 74, in cli
hub = USBHub(device=dict(disable_i2c=disable_i2c))
File "c:\python38\lib\site-packages\capablerobot_usbhub\main.py", line 88, in __init__
self.attach(vendor, product)
File "c:\python38\lib\site-packages\capablerobot_usbhub\main.py", line 188, in attach
self.devices[device.key] = device
File "c:\python38\lib\site-packages\capablerobot_usbhub\device.py", line 211, in key
return self.serial[-self.main.KEY_LENGTH:]
File "c:\python38\lib\site-packages\capablerobot_usbhub\device.py", line 192, in serial
data = self.i2c.read_i2c_block_data(EEPROM_I2C_ADDR, EEPROM_EUI_ADDR, EEPROM_EUI_BYTES)
File "c:\python38\lib\site-packages\capablerobot_usbhub\i2c.py", line 176, in read_i2c_block_data
raise OSError('Unable to perform sucessful I2C read block data')
OSError: Unable to perform sucessful I2C read block data
Yeah - the firmware update script does need some work.
Do you get that error if you run with the "--disable-i2c" flag set? Even with the pre-release host-side software, the default behavior is to use I2C.
I get a similar but different error
> usbhub --disable-i2c id
Hub Key : 1-28 (0)
MPN : None
Traceback (most recent call last):
File "c:\python38\lib\runpy.py", line 193, in _run_module_as_main
return _run_code(code, main_globals, None,
File "c:\python38\lib\runpy.py", line 86, in _run_code
exec(code, run_globals)
File "C:\Python38\Scripts\usbhub.exe\__main__.py", line 7, in <module>
File "c:\python38\lib\site-packages\capablerobot_usbhub\console.py", line 239, in main
cli()
File "c:\python38\lib\site-packages\click\core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "c:\python38\lib\site-packages\click\core.py", line 782, in main
rv = self.invoke(ctx)
File "c:\python38\lib\site-packages\click\core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "c:\python38\lib\site-packages\click\core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "c:\python38\lib\site-packages\click\core.py", line 610, in invoke
return callback(*args, **kwargs)
File "c:\python38\lib\site-packages\capablerobot_usbhub\console.py", line 111, in id
print("Revision : {}".format(device.revision))
File "c:\python38\lib\site-packages\capablerobot_usbhub\device.py", line 252, in revision
data, _ = self.register_read(addr=0x3004, length=2)
File "c:\python38\lib\site-packages\capablerobot_usbhub\device.py", line 117, in register_read
data = list(self.handle.ctrl_transfer(REQ_IN, self.CMD_REG_READ, value, index, length))
File "c:\python38\lib\site-packages\usb\core.py", line 1071, in ctrl_transfer
self._ctx.managed_open()
File "c:\python38\lib\site-packages\usb\core.py", line 113, in wrapper
return f(self, *args, **kwargs)
File "c:\python38\lib\site-packages\usb\core.py", line 131, in managed_open
self.handle = self.backend.open_device(self.dev)
File "c:\python38\lib\site-packages\usb\backend\libusb1.py", line 804, in open_device
return _DeviceHandle(dev)
File "c:\python38\lib\site-packages\usb\backend\libusb1.py", line 652, in __init__
_check(_lib.libusb_open(self.devid, byref(self.handle)))
File "c:\python38\lib\site-packages\usb\backend\libusb1.py", line 604, in _check
raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 2] Entity not found
That is progress.
It look like reading the device revisions (register 0x3004) is failing due to the the device handle not existing -- but I might be reading that stack trace a bit incorrectly (on a plane which is about to pull back from the gate).
I will be able to look into this in more detail tomorrow morning.
Have you done the register step to assign the device to the correct backend?
pip install capablerobot_usbregister
usbregister device usbhub
Have a good flight!
I have done that, yes. Here's the proof in Zadig:
Side note, shouldn't the USB registration using libwdi be unnecessary, since the device supports WCID?
Hold on. usbregister
attempts to assign the libusbk driver to the device, but apparently that isn't sticking (maybe thanks to WCID?)
Well, that was indeed the problem. When I used Zadig to switch the device to the libusbK driver, usbhub id
worked, with or without the --disable-i2c
option.
Shouldn't the device request the libusbK driver using WCID? (screenshot taken from https://github.com/pbatard/libwdi/wiki/WCID-Devices#microsoft-compatible-id-feature-descriptor)
I've encountered the same issue on my setup. I have two hubs of different revisions, both of which I have updated the firmware on with the method outlined above in this thread. I haven't tried usbregister
yet, is that for Linux hosts? Currently running this on Ubuntu 20.04.
gsgadmin@testserver:~/CapableRobot_USBHub_Firmware$ pip install git+https://github.com/CapableRobot/CapableRobot_USBHub_Driver --upgrade
Collecting git+https://github.com/CapableRobot/CapableRobot_USBHub_Driver
Cloning https://github.com/CapableRobot/CapableRobot_USBHub_Driver to /tmp/pip-req-build-kz0x0fye
Running command git clone -q https://github.com/CapableRobot/CapableRobot_USBHub_Driver /tmp/pip-req-build-kz0x0fye
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing wheel metadata ... done
Requirement already satisfied, skipping upgrade: pyusb<2.0.0,>=1.0.2 in /home/gsgadmin/.local/lib/python3.8/site-packages (from capablerobot-usbhub==0.5.0) (1.2.1)
Requirement already satisfied, skipping upgrade: click<8.0,>=7.0 in /usr/lib/python3/dist-packages (from capablerobot-usbhub==0.5.0) (7.0)
Requirement already satisfied, skipping upgrade: construct<3.0.0,>=2.9.51 in /home/gsgadmin/.local/lib/python3.8/site-packages (from capablerobot-usbhub==0.5.0) (2.10.68)
Requirement already satisfied, skipping upgrade: pyyaml<6.0,>=5.3 in /usr/lib/python3/dist-packages (from capablerobot-usbhub==0.5.0) (5.3.1)
Building wheels for collected packages: capablerobot-usbhub
Building wheel for capablerobot-usbhub (PEP 517) ... done
Created wheel for capablerobot-usbhub: filename=capablerobot_usbhub-0.5.0-py3-none-any.whl size=595499 sha256=0a31f9936a02aa21518fe8a91a11b9396cacf3c26274dc255f366aff020cd78b
Stored in directory: /tmp/pip-ephem-wheel-cache-wue96tlb/wheels/b7/dc/4d/3c0a501ef644e6910208ee1c1a917474d91e9b37798a9c420f
Successfully built capablerobot-usbhub
Installing collected packages: capablerobot-usbhub
Attempting uninstall: capablerobot-usbhub
Found existing installation: capablerobot-usbhub 0.5.0
Uninstalling capablerobot-usbhub-0.5.0:
Successfully uninstalled capablerobot-usbhub-0.5.0
Successfully installed capablerobot-usbhub-0.5.0
gsgadmin@testserver:~/CapableRobot_USBHub_Firmware$
gsgadmin@testserver:~/CapableRobot_USBHub_Firmware$ ./usbhub_firmware.py firmware --force /media/gsgadmin/CIRCUITPY
Updating : lib/capablerobot_ucs2113.py
Updating : lib/capablerobot_eeprom.py
Updating : lib/capablerobot_usbhub.py
Updating : lib/capablerobot_tlc59116.py
Updating : lib/adafruit_bus_device/i2c_device.py
Updating : lib/adafruit_bus_device/spi_device.py
Updating : lib/adafruit_bus_device/__init__.py
Updating : code.py from code.py
gsgadmin@testserver:~/CapableRobot_USBHub_Firmware$ usbhub id
Hub Key : D9D1 (0)
MPN : CRZRYC
Revision : 1
Serial : 801F12FFFE3CD9D1
USB Path : 1-92
gsgadmin@testserver:~/CapableRobot_USBHub_Firmware$ ./usbhub_firmware.py firmware --force /media/gsgadmin/CIRCUITPY
Updating : lib/capablerobot_ucs2113.py
Updating : lib/capablerobot_eeprom.py
Updating : lib/capablerobot_usbhub.py
Updating : lib/capablerobot_tlc59116.py
Updating : lib/adafruit_bus_device/i2c_device.py
Updating : lib/adafruit_bus_device/spi_device.py
Updating : lib/adafruit_bus_device/__init__.py
Updating : code.py from code.py
gsgadmin@testserver:~/CapableRobot_USBHub_Firmware$ usbhub id
Hub Key : D9D1 (0)
MPN : CRZRYC
Revision : 1
Serial : 801F12FFFE3CD9D1
USB Path : 1-97
Hub Key : 624C (1)
MPN : CRZRYC
Revision : 2
Serial : 682719FFFEA6624C
USB Path : 1-95
gsgadmin@testserver:~/CapableRobot_USBHub_Firmware$ cd ../greatfet/ci-scripts/
gsgadmin@testserver:~/greatfet/ci-scripts$ usbhub --hub D9D1 power state
Port 1 Port 2 Port 3 Port 4
on on on on
gsgadmin@testserver:~/greatfet/ci-scripts$ usbhub --hub 624C power state
Port 1 Port 2 Port 3 Port 4
on on on on
gsgadmin@testserver:~/greatfet/ci-scripts$ ./configure-hubs.sh --off
gsgadmin@testserver:~/greatfet/ci-scripts$ usbhub --hub D9D1 power state
Port 1 Port 2 Port 3 Port 4
off off off off
gsgadmin@testserver:~/greatfet/ci-scripts$ usbhub --hub 624C power state
Port 1 Port 2 Port 3 Port 4
off off off off
gsgadmin@testserver:~/greatfet/ci-scripts$ ./configure-hubs.sh --on
gsgadmin@testserver:~/greatfet/ci-scripts$ usbhub --hub D9D1 power state
Port 1 Port 2 Port 3 Port 4
on on on on
gsgadmin@testserver:~/greatfet/ci-scripts$ usbhub --hub 624C power state
Port 1 Port 2 Port 3 Port 4
on on on on
gsgadmin@testserver:~/greatfet/ci-scripts$ ./configure-hubs.sh --reset
Traceback (most recent call last):
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/i2c.py", line 133, in read_bytes
data = list(self.hub.handle.ctrl_transfer(REQ_IN+1, self.CMD_I2C_READ, cmd, 0, number, timeout=self.timeout))
File "/home/gsgadmin/.local/lib/python3.8/site-packages/usb/core.py", line 1082, in ctrl_transfer
ret = self._ctx.backend.ctrl_transfer(
File "/home/gsgadmin/.local/lib/python3.8/site-packages/usb/backend/libusb1.py", line 893, in ctrl_transfer
ret = _check(self.lib.libusb_control_transfer(
File "/home/gsgadmin/.local/lib/python3.8/site-packages/usb/backend/libusb1.py", line 602, in _check
raise USBTimeoutError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBTimeoutError: [Errno 110] Operation timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/gsgadmin/.local/bin/usbhub", line 8, in <module>
sys.exit(main())
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/console.py", line 237, in main
cli()
File "/usr/lib/python3/dist-packages/click/core.py", line 764, in __call__
return self.main(*args, **kwargs)
File "/usr/lib/python3/dist-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/usr/lib/python3/dist-packages/click/core.py", line 1134, in invoke
Command.invoke(self, ctx)
File "/usr/lib/python3/dist-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/lib/python3/dist-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/console.py", line 74, in cli
hub = USBHub(device=dict(disable_i2c=disable_i2c))
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/main.py", line 88, in __init__
self.attach(vendor, product)
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/main.py", line 188, in attach
self.devices[device.key] = device
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/device.py", line 212, in key
return self.serial[-self.main.KEY_LENGTH:]
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/device.py", line 193, in serial
data = self.i2c.read_i2c_block_data(EEPROM_I2C_ADDR, EEPROM_EUI_ADDR, EEPROM_EUI_BYTES)
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/i2c.py", line 186, in read_i2c_block_data
return self.read_bytes(addr, number, try_lock=False)
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/i2c.py", line 140, in read_bytes
raise OSError('Unable to perform sucessful I2C read')
OSError: Unable to perform sucessful I2C read
gsgadmin@testserver:~/greatfet/ci-scripts$ usbhub id
Traceback (most recent call last):
File "/home/gsgadmin/.local/bin/usbhub", line 8, in <module>
sys.exit(main())
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/console.py", line 237, in main
cli()
File "/usr/lib/python3/dist-packages/click/core.py", line 764, in __call__
return self.main(*args, **kwargs)
File "/usr/lib/python3/dist-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/usr/lib/python3/dist-packages/click/core.py", line 1134, in invoke
Command.invoke(self, ctx)
File "/usr/lib/python3/dist-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/lib/python3/dist-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/console.py", line 74, in cli
hub = USBHub(device=dict(disable_i2c=disable_i2c))
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/main.py", line 88, in __init__
self.attach(vendor, product)
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/main.py", line 187, in attach
device = USBHubDevice(weakref.proxy(self), handle, **self.device_kwargs)
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/device.py", line 94, in __init__
logging.debug("Firmware version {} running on {}".format(self.config.version, self.config.circuitpython_version))
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/config.py", line 88, in version
buf, _ = self.hub.register_read(addr=_MEM_IDENT, length=4)
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/device.py", line 118, in register_read
data = list(self.handle.ctrl_transfer(REQ_IN, self.CMD_REG_READ, value, index, length))
File "/home/gsgadmin/.local/lib/python3.8/site-packages/usb/core.py", line 1082, in ctrl_transfer
ret = self._ctx.backend.ctrl_transfer(
File "/home/gsgadmin/.local/lib/python3.8/site-packages/usb/backend/libusb1.py", line 893, in ctrl_transfer
ret = _check(self.lib.libusb_control_transfer(
File "/home/gsgadmin/.local/lib/python3.8/site-packages/usb/backend/libusb1.py", line 602, in _check
raise USBTimeoutError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBTimeoutError: [Errno 110] Operation timed out
gsgadmin@testserver:~/greatfet/ci-scripts$ usbhub --disable-i2c id
Traceback (most recent call last):
File "/home/gsgadmin/.local/bin/usbhub", line 8, in <module>
sys.exit(main())
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/console.py", line 237, in main
cli()
File "/usr/lib/python3/dist-packages/click/core.py", line 764, in __call__
return self.main(*args, **kwargs)
File "/usr/lib/python3/dist-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/usr/lib/python3/dist-packages/click/core.py", line 1134, in invoke
Command.invoke(self, ctx)
File "/usr/lib/python3/dist-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/lib/python3/dist-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/console.py", line 74, in cli
hub = USBHub(device=dict(disable_i2c=disable_i2c))
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/main.py", line 88, in __init__
self.attach(vendor, product)
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/main.py", line 187, in attach
device = USBHubDevice(weakref.proxy(self), handle, **self.device_kwargs)
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/device.py", line 94, in __init__
logging.debug("Firmware version {} running on {}".format(self.config.version, self.config.circuitpython_version))
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/config.py", line 88, in version
buf, _ = self.hub.register_read(addr=_MEM_IDENT, length=4)
File "/home/gsgadmin/.local/lib/python3.8/site-packages/capablerobot_usbhub/device.py", line 118, in register_read
data = list(self.handle.ctrl_transfer(REQ_IN, self.CMD_REG_READ, value, index, length))
File "/home/gsgadmin/.local/lib/python3.8/site-packages/usb/core.py", line 1082, in ctrl_transfer
ret = self._ctx.backend.ctrl_transfer(
File "/home/gsgadmin/.local/lib/python3.8/site-packages/usb/backend/libusb1.py", line 893, in ctrl_transfer
ret = _check(self.lib.libusb_control_transfer(
File "/home/gsgadmin/.local/lib/python3.8/site-packages/usb/backend/libusb1.py", line 602, in _check
raise USBTimeoutError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBTimeoutError: [Errno 110] Operation timed out
Sorry it's such a huge paste, this is what the script I'm using to control the ports looks like
#!/bin/bash
usbhub --hub D9D1 power state --port 1 $1
usbhub --hub D9D1 power state --port 2 $1
usbhub --hub D9D1 power state --port 3 $1
usbhub --hub D9D1 power state --port 4 $1
usbhub --hub 624C power state --port 1 $1
usbhub --hub 624C power state --port 2 $1
usbhub --hub 624C power state --port 3 $1
usbhub --hub 624C power state --port 4 $1
@grvvy Few notes & thoughts for you:
usbregister
is only needed (and only works) on windows. In linux, you do not need it.#!/bin/bash
usbhub --disable-i2c --hub D9D1 power state --port 1,2,3,4 $1
usbhub --disable-i2c --hub 624C power state --port 1,2,3,4 $1
Hi @osterwood, thanks for the response!
The problem with using --disable-i2c
in this scenario is that the hub key changes:
$ usbhub --disable-i2c id
Hub Key : 1-106 (0)
MPN : None
Revision : 1
Serial : None
USB Path : 1-106
Hub Key : 1-109 (1)
MPN : None
Revision : 2
Serial : None
USB Path : 1-109
Is there a way to make sure one of the hub's keys is always 0 and the other's is always 1?
You can use usb path as the hub key on the command line interface (e.g. 1-106 or 1-109), but I believe those increment if the Hub were to be unplugged or power cycled (and reset upon boot). Not ideal at all.
So, I just wrote and pushed a commit (https://github.com/CapableRobot/CapableRobot_USBHub_Driver/commit/8fb6c78b7994c8211975710f60490c92b7b6d88c) which extracts MPN, serial, and revision from the customized USB descriptor -- before falling back to using I2C (unless the --disable-i2c flag has been set).
Note this will need recent USB Hub firmware, as older firmware did not set the product description descriptor. Please try re-installing the host-side driver via git and let me know how this new version works out.
» python capablerobot_usbhub/console.py --disable-i2c id
Hub Key : 9FCF (0)
MPN : CRZRYC
Revision : 1
Serial : 3C9FCF
USB Path : 8-12
Hub Key : B6B1 (1)
MPN : CRR3C4
Revision : 0
Serial : 36B6B1
USB Path : 8-5
This is working great! Thanks for the quick patch :beers:
Glad to hear! Let me know if you run into any other issues.
Hi Chris, I am running into this issue on a Hub I recently received. It looks like there is a patch but it has not been released to pip?
Hi, After repeated ON/OFF cycles testing, the hub failed to communicate via I2C interface. This happens about 15-20 cycles and on two different Hubs. here is the backtrace: [root@linux] python3 status.py Traceback (most recent call last): File "/opt/CapableRobot_USBHub_Driver-0.2.8/capablerobot_usbhub/i2c.py", line 147, in read_i2c_block_data length = self.hub.handle.ctrl_transfer(REQ_OUT+1, self.CMD_I2C_WRITE, cmd, 0, [register], timeout=self.timeout) File "/usr/local/lib/python3.6/site-packages/pyusb-1.1.0-py3.6.egg/usb/core.py", line 1077, in ctrl_transfer File "/usr/local/lib/python3.6/site-packages/pyusb-1.1.0-py3.6.egg/usb/backend/libusb1.py", line 901, in ctrl_transfer File "/usr/local/lib/python3.6/site-packages/pyusb-1.1.0-py3.6.egg/usb/backend/libusb1.py", line 602, in _check usb.core.USBTimeoutError: [Errno 110] Operation timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File "status.py", line 18, in
hub = capablerobot_usbhub.USBHub()
File "/opt/CapableRobot_USBHub_Driver-0.2.8/capablerobot_usbhub/main.py", line 86, in init
self.attach(vendor, product)
File "/opt/CapableRobot_USBHub_Driver-0.2.8/capablerobot_usbhub/main.py", line 184, in attach
self.devices[device.key] = device
File "/opt/CapableRobot_USBHub_Driver-0.2.8/capablerobot_usbhub/device.py", line 183, in key
return self.serial[-self.main.KEY_LENGTH:]
File "/opt/CapableRobot_USBHub_Driver-0.2.8/capablerobot_usbhub/device.py", line 171, in serial
data = self.i2c.read_i2c_block_data(EEPROM_I2C_ADDR, EEPROM_EUI_ADDR, EEPROM_EUI_BYTES)
File "/opt/CapableRobot_USBHub_Driver-0.2.8/capablerobot_usbhub/i2c.py", line 157, in read_i2c_block_data
raise OSError('Unable to perform sucessful I2C read block data')
OSError: Unable to perform sucessful I2C read block data
[root@linux]
Removing the power adaptor and resetting the hub would bring it back to life again. here is more info about the hub: [root@linux]]# usbhub id
Revision / Serial : CRZRYC / 801F12FFFE3CD434 [root@linux]#