diff --git a/firmware/src/commands.c b/firmware/src/commands.c index 2f5e50d..d6a5d05 100644 --- a/firmware/src/commands.c +++ b/firmware/src/commands.c @@ -15,6 +15,8 @@ #include "save.h" #include "cli.h" +#include "aime.h" + #define SENSE_LIMIT_MAX 9 #define SENSE_LIMIT_MIN -9 @@ -61,6 +63,12 @@ static void disp_hid() mai_cfg->hid.nkro <= 2 ? nkro[mai_cfg->hid.nkro] : "key1"); } +static void disp_aime() +{ + printf("[AIME]\n"); + printf(" Virtual AIC: %s\n", mai_cfg->virtual_aic ? "ON" : "OFF"); +} + static void disp_gpio() { printf("[GPIO]\n"); @@ -75,7 +83,7 @@ static void disp_gpio() void handle_display(int argc, char *argv[]) { - const char *usage = "Usage: display [rgb|sense|hid|gpio]\n"; + const char *usage = "Usage: display [rgb|sense|hid|gpio|aime]\n"; if (argc > 1) { printf(usage); return; @@ -86,11 +94,12 @@ void handle_display(int argc, char *argv[]) disp_sense(); disp_hid(); disp_gpio(); + disp_aime(); return; } - const char *choices[] = {"rgb", "sense", "hid", "gpio"}; - switch (cli_match_prefix(choices, 4, argv[0])) { + const char *choices[] = {"rgb", "sense", "hid", "gpio", "aime"}; + switch (cli_match_prefix(choices, 5, argv[0])) { case 0: disp_rgb(); break; @@ -103,6 +112,9 @@ void handle_display(int argc, char *argv[]) case 3: disp_gpio(); break; + case 4: + disp_aime(); + break; default: printf(usage); break; @@ -444,6 +456,27 @@ static void handle_gpio(int argc, char *argv[]) disp_gpio(); } +static void handle_virtual(int argc, char *argv[]) +{ + const char *usage = "Usage: virtual \n"; + if (argc != 1) { + printf("%s", usage); + return; + } + + const char *commands[] = { "on", "off" }; + int match = cli_match_prefix(commands, 2, argv[0]); + if (match < 0) { + printf("%s", usage); + return; + } + + mai_cfg->virtual_aic = (match == 0); + + aime_virtual_aic(mai_cfg->virtual_aic); + config_changed(); +} + void commands_init() { cli_register("display", handle_display, "Display all config."); @@ -459,4 +492,5 @@ void commands_init() cli_register("save", handle_save, "Save config to flash."); cli_register("gpio", handle_gpio, "Set GPIO pins for buttons."); cli_register("factory", config_factory_reset, "Reset everything to default."); + cli_register("virtual", handle_virtual, "Virtual AIC card on AIME."); } diff --git a/firmware/src/config.c b/firmware/src/config.c index 80b539f..b2c3108 100644 --- a/firmware/src/config.c +++ b/firmware/src/config.c @@ -33,6 +33,7 @@ static mai_cfg_t default_cfg = { .alt = { .buttons = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, }, + .virtual_aic = false, }; mai_runtime_t *mai_runtime; diff --git a/firmware/src/config.h b/firmware/src/config.h index 3323727..2c04bd8 100644 --- a/firmware/src/config.h +++ b/firmware/src/config.h @@ -33,6 +33,7 @@ typedef struct __attribute__((packed)) { struct { uint8_t buttons[12]; } alt; + bool virtual_aic; } mai_cfg_t; typedef struct { diff --git a/firmware/src/main.c b/firmware/src/main.c index 79b0534..c501a66 100644 --- a/firmware/src/main.c +++ b/firmware/src/main.c @@ -21,6 +21,9 @@ #include "tusb.h" #include "usb_descriptors.h" +#include "aime.h" +#include "nfc.h" + #include "board_defs.h" #include "touch.h" @@ -51,6 +54,25 @@ static void run_lights() } } + +const int aime_intf = 3; +static void cdc_aime_putc(uint8_t byte) +{ + tud_cdc_n_write(aime_intf, &byte, 1); + tud_cdc_n_write_flush(aime_intf); +} + +static void aime_run() +{ + if (tud_cdc_n_available(aime_intf)) { + uint8_t buf[32]; + uint32_t count = tud_cdc_n_read(aime_intf, buf, sizeof(buf)); + + for (int i = 0; i < count; i++) { + aime_feed(buf[i]); + } + } +} static mutex_t core1_io_lock; static void core1_loop() { @@ -74,6 +96,7 @@ static void core0_loop() io_update(); cli_run(); + aime_run(); save_loop(); cli_fps_count(0); @@ -105,6 +128,11 @@ void init() button_init(); rgb_init(); + nfc_attach_i2c(I2C_PORT); + nfc_init(); + aime_init(cdc_aime_putc); + aime_virtual_aic(mai_cfg->virtual_aic); + cli_init("mai_pico>", "\n << Mai Pico Controller >>\n" " https://github.com/whowechina\n\n"); commands_init(); diff --git a/firmware/src/tusb_config.h b/firmware/src/tusb_config.h index d404cfc..bcb827d 100644 --- a/firmware/src/tusb_config.h +++ b/firmware/src/tusb_config.h @@ -97,7 +97,7 @@ extern "C" { //------------- CLASS -------------// #define CFG_TUD_HID 2 -#define CFG_TUD_CDC 3 +#define CFG_TUD_CDC 4 #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 3cce6b0..e6d0f3e 100644 --- a/firmware/src/usb_descriptors.c +++ b/firmware/src/usb_descriptors.c @@ -87,12 +87,13 @@ enum { ITF_NUM_JOY, ITF_NUM_NKRO, ITF_NUM_CDC_CLI, ITF_NUM_CDC_CLI_DATA, ITF_NUM_CDC_TOUCH, ITF_NUM_CDC_TOUCH_DATA, ITF_NUM_CDC_LED, ITF_NUM_CDC_LED_DATA, + ITF_NUM_CDC_AIME, ITF_NUM_CDC_AIME_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 * 3) + TUD_CDC_DESC_LEN * 4) #define EPNUM_JOY 0x81 #define EPNUM_OUTPUT 0x01 @@ -105,10 +106,14 @@ enum { ITF_NUM_JOY, ITF_NUM_NKRO, #define EPNUM_CDC_TOUCH_NOTIF 0x85 #define EPNUM_CDC_TOUCH_OUT 0x06 #define EPNUM_CDC_TOUCH_IN 0x86 + #define EPNUM_CDC_LED_NOTIF 0x87 #define EPNUM_CDC_LED_OUT 0x08 #define EPNUM_CDC_LED_IN 0x88 +#define EPNUM_CDC_AIME_NOTIF 0x89 +#define EPNUM_CDC_AIME_OUT 0x0a +#define EPNUM_CDC_AIME_IN 0x8a uint8_t const desc_configuration_joy[] = { // Config number, interface count, string index, total length, attribute, @@ -134,6 +139,9 @@ uint8_t const desc_configuration_joy[] = { TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_LED, 8, EPNUM_CDC_LED_NOTIF, 8, EPNUM_CDC_LED_OUT, EPNUM_CDC_LED_IN, 64), + + TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_AIME, 9, EPNUM_CDC_AIME_NOTIF, + 8, EPNUM_CDC_AIME_OUT, EPNUM_CDC_AIME_IN, 64), }; // Invoked when received GET CONFIGURATION DESCRIPTOR @@ -157,9 +165,10 @@ static const char *string_desc_arr[] = { 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", - "Mai Pico LED Serial Port", + "Mai Pico Command Line", + "Mai Pico Touch", + "Mai Pico LED", + "Mai Pico AIME", }; // Invoked when received GET STRING DESCRIPTOR request