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

Fix Joystick HID detection #408

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open

Fix Joystick HID detection #408

wants to merge 14 commits into from

Conversation

dim13
Copy link

@dim13 dim13 commented Jul 4, 2024

Fix detection of Joystick HID on MacOS.

Cleanup mis-configured HID descriptor.

Fix native build on MacOS.

Closes #129

Relates to #152, #348, #401

The magic part was:

DCD_PMA_Config(pdev, HID_IN_EP,USB_SNG_BUF, HID_IN_TX_ADDRESS);

Tested with https://www.geo-fs.com/, AbsoluteRC, Heli-X10 and crrcsim.

Full Speed device @ 1 (0x00100000): .............................................   Composite device: "FS-i6X Joystick"
    Port Information:   0x001a
           Not Captive
           Attached to Root Hub
           External Device
           Connected
           Enabled
    Number Of Endpoints (includes EP0):   
        Total Endpoints for Configuration 1 (current):   2
    Device Descriptor   
        Descriptor Version Number:   0x0200
        Device Class:   0   (Composite)
        Device Subclass:   0
        Device Protocol:   0
        Device MaxPacketSize:   64
        Device VendorID/ProductID:   0x1209/0x4F54   (unknown vendor)
        Device Version Number:   0x0200
        Number of Configurations:   1
        Manufacturer String:   1 "OpenTX"
        Product String:   2 "FS-i6X Joystick"
        Serial Number String:   3 "00000000001B"
    Configuration Descriptor (current config)   
        Length (and contents):   34
            Raw Descriptor (hex)    0000: 09 02 22 00 01 01 00 C0  32 09 04 00 00 01 03 00  
            Raw Descriptor (hex)    0010: 00 00 09 21 11 01 00 01  22 38 00 07 05 81 03 40  
            Raw Descriptor (hex)    0020: 00 07 
        Number of Interfaces:   1
        Configuration Value:   1
        Attributes:   0xC0 (self-powered)
        MaxPower:   100 mA
        Interface #0 - HID   
            Alternate Setting   0
            Number of Endpoints   1
            Interface Class:   3   (HID)
            Interface Subclass;   0
            Interface Protocol:   0
            HID Descriptor   
                Descriptor Version Number:   0x0111
                Country Code:   0
                Descriptor Count:   1
                Descriptor 1   
                    Type:   0x22  (Report Descriptor)
                    Length (and contents):   56
                        Raw Descriptor (hex)    0000: 05 01 09 05 A1 01 A1 00  05 01 09 30 09 31 09 32  
                        Raw Descriptor (hex)    0010: 09 33 09 34 09 35 09 36  09 36 16 00 00 26 FF 07  
                        Raw Descriptor (hex)    0020: 75 10 95 08 81 02 05 09  19 01 29 10 15 00 25 01  
                        Raw Descriptor (hex)    0030: 95 10 75 01 81 02 C0 C0  
                    Parsed Report Descriptor:   
                          Usage Page    (Generic Desktop) 
                          Usage (GamePad)    
                              Collection (Application)    
                                    Collection (Physical)    
                                      Usage Page    (Generic Desktop) 
                                      Usage (X)    
                                      Usage (Y)    
                                      Usage (Z)    
                                      Usage (Rx)    
                                      Usage (Ry)    
                                      Usage (Rz)    
                                      Usage (Slider)    
                                      Usage (Slider)    
                                      Logical Minimum.........    (0)  
                                      Logical Maximum.........    (2047)  
                                      Report Size.............    (16)  
                                      Report Count............    (8)  
                                      Input...................   (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bitfield) 
                                      Usage Page    (Button) 
                                      Usage Minimum...........    (1)  
                                      Usage Maximum...........    (16)  
                                      Logical Minimum.........    (0)  
                                      Logical Maximum.........    (1)  
                                      Report Count............    (16)  
                                      Report Size.............    (1)  
                                      Input...................   (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bitfield) 
                                    End Collection     
                              End Collection     
            Endpoint 0x81 - Interrupt Input   
                Address:   0x81  (IN)
                Attributes:   0x03  (Interrupt)
                Max Packet Size:   64
                Polling Interval:   7 ms

@dim13 dim13 marked this pull request as ready for review July 4, 2024 19:46
@dim13
Copy link
Author

dim13 commented Jul 5, 2024

Test firmware: openi6x-1.11.1-joystick.bin.gz -- confirmed to work on MacOS, Debian 10 and Windows 7.

SHA1 (openi6x-1.11.1-joystick.bin) = b43928371f537b7026863470da6ee12885806aa2

@dim13
Copy link
Author

dim13 commented Jul 5, 2024

In order to build natively on Mac, you'll need

brew install --cask gcc-arm-embedded

instead of

brew install arm-none-eabi-gcc

as it is missing includes.

@yincrash
Copy link

yincrash commented Jul 7, 2024

successfully built the firmware on a mac with sonoma 14.5 and flashed i6x and tested as a joystick successfully using https://hardwaretester.com/gamepad

@ajjjjjjjj
Copy link
Member

Closes #275

@dim13
Copy link
Author

dim13 commented Jul 7, 2024

Raw ADC test firmware:
openx6i-1.11.1-adc-joystick.bin.gz

Reduces number of axels to 6 (4 axes + 2 potentiometers) and buttons number to 8 (the upper half wasn't used anyway):

2024-07-08 00:55:46.460 usbdiagnose[78404:22469311] USB Prober: Error reading USBVendors.txt from the Resources directory
Full Speed device @ 1 (0x01100000): .............................................   Composite device: "FS-i6X Joystick"
    Port Information:   0x001a
           Not Captive
           Attached to Root Hub
           External Device
           Connected
           Enabled
    Number Of Endpoints (includes EP0):
        Total Endpoints for Configuration 1 (current):   2
    Device Descriptor
        Descriptor Version Number:   0x0200
        Device Class:   0   (Composite)
        Device Subclass:   0
        Device Protocol:   0
        Device MaxPacketSize:   64
        Device VendorID/ProductID:   0x1209/0x4F54   (unknown vendor)
        Device Version Number:   0x0200
        Number of Configurations:   1
        Manufacturer String:   1 "OpenTX"
        Product String:   2 "FS-i6X Joystick"
        Serial Number String:   3 "00000000001B"
    Configuration Descriptor (current config)
        Length (and contents):   34
            Raw Descriptor (hex)    0000: 09 02 22 00 01 01 00 C0  32 09 04 00 00 01 03 00
            Raw Descriptor (hex)    0010: 00 00 09 21 11 01 00 01  22 2F 00 07 05 81 03 40
            Raw Descriptor (hex)    0020: 00 07
        Number of Interfaces:   1
        Configuration Value:   1
        Attributes:   0xC0 (self-powered)
        MaxPower:   100 mA
        Interface #0 - HID
            Alternate Setting   0
            Number of Endpoints   1
            Interface Class:   3   (HID)
            Interface Subclass;   0
            Interface Protocol:   0
            HID Descriptor
                Descriptor Version Number:   0x0111
                Country Code:   0
                Descriptor Count:   1
                Descriptor 1
                    Type:   0x22  (Report Descriptor)
                    Length (and contents):   47
                        Raw Descriptor (hex)    0000: 05 01 09 04 A1 01 05 01  09 30 09 31 09 32 09 33
                        Raw Descriptor (hex)    0010: 09 34 09 35 15 81 25 7F  75 08 95 06 81 02 05 09
                        Raw Descriptor (hex)    0020: 19 01 29 08 15 00 25 01  75 01 95 08 81 02 C0
                    Parsed Report Descriptor:
                          Usage Page    (Generic Desktop)
                          Usage (Joystick)
                              Collection (Application)
                                Usage Page    (Generic Desktop)
                                Usage (X)
                                Usage (Y)
                                Usage (Z)
                                Usage (Rx)
                                Usage (Ry)
                                Usage (Rz)
                                Logical Minimum.........    (-127)
                                Logical Maximum.........    (127)
                                Report Size.............    (8)
                                Report Count............    (6)
                                Input...................   (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bitfield)
                                Usage Page    (Button)
                                Usage Minimum...........    (1)
                                Usage Maximum...........    (8)
                                Logical Minimum.........    (0)
                                Logical Maximum.........    (1)
                                Report Size.............    (1)
                                Report Count............    (8)
                                Input...................   (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bitfield)
                              End Collection
            Endpoint 0x81 - Interrupt Input
                Address:   0x81  (IN)
                Attributes:   0x03  (Interrupt)
                Max Packet Size:   64
                Polling Interval:   7 ms
Screenshot 2024-07-08 at 00 58 09

Copy link
Member

@ajjjjjjjj ajjjjjjjj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix!
This issue gave me a lot of headaches.

radio/src/CMakeLists.txt Outdated Show resolved Hide resolved

// test to see if TX buffer is free
#if defined(STM32F0)
if (USBD_HID_SendReport(&USB_Device_dev, 0, 0) == USBD_OK) {
#else
if (USBD_HID_SendReport(&USB_OTG_dev, 0, 0) == USBD_OK) {
#endif
//buttons
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also here - please keep it as in EdgeTX/OpenTX, it keeps this project as close to EdgeTX as possible to backport features and track issues, see:
https://github.com/EdgeTX/edgetx/blob/main/radio/src/targets/common/arm/stm32/usb_driver.cpp

Copy link
Author

@dim13 dim13 Jul 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would argue, that upstream implementation is plain broken and not worth to keep. Even with detection fix it does not work as generally expected. For example it depends on currently chosen model. You get different results with different models.

I would say, that it is would be more expected for it to "just work" as game controller independent from transmitter settings.

However I'm willing to keep old broken implementation in-place and make it configurable instead.

However keep in mind, that buttons are not working at all with old definition.

Copy link
Member

@ajjjjjjjj ajjjjjjjj Jul 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Buttons are not working, or are not set up in model inputs?

radio/src/targets/common/arm/stm32/usbd_hid_joystick.c Outdated Show resolved Hide resolved
@@ -110,7 +110,7 @@ static const uint8_t *USBD_HID_GetCfgDesc (uint8_t speed, uint16_t *length);
__ALIGN_BEGIN static const uint8_t HID_JOYSTICK_ReportDesc[] __ALIGN_END =
{
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x05, // USAGE (Game Pad)
0x09, 0x04, // USAGE (Joystick)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is 0x05 in EdgeTX, I'm not against the change but is there a specific reason to change it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Value from original firmware, IMHO more suitable for the use. Doesn't do much however.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is port of OpenTX/EdgeTX and there is no specific reason to change that, it should stay as it was.

radio/src/targets/common/arm/stm32/usb_driver.cpp Outdated Show resolved Hide resolved
@ajjjjjjjj
Copy link
Member

I finally have tested it on Linux: Crrcsim, jstest-gtk, .
After connecting i see lot of: usb 1-2: input irq status -75 received, no inputs are working no matter the build option: JOYSTICK=OUTPUTS or INPUTS.

Some other thoughts:

  • This change is far beyond fix and modifies how OpenTX has it designed: Why ReportSent and report flags are removed?
  • I have noting against ADC_JOYSTICK feature but not as default build option.
  • Workarounds of previous implementation for JOYSTICK=OUTPUTS are present breaking outputs, but i can fix this in separate PR.
  • I have tested just the "fix" part on master and it worked fine.

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

Successfully merging this pull request may close these issues.

USB Joystick does not work on macOS
3 participants