Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pico: HID input #769

Merged
merged 5 commits into from
Apr 27, 2023
Merged
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
14 changes: 13 additions & 1 deletion 32blit-pico/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ target_sources(BlitHalPico INTERFACE
${CMAKE_CURRENT_LIST_DIR}/main.cpp
${CMAKE_CURRENT_LIST_DIR}/storage.cpp
${CMAKE_CURRENT_LIST_DIR}/st7789.cpp
${CMAKE_CURRENT_LIST_DIR}/usb.cpp
${CMAKE_CURRENT_LIST_DIR}/usb_descriptors.c
)

Expand Down Expand Up @@ -81,6 +80,9 @@ endif()
if(NOT BLIT_INPUT_DRIVER)
set(BLIT_INPUT_DRIVER "none")
endif()
if(NOT BLIT_USB_DRIVER)
set(BLIT_USB_DRIVER "device")
endif()

# driver dependencies
if(BLIT_AUDIO_DRIVER STREQUAL "i2s")
Expand All @@ -99,6 +101,15 @@ elseif(BLIT_DISPLAY_DRIVER STREQUAL "st7789")
list(APPEND BLIT_BOARD_DEFINITIONS DISPLAY_ST7789) # config defaults use this, also some games are using it for picosystem detection
endif()

if(BLIT_INPUT_DRIVER STREQUAL "usb_hid")
list(APPEND BLIT_BOARD_DEFINITIONS INPUT_USB_HID)
endif()

if(BLIT_USB_DRIVER STREQUAL "host")
list(APPEND BLIT_BOARD_DEFINITIONS USB_HOST)
list(APPEND BLIT_BOARD_LIBRARIES tinyusb_host)
endif()

# late SDK init
# (pico_sdk_init needs to be after importing extras, which we don't know if we'll need until now)
if(BLIT_REQUIRE_PICO_EXTRAS)
Expand All @@ -115,6 +126,7 @@ target_sources(BlitHalPico INTERFACE
${CMAKE_CURRENT_LIST_DIR}/audio_${BLIT_AUDIO_DRIVER}.cpp
${CMAKE_CURRENT_LIST_DIR}/display_${BLIT_DISPLAY_DRIVER}.cpp
${CMAKE_CURRENT_LIST_DIR}/input_${BLIT_INPUT_DRIVER}.cpp
${CMAKE_CURRENT_LIST_DIR}/usb_${BLIT_USB_DRIVER}.cpp
)

if(BLIT_ENABLE_CORE1)
Expand Down
2 changes: 2 additions & 0 deletions 32blit-pico/board/vgaboard/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ set(BLIT_BOARD_DEFINITIONS

blit_driver(audio i2s)
blit_driver(display scanvideo)
blit_driver(input usb_hid)
blit_driver(usb host)
129 changes: 129 additions & 0 deletions 32blit-pico/input_usb_hid.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// GPIO dpad + ABXY
#include "input.hpp"

#include "hardware/gpio.h"

#include "pico/binary_info.h"

#include "class/hid/hid.h"

#include "engine/api_private.hpp"
#include "engine/input.hpp"

// from USB code
extern uint32_t hid_gamepad_id;
extern bool hid_keyboard_detected;
extern uint8_t hid_joystick[2];
extern uint8_t hid_hat;
extern uint32_t hid_buttons;
extern uint8_t hid_keys[6];

struct GamepadMapping {
uint32_t id; // vid:pid
uint8_t a, b, x, y;
uint8_t menu, home, joystick;
};

static const GamepadMapping gamepad_mappings[]{
{0x15320705, 0, 1, 3, 4, 16, 15, 13}, // Razer Raiju Mobile
{0x20D6A711, 2, 1, 3, 0, 8, 12, 10}, // PowerA wired Switch pro controller
{0x00000000, 0, 1, 2, 3, 4, 5, 6} // probably wrong fallback
};

// hat -> dpad
const uint32_t dpad_map[]{
blit::Button::DPAD_UP,
blit::Button::DPAD_UP | blit::Button::DPAD_RIGHT,
blit::Button::DPAD_RIGHT,
blit::Button::DPAD_DOWN | blit::Button::DPAD_RIGHT,
blit::Button::DPAD_DOWN,
blit::Button::DPAD_DOWN | blit::Button::DPAD_LEFT,
blit::Button::DPAD_LEFT,
blit::Button::DPAD_UP | blit::Button::DPAD_LEFT,
0
};

void init_input() {
}

void update_input() {
using namespace blit;

// keyboard
if(hid_keyboard_detected) {
uint32_t new_buttons = 0;

for(int i = 0; i < 6; i++) {
switch(hid_keys[i]) {
case HID_KEY_ARROW_UP:
case HID_KEY_W:
new_buttons |= uint32_t(Button::DPAD_UP);
break;
case HID_KEY_ARROW_DOWN:
case HID_KEY_S:
new_buttons |= uint32_t(Button::DPAD_DOWN);
break;
case HID_KEY_ARROW_LEFT:
case HID_KEY_A:
new_buttons |= uint32_t(Button::DPAD_LEFT);
break;
case HID_KEY_ARROW_RIGHT:
case HID_KEY_D:
new_buttons |= uint32_t(Button::DPAD_RIGHT);
break;

case HID_KEY_Z:
case HID_KEY_U:
new_buttons |= uint32_t(Button::A);
break;
case HID_KEY_X:
case HID_KEY_I:
new_buttons |= uint32_t(Button::B);
break;
case HID_KEY_C:
case HID_KEY_O:
new_buttons |= uint32_t(Button::X);
break;
case HID_KEY_V:
case HID_KEY_P:
new_buttons |= uint32_t(Button::Y);
break;

case HID_KEY_1:
new_buttons |= uint32_t(Button::HOME);
break;

case HID_KEY_2:
case HID_KEY_ESCAPE:
new_buttons |= uint32_t(Button::MENU);
break;

case HID_KEY_3:
new_buttons |= uint32_t(Button::JOYSTICK);
break;
}
}

api.buttons = new_buttons;
}

if(!hid_gamepad_id)
return;

// gamepad
auto mapping = gamepad_mappings;
while(mapping->id && mapping->id != hid_gamepad_id)
mapping++;

api.buttons = dpad_map[hid_hat > 8 ? 8 : hid_hat]
| (hid_buttons & (1 << mapping->a) ? uint32_t(Button::A) : 0)
| (hid_buttons & (1 << mapping->b) ? uint32_t(Button::B) : 0)
| (hid_buttons & (1 << mapping->x) ? uint32_t(Button::X) : 0)
| (hid_buttons & (1 << mapping->y) ? uint32_t(Button::Y) : 0)
| (hid_buttons & (1 << mapping->menu) ? uint32_t(Button::MENU) : 0)
| (hid_buttons & (1 << mapping->home) ? uint32_t(Button::HOME) : 0)
| (hid_buttons & (1 << mapping->joystick) ? uint32_t(Button::JOYSTICK) : 0);

api.joystick.x = (float(hid_joystick[0]) - 0x80) / 0x80;
api.joystick.y = (float(hid_joystick[1]) - 0x80) / 0x80;
}
36 changes: 36 additions & 0 deletions 32blit-pico/tusb_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,23 @@
#endif

// Device mode with rhport and speed defined by board.mk
#ifdef USB_HOST
#if BOARD_DEVICE_RHPORT_NUM == 0
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | BOARD_DEVICE_RHPORT_SPEED)
#elif BOARD_DEVICE_RHPORT_NUM == 1
#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_HOST | BOARD_DEVICE_RHPORT_SPEED)
#else
#error "Incorrect RHPort configuration"
#endif
#else
#if BOARD_DEVICE_RHPORT_NUM == 0
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED)
#elif BOARD_DEVICE_RHPORT_NUM == 1
#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED)
#else
#error "Incorrect RHPort configuration"
#endif
#endif

// This example doesn't use an RTOS
#ifndef CFG_TUSB_OS
Expand Down Expand Up @@ -91,6 +101,31 @@
// DEVICE CONFIGURATION
//--------------------------------------------------------------------

#ifdef USB_HOST

// Size of buffer to hold descriptors and other data used for enumeration
#define CFG_TUH_ENUMERATION_BUFSIZE 256

#define CFG_TUH_HUB 0
#define CFG_TUH_CDC 0
#ifdef INPUT_USB_HID
#define CFG_TUH_HID 4 // typical keyboard + mouse device can have 3-4 HID interfaces
#else
#define CFG_TUH_HID 0
#endif
#define CFG_TUH_MSC 0
#define CFG_TUH_VENDOR 0

// max device support (excluding hub device)
// 1 hub typically has 4 ports
#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1)

//------------- HID -------------//

#define CFG_TUH_HID_EP_BUFSIZE 64

#else

#ifndef CFG_TUD_ENDPOINT0_SIZE
#define CFG_TUD_ENDPOINT0_SIZE 64
#endif
Expand All @@ -111,6 +146,7 @@

// MSC Buffer size of Device Mass storage
#define CFG_TUD_MSC_EP_BUFSIZE 512
#endif

#ifdef __cplusplus
}
Expand Down
1 change: 1 addition & 0 deletions 32blit-pico/usb.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ void update_usb();

void usb_debug(const char *message);

// TODO: separate multiplayer from usb
bool is_multiplayer_connected();
void set_multiplayer_enabled(bool enabled);
void send_multiplayer_message(const uint8_t *data, uint16_t len);
4 changes: 4 additions & 0 deletions 32blit-pico/usb_descriptors.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

#include "config.h"

#ifndef USB_HOST

/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
* Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
*
Expand Down Expand Up @@ -182,3 +184,5 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)

return _desc_str;
}

#endif
1 change: 0 additions & 1 deletion 32blit-pico/usb.cpp → 32blit-pico/usb_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ static void send_handshake(bool is_reply = false) {
tud_cdc_write_flush();
}


void init_usb() {
tusb_init();
}
Expand Down
Loading