Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/
49 changes: 49 additions & 0 deletions examples/pico-sdk/gcn-controller-target/usb_serial/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
cmake_minimum_required(VERSION 3.20)

set(JOYBUS_BACKEND_RP2XXX TRUE)
set(LIBJOYBUS_ROOT ${CMAKE_CURRENT_LIST_DIR}/../../../..)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

if(WIN32)
set(USERHOME $ENV{USERPROFILE})
else()
set(USERHOME $ENV{HOME})
endif()
set(sdkVersion 2.2.0)
set(toolchainVersion 14_2_Rel1)
set(picotoolVersion 2.2.0-a4)
set(picoVscode ${USERHOME}/.pico-sdk/cmake/pico-vscode.cmake)
if (EXISTS ${picoVscode})
include(${picoVscode})
endif()
include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)

set(PICO_BOARD pico2 CACHE STRING "Board type")

project(usb_serial C CXX ASM)

# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()

add_subdirectory(${LIBJOYBUS_ROOT} ${CMAKE_BINARY_DIR}/_deps/libjoybus-build)

# Add executable. Default name is the project name, version 0.1

add_executable(usb_serial main.c)

pico_enable_stdio_usb(usb_serial 1)
pico_enable_stdio_uart(usb_serial 0)

target_link_libraries(usb_serial pico_stdlib)
pico_add_extra_outputs(usb_serial)

# pull in common dependencies
target_link_libraries(usb_serial pico_stdlib joybus)

# create map/bin/hex/uf2 file etc.
pico_add_extra_outputs(usb_serial)

# add url via pico_set_program_url
21 changes: 21 additions & 0 deletions examples/pico-sdk/gcn-controller-target/usb_serial/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Pico SDK GameCube Controller Target USB Serial Example

Act as a GameCube controller on RP2XXX devices using the Pico SDK using a serial interface. Simulates button presses when an input is sent over a usb serial connection.

## Building

```bash
cmake -B build -DPICO_ENABLE_STDIO_USB=1 -DPICO_ENABLE_STDIO_UART=0 -DPICO_BOARD=pico2 -DPICO_PLATFORM=rp2350 . && cmake --build build
```
or
```bash
cmake -B build -DPICO_ENABLE_STDIO_USB=1 -DPICO_ENABLE_STDIO_UART=0 . && cmake --build build
```

## Flashing

Enter bootloader mode by holding the BOOTSEL button while plugging in the Pico. Then copy the generated `build/usb_serial.uf2` file to the RPI-RP2 drive that appears, or use `picotool`:

```bash
picotool load -f build/usb_serial.uf2
```
67 changes: 67 additions & 0 deletions examples/pico-sdk/gcn-controller-target/usb_serial/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include <stdio.h>
#include "pico/stdlib.h"

#include <joybus/joybus.h>
#include <joybus/backend/rp2xxx.h>

#define SI_DATA_GPIO 12

struct joybus_rp2xxx rp2xxx_bus;
struct joybus *bus = JOYBUS(&rp2xxx_bus);

static struct joybus_gc_controller gc_controller;

int main()
{
stdio_init_all(); // USB serial
sleep_ms(2000); // allow time to connect

// Initialize Joybus
joybus_rp2xxx_init(&rp2xxx_bus, SI_DATA_GPIO, pio0);
joybus_enable(bus);

// Initialize controller target
joybus_gc_controller_init(&gc_controller, JOYBUS_GAMECUBE_CONTROLLER);

// Register the target on the bus
joybus_target_register(bus, JOYBUS_TARGET(&gc_controller));

while (1) {
// Clear previous button state
gc_controller.input.buttons &= ~JOYBUS_GCN_BUTTON_MASK;

// Read USB serial input (non-blocking)
int ch = getchar_timeout_us(0);

if (ch != PICO_ERROR_TIMEOUT) {
if (ch == 'a')
gc_controller.input.buttons |= JOYBUS_GCN_BUTTON_A;
if (ch == 'b')
gc_controller.input.buttons |= JOYBUS_GCN_BUTTON_B;
if (ch == 'x')
gc_controller.input.buttons |= JOYBUS_GCN_BUTTON_X;
if (ch == 'y')
gc_controller.input.buttons |= JOYBUS_GCN_BUTTON_Y;
if (ch == 's')
gc_controller.input.buttons |= JOYBUS_GCN_BUTTON_START;
if (ch == 'z')
gc_controller.input.buttons |= JOYBUS_GCN_BUTTON_Z;
if (ch == 'l')
gc_controller.input.buttons |= JOYBUS_GCN_BUTTON_L;
if (ch == 'r')
gc_controller.input.buttons |= JOYBUS_GCN_BUTTON_R;
if (ch == 'u')
gc_controller.input.buttons |= JOYBUS_GCN_BUTTON_UP;
if (ch == 'd')
gc_controller.input.buttons |= JOYBUS_GCN_BUTTON_DOWN;
if (ch == 'L')
gc_controller.input.buttons |= JOYBUS_GCN_BUTTON_LEFT;
if (ch == 'R')
gc_controller.input.buttons |= JOYBUS_GCN_BUTTON_RIGHT;
}

sleep_ms(10);
}

return 0;
}