jnweiger / led-name-badge-ls32

Upload tool for an led name tag with USB-HID interface
GNU General Public License v2.0
223 stars 81 forks source link

ValueError: Invalid endpoint address 0x1 #36

Open ghosty-be opened 1 year ago

ghosty-be commented 1 year ago

Tried on Linux Mint 20.3 and 21 (debian - ubuntu based): installed python3-usb through apt, python3-pil was already installed by default. copied the udev rule and reloaded Device: NB1144 tried running with and without sudo, even directly as root.

When I try the example I get the following error: ./led-badge-11x44.py "Hello" using [wch.cn CH583] bus=5 dev=10 Type: 11x44 Traceback (most recent call last): File "/usr/lib/python3/dist-packages/usb/core.py", line 223, in get_interface_and_endpoint return self._ep_info[endpoint_address] KeyError: 1

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "./led-badge-11x44.py", line 523, in dev.write(1, buf[i64:i64+64]) File "/usr/lib/python3/dist-packages/usb/core.py", line 940, in write intf, ep = self._ctx.setup_request(self, endpoint) File "/usr/lib/python3/dist-packages/usb/core.py", line 102, in wrapper return f(self, *args, *kwargs) File "/usr/lib/python3/dist-packages/usb/core.py", line 215, in setup_request intf, ep = self.get_interface_and_endpoint(device, endpoint_address) File "/usr/lib/python3/dist-packages/usb/core.py", line 102, in wrapper return f(self, args, **kwargs) File "/usr/lib/python3/dist-packages/usb/core.py", line 231, in get_interface_and_endpoint raise ValueError('Invalid endpoint address ' + hex(endpoint_address)) ValueError: Invalid endpoint address 0x1

ghosty-be commented 1 year ago

ok looking through this: https://github.com/python-escpos/python-escpos/issues/384 I figured doing this: $ lsusb -v -d 0416:5020

Bus 005 Device 006: ID 0416:5020 Winbond Electronics Corp. Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x0416 Winbond Electronics Corp. idProduct 0x5020 bcdDevice 0.00 iManufacturer 1 wch.cn iProduct 2 CH583 iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 0x0029 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 4 (error) bmAttributes 0xa0 (Bus Powered) Remote Wakeup MaxPower 70mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 5 (error) HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.00 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 34 Report Descriptors: UNAVAILABLE Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 1 can't get debug descriptor: Resource temporarily unavailable Device Status: 0x0000 (Bus Powered)

which shows the OUT endpoint = 0x02 or 2 ... so I changed this:

$ diff led-badge-11x44.py led-badge-11x44.py.orig 
523c523
<     dev.write(2, buf[i*64:i*64+64])
---
>     dev.write(1, buf[i*64:i*64+64])

And that appears to work as designed...

ghosty-be commented 1 year ago

according to this: https://github.com/pyusb/pyusb/blob/master/docs/tutorial.rst this looks like a better idea, to detect the endpoint, rather than hard code it?

$ diff led-badge-11x44.py led-badge-11x44.py.orig 
521,530d520
<   cfg = dev.get_active_configuration()
<   intf = cfg[(0,0)]
< 
<   ep = usb.util.find_descriptor(
<       intf,
<       # match the first OUT endpoint
<       custom_match = \
<       lambda e: \
<           usb.util.endpoint_direction(e.bEndpointAddress) == \
<           usb.util.ENDPOINT_OUT)
533,534c523
<     #dev.write(2, buf[i*64:i*64+64])
<     ep.write(buf[i*64:i*64+64])
---
>     dev.write(1, buf[i*64:i*64+64])
ids93216 commented 1 year ago

I have same problem here, after editing dev.write, it works! Thank you

KaeTuuN commented 11 months ago

@ghosty-be Maybe you can make a PR for that so @jnweiger may merge it! :-)

dirkhillbrecht commented 11 months ago

I'd like to stress that this patch fixes the described issue for the usb.core code path on Linux. However, newer versions of the hardware do not seem to work with this approach generally any more, even with the fix. You need to switch to pyhidapi access and apply a fix to make it working again. Pull Request pending.

azrdev commented 7 months ago

PR: https://github.com/jnweiger/led-name-badge-ls32/pull/42

sarduri commented 7 months ago

Changeing Line in led-badge-11x44.py to dev.write(2, buf[i 64:i 64 + 64]) Worked for me. But only once. Then I have to desconnect the device and reconnect it again. Is there a way to avoid this behavior? I want to use it as a simple display for the desktop. (Linux Ubuntu)

jnweiger commented 6 months ago

42 is merged.

bensartori commented 6 months ago

The point with the endpoint number is closely connected to #37, because these devices seem to use Endpoint 2 instead of 1. They also use another USB-to-serial chip. My idea is to automatically use the only endpoint available, instead of a fixed one. I'l try to implement this somewhen in the next weeks (cannot promise...)

bensartori commented 6 months ago

Hello ghost.be, oh, I have overseen that you already did a patch as proposal. I'll try it soon.

fcartegnie commented 6 months ago

Libusbhid does not seem to set-up easily

I have a simpler workaround for now, without hardcoding see https://github.com/fossasia/led-name-badge-ls32/commit/ae7195e94318ab711147173b081df2dd2e59fd12