mirror of
https://github.com/speedypotato/Pico-Game-Controller.git
synced 2026-09-29 10:18:01 +03:00
Merge pull request #4 from speedypotato/feature/pico-sdk_1.2.0_update
Updated functions for pico-sdk 1.2.0, updated ReadMe
This commit is contained in:
@@ -1,18 +1,29 @@
|
||||
# Pico-Game-Controller
|
||||
|
||||
WIP code for a rhythm game controller using a Raspberry Pi Pico. Intended for SDVX but is capable of handling 11 buttons, 11 LEDs, and 2 encoders.
|
||||
WIP code for a rhythm game controller using a Raspberry Pi Pico. Intended for SDVX but is capable of handling 11 buttons, 11 LEDs, and 2 encoders.
|
||||
|
||||
Currently working/fixed:
|
||||
|
||||
- Gamepad mode - untested on EAC - default boot mode
|
||||
- Keyboard & Mouse Mode - limited to 6KRO - hold btn-a to enter kb mode
|
||||
- HID LEDs with Reactive LED fallback - untested
|
||||
- sdvx/iidx spoof - untested on EAC
|
||||
- 1000hz polling
|
||||
- Fix 0-~71% encoder rollover in gamepad mode, uint32 max val isn't divisible evenly by ppr*4 for joystick - thanks friends
|
||||
- Fix 0-~71% encoder rollover in gamepad mode, uint32 max val isn't divisible evenly by ppr\*4 for joystick - thanks friends
|
||||
- Switch and LED pins are now staggered for easier wiring
|
||||
|
||||
TODO:
|
||||
|
||||
- Store last mode in flash memory https://www.raspberrypi.org/forums/viewtopic.php?t=305570
|
||||
- nkro
|
||||
- debounce
|
||||
- split input updating into pi pico's second core?
|
||||
|
||||
How to Use:
|
||||
|
||||
- For basic flashing, see README in build_uf2
|
||||
- Otherwise, setup the C++ environment for the Pi Pico as per https://datasheets.raspberrypi.org/pico/getting-started-with-pico.pdf
|
||||
- Build pico-examples directory once to ensure all the tinyusb and other libraries are there. You might have to move the pico-sdk folder into pico-examples/build for it to play nice.
|
||||
- Move pico-sdk back outside to the same level directory as Pico-Game-Controller.
|
||||
- Open Pico-Game-Controller in VSCode(assuming this is setup for the Pi Pico) and see if everything builds.
|
||||
- Tweakable parameters: Pinout, bindings in pico_game_controller.c, USB device reporting as SDVX/IIDX(con_mode) in usb_descriptors.c
|
||||
|
||||
Binary file not shown.
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Pico SDVX
|
||||
* Pico Game Controller
|
||||
* @author SpeedyPotato
|
||||
*
|
||||
* Based off dev_hid_composite, mdxtinkernick/pico_encoders, and
|
||||
* Based off tinyusb's hid_composite, mdxtinkernick/pico_encoders, and
|
||||
* Drewol/rp2040-gamecon
|
||||
*/
|
||||
|
||||
@@ -343,9 +343,11 @@ int main(void) {
|
||||
// Invoked when received GET_REPORT control request
|
||||
// Application must fill buffer report's content and return its length.
|
||||
// Return zero will cause the stack to STALL request
|
||||
uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type,
|
||||
uint8_t *buffer, uint16_t reqlen) {
|
||||
uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id,
|
||||
hid_report_type_t report_type, uint8_t* buffer,
|
||||
uint16_t reqlen) {
|
||||
// TODO not Implemented
|
||||
(void)itf;
|
||||
(void)report_id;
|
||||
(void)report_type;
|
||||
(void)buffer;
|
||||
@@ -356,8 +358,10 @@ uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type,
|
||||
|
||||
// Invoked when received SET_REPORT control request or
|
||||
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
|
||||
void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type,
|
||||
uint8_t const *buffer, uint16_t bufsize) {
|
||||
void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id,
|
||||
hid_report_type_t report_type, uint8_t const* buffer,
|
||||
uint16_t bufsize) {
|
||||
(void)itf;
|
||||
if (report_id == 2 && report_type == HID_REPORT_TYPE_OUTPUT &&
|
||||
buffer[0] == 2 && bufsize >= sizeof(lights_report)) // light data
|
||||
{
|
||||
|
||||
+27
-8
@@ -34,21 +34,40 @@ extern "C" {
|
||||
// COMMON CONFIGURATION
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// defined by compiler flags for flexibility
|
||||
// defined by board.mk
|
||||
#ifndef CFG_TUSB_MCU
|
||||
#error CFG_TUSB_MCU must be defined
|
||||
#endif
|
||||
|
||||
#if CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || \
|
||||
CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_NUC505 || \
|
||||
CFG_TUSB_MCU == OPT_MCU_CXD56
|
||||
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
|
||||
// RHPort number used for device can be defined by board.mk, default to port 0
|
||||
#ifndef BOARD_DEVICE_RHPORT_NUM
|
||||
#define BOARD_DEVICE_RHPORT_NUM 0
|
||||
#endif
|
||||
|
||||
// RHPort max operational speed can defined by board.mk
|
||||
// Default to Highspeed for MCU with internal HighSpeed PHY (can be port
|
||||
// specific), otherwise FullSpeed
|
||||
#ifndef BOARD_DEVICE_RHPORT_SPEED
|
||||
#if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || \
|
||||
CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_NUC505 || \
|
||||
CFG_TUSB_MCU == OPT_MCU_CXD56)
|
||||
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED
|
||||
#else
|
||||
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
|
||||
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Device mode with rhport and speed defined by board.mk
|
||||
#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
|
||||
|
||||
#ifndef CFG_TUSB_OS
|
||||
#define CFG_TUSB_OS OPT_OS_PICO
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#endif
|
||||
|
||||
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||
@@ -84,7 +103,7 @@ extern "C" {
|
||||
#define CFG_TUD_VENDOR 0
|
||||
|
||||
// HID buffer size Should be sufficient to hold ID (if any) + Data
|
||||
#define CFG_TUD_HID_BUFSIZE 16
|
||||
#define CFG_TUD_HID_EP_BUFSIZE 16
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+18
-14
@@ -48,7 +48,6 @@
|
||||
//--------------------------------------------------------------------+
|
||||
// Device Descriptors
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
tusb_desc_device_t const desc_device = {
|
||||
.bLength = sizeof(tusb_desc_device_t),
|
||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||
@@ -70,8 +69,8 @@ tusb_desc_device_t const desc_device = {
|
||||
|
||||
// Invoked when received GET DEVICE DESCRIPTOR
|
||||
// Application return pointer to descriptor
|
||||
uint8_t const *tud_descriptor_device_cb(void) {
|
||||
return (uint8_t const *)&desc_device;
|
||||
uint8_t const* tud_descriptor_device_cb(void) {
|
||||
return (uint8_t const*)&desc_device;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -87,7 +86,10 @@ uint8_t const desc_hid_report[] = {
|
||||
// Invoked when received GET HID REPORT DESCRIPTOR
|
||||
// Application return pointer to descriptor
|
||||
// Descriptor contents must exist long enough for transfer to complete
|
||||
uint8_t const *tud_hid_descriptor_report_cb(void) { return desc_hid_report; }
|
||||
uint8_t const* tud_hid_descriptor_report_cb(uint8_t itf) {
|
||||
(void)itf;
|
||||
return desc_hid_report;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Configuration Descriptor
|
||||
@@ -105,16 +107,16 @@ uint8_t const desc_configuration[] = {
|
||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN,
|
||||
TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||
|
||||
// Interface number, string index, protocol, report descriptor len, EP In &
|
||||
// Out address, size & polling interval
|
||||
TUD_HID_DESCRIPTOR(ITF_NUM_HID, 0, HID_PROTOCOL_NONE,
|
||||
sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_BUFSIZE,
|
||||
1)};
|
||||
// Interface number, string index, protocol, report descriptor len, EP In
|
||||
// address, size & polling interval
|
||||
TUD_HID_DESCRIPTOR(ITF_NUM_HID, 0, HID_ITF_PROTOCOL_NONE,
|
||||
sizeof(desc_hid_report), EPNUM_HID,
|
||||
CFG_TUD_HID_EP_BUFSIZE, 1)};
|
||||
|
||||
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||
// Application return pointer to descriptor
|
||||
// Descriptor contents must exist long enough for transfer to complete
|
||||
uint8_t const *tud_descriptor_configuration_cb(uint8_t index) {
|
||||
uint8_t const* tud_descriptor_configuration_cb(uint8_t index) {
|
||||
(void)index; // for multiple configurations
|
||||
return desc_configuration;
|
||||
}
|
||||
@@ -127,7 +129,7 @@ uint8_t const *tud_descriptor_configuration_cb(uint8_t index) {
|
||||
#define iidx_prod "beatmania IIDX controller premium model"
|
||||
|
||||
// array of pointer to string descriptors
|
||||
char const *string_desc_arr[] = {
|
||||
char const* string_desc_arr[] = {
|
||||
(const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409)
|
||||
"Konami Amusement", // 1: Manufacturer
|
||||
con_mode ? iidx_prod : sdvx_prod, // 2: Product
|
||||
@@ -139,7 +141,7 @@ static uint16_t _desc_str[32];
|
||||
// Invoked when received GET STRING DESCRIPTOR request
|
||||
// Application return pointer to descriptor, whose contents must exist long
|
||||
// enough for transfer to complete
|
||||
uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
||||
uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
||||
(void)langid;
|
||||
|
||||
uint8_t chr_count;
|
||||
@@ -148,17 +150,19 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
||||
memcpy(&_desc_str[1], string_desc_arr[0], 2);
|
||||
chr_count = 1;
|
||||
} else {
|
||||
// Convert ASCII string into UTF-16
|
||||
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
|
||||
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
|
||||
|
||||
if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])))
|
||||
return NULL;
|
||||
|
||||
const char *str = string_desc_arr[index];
|
||||
const char* str = string_desc_arr[index];
|
||||
|
||||
// Cap at max char
|
||||
chr_count = strlen(str);
|
||||
if (chr_count > 31) chr_count = 31;
|
||||
|
||||
// Convert ASCII string into UTF-16
|
||||
for (uint8_t i = 0; i < chr_count; i++) {
|
||||
_desc_str[1 + i] = str[i];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user