mirror of
https://github.com/speedypotato/Pico-Game-Controller.git
synced 2026-10-01 03:07:55 +03:00
NKRO Added
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
# 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 or IIDX but is capable of handling 11 buttons, 11 LEDs, and 2 encoders.
|
||||
|
||||
Currently working/fixed:
|
||||
|
||||
- Gamepad mode - default boot mode
|
||||
- Keyboard & Mouse Mode - limited to 6KRO - hold btn-a to enter kb mode
|
||||
- NKRO Keyboard & Mouse Mode - hold first button to enter kb mode
|
||||
- HID LEDs with Reactive LED fallback
|
||||
- sdvx/iidx spoof - Tested on EAC
|
||||
- 1000hz polling
|
||||
@@ -16,7 +16,6 @@ Currently working/fixed:
|
||||
TODO:
|
||||
|
||||
- Store last mode in flash memory https://www.raspberrypi.org/forums/viewtopic.php?t=305570
|
||||
- nkro
|
||||
- debounce
|
||||
- ws2812b rgb on second core?
|
||||
- split input updating into pi pico's second core?
|
||||
@@ -29,3 +28,13 @@ How to Use:
|
||||
- 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
|
||||
|
||||
Thanks to:
|
||||
|
||||
- Everyone in the Cons & Stuff Discord for providing near instant support to questions.
|
||||
- https://github.com/hathach/tinyusb/tree/master/examples/device/hid_composite
|
||||
- https://github.com/mdxtinkernick/pico_encoders for encoders which performed better than both interrupts and polling.
|
||||
- My SE buddies who helped come up with a solution for the encoder rollover edge case scenario.
|
||||
- https://github.com/Drewol/rp2040-gamecon for usb gamepad descriptor info.
|
||||
- https://github.com/veroxzik/arduino-konami-spoof for konami spoof usb descriptor info.
|
||||
- https://github.com/veroxzik/roxy-firmware for nkro descriptor and logic info.
|
||||
Binary file not shown.
+12
-23
@@ -1,9 +1,6 @@
|
||||
/*
|
||||
* Pico Game Controller
|
||||
* @author SpeedyPotato
|
||||
*
|
||||
* Based off tinyusb's hid_composite, mdxtinkernick/pico_encoders, and
|
||||
* Drewol/rp2040-gamecon
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -29,7 +26,7 @@
|
||||
// MODIFY KEYBINDS HERE, MAKE SURE LENGTHS MATCH SW_GPIO_SIZE
|
||||
const uint8_t SW_KEYCODE[] = {HID_KEY_D, HID_KEY_F, HID_KEY_J, HID_KEY_K,
|
||||
HID_KEY_C, HID_KEY_M, HID_KEY_A, HID_KEY_B,
|
||||
HID_KEY_1, HID_KEY_C, HID_KEY_D};
|
||||
HID_KEY_1, HID_KEY_E, HID_KEY_G};
|
||||
const uint8_t SW_GPIO[] = {
|
||||
4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 27,
|
||||
};
|
||||
@@ -157,31 +154,23 @@ void key_mode() {
|
||||
if (tud_hid_ready()) {
|
||||
/*------------- Keyboard -------------*/
|
||||
if (sw_changed) {
|
||||
bool is_pressed = false;
|
||||
int keycode_idx = 0;
|
||||
uint8_t keycode[6] = {0}; // looks like we are limited to 6kro?
|
||||
uint8_t nkro_report[32] = {0};
|
||||
for (int i = 0; i < SW_GPIO_SIZE; i++) {
|
||||
if (sw_val[i]) {
|
||||
// use to avoid send multiple consecutive zero report for keyboard
|
||||
keycode[keycode_idx] = SW_KEYCODE[i];
|
||||
keycode_idx = ++keycode_idx % SW_GPIO_SIZE;
|
||||
is_pressed = true;
|
||||
uint8_t bit = SW_KEYCODE[i] % 8;
|
||||
uint8_t byte = (SW_KEYCODE[i] / 8) + 1;
|
||||
if (SW_KEYCODE[i] >= 240 && SW_KEYCODE[i] <= 247) {
|
||||
nkro_report[0] |= (1 << bit);
|
||||
} else if (byte > 0 && byte <= 31) {
|
||||
nkro_report[byte] |= (1 << bit);
|
||||
}
|
||||
|
||||
prev_sw_val[i] = sw_val[i];
|
||||
// Reactive Lighting On
|
||||
gpio_put(LED_GPIO[i], 1);
|
||||
} else {
|
||||
// Reactive Lighting Off
|
||||
gpio_put(LED_GPIO[i], 0);
|
||||
}
|
||||
}
|
||||
if (is_pressed) {
|
||||
// Send key report
|
||||
tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, keycode);
|
||||
} else {
|
||||
// Send empty key report if previously has key pressed
|
||||
tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL);
|
||||
}
|
||||
// Send key report
|
||||
tud_hid_n_report(0x00, REPORT_ID_KEYBOARD, &nkro_report,
|
||||
sizeof(nkro_report));
|
||||
sw_changed = false;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -103,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_EP_BUFSIZE 16
|
||||
#define CFG_TUD_HID_EP_BUFSIZE 64
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ uint8_t const* tud_descriptor_device_cb(void) {
|
||||
uint8_t const desc_hid_report[] = {
|
||||
GAMECON_REPORT_DESC_JOYSTICK(HID_REPORT_ID(REPORT_ID_JOYSTICK)),
|
||||
GAMECON_REPORT_DESC_LIGHTS(HID_REPORT_ID(REPORT_ID_LIGHTS)),
|
||||
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(REPORT_ID_KEYBOARD)),
|
||||
GAMECON_REPORT_DESC_NKRO(HID_REPORT_ID(REPORT_ID_KEYBOARD)),
|
||||
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(REPORT_ID_MOUSE))};
|
||||
|
||||
// Invoked when received GET HID REPORT DESCRIPTOR
|
||||
|
||||
@@ -42,3 +42,15 @@ enum {
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(40), /*Padding*/ \
|
||||
HID_INPUT(HID_CONSTANT | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
HID_COLLECTION_END
|
||||
|
||||
// NKRO Descriptor
|
||||
#define GAMECON_REPORT_DESC_NKRO(...) \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), HID_USAGE(HID_USAGE_PAGE_KEYBOARD), \
|
||||
HID_COLLECTION(HID_COLLECTION_APPLICATION), \
|
||||
__VA_ARGS__ HID_REPORT_SIZE(1), HID_REPORT_COUNT(8), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_KEYBOARD), HID_USAGE_MIN(224), \
|
||||
HID_USAGE_MAX(231), HID_LOGICAL_MIN(0), HID_LOGICAL_MAX(1), \
|
||||
HID_INPUT(HID_VARIABLE), HID_REPORT_SIZE(1), HID_REPORT_COUNT(31 * 8), \
|
||||
HID_LOGICAL_MIN(0), HID_LOGICAL_MAX(1), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_KEYBOARD), HID_USAGE_MIN(0), \
|
||||
HID_USAGE_MAX(31 * 8 - 1), HID_INPUT(HID_VARIABLE), HID_COLLECTION_END
|
||||
|
||||
Reference in New Issue
Block a user