I have a GPIO from a Raspberry PI connected to a Nintendo 64 system like so:
From what I've gathered and observed, the data line on the N64 system is an open-collector output. The line is tied high when data is not being transmitted and pulled low to transmit.
The PI supports pull up/down configurations for the GPIO pins, but I don't see anything about an open-collector configuration.
With my current setup, I am able to read data from the N64 with the PI. However, I'm completely stuck on how to pull the data line low in a non-destructive manner using the GPIO pin, and also read from the same pin.
Is this something I can accomplish without additional hardware? Or do I need to add something like a transistor that I can switch with the PI to connect the data line to ground? If I do that, how will I read data?
As you can see, I know just enough to thoroughly confuse myself, but not enough to solve the problem.
Thanks for your help!
Best Answer
Assuming the Raspberry Pi is just a consumer of data its GPIO would be configured as an input, and whether or not you enable a pull-up resistor would depend on if that's built into the controller or not. I can't think of a reason why the Raspberry Pi would ever actively drive the data line. I would guess you need to enable the pull-up on the Raspberry Pi, because otherwise what's the point of having an open collector interface on the controller. You might need to use an external pull-up resistor if the internal pull-up is too weak; the tutorial I reference below suggests 2.2k Ohms, whereas the internal pull-ups on the Pi are likely > 30k.
I wonder whether you're actually going to be able to get sufficiently frequent / deterministic sampling of the signal on the Raspberry Pi by polling the GPIO though, in order to decode the (presumably) serial data coming from the controller. I'm not familiar with the N64 controller protocol, so it's hard to say.
I found this reference on the internet, which might be helpful to you:
Looks like a serial Pulse Width Modulation encoding. I'm skeptical that one can decode this with a Raspberry Pi easily. It would, on the other hand, be trivial to decode with a microcontroller, e.g. using pin change interrupts and/or hardware timers / input capture interrupts.
Update
Seeing as it is a bi-directional bus, you should indeed never set the GPIO to an output-HIGH. When you want the output to be HIGH, you just st it to an input with pull-up enabled (or no pull-up maybe). When you want to output LOW, set the GPIO to an output low. Again though, I doubt you can get the timing right with a Pi given the O/S in the way.