[SOLVED] PS1 controllers random input
I rewrote large portions of the driver to separate the command pins and join the data pin. I also implemented the acknowledge pin. However the problem still happens. I switched controllers just for fun. Same issue there as well. Now with the acknowledge pin implemented though, I can see huge timing problems under the hood. The controller goes in and out when the system is stressed. Very curious. I do wonder if these GPIO's just aren't reacting as quickly to the commands as the driver expects.
After everything, I started tinkering with the clock phase length. Raising it caused the issue to disappear.
My theory is that, under load, the driver's timings start to decrease, making it wait for too short of a time between inputs.
Now that I've implemented the acknowledge line, it should be fully possible for the driver to support auto detecting when a controller is plugged in or unplugged. This way, any inputs are cleaned up if a USB controller is plugged in.
Auto-detection on GPIO would be perfect! But I don't understand the last sentence... that means if You plug in an USB controller, the GPIO controllers will be disabled, or?
@Jofo the idea is that, the driver doesn't create any input devices if nothing is plugged in. That way, emulators don't get confused if nothing is plugged into the controller ports. I don't know if it helps anything, it was just a thought.
That is a great idea! But I guess it wont be so easy, because there are many types of controllers that can be hooked on the GPIO.
@Jofo I was really just talking about the PSX support, I can't speak off the top of my head about how "smart" other controller buses are.
Anyway, I've got a bit more tinkering to do, but from what I can tell, my problem is fixed. I played Star Fox for SNES for like 10 minutes without any random button pushes. I don't think I'll bother putting this fix anywhere since not many people seem to be using it.
Well I am definitelly interested in the fix
@Jofo I took some time away from the playstations to finish my Sega Genesis project, so I put this down for a minute. I've not forgotten about this, though.
Today I found a thread stating that the delay function the driver relies on to do its talking to the controllers, is heavily influenced by CPU frequency scaling, which can absolutely cause these issues. Do you still have your project? Can you check which CPU frequency scaling governor you are using?
I'm going back to the drawing board to try and see if I can get the best of both worlds - accurate delays while leaving the CPU frequency scaling active. I am going to look into tapping into the Pi's on board timer to guarantee microsecond-level timing
I still have not build the adapter, getting the parts now, but I am willing to help.
How do I check the governor?
It requires a library to read it, don't even worry about the governor.
I actually played with my CPU governor to see what would happen. I even set it to performance. I was actually surprised to see that I got almost the same results. I used the cpufrequtils library to set it.
The one bit of good news, though - I was able to find the "best" delay value for the clock. I found that if I turned it really high, the pad in digital mode worked great, but in analog mode it was almost non-functioning.
So at this point, I have it working, but I don't know how to get the fix to you. I can try to walk you through the process of editing the C file with the new delay value, but it will require re-compiling. I don't know enough about Linux to try and get you a new .deb file.
BTW does the driver have any GIT/SVN repository? Maybe instead of sending me the changes You can commit it to official repository...
Another thing mentioned f.e. here, section 4.4:
Wouldn't the delay fix this issue?
I still don't have the adaptor built, so cannot test, hopefully this/next week
@Jofo Try it and see. I didn't even know about the delay. I never even found that particular blog post in my searching, it may have saved me effort early on. The documentation on this driver is just plain awful, and the support on the forums is clearly non existent.
I'm done with my PSX projects and have moved on to my PSone projects. Funny enough, the PSone has a different controller pinout - the ATT line is unique for each controller and all other wires are combined. So I had to change the driver so that I could re use the PSone board on those and save myself some hassle with making my own PCB, since unfortunately, the ports use the PSone board for clearance.
My PSone projects require hot plugging of the controllers and there's just too many hiccups in the communication on the Pi to try and salvage anything from it. So I've moved my controller communication logic into a small microcontroller and am using I2C to communicate with the Pi. I want to add rumble support down the line anyway, so I'm just going to roll my own uinput driver to send the I2C messages. Thus I'm not bothering to mess with the gamecon driver anymore.
So rumble is not supported in the GPIO driver? And where can I download source code for the GPIO driver?
@Katemonster I've found the source code for the driver, can You please send me Your edited version? Thanks.
@Jofo I'm not at my PC but if you still want it I can send it. I have the original driver (without my changes to the wiring) and my version of the driver. Before we go messing with your driver though, are you actually having problems?
I have created a rumble-capable driver, requiring some re-wire, but I am having difficulties with random start-selects, although I've reduced clock quite a lot, now at 8us and "so far so good" - testing it.
When I spoke to my colleagues, who design boards & stuff, they said it's almost impossible to resolve it without a dedicated chip. There will always be a possibility of an error, because f.e. the udelay may get interrupted, the whole driver re-scheduled, etc.. so what we try to do is to reduce the error to an absolutely minimal rate.
Katemonster last edited by Katemonster
Took me a minute to read through your thread. I will talk about where I'm at currently.
My setup involves a 4.6k ohm pull-up resistor. I've changed the wiring from the original gamecon driver in order to match the wiring schematic of the PSone. In short, DATA, CMD, CLOCK, and ACK are all wired together, but ATT (this line actually wakes up the desired controller) is separate. Sounds like you've gotten by without it, but I did a test recently where I took the original driver and applied "filtering" to the select button inputs, and I got random pushes of the start button. I'm guessing the behavior is 100% like what you're experiencing.
This is very promising though! Good work on your driver, I'm mostly glad to hear that somebody else had luck with it. I admit, I lost a lot of faith when this thread mostly got crickets.
BTW, to get rid of random button pushes (in my case, the select button, constantly), I added a "filtering" mechanism, where I kept track of the button "history" of the select button. Only if I've seen the button pressed for more than 5 cycles (~100 ms or so) do I send the input to the GUI. Doing this made my issues disappear entirely. I'm very sorry, I keep happening to check this post when I'm away from my PC. I will try very hard to post both versions of the driver when I get home, the one with the original wiring, and the one with the updated wiring.
Your colleague is absolutely correct, however, about using a dedicated microcontroller due to timing changes. During many instances, I was able to leave the controller sitting on the desk without experiencing random inputs, however, the moment I entered a game (a.k.a. added CPU load) the random inputs started. That's why I ended up resorting to my "filtering".
My latest scheme involves playing with the Intel NUC, and I wrote a PSX reader in Arduino and am using it to communicate with the NUC via USB serial. I wrote the NUC-side driver using C++ and UInput, and only got it working last night, so I can't speak on random inputs quite yet, but just looking at the bus in a serial reader, it seems extremely reliable. I'm not 100% ready to post this one yet, since it's still very experimental, but so far, very promising. Technically, the same code should compile on the Pi. I just need to minimize the CPU load. I'm jealous you were able to figure out rumble, though - I'm glad somebody else cares about rumble thumbs up
Katemonster last edited by Katemonster
OK, I'll begin posting my files that I am working with.
First, my version of gamecon_gpio_rpi
The wiring I've spoken briefly about, but here goes, PSX on the left, Pi on the right:
Data(all) - GPIO14
Command(all) - GPIO15
Clock(all) - GPIO18
Acknowledge(all) - GPIO23
Attention/Select(Player 1) - GPIO0
Attention/Select(Player 2) - GPIO1
Attention/Select(Player 3) - GPIO4
Attention/Select(Player 4) - GPIO7
Attention/Select(Player 5) - GPIO2
Attention/Select(Player 6) - GPIO3
I won't say it's perfect, but I found it very reliable in the tests I did. I use a PSX_DELAY of 5, by the way. Also of note, since it should be relatively easy to copy paste into your code, is my "filtering". Without walking you through in detail, if you look at all references of gc_psx_select_state and GC_PSX_SELECT_PROTECT , hopefully it will be clear. Otherwise, ask! :)
Next is my NUC stuff, for anyone curious. I will say, one advantage the Arduino has over the Pi, is that the internal pull-up resistors seem to work well with the PSX input lines. I do not use external pull-up resistors.
psx bus reader INO file
project folder of NUC-side code
The project borrowed a lot from xboxdrv. I don't know how I would have figured out uinput without their example. I already was able to make the controllers hot-pluggable, the driver detects when one has been plugged in or removed. I'll surely be adding rumble support to my NUC based on your code, Jofo. :) I'll post it when it's done.
Thanks! I will look into it...
EDIT: implemented in my driver, testing...
@Jofo Have you had time to test out my filtering?