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

Tracking issue for input handler debugging #962

Open
Koston-0xDEADBEEF opened this issue Feb 1, 2025 · 5 comments
Open

Tracking issue for input handler debugging #962

Koston-0xDEADBEEF opened this issue Feb 1, 2025 · 5 comments

Comments

@Koston-0xDEADBEEF
Copy link
Contributor

Koston-0xDEADBEEF commented Feb 1, 2025

Over the past week or so, I've been trying to learn how controller inputs are handled. Mainly digging into input.cpp, to the bother and amusement of @birdybro (thanks for help!). In the process I've come across multiple issues, so I'm creating this issue for tracking the efforts.

Related issues:
MiSTer-devel/ao486_MiSTer#181 (Analog joystick intermittent loss of inputs)
MiSTer-devel/ao486_MiSTer#127 (Joystick doesn't handle diagonal directions)
#723 (Feature request for ability to map Z axis/throttle)

Progress so far:

As part of debugging ao486 issue #127, I've used an iBuffalo gamepad for testing (0583:2060 Padix Co., Ltd (Rockfire) USB,2-axis 8-button gamepad). Existing button mapping was causing the problem with diagonals, but a more disturbing problem came up while looking into it. This gamepad is flooding the input event device node with bogus inputs, and this only happens on the MiSTer. To isolate the problem, I wrote a tiny test program:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/poll.h>
#include <linux/input.h>
#include <time.h>

int main(int argc, char *argv[]) {
    struct pollfd pfd[1];
    uint32_t timeout = 200;
    struct input_event ev;

    if (argc != 2) exit(2);

    pfd[0].fd = open(argv[1], O_RDWR | O_CLOEXEC);
    pfd[0].events = POLLIN;

    while (1) {
        int ret = poll(pfd, 1, timeout);
        if (ret < 0) exit(0);
        if (!ret) continue;

        memset(&ev, 0, sizeof(ev));
        read(pfd[0].fd, &ev, sizeof(ev));
        printf("time: %d.%d type: 0x%x code: 0x%x value: 0x%x\n",
                ev.time.tv_sec, ev.time.tv_usec, ev.type, ev.code, ev.value);
    }
}

Sample output for the iBuffalo event device:

time: 1738417235.276110 type: 0x3 code: 0x0 value: 0x80
time: 1738417235.276110 type: 0x0 code: 0x0 value: 0x0
time: 1738417235.277115 type: 0x3 code: 0x1 value: 0x7f
time: 1738417235.277115 type: 0x0 code: 0x0 value: 0x0
time: 1738417235.280107 type: 0x3 code: 0x0 value: 0x7f
time: 1738417235.280107 type: 0x0 code: 0x0 value: 0x0
time: 1738417235.281117 type: 0x3 code: 0x1 value: 0x80
time: 1738417235.281117 type: 0x0 code: 0x0 value: 0x0
time: 1738417235.284106 type: 0x3 code: 0x0 value: 0x80
time: 1738417235.284106 type: 0x0 code: 0x0 value: 0x0
time: 1738417235.288115 type: 0x3 code: 0x0 value: 0x7f

This looks like jitter from an analog joystick, and most of it can be eliminated by defining a fuzz value for the device:
evdev-joystick --e /dev/input/by-id/usb-0583_USB_2-axis_8-button_gamepad-event-joystick --f 4

I suspect this is a problem caused by the controller and some workaround in the input driver on my test laptop (Linux 6.1) is hiding it, but the kernel on MiSTer (Linux 5.15.1) doesn't have it. Or, it's just another Linux bug. Whatever it is, having the MiSTer input handler deal with a flood of bogus inputs is a headache for both debugging the input handler and the handler itself. I'll try to overcome my aversion for reading/debugging Linux sources and find out what's going on.

Beyond that, it looks like I need to learn at least basics of HDL coding in order to understand how inputs are handled on the core side. ao486 specifically has some kind of automated switching between analog axis and digital d-pad modes, but the function and purpose of it is unclear.

@Koston-0xDEADBEEF
Copy link
Contributor Author

Koston-0xDEADBEEF commented Feb 1, 2025

As addendum, here's an example gdb(1) script for automated monitoring of X/Y analog axis input changes of a specific device. Maintaining axis status in the script was needed to filter out a lot of noise (which shouldn't exist in the first place).

set pagination off
set logging file gdb.output
set logging on

set $lx = 0
set $ly = 0
set $rx = 0
set $ry = 0

# user_io_l_analog_joystick()
break input.cpp:2196 if input[dev].pid == 8288 && x != $lx
    commands
    set $lx = x
    p/x y << 8 | x
    continue
end

break input.cpp:2196 if input[dev].pid == 8288 && y != $ly
    commands
    set $ly = y
    p/x y << 8 | x
    continue
end

# user_io_r_analog_joystick()
break input.cpp:2200 if input[dev].pid == 8288 && x != $rx
    commands
    set $rx = x
    p/x y << 8 | x
    continue
end

break input.cpp:2200 if input[dev].pid == 8288 && y != $ry
    commands
    set $ry = y
    p/x y << 8 | x
    continue
end

continue

Usage: Compile MiSTer with DEBUG=1 make, copy source tree onto the device and run gdb:

gdb -p $(pidof MiSTer) -iex "directory /path/to/Main_MiSTer" --command /path/to/script.gdb

@Koston-0xDEADBEEF
Copy link
Contributor Author

Another observation: A joystick configuration "2 buttons / 2 joysticks / joy 1 enabled / joy 2 disabled" causes ao486 core to slow down. This is observable by starting TIE Fighter with aforementioned configuration, then during intro music switch "2 joysticks" to "2 sticks" and the music tempo goes up considerably.

@sorgelig
Copy link
Member

sorgelig commented Feb 3, 2025

Just use a better gamepad like DualShock 4, DualSense, XBox One..

@Koston-0xDEADBEEF
Copy link
Contributor Author

Just use a better gamepad like DualShock 4, DualSense, XBox One..

Most issues mentioned above aren't controller specific. The one that is - garbage data in USB traffic - is now narrowed down to either a misbehaving device, or, what is starting to seem much more likely, a bug in the USB host controller driver (dwc2).

@sorgelig
Copy link
Member

sorgelig commented Feb 4, 2025

Spamming input devices is known issue for long time already, especially if such joysticks have accelerometer.

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

No branches or pull requests

2 participants