diff --git a/Production/firmware/mai_pico.uf2 b/Production/firmware/mai_pico.uf2 index 4cd1162..16e737a 100644 Binary files a/Production/firmware/mai_pico.uf2 and b/Production/firmware/mai_pico.uf2 differ diff --git a/firmware/src/board_defs.h b/firmware/src/board_defs.h index e239b75..a5f8b25 100644 --- a/firmware/src/board_defs.h +++ b/firmware/src/board_defs.h @@ -12,14 +12,14 @@ #define RGB_PIN 13 #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 */ // P1: WEDCXZAQ34 P2: (Numpad)89632147*- -#define BUTTON_NKRO_MAP_P1 "\x1a\x08\x07\x06\x1b\x1d\x04\x14\x20\x21" -#define BUTTON_NKRO_MAP_P2 "\x60\x61\x5e\x5b\x5a\x59\x5c\x5f\x55\x56" +#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\x57" #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, \ diff --git a/firmware/src/commands.c b/firmware/src/commands.c index d5c5874..47614cc 100644 --- a/firmware/src/commands.c +++ b/firmware/src/commands.c @@ -10,6 +10,7 @@ #include "tusb.h" #include "touch.h" +#include "button.h" #include "config.h" #include "save.h" #include "cli.h" @@ -367,7 +368,7 @@ static void handle_save() save_request(true); } -static void handle_factory_reset() +static void handle_joy_reset() { config_factory_reset(); printf("Factory reset done.\n"); diff --git a/firmware/src/hid.c b/firmware/src/hid.c index b0dd8b9..2423398 100644 --- a/firmware/src/hid.c +++ b/firmware/src/hid.c @@ -10,7 +10,13 @@ #include "hid.h" 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; struct __attribute__((packed)) { @@ -18,11 +24,28 @@ struct __attribute__((packed)) { uint8_t keymap[15]; } 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() { if (tud_hid_ready()) { 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)); } 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_p2[10] = BUTTON_NKRO_MAP_P2; +const char keymap_p1[] = BUTTON_NKRO_MAP_P1; +const char keymap_p2[] = BUTTON_NKRO_MAP_P2; static void gen_nkro_report() { diff --git a/firmware/src/usb_descriptors.c b/firmware/src/usb_descriptors.c index 354aea0..dbf82b1 100644 --- a/firmware/src/usb_descriptors.c +++ b/firmware/src/usb_descriptors.c @@ -36,8 +36,8 @@ tusb_desc_device_t desc_device_joy = { .bDeviceProtocol = 0x00, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - .idVendor = 0x1f2d, - .idProduct = 0x0123, + .idVendor = 0x0ca3, + .idProduct = 0x0021, .bcdDevice = 0x0100, .iManufacturer = 0x01, @@ -148,10 +148,10 @@ static char serial_number_str[24] = "123456\0"; // array of pointer to string descriptors static const char *string_desc_arr[] = { (const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409) - "WHowe", // 1: Manufacturer - "Mai Pico Controller", // 2: Product - serial_number_str, // 3: Serials, use chip ID - "Mai Pico Joystick", + "SEGA", // 1: Manufacturer + "Mai 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;", "Mai Pico NKRO", "Mai Pico Command Serial Port", "Mai Pico Touch Serial Port", @@ -163,7 +163,7 @@ static 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); @@ -176,32 +176,11 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) pico_get_unique_board_id(&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 *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); - } + const char *str = string_desc_arr[index]; uint8_t chr_count = strlen(str); - if (chr_count > 63) { - chr_count = 63; + if (chr_count > 128) { + chr_count = 128; } // Convert ASCII string into UTF-16 diff --git a/firmware/src/usb_descriptors.h b/firmware/src/usb_descriptors.h index 5f7bcbe..c533016 100644 --- a/firmware/src/usb_descriptors.h +++ b/firmware/src/usb_descriptors.h @@ -16,20 +16,89 @@ 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 +// Joystick Report Descriptor to Emulate IO4 #define MAIPICO_REPORT_DESC_JOYSTICK \ HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \ HID_USAGE(HID_USAGE_DESKTOP_JOYSTICK), \ HID_COLLECTION(HID_COLLECTION_APPLICATION), \ HID_REPORT_ID(REPORT_ID_JOYSTICK) \ - HID_USAGE_PAGE(HID_USAGE_PAGE_BUTTON), \ - HID_USAGE_MIN(1), HID_USAGE_MAX(10), \ - HID_LOGICAL_MIN(0), HID_LOGICAL_MAX(1), \ - HID_REPORT_COUNT(10), HID_REPORT_SIZE(1), \ + \ + 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 - 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 #define MAIPICO_REPORT_DESC_NKRO \