Button via IO4 Support

This commit is contained in:
whowechina 2023-12-09 20:30:23 +08:00
parent be41372545
commit 1eaba3adb5
6 changed files with 120 additions and 48 deletions

Binary file not shown.

View File

@ -12,14 +12,14 @@
#define RGB_PIN 13 #define RGB_PIN 13
#define RGB_ORDER GRB // or RGB #define RGB_ORDER GRB // or RGB
#define RGB_BUTTON_MAP { 5, 4, 3, 2, 1, 0, 7, 6, 8, 9 } #define RGB_BUTTON_MAP { 5, 4, 3, 2, 1, 0, 7, 6, 8, 9, 10 }
#define BUTTON_DEF { 1, 0, 4, 5, 8, 9, 3, 2, 10, 11 } #define BUTTON_DEF { 1, 0, 4, 5, 8, 9, 3, 2, 12, 10, 11}
/* HID Keycode: https://github.com/hathach/tinyusb/blob/master/src/class/hid/hid.h */ /* HID Keycode: https://github.com/hathach/tinyusb/blob/master/src/class/hid/hid.h */
// P1: WEDCXZAQ34 P2: (Numpad)89632147*- // P1: WEDCXZAQ34 P2: (Numpad)89632147*-
#define BUTTON_NKRO_MAP_P1 "\x1a\x08\x07\x06\x1b\x1d\x04\x14\x20\x21" #define BUTTON_NKRO_MAP_P1 "\x1a\x08\x07\x06\x1b\x1d\x04\x14\x20\x21\x22"
#define BUTTON_NKRO_MAP_P2 "\x60\x61\x5e\x5b\x5a\x59\x5c\x5f\x55\x56" #define BUTTON_NKRO_MAP_P2 "\x60\x61\x5e\x5b\x5a\x59\x5c\x5f\x55\x56\x57"
#define TOUCH_MAP { E3, A2, B2, D2, E2, A1, B1, D1, E1, C2, A8, B8, \ #define TOUCH_MAP { E3, A2, B2, D2, E2, A1, B1, D1, E1, C2, A8, B8, \
D8, E8, A7, B7, D7, E7, A6, B6, D6, E6, A5, B5, \ D8, E8, A7, B7, D7, E7, A6, B6, D6, E6, A5, B5, \

View File

@ -10,6 +10,7 @@
#include "tusb.h" #include "tusb.h"
#include "touch.h" #include "touch.h"
#include "button.h"
#include "config.h" #include "config.h"
#include "save.h" #include "save.h"
#include "cli.h" #include "cli.h"
@ -367,7 +368,7 @@ static void handle_save()
save_request(true); save_request(true);
} }
static void handle_factory_reset() static void handle_joy_reset()
{ {
config_factory_reset(); config_factory_reset();
printf("Factory reset done.\n"); printf("Factory reset done.\n");

View File

@ -10,7 +10,13 @@
#include "hid.h" #include "hid.h"
struct __attribute__((packed)) { struct __attribute__((packed)) {
uint16_t buttons; 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; } hid_joy;
struct __attribute__((packed)) { struct __attribute__((packed)) {
@ -18,11 +24,28 @@ struct __attribute__((packed)) {
uint8_t keymap[15]; uint8_t keymap[15];
} hid_nkro; } hid_nkro;
static uint16_t native_to_io4(uint16_t button)
{
static const int target_pos[] = { 2, 3, 0, 15, 14, 13, 12, 11, 1, 9, 6 };
uint16_t io4btn = 0;
for (int i = 0; i < 8; i++) {
bool pressed = button & (1 << i);
io4btn |= pressed ? 0 : (1 << target_pos[i]);
}
for (int i = 8; i < 11; i++) {
bool pressed = button & (1 << i);
io4btn |= pressed ? (1 << target_pos[i]) : 0;
}
return io4btn;
}
static void report_usb_hid() static void report_usb_hid()
{ {
if (tud_hid_ready()) { if (tud_hid_ready()) {
if (mai_cfg->hid.joy) { if (mai_cfg->hid.joy) {
hid_joy.buttons = button_read(); uint16_t buttons = button_read();
hid_joy.buttons[0] = native_to_io4(buttons);
hid_joy.buttons[1] = native_to_io4(0);
tud_hid_n_report(0, REPORT_ID_JOYSTICK, &hid_joy, sizeof(hid_joy)); tud_hid_n_report(0, REPORT_ID_JOYSTICK, &hid_joy, sizeof(hid_joy));
} }
if (mai_cfg->hid.nkro) { if (mai_cfg->hid.nkro) {
@ -31,8 +54,8 @@ static void report_usb_hid()
} }
} }
const char keymap_p1[10] = BUTTON_NKRO_MAP_P1; const char keymap_p1[] = BUTTON_NKRO_MAP_P1;
const char keymap_p2[10] = BUTTON_NKRO_MAP_P2; const char keymap_p2[] = BUTTON_NKRO_MAP_P2;
static void gen_nkro_report() static void gen_nkro_report()
{ {

View File

@ -36,8 +36,8 @@ tusb_desc_device_t desc_device_joy = {
.bDeviceProtocol = 0x00, .bDeviceProtocol = 0x00,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = 0x1f2d, .idVendor = 0x0ca3,
.idProduct = 0x0123, .idProduct = 0x0021,
.bcdDevice = 0x0100, .bcdDevice = 0x0100,
.iManufacturer = 0x01, .iManufacturer = 0x01,
@ -148,10 +148,10 @@ static char serial_number_str[24] = "123456\0";
// array of pointer to string descriptors // array of pointer to string descriptors
static const char *string_desc_arr[] = { static const char *string_desc_arr[] = {
(const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409) (const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409)
"WHowe", // 1: Manufacturer "SEGA", // 1: Manufacturer
"Mai Pico Controller", // 2: Product "Mai Pico", // 2: Product
serial_number_str, // 3: Serials, use chip ID serial_number_str, // 3: Serials, use chip ID
"Mai Pico Joystick", "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;",
"Mai Pico NKRO", "Mai Pico NKRO",
"Mai Pico Command Serial Port", "Mai Pico Command Serial Port",
"Mai Pico Touch Serial Port", "Mai Pico Touch Serial Port",
@ -163,7 +163,7 @@ static const char *string_desc_arr[] = {
// enough for transfer to complete // 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)
{ {
static uint16_t _desc_str[64]; static uint16_t _desc_str[128];
if (index == 0) { if (index == 0) {
memcpy(&_desc_str[1], string_desc_arr[0], 2); memcpy(&_desc_str[1], string_desc_arr[0], 2);
@ -177,31 +177,10 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
sprintf(serial_number_str, "%016llx", *(uint64_t *)&board_id); sprintf(serial_number_str, "%016llx", *(uint64_t *)&board_id);
} }
const size_t base_num = sizeof(string_desc_arr) / sizeof(string_desc_arr[0]); const char *str = string_desc_arr[index];
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);
}
uint8_t chr_count = strlen(str); uint8_t chr_count = strlen(str);
if (chr_count > 63) { if (chr_count > 128) {
chr_count = 63; chr_count = 128;
} }
// Convert ASCII string into UTF-16 // Convert ASCII string into UTF-16

View File

@ -16,20 +16,89 @@ enum {
#define HID_STRING_MAXIMUM(x) HID_REPORT_ITEM(x, 9, RI_TYPE_LOCAL, 1) #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) #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 // Joystick Report Descriptor to Emulate IO4
// Button Map | X | Y
#define MAIPICO_REPORT_DESC_JOYSTICK \ #define MAIPICO_REPORT_DESC_JOYSTICK \
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \ HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
HID_USAGE(HID_USAGE_DESKTOP_JOYSTICK), \ HID_USAGE(HID_USAGE_DESKTOP_JOYSTICK), \
HID_COLLECTION(HID_COLLECTION_APPLICATION), \ HID_COLLECTION(HID_COLLECTION_APPLICATION), \
HID_REPORT_ID(REPORT_ID_JOYSTICK) \ HID_REPORT_ID(REPORT_ID_JOYSTICK) \
HID_USAGE_PAGE(HID_USAGE_PAGE_BUTTON), \ \
HID_USAGE_MIN(1), HID_USAGE_MAX(10), \ HID_REPORT_COUNT(1), HID_REPORT_SIZE(16), \
HID_LOGICAL_MIN(0), HID_LOGICAL_MAX(1), \ HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
HID_REPORT_COUNT(10), HID_REPORT_SIZE(1), \ HID_USAGE(HID_USAGE_DESKTOP_X), \
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \ HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
HID_REPORT_COUNT(1), HID_REPORT_SIZE(16 - 10), /*Padding*/ \ \
HID_INPUT(HID_CONSTANT | 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_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_COLLECTION_END HID_COLLECTION_END
#define MAIPICO_REPORT_DESC_NKRO \ #define MAIPICO_REPORT_DESC_NKRO \