diff --git a/firmware/src/CMakeLists.txt b/firmware/src/CMakeLists.txt index f7b072c..87f5f97 100644 --- a/firmware/src/CMakeLists.txt +++ b/firmware/src/CMakeLists.txt @@ -2,7 +2,7 @@ function(make_firmware board board_def) pico_sdk_init() add_executable(${board} main.c light.c button.c spin.c save.c config.c commands.c cli.c - tmag5273.c hid.c usb_descriptors.c) + tmag5273.c usb_descriptors.c) target_compile_definitions(${board} PUBLIC ${board_def}) pico_enable_stdio_usb(${board} 1) pico_enable_stdio_uart(${board} 0) diff --git a/firmware/src/board_defs.h b/firmware/src/board_defs.h index 88eecc5..a7ef8fc 100644 --- a/firmware/src/board_defs.h +++ b/firmware/src/board_defs.h @@ -14,7 +14,7 @@ #define BUS_I2C_FREQ 400*1000 #define SPIN_DEF { 13, 12, 11, 10, 9 } -#define BUTTON_DEF { 16, 17, 18, 19, 20, 21, 22, 2 } +#define BUTTON_DEF { 16, 17, 18, 19, 20, 22, 21, 2 } #else diff --git a/firmware/src/commands.c b/firmware/src/commands.c index 9dc62bd..0ffbc86 100644 --- a/firmware/src/commands.c +++ b/firmware/src/commands.c @@ -32,9 +32,15 @@ static void disp_hid() musec_cfg->hid.nkro ? "on" : "off" ); } +static void disp_spin() +{ + printf("[Spin]\n"); + printf(" Units per turn: %d.\n", musec_cfg->spin.units_per_turn); +} + void handle_display(int argc, char *argv[]) { - const char *usage = "Usage: display [light|hid\n"; + const char *usage = "Usage: display [light|spin|hid]\n"; if (argc > 1) { printf(usage); return; @@ -42,16 +48,20 @@ void handle_display(int argc, char *argv[]) if (argc == 0) { disp_light(); + disp_spin(); disp_hid(); return; } - const char *choices[] = {"light", "hid" }; + const char *choices[] = {"light", "spin", "hid" }; switch (cli_match_prefix(choices, count_of(choices), argv[0])) { case 0: disp_light(); break; case 1: + disp_spin(); + break; + case 2: disp_hid(); break; default: @@ -96,6 +106,26 @@ static void handle_level(int argc, char *argv[]) disp_light(); } +static void handle_spin(int argc, char *argv[]) +{ + const char *usage = "Usage: spin \n" + " units_per_turn: 20..255\n"; + if (argc != 1) { + printf(usage); + return; + } + + int units = cli_extract_non_neg_int(argv[0], 0); + if ((units < 20) || (units > 255)) { + printf(usage); + return; + } + + musec_cfg->spin.units_per_turn = units; + config_changed(); + disp_spin(); +} + static void handle_hid(int argc, char *argv[]) { const char *usage = "Usage: hid \n"; @@ -128,38 +158,12 @@ static void handle_factory_reset() printf("Factory reset done.\n"); } -static void handle_i2c(int argc, char *argv[]) -{ - if (argc != 1) { - return; - } - - const char *choices[] = {"set", "read", "change"}; - int match = cli_match_prefix(choices, count_of(choices), argv[0]); - if (match < 0) { - return; - } - - if (match == 0) { - } else if (match == 1) { - for (int i = 0; i <= 0x1c; i++) { - printf("0x%02x:%02x\n", i, tmag5273_read_reg(i)); - } - - uint16_t angle = tmag5273_read_angle(); - printf("angle: %d (%04x)\n", angle, angle); - } else if (match == 2) { - tmag5273_change_addr(0x12); - } -} - - void commands_init() { cli_register("display", handle_display, "Display all config."); cli_register("level", handle_level, "Set LED brightness level."); + cli_register("spin", handle_spin, "Set spin rate."); cli_register("hid", handle_hid, "Set HID mode."); cli_register("save", handle_save, "Save config to flash."); - cli_register("i2c", handle_i2c, "I2C test."); cli_register("factory", handle_factory_reset, "Reset everything to default."); } diff --git a/firmware/src/config.c b/firmware/src/config.c index d663b4e..b59da3d 100644 --- a/firmware/src/config.c +++ b/firmware/src/config.c @@ -12,20 +12,8 @@ musec_cfg_t *musec_cfg; static musec_cfg_t default_cfg = { - .lever = { - 2000, 2500, 0, - }, - .light = { - .level = 128, - .reserved = { 0 }, - }, - .tof = { - .roi = 12, - .reserved = { 0 }, - }, - .sound = { - .volume = 127, - .reserved = { 0 }, + .spin = { + .units_per_turn = 80, }, .hid = { .joy = 1, diff --git a/firmware/src/config.h b/firmware/src/config.h index 94397dc..2ac3fd8 100644 --- a/firmware/src/config.h +++ b/firmware/src/config.h @@ -16,24 +16,13 @@ typedef struct { typedef struct __attribute__((packed)) { struct { - uint16_t min; - uint16_t max; - uint8_t invert:1; - uint8_t reserved:7; - } lever; + uint8_t units_per_turn; + } spin; struct { rgb_hsv_t colors[12]; uint8_t level; uint8_t reserved[15]; } light; - struct { - uint8_t volume; - uint8_t reserved[3]; - } sound; - struct { - uint8_t roi; - uint8_t reserved[7]; - } tof; struct { uint8_t joy : 4; uint8_t nkro : 4; diff --git a/firmware/src/hid.c b/firmware/src/hid.c deleted file mode 100644 index cc3c92f..0000000 --- a/firmware/src/hid.c +++ /dev/null @@ -1,154 +0,0 @@ -#include -#include - -#include "board_defs.h" - -#include "tusb.h" -#include "usb_descriptors.h" -#include "button.h" -#include "config.h" -#include "light.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; - -static void gen_hid_analogs() -{ -} - -static void gen_hid_buttons() -{ - 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 - }; - - 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); - } - } -} - -static void gen_hid_coins() -{ -} - -static void report_usb_hid() -{ - if (tud_hid_ready()) { - if (musec_cfg->hid.joy || musec_runtime.key_stuck) { - gen_hid_analogs(); - gen_hid_buttons(); - gen_hid_coins(); - tud_hid_n_report(0, REPORT_ID_JOYSTICK, &hid_joy, sizeof(hid_joy)); - } - if (musec_cfg->hid.nkro && !musec_runtime.key_stuck) { - tud_hid_n_report(1, 0, &hid_nkro, sizeof(hid_nkro)); - } - } -} - -static void gen_nkro_report() -{ - if (!musec_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; - -static void update_led(const uint8_t data[4]) -{ - const uint8_t led_bit[18] = { 30, 31, 28, 26, 27, 29, 23, 25, 24, - 20, 22, 21, 17, 19, 18, 14, 16, 15 }; - - uint32_t leds = (data[0] << 24) | (data[1] << 16) | - (data[2] << 8) | data[3]; - - for (uint8_t i = 0; i < 6; i++) { - bool r = leds & (1 << led_bit[i * 3 + 1]); - bool g = leds & (1 << led_bit[i * 3 + 2]); - bool b = leds & (1 << led_bit[i * 3]); - uint32_t color = rgb32(r ? 0xff : 0, g ? 0xff : 0, b ? 0xff : 0, false); - light_set_main(i, color, true); - } -} - -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; - printf("USB set timeout/sampling\n"); - break; - case 0x03: // Clear Board Status - hid_joy.chutes[0] = 0; - hid_joy.chutes[1] = 0; - hid_joy.system_status = 0x00; - printf("USB clear status\n"); - break; - case 0x04: // Set General Output - // LED - update_led(output->payload); - break; - case 0x41: // I don't know what this is - break; - default: - printf("USB unknown cmd: %d\n", output->cmd); - break; - } - } -} diff --git a/firmware/src/hid.h b/firmware/src/hid.h deleted file mode 100644 index ea175f0..0000000 --- a/firmware/src/hid.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * HID Report Functions - * WHowe - */ - -#ifndef HID_H_ -#define HID_H_ - -void hid_update(); -void hid_proc(const uint8_t *data, uint8_t len); - -#endif diff --git a/firmware/src/light.c b/firmware/src/light.c index e866c6a..700b9aa 100644 --- a/firmware/src/light.c +++ b/firmware/src/light.c @@ -20,9 +20,9 @@ #include "board_defs.h" #include "config.h" -#define HID_TIMEOUT 300*1000*1000 +#define HID_TIMEOUT 10*1000*1000 -static uint32_t buf_rgb[37]; // left 3 + right 3 + button 4 * 7 + indicator 5 +static uint32_t buf_rgb[22]; // button 4 * 5 + aux * 2 static inline uint32_t _rgb32(uint32_t c1, uint32_t c2, uint32_t c3, bool gamma_fix) { @@ -131,64 +131,42 @@ void light_set(uint8_t index, uint32_t color) buf_rgb[index] = apply_level(color); } -void light_set_main(uint8_t index, uint32_t color, bool hid) +static bool bypass_check(bool hid) { static uint64_t hid_timeout = 0; uint64_t now = time_us_64(); - if (!hid && (now < hid_timeout)) { + + if (hid) { + hid_timeout = now + HID_TIMEOUT; + return false; + } + + return now < hid_timeout; +} + +void light_set_main(uint8_t index, uint32_t color, bool hid) +{ + if (bypass_check(hid)) { return; } - if (hid) { - hid_timeout = time_us_64() + HID_TIMEOUT; - } - - if (index < 3) { - light_set(index * 4 + 4, color); - light_set(index * 4 + 5, color); - light_set(index * 4 + 6, color); - light_set(index * 4 + 7, color); - } else if (index < 6) { - light_set(index * 4 + 9, color); - light_set(index * 4 + 10, color); - light_set(index * 4 + 11, color); - light_set(index * 4 + 12, color); + for (int i = 0; i < 4; i++) { + light_set(index * 4 + i, color); } } -void light_set_aux(uint8_t index, uint32_t color) +void light_set_start(uint32_t color, bool hid) { - if (index == 0) { - light_set(0, color); - } else if (index == 1) { - light_set(36, color); + if (bypass_check(hid)) { + return; } + light_set(20, color); } -void light_set_wad(uint8_t index, uint32_t color) +void light_set_aux(uint32_t color, bool hid) { - if (index == 0) { - light_set(1, color); - light_set(2, color); - light_set(3, color); - } else if (index == 1) { - light_set(33, color); - light_set(34, color); - light_set(35, color); - } -} - -void light_set_pos(uint8_t pos, uint32_t color) -{ - pos = pos * 5 / 256; - for (int i = 0; i < 5; i++) { - light_set(16 + i, (i == pos) ? color : 0); - } -} - -void light_set_aime(uint32_t color) -{ - for (int i = 0; i < 5; i++) { - light_set(16 + i, color); + if (bypass_check(hid)) { + return; } + light_set(21, color); } diff --git a/firmware/src/light.h b/firmware/src/light.h index 5851bf5..5be7759 100644 --- a/firmware/src/light.h +++ b/firmware/src/light.h @@ -20,10 +20,8 @@ uint32_t rgb32_from_hsv(uint8_t h, uint8_t s, uint8_t v); uint32_t load_color(const rgb_hsv_t *color); void light_set_main(uint8_t index, uint32_t color, bool hid); -void light_set_aux(uint8_t index, uint32_t color); -void light_set_wad(uint8_t index, uint32_t color); -void light_set_pos(uint8_t pos, uint32_t color); -void light_set_aime(uint32_t color); +void light_set_start(uint32_t color, bool hid); +void light_set_aux(uint32_t color, bool hid); void light_set(uint8_t index, uint32_t color); diff --git a/firmware/src/main.c b/firmware/src/main.c index 8aca678..8455479 100644 --- a/firmware/src/main.c +++ b/firmware/src/main.c @@ -28,14 +28,24 @@ #include "cli.h" #include "commands.h" -#include "hid.h" - #include "light.h" #include "button.h" #include "spin.h" static void run_lights() { + uint32_t phase = time_us_32() >> 16; + uint16_t button = button_read(); + for (int i = 0; i < 5; i++) { + uint32_t color = rgb32_from_hsv(phase + i * 35, 255, 255); + if (button & (1 << i)) { + color = rgb32(255, 255, 255, false); + } + light_set_main(i, color, false); + } + + light_set_start((button & 0x20) ? 0xffffff : rgb32(255, 10, 10, false), false); + light_set_aux((button & 0x40) ? 0xffffff : rgb32(180, 180, 10, false), false); } static mutex_t core1_io_lock; @@ -52,14 +62,21 @@ static void core1_loop() } } -static void read_spin() +struct __attribute__((packed)) { + uint8_t buttons; + uint8_t joy[6]; +} hid_report = {0}; + +static void hid_update() { - for (int i = 0; i < spin_num(); i++) { - uint16_t angle = spin_read(i); - float deg = angle / 16.0f; - printf(" %d:%7.2f", i, deg); + uint16_t buttons = button_read(); + hid_report.buttons = buttons; + for (int i = 0; i < 5; i++) { + hid_report.joy[i] = spin_units(i); + } + if (tud_hid_ready()) { + tud_hid_n_report(0, REPORT_ID_JOYSTICK, &hid_report, sizeof(hid_report)); } - printf("\n"); } static void core0_loop() @@ -76,7 +93,6 @@ static void core0_loop() spin_update(); hid_update(); - read_spin(); sleep_us(900); } @@ -138,12 +154,6 @@ int main(void) return 0; } -struct __attribute__((packed)) { - uint16_t buttons; - uint8_t HAT; - uint32_t axis; -} hid_joy_out = {0}; - // Invoked when received GET_REPORT control request // Application must fill buffer report's content and return its length. // Return zero will cause the stack to STALL request @@ -161,5 +171,13 @@ 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) { - hid_proc(buffer, bufsize); + if ((report_id == REPORT_ID_LIGHTS) && (bufsize >= 18)) { + printf("Set from USB %d-%d: %d\n", report_id, report_type, bufsize); + for (int i = 0; i < 5; i++) { + uint32_t color = rgb32(buffer[i * 3], buffer[i * 3 + 1], buffer[i * 3 + 2], false); + light_set_main(i, color, true); + } + light_set_start(rgb32(buffer[15], buffer[16], buffer[17], false), true); + light_set_aux(rgb32(buffer[15], buffer[16], buffer[17], false), true); + } } diff --git a/firmware/src/spin.c b/firmware/src/spin.c index db8fd46..a975582 100644 --- a/firmware/src/spin.c +++ b/firmware/src/spin.c @@ -19,6 +19,7 @@ #include "tmag5273.h" static const uint8_t spin_enablers[] = SPIN_DEF; +const uint16_t FULL_SCALE = 360 * 16; #define SPIN_NUM (count_of(spin_enablers)) @@ -41,6 +42,11 @@ void spin_init() tmag5273_init(i, BUS_I2C); tmag5273_init_sensor(); } + + if (musec_cfg->spin.units_per_turn == 0) { + musec_cfg->spin.units_per_turn = 80; + config_changed(); + } } uint8_t spin_num() @@ -65,3 +71,24 @@ uint16_t spin_read(uint8_t index) } return spin_reading[index]; } + +uint16_t spin_units(uint8_t index) +{ + static uint16_t last[SPIN_NUM] = {0}; + static int counter[SPIN_NUM] = {0}; + + int delta = spin_reading[index] - last[index]; + if (delta > FULL_SCALE / 2) { + delta -= FULL_SCALE; + } else if (delta < -FULL_SCALE / 2) { + delta += FULL_SCALE; + } + + int resolution = FULL_SCALE / musec_cfg->spin.units_per_turn; + if ((delta <= -resolution) || (delta >= resolution)) { + last[index] = spin_reading[index]; + counter[index] += delta; + } + + return counter[index] * musec_cfg->spin.units_per_turn / FULL_SCALE; +} diff --git a/firmware/src/spin.h b/firmware/src/spin.h index 1b0f296..a3964cb 100644 --- a/firmware/src/spin.h +++ b/firmware/src/spin.h @@ -14,5 +14,6 @@ void spin_init(); uint8_t spin_num(); void spin_update(); uint16_t spin_read(uint8_t index); +uint16_t spin_units(uint8_t index); #endif diff --git a/firmware/src/tmag5273.c b/firmware/src/tmag5273.c index d473236..15f555d 100644 --- a/firmware/src/tmag5273.c +++ b/firmware/src/tmag5273.c @@ -89,6 +89,7 @@ bool tmag5273_init_sensor() { tmag5273_write_reg(0x03, 0x01 << 2); // Enable angle calculation tmag5273_write_reg(0x02, 0x03 << 4); // X-Y + tmag5273_write_reg(0x00, 0x03 << 2); // 8x average mode tmag5273_write_reg(0x01, 0x02); // Continuous mode return true; } diff --git a/firmware/src/tusb_config.h b/firmware/src/tusb_config.h index c2a4dc0..0dd98ce 100644 --- a/firmware/src/tusb_config.h +++ b/firmware/src/tusb_config.h @@ -96,8 +96,8 @@ extern "C" { #endif //------------- CLASS -------------// -#define CFG_TUD_HID 2 -#define CFG_TUD_CDC 2 +#define CFG_TUD_HID 1 +#define CFG_TUD_CDC 1 #define CFG_TUD_MSC 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 diff --git a/firmware/src/usb_descriptors.c b/firmware/src/usb_descriptors.c index 2a3f55f..5fdf027 100644 --- a/firmware/src/usb_descriptors.c +++ b/firmware/src/usb_descriptors.c @@ -36,7 +36,7 @@ tusb_desc_device_t desc_device_joy = { .bDeviceProtocol = 0x00, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - .idVendor = 0x0ca3, + .idVendor = 0xcabe, .idProduct = 0x0021, .bcdDevice = 0x0100, @@ -59,10 +59,7 @@ uint8_t const* tud_descriptor_device_cb(void) { uint8_t const desc_hid_report_joy[] = { MUSEC_PICO_REPORT_DESC_JOYSTICK, -}; - -uint8_t const desc_hid_report_nkro[] = { - MUSEC_PICO_REPORT_DESC_NKRO, + MUSEC_PICO_REPORT_DESC_LIGHTS, }; // Invoked when received GET HID REPORT DESCRIPTOR @@ -73,8 +70,6 @@ uint8_t const* tud_hid_descriptor_report_cb(uint8_t itf) switch (itf) { case 0: return desc_hid_report_joy; - case 1: - return desc_hid_report_nkro; default: return NULL; } @@ -83,28 +78,18 @@ uint8_t const* tud_hid_descriptor_report_cb(uint8_t itf) // Configuration Descriptor //--------------------------------------------------------------------+ -enum { ITF_NUM_JOY, ITF_NUM_NKRO, - ITF_NUM_CLI, ITF_NUM_CLI_DATA, ITF_NUM_AIME, ITF_NUM_AIME_DATA, - ITF_NUM_TOTAL }; +enum { ITF_NUM_JOY, ITF_NUM_CLI, ITF_NUM_CLI_DATA, ITF_NUM_TOTAL }; #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + \ - TUD_HID_INOUT_DESC_LEN * 1 + \ TUD_HID_DESC_LEN * 1 + \ - TUD_CDC_DESC_LEN * 2) + TUD_CDC_DESC_LEN * 1) -#define EPNUM_JOY_OUT 0x01 -#define EPNUM_JOY_IN 0x81 - -#define EPNUM_NKRO 0x87 +#define EPNUM_JOY 0x81 #define EPNUM_CLI_NOTIF 0x89 #define EPNUM_CLI_OUT 0x0a #define EPNUM_CLI_IN 0x8a -#define EPNUM_AIME_NOTIF 0x8b -#define EPNUM_AIME_OUT 0x0c -#define EPNUM_AIME_IN 0x8c - uint8_t const desc_configuration_joy[] = { // Config number, interface count, string index, total length, attribute, // power in mA @@ -113,20 +98,12 @@ 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, + TUD_HID_DESCRIPTOR(ITF_NUM_JOY, 4, HID_ITF_PROTOCOL_NONE, + sizeof(desc_hid_report_joy), EPNUM_JOY, CFG_TUD_HID_EP_BUFSIZE, 1), - - 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, 6, EPNUM_CLI_NOTIF, + + TUD_CDC_DESCRIPTOR(ITF_NUM_CLI, 5, 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 @@ -143,13 +120,29 @@ static char serial_number_str[24] = "123456\0"; static const char *string_desc_arr[] = { (const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409) - "SEGA", // 1: Manufacturer - "Musec 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;", - "Musec Pico NKRO", - "Musec Pico CLI", - "Mai Pico AIME Port", + "WHowe", // 1: Manufacturer + "Musec Pico", // 2: Product + serial_number_str, // 3: Serials, use chip ID + "Musec Pico Joystick", + "Musec Pico CLI Port", + "Spinner 1 R", + "Spinner 1 G", + "Spinner 1 B", + "Spinner 2 R", + "Spinner 2 G", + "Spinner 2 B", + "Spinner 3 R", + "Spinner 3 G", + "Spinner 3 B", + "Spinner 4 R", + "Spinner 4 G", + "Spinner 4 B", + "Spinner 5 R", + "Spinner 5 G", + "Spinner 5 B", + "Title R", + "Title G", + "Title B", }; // Invoked when received GET STRING DESCRIPTOR request diff --git a/firmware/src/usb_descriptors.h b/firmware/src/usb_descriptors.h index dc0a797..bf84301 100644 --- a/firmware/src/usb_descriptors.h +++ b/firmware/src/usb_descriptors.h @@ -6,7 +6,7 @@ enum { REPORT_ID_JOYSTICK = 1, - REPORT_ID_OUTPUT = 16, + REPORT_ID_LIGHTS, }; // because they are missing from tusb_hid.h @@ -17,135 +17,40 @@ 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 to Emulate IO4 -#define MUSEC_PICO_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_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_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, \ +#define MUSEC_PICO_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(8), \ + HID_LOGICAL_MIN(0), HID_LOGICAL_MAX(1), \ + HID_REPORT_COUNT(8), HID_REPORT_SIZE(1), \ + HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \ + HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \ + HID_LOGICAL_MIN(0x00), HID_LOGICAL_MAX_N(0x00ff, 2), \ + HID_USAGE(HID_USAGE_DESKTOP_X), HID_USAGE(HID_USAGE_DESKTOP_Y), \ + HID_USAGE(HID_USAGE_DESKTOP_Z), \ + HID_USAGE(HID_USAGE_DESKTOP_RX), HID_USAGE(HID_USAGE_DESKTOP_RY), \ + HID_USAGE(HID_USAGE_DESKTOP_RZ), \ + HID_REPORT_COUNT(6), HID_REPORT_SIZE(8), \ + HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \ HID_COLLECTION_END -#define MUSEC_PICO_REPORT_DESC_NKRO \ - HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \ - HID_USAGE(HID_USAGE_DESKTOP_KEYBOARD), \ - HID_COLLECTION(HID_COLLECTION_APPLICATION), \ - /* Modifier */ \ - 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_DATA | HID_VARIABLE | HID_ABSOLUTE), \ - /* LED output that we don't care */ \ - HID_REPORT_COUNT(5), \ - HID_REPORT_SIZE(1), \ - HID_USAGE_PAGE(HID_USAGE_PAGE_LED), \ - HID_USAGE_MIN(1), \ - HID_USAGE_MAX(5), \ - HID_OUTPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \ - HID_REPORT_COUNT(1), \ - HID_REPORT_SIZE(3), \ - HID_OUTPUT(HID_CONSTANT), \ - /* Full Keyboard Bitmap */ \ - HID_REPORT_SIZE(1), \ - HID_REPORT_COUNT(120), \ - HID_LOGICAL_MIN(0), \ - HID_LOGICAL_MAX(1), \ - HID_USAGE_PAGE(HID_USAGE_PAGE_KEYBOARD), \ - HID_USAGE_MIN(0), \ - HID_USAGE_MAX(119), \ - HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \ - HID_COLLECTION_END - -// HID_REPORT_ID(REPORT_ID_NKRO) +#define MUSEC_PICO_REPORT_DESC_LIGHTS \ + HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \ + HID_USAGE(0x00), \ + HID_COLLECTION(HID_COLLECTION_APPLICATION), \ + HID_REPORT_ID(REPORT_ID_LIGHTS) \ + HID_REPORT_COUNT(18), HID_REPORT_SIZE(8), \ + HID_LOGICAL_MIN(0x00), HID_LOGICAL_MAX_N(0x00ff, 2), \ + HID_USAGE_PAGE(HID_USAGE_PAGE_ORDINAL), \ + HID_STRING_MINIMUM(6), HID_STRING_MAXIMUM(23), \ + HID_USAGE_MIN(1), HID_USAGE_MAX(255), \ + HID_OUTPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \ + HID_REPORT_COUNT(1), \ + HID_REPORT_SIZE(8), /*Padding*/ \ + HID_INPUT(HID_CONSTANT | HID_VARIABLE | HID_ABSOLUTE), \ + HID_COLLECTION_END #endif /* USB_DESCRIPTORS_H_ */