mirror of
https://github.com/whowechina/geki_pico.git
synced 2025-01-31 11:53:43 +01:00
IO4 HID
This commit is contained in:
parent
edb04529f1
commit
1ef3c14dfa
@ -4,8 +4,8 @@ set(LWIP_ROOT ${PICO_SDK_PATH}/lib/lwip)
|
||||
function(make_firmware board board_def)
|
||||
pico_sdk_init()
|
||||
add_executable(${board}
|
||||
main.c light.c button.c gimbal.c sound.c wad.c vl53l0x.c save.c config.c commands.c
|
||||
cli.c usb_descriptors.c)
|
||||
main.c light.c button.c gimbal.c sound.c wad.c vl53l0x.c save.c config.c
|
||||
commands.c cli.c hid.c usb_descriptors.c)
|
||||
target_compile_definitions(${board} PUBLIC ${board_def})
|
||||
pico_enable_stdio_usb(${board} 1)
|
||||
pico_enable_stdio_uart(${board} 0)
|
||||
|
@ -53,7 +53,7 @@ static geki_cfg_t default_cfg = {
|
||||
},
|
||||
};
|
||||
|
||||
geki_runtime_t *geki_runtime;
|
||||
geki_runtime_t geki_runtime;
|
||||
|
||||
static void config_loaded()
|
||||
{
|
||||
|
@ -44,10 +44,11 @@ typedef struct __attribute__((packed)) {
|
||||
|
||||
typedef struct {
|
||||
uint16_t fps[2];
|
||||
bool key_stuck;
|
||||
} geki_runtime_t;
|
||||
|
||||
extern geki_cfg_t *geki_cfg;
|
||||
extern geki_runtime_t *geki_runtime;
|
||||
extern geki_runtime_t geki_runtime;
|
||||
|
||||
void config_init();
|
||||
void config_changed(); // Notify the config has changed
|
||||
|
135
firmware/src/hid.c
Normal file
135
firmware/src/hid.c
Normal file
@ -0,0 +1,135 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "board_defs.h"
|
||||
|
||||
#include "tusb.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "button.h"
|
||||
#include "gimbal.h"
|
||||
#include "wad.h"
|
||||
#include "config.h"
|
||||
#include "hid.h"
|
||||
|
||||
struct __attribute__((packed)) {
|
||||
uint16_t adcs[8];
|
||||
uint16_t spinners[4];
|
||||
uint16_t chutes[2];
|
||||
uint16_t buttons[2];
|
||||
uint8_t system_status;
|
||||
uint8_t usb_status;
|
||||
uint8_t padding[29];
|
||||
} hid_joy;
|
||||
|
||||
struct __attribute__((packed)) {
|
||||
uint8_t modifier;
|
||||
uint8_t keymap[15];
|
||||
} hid_nkro;
|
||||
|
||||
const static struct {
|
||||
uint8_t group;
|
||||
uint8_t bit;
|
||||
} button_to_io4_map[] = {
|
||||
{ 0, 0 }, { 0, 5 }, { 0, 4 }, // Left ABC
|
||||
{ 0, 1 }, { 1, 0 }, { 0, 15 }, // Right ABC
|
||||
{ 1, 14 }, { 0, 13 }, // AUX 12
|
||||
}, wad_left = { 1, 15 }, wad_right = { 0, 14 };
|
||||
|
||||
|
||||
static void report_usb_hid()
|
||||
{
|
||||
if (tud_hid_ready()) {
|
||||
if (geki_cfg->hid.joy || geki_runtime.key_stuck) {
|
||||
hid_joy.adcs[0] = (gimbal_read() - 128) << 8;
|
||||
|
||||
static uint16_t last_buttons = 0;
|
||||
uint16_t buttons = button_read();
|
||||
hid_joy.buttons[0] = 0;
|
||||
hid_joy.buttons[1] = 0;
|
||||
for (int i = 0; i < button_num(); i++) {
|
||||
uint8_t group = button_to_io4_map[i].group;
|
||||
uint8_t bit = button_to_io4_map[i].bit;
|
||||
if (buttons & (1 << i)) {
|
||||
hid_joy.buttons[group] |= (1 << bit);
|
||||
}
|
||||
}
|
||||
if (wad_read_left()) {
|
||||
hid_joy.buttons[wad_left.group] |= (1 << wad_left.bit);
|
||||
}
|
||||
if (wad_read_right()) {
|
||||
hid_joy.buttons[wad_right.group] |= (1 << wad_right.bit);
|
||||
}
|
||||
|
||||
if ((last_buttons ^ buttons) & (1 << 11)) {
|
||||
if (buttons & (1 << 11)) {
|
||||
// just pressed coin button
|
||||
hid_joy.chutes[0] += 0x100;
|
||||
}
|
||||
}
|
||||
tud_hid_n_report(0, REPORT_ID_JOYSTICK, &hid_joy, sizeof(hid_joy));
|
||||
last_buttons = buttons;
|
||||
}
|
||||
if (geki_cfg->hid.nkro && !geki_runtime.key_stuck) {
|
||||
tud_hid_n_report(1, 0, &hid_nkro, sizeof(hid_nkro));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gen_nkro_report()
|
||||
{
|
||||
if (!geki_cfg->hid.nkro) {
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
const char keymap[] = "\x1a\x08\x07\x06\x1b\x1d\x04\x14\x20\x3a\x3b\x3c";
|
||||
uint16_t buttons = button_read();
|
||||
for (int i = 0; i < button_num(); i++) {
|
||||
uint8_t code = keymap[i];
|
||||
uint8_t byte = code / 8;
|
||||
uint8_t bit = code % 8;
|
||||
if (buttons & (1 << i)) {
|
||||
hid_nkro.keymap[byte] |= (1 << bit);
|
||||
} else {
|
||||
hid_nkro.keymap[byte] &= ~(1 << bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hid_update()
|
||||
{
|
||||
gen_nkro_report();
|
||||
report_usb_hid();
|
||||
}
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t report_id;
|
||||
uint8_t cmd;
|
||||
uint8_t payload[62];
|
||||
} hid_output_t;
|
||||
|
||||
void hid_proc(const uint8_t *data, uint8_t len)
|
||||
{
|
||||
hid_output_t *output = (hid_output_t *)data;
|
||||
if (output->report_id == REPORT_ID_OUTPUT) {
|
||||
switch (output->cmd) {
|
||||
case 0x01: // Set Timeout
|
||||
case 0x02: // Set Sampling Count
|
||||
hid_joy.system_status = 0x30;
|
||||
break;
|
||||
case 0x03: // Clear Board Status
|
||||
hid_joy.chutes[0] = 0;
|
||||
hid_joy.chutes[1] = 0;
|
||||
hid_joy.system_status = 0x00;
|
||||
break;
|
||||
case 0x04: // Set General Output
|
||||
// LED
|
||||
break;
|
||||
case 0x41: // I don't know what this is
|
||||
break;
|
||||
default:
|
||||
printf("USB unknown cmd: %d\n", output->cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
12
firmware/src/hid.h
Normal file
12
firmware/src/hid.h
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* HID Report Functions
|
||||
* WHowe <github.com/whowechina>
|
||||
*/
|
||||
|
||||
#ifndef HID_H_
|
||||
#define HID_H_
|
||||
|
||||
void hid_update();
|
||||
void hid_proc(const uint8_t *data, uint8_t len);
|
||||
|
||||
#endif
|
@ -28,92 +28,14 @@
|
||||
#include "cli.h"
|
||||
#include "commands.h"
|
||||
|
||||
#include "hid.h"
|
||||
|
||||
#include "light.h"
|
||||
#include "button.h"
|
||||
#include "gimbal.h"
|
||||
#include "wad.h"
|
||||
#include "sound.h"
|
||||
|
||||
struct __attribute__((packed)) {
|
||||
uint16_t buttons;
|
||||
uint8_t HAT;
|
||||
uint8_t lx;
|
||||
uint8_t ly;
|
||||
uint8_t rx;
|
||||
uint8_t ry;
|
||||
uint8_t vendor;
|
||||
} hid_joy;
|
||||
|
||||
struct __attribute__((packed)) {
|
||||
uint8_t modifier;
|
||||
uint8_t keymap[15];
|
||||
} hid_nkro, sent_hid_nkro;
|
||||
|
||||
void report_usb_hid()
|
||||
{
|
||||
if (tud_hid_ready()) {
|
||||
hid_joy.HAT = 0x08;
|
||||
hid_joy.vendor = 0;
|
||||
if (geki_cfg->hid.joy) {
|
||||
tud_hid_n_report(0x00, 0, &hid_joy, sizeof(hid_joy));
|
||||
}
|
||||
if (geki_cfg->hid.nkro &&
|
||||
(memcmp(&hid_nkro, &sent_hid_nkro, sizeof(hid_nkro)) != 0)) {
|
||||
sent_hid_nkro = hid_nkro;
|
||||
tud_hid_n_report(0x02, 0, &sent_hid_nkro, sizeof(sent_hid_nkro));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define SWITCH_BIT_Y (1U << 0)
|
||||
#define SWITCH_BIT_B (1U << 1)
|
||||
#define SWITCH_BIT_A (1U << 2)
|
||||
#define SWITCH_BIT_X (1U << 3)
|
||||
#define SWITCH_BIT_L (1U << 4)
|
||||
#define SWITCH_BIT_R (1U << 5)
|
||||
#define SWITCH_BIT_ZL (1U << 6)
|
||||
#define SWITCH_BIT_ZR (1U << 7)
|
||||
#define SWITCH_BIT_MINUS (1U << 8)
|
||||
#define SWITCH_BIT_PLUS (1U << 9)
|
||||
#define SWITCH_BIT_L3 (1U << 10)
|
||||
#define SWITCH_BIT_R3 (1U << 11)
|
||||
#define SWITCH_BIT_HOME (1U << 12)
|
||||
|
||||
static void gen_joy_report()
|
||||
{
|
||||
hid_joy.lx = gimbal_read();
|
||||
|
||||
uint16_t button = button_read();
|
||||
hid_joy.buttons = 0;
|
||||
hid_joy.buttons |= (button & 0x01) ? SWITCH_BIT_L : 0;
|
||||
hid_joy.buttons |= (button & 0x02) ? SWITCH_BIT_R : 0;
|
||||
if (button & 0x08) {
|
||||
hid_joy.buttons |= (button & 0x04) ? SWITCH_BIT_MINUS : 0;
|
||||
hid_joy.buttons |= (button & 0x10) ? SWITCH_BIT_PLUS : 0;
|
||||
} else {
|
||||
hid_joy.buttons |= (button & 0x04) ? SWITCH_BIT_B : 0;
|
||||
hid_joy.buttons |= (button & 0x10) ? SWITCH_BIT_A : 0;
|
||||
}
|
||||
}
|
||||
|
||||
const uint8_t keycode_table[128][2] = { HID_ASCII_TO_KEYCODE };
|
||||
const uint8_t keymap[38 + 1] = NKRO_KEYMAP; // 32 keys, 6 air keys, 1 terminator
|
||||
static void gen_nkro_report()
|
||||
{
|
||||
for (int i = 0; i < 6; i++) {
|
||||
uint8_t code = keycode_table[keymap[32 + i]][1];
|
||||
uint8_t byte = code / 8;
|
||||
uint8_t bit = code % 8;
|
||||
if (hid_joy.buttons & (1 << i)) {
|
||||
hid_nkro.keymap[byte] |= (1 << bit);
|
||||
} else {
|
||||
hid_nkro.keymap[byte] &= ~(1 << bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t last_hid_time = 0;
|
||||
|
||||
static void run_lights()
|
||||
{
|
||||
int gimbal = gimbal_read();
|
||||
@ -173,8 +95,8 @@ static void run_lights()
|
||||
|
||||
static void run_sound()
|
||||
{
|
||||
sound_set(0, wad_read_left());
|
||||
sound_set(1, wad_read_right());
|
||||
//sound_set(0, wad_read_left());
|
||||
//sound_set(1, wad_read_right());
|
||||
}
|
||||
|
||||
static mutex_t core1_io_lock;
|
||||
@ -204,10 +126,9 @@ static void core0_loop()
|
||||
|
||||
button_update();
|
||||
wad_update();
|
||||
gen_joy_report();
|
||||
gen_nkro_report();
|
||||
report_usb_hid();
|
||||
|
||||
|
||||
hid_update();
|
||||
|
||||
sleep_us(900);
|
||||
}
|
||||
}
|
||||
@ -295,8 +216,5 @@ 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)
|
||||
{
|
||||
if (report_type == HID_REPORT_TYPE_OUTPUT) {
|
||||
last_hid_time = time_us_64();
|
||||
return;
|
||||
}
|
||||
hid_proc(buffer, bufsize);
|
||||
}
|
||||
|
@ -96,8 +96,8 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
//------------- CLASS -------------//
|
||||
#define CFG_TUD_HID 3
|
||||
#define CFG_TUD_CDC 1
|
||||
#define CFG_TUD_HID 2
|
||||
#define CFG_TUD_CDC 2
|
||||
#define CFG_TUD_MSC 0
|
||||
#define CFG_TUD_MIDI 0
|
||||
#define CFG_TUD_VENDOR 0
|
||||
|
@ -24,24 +24,9 @@
|
||||
*/
|
||||
|
||||
#include "usb_descriptors.h"
|
||||
|
||||
#include "pico/unique_id.h"
|
||||
#include "tusb.h"
|
||||
|
||||
/* 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.
|
||||
*
|
||||
* Auto ProductID layout's Bitmap:
|
||||
* [MSB] HID | MSC | CDC [LSB]
|
||||
*/
|
||||
#define _PID_MAP(itf, n) ((CFG_TUD_##itf) << (n))
|
||||
#define USB_PID \
|
||||
(0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \
|
||||
_PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4))
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Device Descriptors
|
||||
//--------------------------------------------------------------------+
|
||||
tusb_desc_device_t desc_device_joy = {
|
||||
.bLength = sizeof(tusb_desc_device_t),
|
||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||
@ -51,8 +36,8 @@ tusb_desc_device_t desc_device_joy = {
|
||||
.bDeviceProtocol = 0x00,
|
||||
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||
|
||||
.idVendor = 0x0f0d,
|
||||
.idProduct = 0x0092,
|
||||
.idVendor = 0x0ca3,
|
||||
.idProduct = 0x0021,
|
||||
.bcdDevice = 0x0100,
|
||||
|
||||
.iManufacturer = 1,
|
||||
@ -76,11 +61,6 @@ uint8_t const desc_hid_report_joy[] = {
|
||||
GEKI_PICO_REPORT_DESC_JOYSTICK,
|
||||
};
|
||||
|
||||
uint8_t const desc_hid_report_led[] = {
|
||||
GEKI_PICO_LED_HEADER,
|
||||
GEKI_PICO_LED_FOOTER
|
||||
};
|
||||
|
||||
uint8_t const desc_hid_report_nkro[] = {
|
||||
GEKI_PICO_REPORT_DESC_NKRO,
|
||||
};
|
||||
@ -94,8 +74,6 @@ uint8_t const* tud_hid_descriptor_report_cb(uint8_t itf)
|
||||
case 0:
|
||||
return desc_hid_report_joy;
|
||||
case 1:
|
||||
return desc_hid_report_led;
|
||||
case 2:
|
||||
return desc_hid_report_nkro;
|
||||
default:
|
||||
return NULL;
|
||||
@ -105,20 +83,19 @@ uint8_t const* tud_hid_descriptor_report_cb(uint8_t itf)
|
||||
// Configuration Descriptor
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
enum { ITF_NUM_JOY, ITF_NUM_LED, ITF_NUM_NKRO,
|
||||
ITF_NUM_CLI, ITF_NUM_CLI_DATA,
|
||||
enum { ITF_NUM_JOY, ITF_NUM_NKRO,
|
||||
ITF_NUM_CLI, ITF_NUM_CLI_DATA, ITF_NUM_AIME, ITF_NUM_AIME_DATA,
|
||||
ITF_NUM_TOTAL };
|
||||
|
||||
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + \
|
||||
TUD_HID_INOUT_DESC_LEN * 1 + \
|
||||
TUD_HID_DESC_LEN * 2 + \
|
||||
TUD_CDC_DESC_LEN * 1)
|
||||
TUD_HID_DESC_LEN * 1 + \
|
||||
TUD_CDC_DESC_LEN * 2)
|
||||
|
||||
#define EPNUM_JOY_OUT 0x01
|
||||
#define EPNUM_JOY_IN 0x81
|
||||
|
||||
#define EPNUM_LED 0x86
|
||||
#define EPNUM_KEY 0x87
|
||||
#define EPNUM_NKRO 0x87
|
||||
|
||||
#define EPNUM_CLI_NOTIF 0x89
|
||||
#define EPNUM_CLI_OUT 0x0a
|
||||
@ -140,16 +117,16 @@ uint8_t const desc_configuration_joy[] = {
|
||||
sizeof(desc_hid_report_joy), EPNUM_JOY_OUT, EPNUM_JOY_IN,
|
||||
CFG_TUD_HID_EP_BUFSIZE, 1),
|
||||
|
||||
TUD_HID_DESCRIPTOR(ITF_NUM_LED, 5, HID_ITF_PROTOCOL_NONE,
|
||||
sizeof(desc_hid_report_led), EPNUM_LED,
|
||||
CFG_TUD_HID_EP_BUFSIZE, 4),
|
||||
|
||||
TUD_HID_DESCRIPTOR(ITF_NUM_NKRO, 6, HID_ITF_PROTOCOL_NONE,
|
||||
sizeof(desc_hid_report_nkro), EPNUM_KEY,
|
||||
TUD_HID_DESCRIPTOR(ITF_NUM_NKRO, 5, HID_ITF_PROTOCOL_NONE,
|
||||
sizeof(desc_hid_report_nkro), EPNUM_NKRO,
|
||||
CFG_TUD_HID_EP_BUFSIZE, 1),
|
||||
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CLI, 7, EPNUM_CLI_NOTIF,
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CLI, 6, EPNUM_CLI_NOTIF,
|
||||
8, EPNUM_CLI_OUT, EPNUM_CLI_IN, 64),
|
||||
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_AIME, 7, EPNUM_AIME_NOTIF,
|
||||
8, EPNUM_AIME_OUT, EPNUM_AIME_IN, 64),
|
||||
|
||||
};
|
||||
|
||||
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||
@ -162,17 +139,17 @@ uint8_t const* tud_descriptor_configuration_cb(uint8_t index) {
|
||||
//--------------------------------------------------------------------+
|
||||
// String Descriptors
|
||||
//--------------------------------------------------------------------+
|
||||
static char serial_number_str[24] = "123456\0";
|
||||
|
||||
// array of pointer to string descriptors
|
||||
const char *string_desc_arr[] = {
|
||||
static const char *string_desc_arr[] = {
|
||||
(const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409)
|
||||
"WHowe", // 1: Manufacturer
|
||||
"Geki Pico Controller", // 2: Product
|
||||
"123456", // 3: Serial
|
||||
"Geki Pico Joystick",
|
||||
"Geki Pico LED",
|
||||
"SEGA", // 1: Manufacturer
|
||||
"Geki Pico", // 2: Product
|
||||
serial_number_str, // 3: Serials, use chip ID
|
||||
"I/O CONTROL BD;15257;01;90;1831;6679A;00;GOUT=14_ADIN=8,E_ROTIN=4_COININ=2_SWIN=2,E_UQ1=41,6;",
|
||||
"Geki Pico NKRO",
|
||||
"Geki Pico CLI Port",
|
||||
"Geki Pico CLI",
|
||||
"Mai Pico AIME Port",
|
||||
};
|
||||
|
||||
// Invoked when received GET STRING DESCRIPTOR request
|
||||
@ -180,39 +157,24 @@ const char *string_desc_arr[] = {
|
||||
// enough for transfer to complete
|
||||
uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
|
||||
{
|
||||
static uint16_t _desc_str[64];
|
||||
static uint16_t _desc_str[128];
|
||||
|
||||
if (index == 0) {
|
||||
memcpy(&_desc_str[1], string_desc_arr[0], 2);
|
||||
_desc_str[0] = (TUSB_DESC_STRING << 8) | (2 + 2);
|
||||
return _desc_str;
|
||||
}
|
||||
|
||||
const size_t base_num = sizeof(string_desc_arr) / sizeof(string_desc_arr[0]);
|
||||
const char *colors[] = {"Blue", "Red", "Green"};
|
||||
char str[64];
|
||||
|
||||
if (index < base_num) {
|
||||
strcpy(str, string_desc_arr[index]);
|
||||
} else if (index < base_num + 48 + 45) {
|
||||
const char *names[] = {"Key ", "Splitter "};
|
||||
int led = index - base_num;
|
||||
int id = led / 6 + 1;
|
||||
int type = led / 3 % 2;
|
||||
int brg = led % 3;
|
||||
sprintf(str, "%s%02d %s", names[type], id, colors[brg]);
|
||||
} else if (index < base_num + 48 + 45 + 18) {
|
||||
int led = index - base_num - 48 - 45;
|
||||
int id = led / 3 + 1;
|
||||
int brg = led % 3;
|
||||
sprintf(str, "Tower %02d %s", id, colors[brg]);
|
||||
} else {
|
||||
sprintf(str, "Unknown %d", index);
|
||||
if (index == 3) {
|
||||
pico_unique_board_id_t board_id;
|
||||
pico_get_unique_board_id(&board_id);
|
||||
sprintf(serial_number_str, "%016llx", *(uint64_t *)&board_id);
|
||||
}
|
||||
|
||||
const char *str = string_desc_arr[index];
|
||||
uint8_t chr_count = strlen(str);
|
||||
if (chr_count > 63) {
|
||||
chr_count = 63;
|
||||
if (chr_count > count_of(_desc_str)) {
|
||||
chr_count = count_of(_desc_str);
|
||||
}
|
||||
|
||||
// Convert ASCII string into UTF-16
|
||||
|
@ -6,10 +6,7 @@
|
||||
|
||||
enum {
|
||||
REPORT_ID_JOYSTICK = 1,
|
||||
REPORT_ID_LED_SLIDER_16 = 4,
|
||||
REPORT_ID_LED_SLIDER_15 = 5,
|
||||
REPORT_ID_LED_TOWER_6 = 6,
|
||||
REPORT_ID_LED_COMPRESSED = 11,
|
||||
REPORT_ID_OUTPUT = 16,
|
||||
};
|
||||
|
||||
// because they are missing from tusb_hid.h
|
||||
@ -20,57 +17,99 @@ enum {
|
||||
#define HID_STRING_MAXIMUM(x) HID_REPORT_ITEM(x, 9, RI_TYPE_LOCAL, 1)
|
||||
#define HID_STRING_MAXIMUM_N(x, n) HID_REPORT_ITEM(x, 9, RI_TYPE_LOCAL, n)
|
||||
|
||||
// Joystick Report Descriptor Template - Based off Drewol/rp2040-gamecon
|
||||
// Button Map | X | Y
|
||||
//HID_REPORT_ID(REPORT_ID_JOYSTICK)
|
||||
|
||||
#define GEKI_PICO_REPORT_DESC_JOYSTICK \
|
||||
// Joystick Report Descriptor to Emulate IO4
|
||||
#define GEKI_PICO_REPORT_DESC_JOYSTICK \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_GAMEPAD), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_JOYSTICK), \
|
||||
HID_COLLECTION(HID_COLLECTION_APPLICATION), \
|
||||
HID_LOGICAL_MIN(0), HID_LOGICAL_MAX(1), \
|
||||
HID_PHYSICAL_MIN(0), HID_PHYSICAL_MAX(1), \
|
||||
HID_REPORT_SIZE(1), HID_REPORT_COUNT(16), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_BUTTON), \
|
||||
HID_USAGE_MIN(1), HID_USAGE_MAX(16), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
HID_REPORT_ID(REPORT_ID_JOYSTICK) \
|
||||
\
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(16), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
|
||||
HID_LOGICAL_MAX(7), \
|
||||
HID_PHYSICAL_MAX_N(315, 2), \
|
||||
HID_REPORT_SIZE(4), HID_REPORT_COUNT(1), \
|
||||
0x65, 0x14, /* Unit */ \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_HAT_SWITCH), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE | HID_NO_NULL_POSITION),\
|
||||
0x65, 0x00, /* Unit None */ \
|
||||
HID_REPORT_COUNT(1), \
|
||||
HID_INPUT(HID_CONSTANT | HID_ARRAY | HID_ABSOLUTE), \
|
||||
\
|
||||
HID_LOGICAL_MAX_N(0xff, 2), HID_PHYSICAL_MAX_N(0xff, 2), /* Analog */ \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_X), HID_USAGE(HID_USAGE_DESKTOP_Y), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_Z), HID_USAGE(HID_USAGE_DESKTOP_RZ), \
|
||||
HID_REPORT_SIZE(8), HID_REPORT_COUNT(4), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_X), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
\
|
||||
HID_USAGE_PAGE_N(HID_USAGE_PAGE_VENDOR, 2), \
|
||||
HID_USAGE(0x20), \
|
||||
HID_REPORT_COUNT(1), \
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(16), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_Y), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
\
|
||||
HID_USAGE_N(0x2621, 2), \
|
||||
HID_REPORT_COUNT(8), \
|
||||
HID_OUTPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
HID_COLLECTION_END
|
||||
|
||||
//HID_USAGE_PAGE_N(9761, 2), HID_REPORT_COUNT(8), HID_OUTPUT(2),
|
||||
|
||||
#define GEKI_PICO_LED_HEADER \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), HID_USAGE(0x00), \
|
||||
HID_COLLECTION(HID_COLLECTION_APPLICATION), \
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(8), \
|
||||
HID_INPUT(HID_CONSTANT | HID_VARIABLE | HID_ABSOLUTE)
|
||||
|
||||
#define GEKI_PICO_LED_FOOTER \
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(16), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_X), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
\
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(16), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_Y), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
\
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(16), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_X), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
\
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(16), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_Y), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
\
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(16), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_X), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
\
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(16), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_Y), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
\
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(16), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_RX), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
\
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(16), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_RY), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
\
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(16), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_RX), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
\
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(16), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_RY), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
\
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(16), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_SLIDER), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
\
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(16), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
|
||||
HID_USAGE(HID_USAGE_DESKTOP_SLIDER), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
\
|
||||
HID_REPORT_COUNT(48), HID_REPORT_SIZE(1), \
|
||||
HID_USAGE_MIN_N(1, 2), HID_USAGE_MAX_N(48, 2), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
\
|
||||
HID_REPORT_COUNT(1), HID_REPORT_SIZE(232), \
|
||||
HID_INPUT(HID_CONSTANT | HID_ABSOLUTE), \
|
||||
\
|
||||
HID_USAGE_PAGE_N(0xffa0, 2), \
|
||||
HID_USAGE(0x00), \
|
||||
HID_REPORT_ID(REPORT_ID_OUTPUT) \
|
||||
HID_COLLECTION(HID_COLLECTION_APPLICATION), \
|
||||
HID_USAGE(0x00), \
|
||||
HID_LOGICAL_MIN(0), HID_LOGICAL_MAX(255), \
|
||||
HID_REPORT_COUNT(63), HID_REPORT_SIZE(8), \
|
||||
HID_OUTPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
HID_COLLECTION_END, \
|
||||
HID_COLLECTION_END
|
||||
|
||||
#define GEKI_PICO_REPORT_DESC_NKRO \
|
||||
|
Loading…
x
Reference in New Issue
Block a user