Overview
GamecubeControllerInput enables reading analog stick and button data from a Nintendo GameCube controller using the Joybus protocol. This provides authentic GameCube controller input with analog sticks and analog shoulder triggers.
Class Declaration
Constructor
GPIO pin number for the GameCube controller data line. This single pin handles bidirectional communication using the Joybus protocol.
Polling rate in Hz (polls per second). Common values:
125- Standard polling rate (8ms intervals)250- Higher responsiveness500- Very high responsiveness1000- Maximum responsiveness
PIO hardware block to use (
pio0 or pio1). The RP2040 has two independent PIO blocks, each with 4 state machines. Use pio1 if pio0 is already in use by other peripherals.PIO state machine number to use (0-3). Set to
-1 for automatic allocation of an available state machine. Manual selection is useful when managing multiple PIO programs.PIO instruction memory offset for loading the Joybus program. Set to
-1 for automatic allocation. Manual control is useful when coordinating multiple PIO programs to avoid memory conflicts.In most cases, use the default values for
pio, sm, and offset to let the firmware automatically manage PIO resources.Methods
ScanSpeed()
ReturnsInputScanSpeed::SLOW, indicating this input source is polled according to its configured polling rate.
Always returns
InputScanSpeed::SLOWUpdateInputs()
Attempts to poll the GameCube controller and updates the input state if new data is received.Reference to the
InputState structure to update with controller data.Input State Fields Updated
When a GameCube controller responds to the poll:The GameCube controller data is mapped to the same fields as Nunchuk input for compatibility with existing game modes. The Z field represents the L shoulder trigger digital press.
GetOffset()
Returns the PIO instruction memory offset used by this input source.The PIO instruction memory offset where the Joybus protocol program is loaded.
Configuration Example
Basic GameCube Controller Input
config.cpp
High-Performance Configuration
config.cpp
Combining with Button Inputs
config.cpp
Using Alternative PIO Block
config.cpp
Hardware Connection
GameCube Controller Cable Pinout
GameCube controllers use a proprietary 6-pin connector:| Pin | Color | Signal | Description |
|---|---|---|---|
| 1 | Yellow | 5V | Power supply (not used for input reading) |
| 2 | Red | DATA | Bidirectional data line |
| 3 | Green | GND | Ground |
| 4 | White | GND | Ground |
| 5 | N/C | - | Not connected |
| 6 | Blue | 3.3V | Logic level (connect to 3.3V) |
Minimal Wiring
For reading controller input only (not providing power to the controller):Pull-up Resistor
The data line requires a pull-up resistor:GameCube Controller Data
Analog Stick Mapping
The main control stick provides 8-bit values:- X Axis: Left stick horizontal movement
- Y Axis: Left stick vertical movement
- Range:
-128(minimum) to+127(maximum) - Center: Approximately
0(controller calibration may vary)
GameCube controllers have both a main control stick and a C-stick. Currently, only the main control stick data is exposed through this input source.
Button Mapping
Thenunchuk_z field maps to the GameCube L shoulder trigger digital press:
Full GameCube button support (A, B, X, Y, D-pad, etc.) is available through the communication backend when using GameCube mode. This input source focuses on analog stick reading for hybrid controllers.
PIO Resource Management
Understanding PIO Blocks
The RP2040 has two PIO blocks:- PIO0 and PIO1: Each with 4 state machines (SM0-SM3)
- Instruction Memory: 32 instructions per PIO block (shared)
- 1 state machine
- ~16 instructions of memory
Resource Conflicts
If you see PIO-related errors during compilation or runtime:-
State Machine Exhaustion: All 4 state machines in use
- Solution: Use the other PIO block (
pio1)
- Solution: Use the other PIO block (
-
Instruction Memory Full: No space for the Joybus program
- Solution: Use the other PIO block or manually manage offsets
-
Offset Conflicts: Programs overlap in instruction memory
- Solution: Manually specify offsets to avoid conflicts
Polling Rate Guidelines
| Rate | Interval | Use Case | CPU Impact |
|---|---|---|---|
| 125Hz | 8ms | Standard, matches original GC adapter | Low |
| 250Hz | 4ms | Improved responsiveness | Medium |
| 500Hz | 2ms | High-performance gaming | High |
| 1000Hz | 1ms | Competitive/professional use | Very High |
Higher polling rates provide lower latency but increase CPU usage. For most applications, 125-250Hz provides excellent responsiveness with minimal overhead.
Performance
- Scan Speed:
SLOW- polled at configured rate - Update Rate: 125-1000Hz (configurable)
- Latency: 1-8ms depending on polling rate
- Protocol: Nintendo Joybus (bit-banged via PIO)
- Timing Precision: Sub-microsecond (PIO hardware timing)
Platform Requirements
Not Available On:
- Arduino (AVR) - No PIO hardware
- STM32 - Different architecture
- ESP32 - Incompatible peripheral set
Troubleshooting
Controller Not Detected
Symptoms:nunchuk_connected remains false
Solutions:
- Verify data pin connection (Red wire)
- Check ground connection (Green/White wires)
- Confirm 3.3V connection on Blue wire
- Test with a known-good GameCube controller
- Verify pull-up resistor on data line
Erratic or Stuck Values
Symptoms: Stick positions freeze or jump randomly Solutions:- Check for loose connections
- Verify polling rate isn’t too high for your setup
- Test with lower polling rate (125Hz)
- Check for electrical interference from nearby wires
PIO Initialization Failure
Symptoms: Firmware won’t start or crashes on init Solutions:- Try different PIO block (
pio1instead ofpio0) - Set
sm = -1to auto-allocate state machine - Set
offset = -1to auto-allocate memory - Check for conflicts with other PIO-based peripherals
High CPU Usage
Symptoms: Other tasks running slowly Solutions:- Reduce polling rate to 125-250Hz
- Use second core for input scanning (see Pico dual-core patterns)
- Profile your firmware to identify bottlenecks
Advanced Usage
Checking PIO Allocation
Dual Controller Setup
Multiple GameCube controllers require separate PIO blocks or careful state machine management.
See Also
- NunchukInput - Alternative analog input source
- GamecubeBackend - GameCube communication backend
- GpioButtonInput - Digital button inputs
- Input Sources - Overview of all input source types
- PIO Programming - RP2040 PIO documentation
