NKRO Added

This commit is contained in:
Nicholas G
2021-07-26 18:04:03 -04:00
parent 5603b39b0f
commit b17ce2efda
6 changed files with 38 additions and 28 deletions
+12 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
}
+1 -1
View File
@@ -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
+12
View File
@@ -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