From c4f3a535e35a5f716e0dd0e625d3f0eec701d7e0 Mon Sep 17 00:00:00 2001 From: whowechina Date: Sun, 25 Feb 2024 19:32:27 +0800 Subject: [PATCH] IO4 output implemented and coin button working --- Production/firmware/mai_pico.uf2 | Bin 118784 -> 119296 bytes README.md | 2 +- README_CN.md | 2 +- firmware/src/board_defs.h | 1 + firmware/src/hid.c | 40 ++++++++++++++++++++++++++++++- firmware/src/hid.h | 1 + firmware/src/main.c | 1 + firmware/src/usb_descriptors.c | 10 +++++--- firmware/src/usb_descriptors.h | 11 +++++++++ 9 files changed, 62 insertions(+), 6 deletions(-) diff --git a/Production/firmware/mai_pico.uf2 b/Production/firmware/mai_pico.uf2 index c11c9e4ff85a7c0b404ed578af9e28cad297823e..d7c9eb13bce40c3781581b05b8b9ad38d58b99a3 100644 GIT binary patch delta 15086 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 A=l}o! diff --git a/README.md b/README.md index 42ab98c..f6c1737 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,7 @@ It's CC-NC. So DIY for yourself and for your friend, don't make money from it. * It has a command line to do configuration. You can use this Web Serial Terminal to connect to the USB serial port of the Mai Pico. (Note: "?" is for help) https://googlechromelabs.github.io/serial-terminal/ -* Button GPIOs can be remapped using `gpio` command. +* Button GPIOs can be remapped using `gpio` command. Firmware supports 8 main buttons on the ring and 4 auxiliary buttons (Test, Service, Navigate and Coin). * Daisy chained RGB LED numbers for each button can be assigned using `rgb` command. * LED brightness can be adjusted by `level` command. * There are MPR121 parameter tuning and sensitive settings, explore them yourself. diff --git a/README_CN.md b/README_CN.md index 9581d78..b2ce8af 100644 --- a/README_CN.md +++ b/README_CN.md @@ -124,7 +124,7 @@ https://github.com/whowechina/ * 它有一个命令行进行配置。你可以使用这个 Web Serial Terminal 连接到 Mai Pico 的 USB 串口。(注意:"?" 是帮助) https://googlechromelabs.github.io/serial-terminal/ -* 可以使用 `gpio` 命令重新映射按钮 GPIOs。 +* 可以使用 `gpio` 命令重新映射按钮 GPIOs,固件支持 8 个主按钮和 4 个辅助按钮(分别是:Test, Service, Navigate, Coin)。 * 可以使用 `rgb` 命令为每个按钮分配串联的 RGB LED 数量。 * 可以通过 `level` 命令调整 LED 的亮度。 * 有 MPR121 参数调整和灵敏度设置,自己探索。 diff --git a/firmware/src/board_defs.h b/firmware/src/board_defs.h index 1e1cdb5..0d498c2 100644 --- a/firmware/src/board_defs.h +++ b/firmware/src/board_defs.h @@ -14,6 +14,7 @@ #define RGB_ORDER GRB // or RGB #define RGB_BUTTON_MAP { 5, 4, 3, 2, 1, 0, 7, 6, 8, 9, 10, 11 } +/* 8 main buttons, Test, Service, Navigate, Coin */ #define BUTTON_DEF { 1, 0, 4, 5, 8, 9, 3, 2, 12, 11, 10, 14 } /* HID Keycode: https://github.com/hathach/tinyusb/blob/master/src/class/hid/hid.h */ diff --git a/firmware/src/hid.c b/firmware/src/hid.c index 5738edf..75fb191 100644 --- a/firmware/src/hid.c +++ b/firmware/src/hid.c @@ -43,10 +43,18 @@ static void report_usb_hid() { if (tud_hid_ready()) { if (mai_cfg->hid.joy) { + static uint16_t last_buttons = 0; uint16_t buttons = button_read(); hid_joy.buttons[0] = native_to_io4(buttons); hid_joy.buttons[1] = native_to_io4(0); + if (last_buttons ^ buttons & (1 << 11)) { + if ((buttons & (1 << 11)) && (hid_joy.chutes[0] < 0xff00)) { + // just pressed coin button + hid_joy.chutes[0] += 0x100; + } + } tud_hid_n_report(0, REPORT_ID_JOYSTICK, &hid_joy, sizeof(hid_joy)); + last_buttons = buttons; } if (mai_cfg->hid.nkro) { tud_hid_n_report(1, 0, &hid_nkro, sizeof(hid_nkro)); @@ -81,4 +89,34 @@ void hid_update() { gen_nkro_report(); report_usb_hid(); -} \ No newline at end of file +} + +typedef struct __attribute__((packed)) { + uint8_t report_id; + uint8_t cmd; + uint8_t payload[62]; +} hid_output_t; + +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; + break; + case 0x03: // Clear Board Status + hid_joy.chutes[0] = 0; + hid_joy.chutes[1] = 0; + hid_joy.system_status = 0x00; + break; + case 0x04: // Set General Output + 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 index 741ca6d..ea175f0 100644 --- a/firmware/src/hid.h +++ b/firmware/src/hid.h @@ -7,5 +7,6 @@ #define HID_H_ void hid_update(); +void hid_proc(const uint8_t *data, uint8_t len); #endif diff --git a/firmware/src/main.c b/firmware/src/main.c index 99f7e6b..79b0534 100644 --- a/firmware/src/main.c +++ b/firmware/src/main.c @@ -135,4 +135,5 @@ 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); } diff --git a/firmware/src/usb_descriptors.c b/firmware/src/usb_descriptors.c index dbf82b1..3cce6b0 100644 --- a/firmware/src/usb_descriptors.c +++ b/firmware/src/usb_descriptors.c @@ -89,9 +89,13 @@ enum { ITF_NUM_JOY, ITF_NUM_NKRO, ITF_NUM_CDC_LED, ITF_NUM_CDC_LED_DATA, ITF_NUM_TOTAL }; -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN * 2 + TUD_CDC_DESC_LEN * 3) +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + \ + TUD_HID_INOUT_DESC_LEN * 1 + \ + TUD_HID_DESC_LEN * 1 + \ + TUD_CDC_DESC_LEN * 3) #define EPNUM_JOY 0x81 +#define EPNUM_OUTPUT 0x01 #define EPNUM_KEY 0x82 #define EPNUM_CDC_CLI_NOTIF 0x83 @@ -114,8 +118,8 @@ uint8_t const desc_configuration_joy[] = { // Interface number, string index, protocol, report descriptor len, EP In // address, size & polling interval - TUD_HID_DESCRIPTOR(ITF_NUM_JOY, 4, HID_ITF_PROTOCOL_NONE, - sizeof(desc_hid_report_joy), EPNUM_JOY, + TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_JOY, 4, HID_ITF_PROTOCOL_NONE, + sizeof(desc_hid_report_joy), EPNUM_OUTPUT, EPNUM_JOY, CFG_TUD_HID_EP_BUFSIZE, 1), TUD_HID_DESCRIPTOR(ITF_NUM_NKRO, 5, HID_ITF_PROTOCOL_NONE, diff --git a/firmware/src/usb_descriptors.h b/firmware/src/usb_descriptors.h index c533016..3a939cf 100644 --- a/firmware/src/usb_descriptors.h +++ b/firmware/src/usb_descriptors.h @@ -6,6 +6,7 @@ enum { REPORT_ID_JOYSTICK = 1, + REPORT_ID_OUTPUT = 16, }; // because they are missing from tusb_hid.h @@ -99,6 +100,16 @@ enum { \ 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, \ HID_COLLECTION_END #define MAIPICO_REPORT_DESC_NKRO \