External power supply for USB to Gamecube adapter (Teensy 3.6)

Status
Not open for further replies.
For my first project, I am building an adapter to use a USB game controller (a Switch Pro Controller in this case) with a Gamecube console.
I got everything working using the USBHost_t36 library and with the Teensy connected to my laptop.

Now, since this adapter is meant to be used on the go, I would like to use the Gamecube cable to power the Teensy from the console instead of my laptop USB port.

The Gamecube console provides these pins:
- 3.3v data (used to communicate with the console both ways)
- 3.3v GND
- 3.3v power
- 5v GND
- 5v power

I am already using the 3.3v data and 3.3v GND pins to communicate with the console.

teensy-gc-procon.jpg

Here come the newbie questions! :D
1) Are the pins provided by the console enough to power the Teensy 3.6 (96Mhz) + USB host port/guest device?
2) Is it safe for me to connect the 5v pin to Vin and 5v GND to the Teensy, even though I already have the 3.3v data and 3.3v GND connected?
3) I read that it is not safe to have both USB and external power at the same time, how can I work around this on the Teensy 3.6?

Thank you for reading and for your help!
 
We can't answer #1, since we have no idea how much power the gamecube provides (or if you've hooked up anything else to the Teensy). It likely has enough power, but until you test it out, you won't know.

(Note, I am a software guy, if somebody answers with more EE grounding, believe them and not me).

Yes, you can connect the 5v to VIN and ground to ground. Note, use the regular ground pins (such as the pin next to pin 0), and not the analog ground pin (between VIN and 3.3v).

The way you prevent using both USB and external power is to cut the solder pad underneath the Teensy so there is no connection between the USB power and VIN. See the back of the card that came with your 3.6 for the location of this pad. Here is an old post about doing this:

If you cut connection between VIN and VUSB, when you program your Teensy, you will need to supply 5v power to VIN. One way to do this is to solder a jumper wire (or female header) to the inner hole for VIN, and then connect VIN to VUSB if you are programming the Teensy and don't have Gamecube adapter attached and turned on.

Alternatively, you can just disconnect the Gamecube when you program the Teensy. After the program has been loaded, unplug the USB cable and plug in the Gamecube. But this requires you to not use both power systems at the same time.
 
Thank you for the thoughtful and useful reply Michael! I'm also from a software background, trying to take my electronics skills to the next level :p

I tried connecting the 5v + GND from the Gamecube console to Vin and GND and the Teensy is booting up.
Using a logic analyzer, I can see that it does successfully communicate with the console.

However, it does not seem to be communicating with the USB controller, I'm guessing because the port is considered "inactive".
This causes the Teensy to send a "neutral" controller state to the console regardless of what buttons I press.
Using a multimeter, it seems that the "5v" pin actually provides ~4.5v, not sure if that matters.

1) At this point, it seems impossible to power the Teensy AND the controller from the Gamecube cable, or am I missing something?

2) The USB controller does however have a battery, and it would be fine to just use the USB cable for data communication.
Is there a way to "trick" the USB host module to turn on and communicate with the controller, without providing power?
 
Hello,

I'm stuck in a similar project but on the software part.

In fact, i try to communicate with the console and i wonder if your work was based on some existing library or example code i could use too or if you had develop your own low level protocol ?

Right now i'm completely stuck regarding the few projects i've found on the web (lot of contradictory and partial intel) so, here i am, throwing a bottle to the sea...:)

Thanks!
 
Hi feistyfawn!

Are you also trying to talk to a GameCube?
To talk to the USB controller, I simply used USBHost_t36, subclassed USBDriver and called USBHost::driver_ready_for_device().
To talk to the GameCube, I implemented the protocol myself using a logic analyzer to make sure the timings were correct (as described at https://web.archive.org/web/2020062...co.uk/crema/hardware/gamecube/gc-control.html). You'll have to use some assembly and adapt your code to the frequency of your CPU.

I don't have access to my setup right now, but if you want to send over some code, I can look at it.
 
Hi feistyfawn!

Are you also trying to talk to a GameCube?
To talk to the USB controller, I simply used USBHost_t36, subclassed USBDriver and called USBHost::driver_ready_for_device().

Hi, it's a good surprise to read you :D
This part (USB controller to Teensy) is already done and indeed i used the same approach. It was not difficult to do since this is well documented and examples are provided.


To talk to the GameCube, I implemented the protocol myself using a logic analyzer to make sure the timings were correct (as described at https://web.archive.org/web/2020062...co.uk/crema/hardware/gamecube/gc-control.html). You'll have to use some assembly and adapt your code to the frequency of your CPU.

I don't have access to my setup right now, but if you want to send over some code, I can look at it.

Ok. This is the part where i'm stuck.
First the good part : For now i'm able to generate the bytes needed with the required timing using bitbanging. It works fine, just for testing i have sent a probe byte (0x00) to a GC controller and it respond with the correct 3 bytes (0x09 0x00 0x03).
So the "sending bytes" part is ok for me.

But, here is where i'm stuck :
1) What is the method to read asyncronous bytes ? I don't know how to handle that at all.
2) Since the data line is bidirectionnal, do you set the digital pin from input to output each time or are you using an other hardware configuration for this pin (related to RX2 pin maybe) ?

Thank you ;)
 
Oh, I guess I did bitbanging too, I didn't know there was a term for it, or that a piece of hardware could do the job for me :p (when you have a hammer...)

To interact with the console, I attached an interrupt on LOW on the pin connected to the data line of the GC controller cable, where the console will poll every so often, using attachInterrupt. The interrupt is set to trigger on LOW, because I remember using a pull-up resistor, but I can't verify since I don't have access to my prototype at the moment.

When the interrupt triggers, I read the first byte, bit by bit essentially doing the opposite of the "sending bytes" part.
The first byte determines the command the GameCube console is sending you, I found some code on GitHub that has the different commands here: https://github.com/NicoHood/Nintendo/blob/master/src/Gamecube.c#L121.

Depending on the command, I read more bytes (0x40 comes with 2 more bytes iirc).
I then switch the pin to output mode, send the response bytes using bitbanging and switch the pin back to input mode to be ready for the next interrupt.

Let me know how it goes :)
Also if you happen to solve the power supply issue I had originally, I'd be happy to know how you did :p
 
Oh, I guess I did bitbanging too, I didn't know there was a term for it, or that a piece of hardware could do the job for me :p (when you have a hammer...)

To interact with the console, I attached an interrupt on LOW on the pin connected to the data line of the GC controller cable, where the console will poll every so often, using attachInterrupt. The interrupt is set to trigger on LOW, because I remember using a pull-up resistor, but I can't verify since I don't have access to my prototype at the moment.

When the interrupt triggers, I read the first byte, bit by bit essentially doing the opposite of the "sending bytes" part.
The first byte determines the command the GameCube console is sending you, I found some code on GitHub that has the different commands here: https://github.com/NicoHood/Nintendo/blob/master/src/Gamecube.c#L121.

Depending on the command, I read more bytes (0x40 comes with 2 more bytes iirc).
I then switch the pin to output mode, send the response bytes using bitbanging and switch the pin back to input mode to be ready for the next interrupt.

Ok, so you are using digital pin as input with interrupt. Good. But i misunderstand something : you use interrupt only for detecting a byte is comming or to read each bit as well ?
Oh, and you say looking for LOW level to start reading the bytes. Why not falling edge (if there is a difference) ?


Let me know how it goes :)
Also if you happen to solve the power supply issue I had originally, I'd be happy to know how you did :p

Of course, no problem !;)
 
I use the interrupt only to know when it's time to read a command. I then actively read the command bit by bit (using timings described here).

Regarding falling or LOW, I think you can use both. My code worked for both Due and T36, and I think Due had a weird glitch with falling, so LOW was more reliable.
 
Status
Not open for further replies.
Back
Top