mirror of
https://github.com/whowechina/musec_pico.git
synced 2026-10-01 11:27:58 +03:00
Firmware working
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
+33
-29
@@ -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 <units_per_turn>\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 <joy|nkro|both>\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.");
|
||||
}
|
||||
|
||||
+2
-14
@@ -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,
|
||||
|
||||
+2
-13
@@ -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;
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
+25
-47
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
+34
-16
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+34
-129
@@ -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_ */
|
||||
|
||||
Reference in New Issue
Block a user