A USB Host xinput driver I use for a few of my personal projects.
- Add
CFG_TUH_XINPUT=1
in yourtusb_config.h
to enable. Where the number should be set to how many XINPUT controllers you want to support. - Increase
CFG_TUH_ENUMERATION_BUFSIZE
if using the Xbox 360 wireless receiver. It needs to be > 321 bytes.
Implement these functions in your application code. Example code provided:
#include "xinput_host.h"
//Since https://github.com/hathach/tinyusb/pull/2222, we can add in custom vendor drivers easily
usbh_class_driver_t const* usbh_app_driver_get_cb(uint8_t* driver_count){
*driver_count = 1;
return &usbh_xinput_driver;
}
void tuh_xinput_report_received_cb(uint8_t dev_addr, uint8_t instance, xinputh_interface_t const* xid_itf, uint16_t len)
{
const xinput_gamepad_t *p = &xid_itf->pad;
const char* type_str;
if (xid_itf->last_xfer_result == XFER_RESULT_SUCCESS)
{
switch (xid_itf->type)
{
case 1: type_str = "Xbox One"; break;
case 2: type_str = "Xbox 360 Wireless"; break;
case 3: type_str = "Xbox 360 Wired"; break;
case 4: type_str = "Xbox OG"; break;
default: type_str = "Unknown";
}
if (xid_itf->connected && xid_itf->new_pad_data)
{
TU_LOG1("[%02x, %02x], Type: %s, Buttons %04x, LT: %02x RT: %02x, LX: %d, LY: %d, RX: %d, RY: %d\n",
dev_addr, instance, type_str, p->wButtons, p->bLeftTrigger, p->bRightTrigger, p->sThumbLX, p->sThumbLY, p->sThumbRX, p->sThumbRY);
//How to check specific buttons
if (p->wButtons & XINPUT_GAMEPAD_A) TU_LOG1("You are pressing A\n");
}
}
tuh_xinput_receive_report(dev_addr, instance);
}
void tuh_xinput_mount_cb(uint8_t dev_addr, uint8_t instance, const xinputh_interface_t *xinput_itf)
{
TU_LOG1("XINPUT MOUNTED %02x %d\n", dev_addr, instance);
// If this is a Xbox 360 Wireless controller we need to wait for a connection packet
// on the in pipe before setting LEDs etc. So just start getting data until a controller is connected.
if (xinput_itf->type == XBOX360_WIRELESS && xinput_itf->connected == false)
{
tuh_xinput_receive_report(dev_addr, instance);
return;
}
tuh_xinput_set_led(dev_addr, instance, 0, true);
tuh_xinput_set_led(dev_addr, instance, 1, true);
tuh_xinput_set_rumble(dev_addr, instance, 0, 0, true);
tuh_xinput_receive_report(dev_addr, instance);
}
void tuh_xinput_umount_cb(uint8_t dev_addr, uint8_t instance)
{
TU_LOG1("XINPUT UNMOUNTED %02x %d\n", dev_addr, instance);
}
Easily link this library with CMake by adding this repo as a git submodule:
git submodule add https://github.com/Ryzee119/tusb_xinput.git src/lib/tusb_xinput
git submodule init
git submodule update
And then adding the following to your project's CMakeLists.txt
config:
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/lib/tusb_xinput xinput_host)
target_link_libraries(you_project_name PRIVATE
...
xinput_host
)