Search code examples
raspberry-piusbhid

Pi Zero as HID Device - no capital letters


I'm currently trying to emulate a keyboard with my pi zero w following several guidelines e.g., https://www.rmedgar.com/blog/using-rpi-zero-as-keyboard-setup-and-device-definition (all 3 parts) or this https://randomnerdtutorials.com/raspberry-pi-zero-usb-keyboard-hid/.

It seems to work but I can only make it type lower-case characters and I have no idea why. So e.g., with this code line (taken from the rmedgar guide)

write_report(chr(32)+NULL_CHAR+chr(11)+NULL_CHAR*5)

it just types a lower case "h" - so it seems that chr(32) is ignored - it is supposed to be SHIFT. I tried to trace the scancod of SHIFT with "showkeys -s" which is showing me 0x2a (push) and 0xaa (release). Then I replaced the 32 in above code with 42 (0x2a in dec) but that changes nothing.

I'm working on an old Thinkpad x230, can it be that the scancodes for shift are different?

Any other points that I'm missing?

Thanks a lot :)


Solution

  • The answer is as pointed out by aja - I was using the wrong descriptor, it should be

    echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 > functions/hid.usb0/report_desc
    

    The full script to enable the HID device on a raspberry pi zero therefore looks like this (mostly copied from the links mentioned in my first question).

    #!/bin/bash
    
    # Create gadget
    mkdir /sys/kernel/config/usb_gadget/mykeyboard
    cd /sys/kernel/config/usb_gadget/mykeyboard
    
    # Add basic information
    echo 0x0100 > bcdDevice # Version 1.0.0
    echo 0x0200 > bcdUSB # USB 2.0
    echo 0x00 > bDeviceClass
    echo 0x00 > bDeviceProtocol
    echo 0x00 > bDeviceSubClass
    echo 0x08 > bMaxPacketSize0
    echo 0x0104 > idProduct # Multifunction Composite Gadget
    echo 0x1d6b > idVendor # Linux Foundation
    
    # Create English locale
    mkdir strings/0x409
    
    echo "My manufacturer" > strings/0x409/manufacturer
    echo "My virtual keyboard" > strings/0x409/product
    echo "0123456789" > strings/0x409/serialnumber
    
    # Create HID function
    mkdir functions/hid.usb0
    
    echo 1 > functions/hid.usb0/protocol
    echo 8 > functions/hid.usb0/report_length # 8-byte reports
    echo 1 > functions/hid.usb0/subclass
    echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 > functions/hid.usb0/report_desc
    
    # Create configuration
    mkdir configs/c.1
    mkdir configs/c.1/strings/0x409
    
    echo 0x80 > configs/c.1/bmAttributes
    echo 200 > configs/c.1/MaxPower # 200 mA
    echo "Example configuration" > configs/c.1/strings/0x409/configuration
    
    # Link HID function to configuration
    ln -s functions/hid.usb0 configs/c.1
    
    #Sleep for 10 seconds
    sleep 10
    
    # Enable gadget
    ls /sys/class/udc > UDC