Skip to content

Raw HID [get_last_received_report()] broken on 9.1.0-beta.3 (Pi Pico rp2040) #9306

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

Closed
dtcooper opened this issue Jun 4, 2024 · 5 comments · Fixed by #9322
Closed

Raw HID [get_last_received_report()] broken on 9.1.0-beta.3 (Pi Pico rp2040) #9306

dtcooper opened this issue Jun 4, 2024 · 5 comments · Fixed by #9322
Assignees
Milestone

Comments

@dtcooper
Copy link

dtcooper commented Jun 4, 2024

CircuitPython version

Adafruit CircuitPython 9.1.0-beta.3 on 2024-05-22; Raspberry Pi Pico with rp2040

Code/REPL

#### boot.py ####

# rawhid_boot.py --
# any changes here only reflected after board reset

import usb_hid

REPORT_COUNT = 63  # size of report in bytes

CUSTOM_REPORT_DESCRIPTOR = bytes((
    0x06, 0x00, 0xff,  # Usage page (Vendor Defined Page1)
    0x09, 0x01,        # Usage (Vendor Page 1)
    0xA1, 0x01,        # Collection (Application)

    0x85, 0x01,        # Report ID (1)
    0x09, 0x00,        # Usage Page (Undefined)
    0x15, 0x00,        # Logical Minimum (0)
    0x26, 0xFF, 0x00,  # Logical Maximum (255)
    0x75, 0x08,        # Report Size (8 bits)
    0x95, REPORT_COUNT, # Report Count (64 fields)
    0x82, 0x02, 0x01,  # Input (Data,Var,Abs,Buf)

    0x85, 0x02,        # Report ID (2)
    0x09, 0x00,        # Usage (Undefined)
    0x09, 0x00,        # Usage Page (Undefined)
    0x15, 0x00,        # Logical Minimum (0)
    0x26, 0xFF, 0x00,  # Logical Maximum (255)
    0x75, 0x08,        # Report Size (8 bits)
    0x95, REPORT_COUNT, # Report Count (64 fields)
    0x92, 0x02, 0x01,  # Output (Data,Var,Abs,Buf)

    0xC0,        # End Collection
))

raw_hid = usb_hid.Device(
    report_descriptor=CUSTOM_REPORT_DESCRIPTOR,
    usage_page=0xff00,         # Vendor defined
    usage=0x01,                # Vendor page 1
    report_ids=(1, 2),
    in_report_lengths=(REPORT_COUNT,0),
    out_report_lengths=(0, REPORT_COUNT),
)

usb_hid.enable( (raw_hid,) )

#### code.py ####

# rawhid_code.py  -- copy to CIRCUITPY as "code.py"
# don't forget to install rawhid_boot.py as "boot.py" and press reset
# works with report IDs up to 63 byte report count
# test with hidapitester like:
# ./hidapitester --usagePage 0xff00 --usage 1 --open -l 64 --send-output 2,3,4,5 --timeout 1000 --read-input 1
# adapted from code presented here:
# https://github.com/libusb/hidapi/issues/478

import time
import usb_hid
import adafruit_hid

raw_hid = adafruit_hid.find_device(usb_hid.devices, usage_page=0xff00, usage=0x01)

print("raw_hid: %04x %04x" % (raw_hid.usage_page, raw_hid.usage) )

while True:
    out_report = raw_hid.get_last_received_report(2) # out from computer
    if out_report:
        print("len:",len(out_report),["%02x" % x for x in out_report])
        time.sleep(0.5)
        print("sending copy on reportid 1")
        in_report = bytearray(out_report)  # copy in case we want to modify
        raw_hid.send_report(in_report, 1);  # in to computer

Behavior

No output observed, whereas in 9.1.0-beta.2 the above example works perfectly.

On 9.1.0-beta.3 with code above tested with no output (see the [...] read 0 bytes [...] line)

dave@tomato:~$ hidapitester --usagePage 0xff00 --usage 1 --open -l 64 --send-output 2,3,4,5 --timeout 1000 --read-input 1
Opening device, vid/pid:0x0000/0x0000, usagePage/usage: FF00/1
Device opened
Writing output report of 64-bytes...wrote 64 bytes:
 02 03 04 05 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
Reading 64-byte input report 0, 1000 msec timeout...read 0 bytes:
Closing device

On 9.1.0-beta.2 with code above, output as expected,

dave@tomato:~$ hidapitester --usagePage 0xff00 --usage 1 --open -l 64 --send-output 2,3,4,5 --timeout 1000 --read-input 1
Opening device, vid/pid:0x0000/0x0000, usagePage/usage: FF00/1
Device opened
Writing output report of 64-bytes...wrote 64 bytes:
 02 03 04 05 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
Reading 64-byte input report 0, 1000 msec timeout...read 64 bytes:
 01 03 04 05 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
Closing device

Description

Given @todbot's example of creating a vendor-defined raw HID to communicate over USB — gist found here and further discussion in GitHub issues found here, I observe communication from my computer to Circuitpython broken as of 9.1.0-beta.3. Note: it works fine in 9.1.0-beta.2.

Additional information

Using 9.1.0-beta.2 is a workaround for now, but hope to help prevent this regression in 9.1.x. Thanks!

@dtcooper dtcooper added the bug label Jun 4, 2024
@dhalbert
Copy link
Collaborator

dhalbert commented Jun 4, 2024

@hathach This is of interest to you. We updated TinyUSB in 9.1.0-beta.3.

@dhalbert dhalbert added the usb label Jun 4, 2024
@dhalbert dhalbert added this to the 9.1.0 milestone Jun 4, 2024
@dhalbert dhalbert self-assigned this Jun 10, 2024
@dhalbert
Copy link
Collaborator

dhalbert commented Jun 10, 2024

I believe this is due to hathach/tinyusb#2253. I'm checking to see how the arguments to tud_hid_set_report_cb() have changed. This affects any use of get_last_received_report(), such as keyboard LED indicators.

@dtcooper
Copy link
Author

Great, thanks for looking into this.

@dtcooper
Copy link
Author

#9322 appears to fix the issue. See pull request for more info. :)

@dtcooper
Copy link
Author

👏 thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants