Add partial PS4 support (no auth)

This commit is contained in:
whowechina
2026-04-12 11:18:53 +08:00
parent ce9171d9de
commit f18e7d6d67
9 changed files with 426 additions and 37 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ function(make_firmware board board_def)
pico_sdk_init()
add_executable(${board}
main.c slider.c rgb.c button.c save.c config.c commands.c
cli.c mpr121.c hebtn.c lzfx.c usb_descriptors.c)
cli.c mpr121.c hebtn.c lzfx.c usb_descriptors.c ps4_feat.c)
target_compile_definitions(${board} PUBLIC ${board_def})
pico_enable_stdio_usb(${board} 1)
pico_enable_stdio_uart(${board} 0)
+9 -6
View File
@@ -62,9 +62,9 @@ static void disp_hall()
static void disp_hid()
{
const char *joy_map[] = {"Switch", "Steam", "Arcade"};
const char *joy_map[] = {"Switch", "Steam", "Arcade", "PS4"};
printf("[HID]\n");
printf(" Keymap: %s\n", joy_map[diva_cfg->hid.joy_map % 3]);
printf(" Keymap: %s\n", joy_map[diva_cfg->hid.joy_map % 4]);
}
void handle_display(int argc, char *argv[])
@@ -175,21 +175,24 @@ static void handle_stat(int argc, char *argv[])
static void handle_keymap(int argc, char *argv[])
{
const char *usage = "Usage: keymap <switch|steam|arcade>\n";
const char *usage = "Usage: keymap <switch|steam|arcade|ps4>\n";
if (argc != 1) {
printf(usage);
return;
}
const char *choices[] = {"switch", "steam", "arcade"};
int match = cli_match_prefix(choices, 3, argv[0]);
const char *choices[] = {"switch", "steam", "arcade", "ps4"};
int match = cli_match_prefix(choices, count_of(choices), argv[0]);
if (match < 0) {
printf(usage);
return;
}
diva_cfg->hid.joy_map = match;
config_changed();
disp_hid();
save_request(true);
printf("Please replug the controller to apply the change.\n");
}
static void handle_filter(int argc, char *argv[])
+7 -1
View File
@@ -31,10 +31,16 @@ static diva_cfg_t default_cfg = {
},
};
diva_runtime_t diva_runtime;
diva_runtime_t diva_runtime = {
.hid_ps4 = false,
};
static void config_loaded()
{
if (diva_cfg->hid.joy_map > 3) {
diva_cfg->hid.joy_map = default_cfg.hid.joy_map;
config_changed();
}
if ((diva_cfg->sense.filter & 0x0f) > 3 ||
((diva_cfg->sense.filter >> 4) & 0x0f) > 3) {
diva_cfg->sense.filter = default_cfg.sense.filter;
+1
View File
@@ -39,6 +39,7 @@ typedef struct __attribute__((packed)) {
typedef struct {
bool diva_plus;
bool hid_ps4;
struct {
bool sensor;
} debug;
+93 -22
View File
@@ -34,13 +34,27 @@
#include "button.h"
#include "hebtn.h"
#include "lzfx.h"
#include "ps4_feat.h"
struct __attribute__((packed)) {
uint16_t buttons; // 16 buttons; see JoystickButtons_t for bit mapping
uint8_t HAT; // HAT switch; one nibble w/ unused nibble
uint32_t axis; // slider touch data
uint8_t VendorSpec;
} hid_joy, sent_hid_joy;
} hid_ns, sent_hid_ns;
struct __attribute__((packed)) {
uint8_t left_x;
uint8_t left_y;
uint8_t right_x;
uint8_t right_y;
uint8_t hat_buttons;
uint8_t buttons_11_4;
uint8_t buttons_counter;
uint8_t trigger_l;
uint8_t trigger_r;
uint8_t vendor[54];
} hid_ps4, sent_hid_ps4;
void report_usb_hid()
{
@@ -52,14 +66,25 @@ void report_usb_hid()
uint64_t now = time_us_64();
hid_joy.HAT = 0x08;
hid_joy.VendorSpec = 0;
if ((memcmp(&hid_joy, &sent_hid_joy, sizeof(hid_joy)) != 0) ||
(now - last_report_joy >= 2000)) {
if (tud_hid_report(0, &hid_joy, sizeof(hid_joy))) {
sent_hid_joy = hid_joy;
if (diva_runtime.hid_ps4) {
hid_ps4.hat_buttons = (hid_ps4.hat_buttons & 0xF0) | 0x08;
if ((memcmp(&hid_ps4, &sent_hid_ps4, sizeof(hid_ps4)) != 0) ||
(now - last_report_joy >= 2000)) {
if (tud_hid_report(REPORT_ID_JOYSTICK, &hid_ps4, sizeof(hid_ps4))) {
sent_hid_ps4 = hid_ps4;
}
last_report_joy = now;
}
} else {
hid_ns.HAT = 0x08;
hid_ns.VendorSpec = 0;
if ((memcmp(&hid_ns, &sent_hid_ns, sizeof(hid_ns)) != 0) ||
(now - last_report_joy >= 2000)) {
if (tud_hid_report(0, &hid_ns, sizeof(hid_ns))) {
sent_hid_ns = hid_ns;
}
last_report_joy = now;
}
last_report_joy = now;
}
}
@@ -68,38 +93,69 @@ static uint16_t unified_button_read()
return button_read() | hebtn_read();
}
const static uint8_t maps[3][7] = {
const static uint8_t maps[4][7] = {
{ 3, 0, 1, 2, 12, 8, 9 },
{ 0, 3, 2, 1, 12, 8, 9 }, // Steam
{ 3, 0, 1, 2, 9, 12, 8 }, // Arcade
{ 0, 1, 2, 3, 12, 8, 9 }, // PS4
};
static uint16_t mapped_buttons;
static void map_buttons()
{
uint16_t button = unified_button_read();
const uint8_t *map = maps[diva_cfg->hid.joy_map % 3];
const uint8_t *map = maps[diva_cfg->hid.joy_map % 4];
hid_joy.buttons = 0;
mapped_buttons = 0;
for (int i = 0; i < 7; i++) {
hid_joy.buttons |= (button & (1 << i)) ? (1 << map[i]) : 0;
mapped_buttons |= (button & (1 << i)) ? (1 << map[i]) : 0;
}
}
static void gen_joy_report()
static uint32_t touch_axis_bits()
{
hid_joy.axis = 0;
uint32_t axis = 0;
int zone_num = slider_zone_num();
for (int i = 0; i < zone_num; i++) {
if (slider_touched(zone_num - 1 - i)) {
uint32_t bits = zone_num > 16 ? (1 << i) : 0x03 << (i * 2);
hid_joy.axis |= bits;
axis |= bits;
}
}
hid_joy.axis ^= 0x80808080;
return axis ^ 0x80808080;
}
static void gen_ns_report()
{
hid_ns.axis = touch_axis_bits();
hid_ns.buttons = mapped_buttons;
}
static void gen_ps4_report()
{
uint16_t ps4_buttons = mapped_buttons;
hid_ps4.left_x = 0x80;
hid_ps4.left_y = 0x80;
hid_ps4.right_x = 0x80;
hid_ps4.right_y = 0x80;
hid_ps4.hat_buttons = (ps4_buttons << 4);
hid_ps4.buttons_11_4 = ps4_buttons >> 4;
hid_ps4.buttons_counter = ps4_buttons >> 12;
hid_ps4.trigger_l = 0;
hid_ps4.trigger_r = 0;
}
static void gen_hid_report()
{
map_buttons();
if (diva_runtime.hid_ps4) {
gen_ps4_report();
} else {
gen_ns_report();
}
}
static void run_lights()
@@ -170,7 +226,7 @@ static void core0_loop()
slider_update();
hebtn_update();
gen_joy_report();
gen_hid_report();
report_usb_hid();
next_frame += 1000;
@@ -214,11 +270,15 @@ static void keymap_check()
diva_cfg->hid.joy_map = 0;
} else if (buttons == 0x02) {
diva_cfg->hid.joy_map = 1;
} else if ((buttons == 0x04) || (buttons == 0x08)) {
} else if (buttons == 0x04) {
diva_cfg->hid.joy_map = 2;
} else if (buttons == 0x08) {
diva_cfg->hid.joy_map = 3;
} else {
return;
}
diva_runtime.hid_ps4 = (diva_cfg->hid.joy_map == 3);
hid_use_ps4(diva_runtime.hid_ps4);
config_changed();
}
@@ -230,9 +290,6 @@ void init()
update_check();
tusb_init();
stdio_init_all();
config_init();
mutex_init(&core1_io_lock);
save_init(0xca44cafe, &core1_io_lock);
@@ -247,6 +304,12 @@ void init()
keymap_check();
diva_runtime.hid_ps4 = (diva_cfg->hid.joy_map == 3);
hid_use_ps4(diva_runtime.hid_ps4);
tusb_init();
stdio_init_all();
cli_init("diva_pico>", "\n << Diva Pico Controller >>\n"
" https://github.com/whowechina\n\n");
@@ -268,6 +331,9 @@ 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)
{
if (diva_runtime.hid_ps4) {
return ps4_feat_get_report(report_id, report_type, buffer, reqlen);
}
printf("Get from USB %d-%d\n", report_id, report_type);
return 0;
}
@@ -278,6 +344,11 @@ 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 (diva_runtime.hid_ps4) {
ps4_feat_set_report(report_id, report_type, buffer, bufsize);
return;
}
if (report_type == HID_REPORT_TYPE_OUTPUT) {
uint8_t obuf[48];
memcpy(obuf, buffer, bufsize);
+174
View File
@@ -0,0 +1,174 @@
#include <string.h>
#include "ps4_feat.h"
static const uint8_t ps4_feat_02[] = {
0xfe, 0xff, 0x0e, 0x00, 0x04, 0x00, 0xd4, 0x22,
0x2a, 0xdd, 0xbb, 0x22, 0x5e, 0xdd, 0x81, 0x22,
0x84, 0xdd, 0x1c, 0x02, 0x1c, 0x02, 0x85, 0x1f,
0xb0, 0xe0, 0xc6, 0x20, 0xb5, 0xe0, 0xb1, 0x20,
0x83, 0xdf, 0x0c, 0x00
};
static const uint8_t ps4_feat_03[] = {
0x21, 0x27, 0x04, 0xcf, 0x00, 0x2c, 0x56,
0x08, 0x00, 0x3d, 0x00, 0xe8, 0x03, 0x04, 0x00,
0xff, 0x7f, 0x0d, 0x0d, 0x00, 0x00, 0x00, 0x00,
0x0d, 0x84, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const uint8_t ps4_feat_12[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x25, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const uint8_t ps4_feat_a3[] = {
0x4a, 0x75, 0x6e, 0x20, 0x20, 0x39, 0x20, 0x32,
0x30, 0x31, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00,
0x31, 0x32, 0x3a, 0x33, 0x36, 0x3a, 0x34, 0x31,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x08, 0xb4, 0x01, 0x00, 0x00, 0x00,
0x07, 0xa0, 0x10, 0x20, 0x00, 0xa0, 0x02, 0x00
};
static const uint8_t ps4_feat_f2[] = {
0x00, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00
};
static const uint8_t ps4_feat_f3[] = {
0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00
};
static uint8_t ps4_feat_13[22];
static uint8_t ps4_feat_14[16];
static uint8_t ps4_feat_15[44];
static uint16_t ps4_feature_size(uint8_t report_id)
{
switch (report_id) {
case 0x02: return sizeof(ps4_feat_02);
case 0x03: return sizeof(ps4_feat_03);
case 0x08: return 3;
case 0x10: return 4;
case 0x11: return 2;
case 0x12: return sizeof(ps4_feat_12);
case 0x13: return sizeof(ps4_feat_13);
case 0x14: return sizeof(ps4_feat_14);
case 0x15: return sizeof(ps4_feat_15);
case 0x80: return 6;
case 0x81: return 6;
case 0x82: return 5;
case 0x83: return 1;
case 0x84: return 4;
case 0x85: return 6;
case 0x86: return 6;
case 0x87: return 35;
case 0x88: return 34;
case 0x89: return 2;
case 0x90: return 5;
case 0x91: return 3;
case 0x92: return 3;
case 0x93: return 12;
case 0xa0: return 6;
case 0xa1: return 1;
case 0xa2: return 1;
case 0xa3: return sizeof(ps4_feat_a3);
case 0xa4: return 13;
case 0xa5: return 21;
case 0xa6: return 21;
case 0xa7: return 1;
case 0xa8: return 1;
case 0xa9: return 8;
case 0xaa: return 1;
case 0xab: return 57;
case 0xac: return 57;
case 0xad: return 11;
case 0xaf: return 2;
case 0xb0: return 63;
case 0xf0: return 63;
case 0xf1: return 63;
case 0xf2: return sizeof(ps4_feat_f2);
case 0xf3: return sizeof(ps4_feat_f3);
default: return 0;
}
}
static const uint8_t *ps4_feature_data(uint8_t report_id)
{
switch (report_id) {
case 0x02: return ps4_feat_02;
case 0x03: return ps4_feat_03;
case 0x12: return ps4_feat_12;
case 0x13: return ps4_feat_13;
case 0x14: return ps4_feat_14;
case 0x15: return ps4_feat_15;
case 0xa3: return ps4_feat_a3;
case 0xf2: return ps4_feat_f2;
case 0xf3: return ps4_feat_f3;
default: return NULL;
}
}
uint16_t ps4_feat_get_report(uint8_t report_id, hid_report_type_t report_type,
uint8_t *buffer, uint16_t reqlen)
{
if (report_type != HID_REPORT_TYPE_FEATURE) {
memset(buffer, 0, reqlen);
return reqlen;
}
uint16_t resp_len = ps4_feature_size(report_id);
const uint8_t *resp = ps4_feature_data(report_id);
if (resp_len == 0) {
resp_len = reqlen;
}
if (resp_len > reqlen) {
resp_len = reqlen;
}
memset(buffer, 0, resp_len);
if (resp != NULL) {
memcpy(buffer, resp, resp_len);
}
return resp_len;
}
void ps4_feat_set_report(uint8_t report_id, hid_report_type_t report_type,
uint8_t const *buffer, uint16_t bufsize)
{
if (report_type != HID_REPORT_TYPE_FEATURE) {
return;
}
uint8_t *dest = NULL;
uint16_t dest_len = 0;
if (report_id == 0x13) {
dest = ps4_feat_13;
dest_len = sizeof(ps4_feat_13);
} else if (report_id == 0x14) {
dest = ps4_feat_14;
dest_len = sizeof(ps4_feat_14);
} else if (report_id == 0x15) {
dest = ps4_feat_15;
dest_len = sizeof(ps4_feat_15);
}
if (dest == NULL) {
return;
}
uint16_t copy_len = bufsize;
if (copy_len > dest_len) {
copy_len = dest_len;
}
memset(dest, 0, dest_len);
memcpy(dest, buffer, copy_len);
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef PS4_FEAT_H
#define PS4_FEAT_H
#include <stdint.h>
#include "tusb.h"
uint16_t ps4_feat_get_report(uint8_t report_id, hid_report_type_t report_type,
uint8_t *buffer, uint16_t reqlen);
void ps4_feat_set_report(uint8_t report_id, hid_report_type_t report_type,
uint8_t const *buffer, uint16_t bufsize);
#endif
+55 -7
View File
@@ -41,10 +41,17 @@
(0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \
_PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4))
static bool use_ps4_hid;
void hid_use_ps4(bool enable)
{
use_ps4_hid = enable;
}
//--------------------------------------------------------------------+
// Device Descriptors
//--------------------------------------------------------------------+
tusb_desc_device_t desc_device_joy = {
tusb_desc_device_t desc_device_ns = {
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200,
@@ -66,20 +73,45 @@ tusb_desc_device_t desc_device_joy = {
.bNumConfigurations = 0x01};
tusb_desc_device_t desc_device_ps4 = {
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = 0x00,
.bDeviceSubClass = 0x00,
.bDeviceProtocol = 0x00,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = DIVAPICO_PS4_VENDOR_ID,
.idProduct = DIVAPICO_PS4_PRODUCT_ID,
.bcdDevice = 0x0100,
.iManufacturer = 0x01,
.iProduct = 0x02,
.iSerialNumber = 0x03,
.bNumConfigurations = 0x01};
// 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_joy;
return use_ps4_hid ?
(uint8_t const*)&desc_device_ps4 :
(uint8_t const*)&desc_device_ns;
}
//--------------------------------------------------------------------+
// HID Report Descriptor
//--------------------------------------------------------------------+
uint8_t const desc_hid_report_joy[] = {
uint8_t const desc_hid_report_ns[] = {
DIVAPICO_REPORT_DESC_JOYSTICK,
};
uint8_t const desc_hid_report_ps4[] = {
DIVAPICO_REPORT_DESC_PS4,
};
uint8_t const desc_hid_report_led[] = {
DIVAPICO_LED_HEADER,
DIVAPICO_REPORT_DESC_LED_SLIDER_1,
@@ -96,7 +128,7 @@ uint8_t const* tud_hid_descriptor_report_cb(uint8_t itf)
{
switch (itf) {
case 0:
return desc_hid_report_joy;
return use_ps4_hid ? desc_hid_report_ps4 : desc_hid_report_ns;
case 1:
return desc_hid_report_led;
default:
@@ -125,7 +157,7 @@ enum { ITF_NUM_JOY, ITF_NUM_LED,
#define EPNUM_CLI_OUT 0x0a
#define EPNUM_CLI_IN 0x8a
uint8_t const desc_configuration_joy[] = {
uint8_t const desc_configuration_ns[] = {
// Config number, interface count, string index, total length, attribute,
// power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN,
@@ -134,7 +166,23 @@ uint8_t const desc_configuration_joy[] = {
// Interface number, string index, protocol, report descriptor len, EP In
// address, size & polling interval
TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_JOY, 4, HID_ITF_PROTOCOL_NONE,
sizeof(desc_hid_report_joy), EPNUM_JOY_OUT, EPNUM_JOY_IN,
sizeof(desc_hid_report_ns), 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_CDC_DESCRIPTOR(ITF_NUM_CLI, 6, EPNUM_CLI_NOTIF,
8, EPNUM_CLI_OUT, EPNUM_CLI_IN, 64),
};
uint8_t const desc_configuration_ps4[] = {
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN,
TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 200),
TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_JOY, 4, HID_ITF_PROTOCOL_NONE,
sizeof(desc_hid_report_ps4), EPNUM_JOY_OUT, EPNUM_JOY_IN,
CFG_TUD_HID_EP_BUFSIZE, 1),
TUD_HID_DESCRIPTOR(ITF_NUM_LED, 5, HID_ITF_PROTOCOL_NONE,
@@ -149,7 +197,7 @@ uint8_t const desc_configuration_joy[] = {
// 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) {
return desc_configuration_joy;
return use_ps4_hid ? desc_configuration_ps4 : desc_configuration_ns;
}
//--------------------------------------------------------------------+
+72
View File
@@ -1,17 +1,23 @@
#ifndef USB_DESCRIPTORS_H_
#define USB_DESCRIPTORS_H_
#include <stdbool.h>
#include "common/tusb_common.h"
#include "device/usbd.h"
enum {
REPORT_ID_JOYSTICK = 1,
REPORT_ID_PS4_OUTPUT = 5,
REPORT_ID_LED_SLIDER_1 = 4,
REPORT_ID_LED_SLIDER_2 = 5,
REPORT_ID_LED_BUTTON = 6,
REPORT_ID_LED_COMPRESSED = 11,
};
#define DIVAPICO_PS4_VENDOR_ID 0x1532
#define DIVAPICO_PS4_PRODUCT_ID 0x0401
// because they are missing from tusb_hid.h
#define HID_STRING_INDEX(x) HID_REPORT_ITEM(x, 7, RI_TYPE_LOCAL, 1)
#define HID_STRING_INDEX_N(x, n) HID_REPORT_ITEM(x, 7, RI_TYPE_LOCAL, n)
@@ -62,6 +68,70 @@ enum {
HID_OUTPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
HID_COLLECTION_END
#define DIVAPICO_REPORT_DESC_PS4 \
0x05, 0x01, 0x09, 0x05, 0xA1, 0x01, \
0x85, 0x01, \
0x09, 0x30, 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, \
0x15, 0x00, 0x26, 0xFF, 0x00, \
0x75, 0x08, 0x95, 0x04, 0x81, 0x02, \
0x09, 0x39, 0x15, 0x00, 0x25, 0x07, 0x35, 0x00, 0x46, 0x3B, 0x01, \
0x65, 0x14, 0x75, 0x04, 0x95, 0x01, 0x81, 0x42, \
0x65, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x0E, \
0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x0E, 0x81, 0x02, \
0x06, 0x00, 0xFF, 0x09, 0x20, 0x75, 0x06, 0x95, 0x01, 0x81, 0x02, \
0x05, 0x01, 0x09, 0x33, 0x09, 0x34, \
0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x02, 0x81, 0x02, \
0x06, 0x00, 0xFF, 0x09, 0x21, 0x95, 0x36, 0x81, 0x02, \
0x85, 0x05, 0x09, 0x22, 0x95, 0x1F, 0x91, 0x02, \
0x85, 0x03, 0x0A, 0x21, 0x27, 0x95, 0x2F, 0xB1, 0x02, \
0x85, 0x02, 0x09, 0x24, 0x95, 0x24, 0xB1, 0x02, \
0x85, 0x08, 0x09, 0x25, 0x95, 0x03, 0xB1, 0x02, \
0x85, 0x10, 0x09, 0x26, 0x95, 0x04, 0xB1, 0x02, \
0x85, 0x11, 0x09, 0x27, 0x95, 0x02, 0xB1, 0x02, \
0x85, 0x12, 0x06, 0x02, 0xFF, 0x09, 0x21, 0x95, 0x0F, 0xB1, 0x02, \
0x85, 0x13, 0x09, 0x22, 0x95, 0x16, 0xB1, 0x02, \
0x85, 0x14, 0x06, 0x05, 0xFF, 0x09, 0x20, 0x95, 0x10, 0xB1, 0x02, \
0x85, 0x15, 0x09, 0x21, 0x95, 0x2C, 0xB1, 0x02, \
0x06, 0x80, 0xFF, \
0x85, 0x80, 0x09, 0x20, 0x95, 0x06, 0xB1, 0x02, \
0x85, 0x81, 0x09, 0x21, 0x95, 0x06, 0xB1, 0x02, \
0x85, 0x82, 0x09, 0x22, 0x95, 0x05, 0xB1, 0x02, \
0x85, 0x83, 0x09, 0x23, 0x95, 0x01, 0xB1, 0x02, \
0x85, 0x84, 0x09, 0x24, 0x95, 0x04, 0xB1, 0x02, \
0x85, 0x85, 0x09, 0x25, 0x95, 0x06, 0xB1, 0x02, \
0x85, 0x86, 0x09, 0x26, 0x95, 0x06, 0xB1, 0x02, \
0x85, 0x87, 0x09, 0x27, 0x95, 0x23, 0xB1, 0x02, \
0x85, 0x88, 0x09, 0x28, 0x95, 0x22, 0xB1, 0x02, \
0x85, 0x89, 0x09, 0x29, 0x95, 0x02, 0xB1, 0x02, \
0x85, 0x90, 0x09, 0x30, 0x95, 0x05, 0xB1, 0x02, \
0x85, 0x91, 0x09, 0x31, 0x95, 0x03, 0xB1, 0x02, \
0x85, 0x92, 0x09, 0x32, 0x95, 0x03, 0xB1, 0x02, \
0x85, 0x93, 0x09, 0x33, 0x95, 0x0C, 0xB1, 0x02, \
0x85, 0xA0, 0x09, 0x40, 0x95, 0x06, 0xB1, 0x02, \
0x85, 0xA1, 0x09, 0x41, 0x95, 0x01, 0xB1, 0x02, \
0x85, 0xA2, 0x09, 0x42, 0x95, 0x01, 0xB1, 0x02, \
0x85, 0xA3, 0x09, 0x43, 0x95, 0x30, 0xB1, 0x02, \
0x85, 0xA4, 0x09, 0x44, 0x95, 0x0D, 0xB1, 0x02, \
0x85, 0xA5, 0x09, 0x45, 0x95, 0x15, 0xB1, 0x02, \
0x85, 0xA6, 0x09, 0x46, 0x95, 0x15, 0xB1, 0x02, \
0x85, 0xA7, 0x09, 0x4A, 0x95, 0x01, 0xB1, 0x02, \
0x85, 0xA8, 0x09, 0x4B, 0x95, 0x01, 0xB1, 0x02, \
0x85, 0xA9, 0x09, 0x4C, 0x95, 0x08, 0xB1, 0x02, \
0x85, 0xAA, 0x09, 0x4E, 0x95, 0x01, 0xB1, 0x02, \
0x85, 0xAB, 0x09, 0x4F, 0x95, 0x39, 0xB1, 0x02, \
0x85, 0xAC, 0x09, 0x50, 0x95, 0x39, 0xB1, 0x02, \
0x85, 0xAD, 0x09, 0x51, 0x95, 0x0B, 0xB1, 0x02, \
0x85, 0xAE, 0x09, 0x52, 0x95, 0x01, 0xB1, 0x02, \
0x85, 0xAF, 0x09, 0x53, 0x95, 0x02, 0xB1, 0x02, \
0x85, 0xB0, 0x09, 0x54, 0x95, 0x3F, 0xB1, 0x02, \
0xC0, \
0x06, 0xF0, 0xFF, 0x09, 0x40, 0xA1, 0x01, \
0x85, 0xF0, 0x09, 0x47, 0x95, 0x3F, 0xB1, 0x02, \
0x85, 0xF1, 0x09, 0x48, 0x95, 0x3F, 0xB1, 0x02, \
0x85, 0xF2, 0x09, 0x49, 0x95, 0x0F, 0xB1, 0x02, \
0x85, 0xF3, 0x0A, 0x01, 0x47, 0x95, 0x07, 0xB1, 0x02, \
0xC0
#define DIVAPICO_LED_HEADER \
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), HID_USAGE(0x00), \
HID_COLLECTION(HID_COLLECTION_APPLICATION), \
@@ -110,4 +180,6 @@ enum {
HID_REPORT_SIZE(8), HID_REPORT_COUNT(63), \
HID_FEATURE(HID_DATA | HID_VARIABLE | HID_ABSOLUTE)
void hid_use_ps4(bool enable);
#endif /* USB_DESCRIPTORS_H_ */