diff --git a/firmware/src/CMakeLists.txt b/firmware/src/CMakeLists.txt index 2685fa6..da7d95c 100644 --- a/firmware/src/CMakeLists.txt +++ b/firmware/src/CMakeLists.txt @@ -4,7 +4,7 @@ set(LWIP_ROOT ${PICO_SDK_PATH}/lib/lwip) function(make_firmware board board_def) pico_sdk_init() add_executable(${board} - main.c touch.c button.c rgb.c save.c config.c cli.c commands.c io.c + main.c touch.c button.c rgb.c save.c config.c cli.c commands.c io.c hid.c mpr121.c usb_descriptors.c) target_compile_definitions(${board} PUBLIC ${board_def}) pico_enable_stdio_usb(${board} 1) diff --git a/firmware/src/board_defs.h b/firmware/src/board_defs.h index 945de2b..1f8eb82 100644 --- a/firmware/src/board_defs.h +++ b/firmware/src/board_defs.h @@ -15,7 +15,11 @@ #define RGB_BUTTON_MAP { 5, 4, 3, 2, 1, 0, 7, 6 } #define BUTTON_DEF { 1, 0, 4, 5, 8, 9, 3, 2 } -#define BUTTON_NKRO_MAP "WEDCXZAQ" + +/* 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 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/cli.c b/firmware/src/cli.c index 3f6ed29..3ba1ffc 100644 --- a/firmware/src/cli.c +++ b/firmware/src/cli.c @@ -6,8 +6,8 @@ #include "pico/stdio.h" #include "pico/stdlib.h" -#include "pico/unique_id.h" #include "cli.h" +#include "save.h" #define MAX_COMMANDS 32 #define MAX_PARAMETERS 6 @@ -58,9 +58,7 @@ int cli_match_prefix(const char *str[], int num, const char *prefix) static void handle_help(int argc, char *argv[]) { printf("%s", cli_logo); - pico_unique_board_id_t sn; - pico_get_unique_board_id(&sn); - printf("\tSN: %016llx\n\n", sn); + printf("\tSN: %016llx\n\n", board_id_64()); printf("Available commands:\n"); for (int i = 0; i < num_commands; i++) { printf("%*s: %s\n", max_cmd_len + 2, commands[i], helps[i]); diff --git a/firmware/src/commands.c b/firmware/src/commands.c index f03b199..1558c65 100644 --- a/firmware/src/commands.c +++ b/firmware/src/commands.c @@ -17,21 +17,11 @@ #define SENSE_LIMIT_MAX 9 #define SENSE_LIMIT_MIN -9 -static void disp_colors() +static void disp_color() { - printf("[Colors]\n"); - printf(" Key upper: %06x, lower: %06x, both: %06x, off: %06x\n", - mai_cfg->colors.key_on_upper, mai_cfg->colors.key_on_lower, - mai_cfg->colors.key_on_both, mai_cfg->colors.key_off); - printf(" Gap: %06x\n", mai_cfg->colors.gap); -} - -static void disp_style() -{ - printf("[Style]\n"); - printf(" Key: %d, Gap: %d, ToF: %d, Level: %d\n", - mai_cfg->style.key, mai_cfg->style.gap, - mai_cfg->style.tof, mai_cfg->style.level); + printf("[Color]\n"); + printf(" Key on: %06x, off: %06x\n Level: %d\n", + mai_cfg->color.key_on, mai_cfg->color.key_off, mai_cfg->color.level); } static void disp_sense() @@ -59,39 +49,35 @@ static void disp_sense() static void disp_hid() { printf("[HID]\n"); - printf(" Joy: %s, NKRO: %s.\n", - mai_cfg->hid.joy ? "on" : "off", - mai_cfg->hid.nkro ? "on" : "off" ); + const char *nkro[] = {"off", "key1", "key2"}; + printf(" Joy: %s, NKRO: %s\n", mai_cfg->hid.joy ? "on" : "off", + mai_cfg->hid.nkro <= 2 ? nkro[mai_cfg->hid.nkro] : "key1"); } void handle_display(int argc, char *argv[]) { - const char *usage = "Usage: display [colors|style|tof|sense|hid]\n"; + const char *usage = "Usage: display [color|sense|hid]\n"; if (argc > 1) { printf(usage); return; } if (argc == 0) { - disp_colors(); - disp_style(); + disp_color(); disp_sense(); disp_hid(); return; } - const char *choices[] = {"colors", "style", "sense", "hid"}; - switch (cli_match_prefix(choices, 5, argv[0])) { + const char *choices[] = {"color", "sense", "hid"}; + switch (cli_match_prefix(choices, 3, argv[0])) { case 0: - disp_colors(); + disp_color(); break; case 1: - disp_style(); - break; - case 2: disp_sense(); break; - case 3: + case 2: disp_hid(); break; default: @@ -114,9 +100,9 @@ static void handle_level(int argc, char *argv[]) return; } - mai_cfg->style.level = level; + mai_cfg->color.level = level; config_changed(); - disp_style(); + disp_color(); } static void handle_stat(int argc, char *argv[]) @@ -143,21 +129,35 @@ static void handle_stat(int argc, char *argv[]) static void handle_hid(int argc, char *argv[]) { - const char *usage = "Usage: hid \n"; + const char *usage = "Usage: hid hid.joy = ((match == 0) || (match == 2)) ? 1 : 0; - mai_cfg->hid.nkro = ((match == 1) || (match == 2)) ? 1 : 0; + switch (match) { + break; + case 1: + mai_cfg->hid.joy = 0; + mai_cfg->hid.nkro = 1; + break; + case 2: + mai_cfg->hid.joy = 0; + mai_cfg->hid.nkro = 2; + break; + case 0: + default: + mai_cfg->hid.joy = 1; + mai_cfg->hid.nkro = 0; + break; + } config_changed(); disp_hid(); } diff --git a/firmware/src/config.c b/firmware/src/config.c index 93f3bac..385038c 100644 --- a/firmware/src/config.c +++ b/firmware/src/config.c @@ -12,23 +12,11 @@ mai_cfg_t *mai_cfg; static mai_cfg_t default_cfg = { - .colors = { - .key_on_upper = 0x00FF00, - .key_on_lower = 0xff0000, - .key_on_both = 0xff0000, - .key_off = 0x000000, - .gap = 0x000000, - }, - .style = { - .key = 0, - .gap = 0, - .tof = 0, + .color = { + .key_on = 0xc0c0c0, + .key_off = 0x080808, .level = 127, }, - .tof = { - .offset = 100, - .pitch = 28, - }, .sense = { .filter = 0x10, .debounce_touch = 1, @@ -44,15 +32,6 @@ mai_runtime_t *mai_runtime; static void config_loaded() { - if (mai_cfg->style.level > 10) { - mai_cfg->style.level = default_cfg.style.level; - config_changed(); - } - if ((mai_cfg->tof.offset < 40) || - (mai_cfg->tof.pitch < 4) || (mai_cfg->tof.pitch > 50)) { - mai_cfg->tof = default_cfg.tof; - config_changed(); - } if ((mai_cfg->sense.filter & 0x0f) > 3 || ((mai_cfg->sense.filter >> 4) & 0x0f) > 3) { mai_cfg->sense.filter = default_cfg.sense.filter; diff --git a/firmware/src/config.h b/firmware/src/config.h index 9428e19..8c7f041 100644 --- a/firmware/src/config.h +++ b/firmware/src/config.h @@ -11,22 +11,10 @@ typedef struct __attribute__((packed)) { struct { - uint32_t key_on_upper; - uint32_t key_on_lower; - uint32_t key_on_both; + uint32_t key_on; uint32_t key_off; - uint32_t gap; - } colors; - struct { - uint8_t key; - uint8_t gap; - uint8_t tof; uint8_t level; - } style; - struct { - uint8_t offset; - uint8_t pitch; - } tof; + } color; struct { int8_t filter; int8_t global; diff --git a/firmware/src/hid.c b/firmware/src/hid.c new file mode 100644 index 0000000..b0dd8b9 --- /dev/null +++ b/firmware/src/hid.c @@ -0,0 +1,61 @@ +#include +#include + +#include "board_defs.h" + +#include "tusb.h" +#include "usb_descriptors.h" +#include "button.h" +#include "config.h" +#include "hid.h" + +struct __attribute__((packed)) { + uint16_t buttons; +} hid_joy; + +struct __attribute__((packed)) { + uint8_t modifier; + uint8_t keymap[15]; +} hid_nkro; + +static void report_usb_hid() +{ + if (tud_hid_ready()) { + if (mai_cfg->hid.joy) { + hid_joy.buttons = button_read(); + tud_hid_n_report(0, REPORT_ID_JOYSTICK, &hid_joy, sizeof(hid_joy)); + } + if (mai_cfg->hid.nkro) { + tud_hid_n_report(1, 0, &hid_nkro, sizeof(hid_nkro)); + } + } +} + +const char keymap_p1[10] = BUTTON_NKRO_MAP_P1; +const char keymap_p2[10] = BUTTON_NKRO_MAP_P2; + +static void gen_nkro_report() +{ + if (!mai_cfg->hid.nkro) { + return; + } + + uint16_t buttons = button_read(); + const char *keymap = (mai_cfg->hid.nkro == 2) ? keymap_p2 : keymap_p1; + for (int i = 0; i < 8; 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(); +} \ No newline at end of file diff --git a/firmware/src/hid.h b/firmware/src/hid.h new file mode 100644 index 0000000..741ca6d --- /dev/null +++ b/firmware/src/hid.h @@ -0,0 +1,11 @@ +/* + * HID Report Functions + * WHowe + */ + +#ifndef HID_H_ +#define HID_H_ + +void hid_update(); + +#endif diff --git a/firmware/src/main.c b/firmware/src/main.c index 361c30c..a16ef8a 100644 --- a/firmware/src/main.c +++ b/firmware/src/main.c @@ -32,69 +32,20 @@ #include "cli.h" #include "commands.h" #include "io.h" - -struct __attribute__((packed)) { - uint16_t buttons; -} hid_joy; - -struct __attribute__((packed)) { - uint8_t modifier; - uint8_t keymap[15]; -} hid_nkro, sent_hid_nkro; - -void report_usb_hid() -{ - if (tud_hid_ready()) { - if (mai_cfg->hid.joy) { - hid_joy.buttons = button_read(); - tud_hid_n_report(0, REPORT_ID_JOYSTICK, &hid_joy, sizeof(hid_joy)); - } - if (mai_cfg->hid.nkro) { - sent_hid_nkro = hid_nkro; - tud_hid_n_report(1, 0, &sent_hid_nkro, sizeof(sent_hid_nkro)); - } - } -} - -const uint8_t keycode_table[128][2] = { HID_ASCII_TO_KEYCODE }; -const char keymap[8] = BUTTON_NKRO_MAP; // 8 buttons -static void gen_nkro_report() -{ - uint16_t buttons = button_read(); - for (int i = 0; i < 8; i++) { - uint8_t code = keycode_table[keymap[i]][1]; - 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); - } - } -} - -static uint64_t last_hid_time = 0; +#include "hid.h" static void run_lights() { uint64_t now = time_us_64(); - if (last_hid_time != 0 && now - last_hid_time < 1000000) { - return; - } - if (io_last_io_time() != 0 && now - io_last_io_time() < 60000000) { return; } uint16_t buttons = button_read(); - uint16_t touch = touch_touchmap(); for (int i = 0; i < 8; i++) { - uint32_t color = 0; + uint32_t color = mai_cfg->color.key_off; if (buttons & (1 << i)) { - color |= 0x00ff00; - } - if (touch & (1 << i)) { - color |= 0xff0000; + color = mai_cfg->color.key_on; } rgb_set_button_color(i, color); } @@ -132,8 +83,7 @@ static void core0_loop() touch_update(); button_update(); - gen_nkro_report(); - report_usb_hid(); + hid_update(); } } @@ -142,12 +92,14 @@ void init() sleep_ms(50); set_sys_clock_khz(150000, true); board_init(); + tusb_init(); stdio_init_all(); config_init(); mutex_init(&core1_io_lock); - save_init(0xca34cafe, &core1_io_lock); + + save_init(board_id_32() ^ 0xcafe1111, &core1_io_lock); touch_init(); button_init(); diff --git a/firmware/src/rgb.c b/firmware/src/rgb.c index 2cd9668..bdfcf9d 100644 --- a/firmware/src/rgb.c +++ b/firmware/src/rgb.c @@ -115,9 +115,9 @@ static inline uint32_t apply_level(uint32_t color) unsigned g = (color >> 8) & 0xff; unsigned b = color & 0xff; - r = r * mai_cfg->style.level / 255; - g = g * mai_cfg->style.level / 255; - b = b * mai_cfg->style.level / 255; + r = r * mai_cfg->color.level / 255; + g = g * mai_cfg->color.level / 255; + b = b * mai_cfg->color.level / 255; return r << 16 | g << 8 | b; } diff --git a/firmware/src/save.c b/firmware/src/save.c index d3b227e..3afec3c 100644 --- a/firmware/src/save.c +++ b/firmware/src/save.c @@ -19,6 +19,7 @@ #include "hardware/flash.h" #include "pico/multicore.h" +#include "pico/unique_id.h" static struct { size_t size; @@ -109,6 +110,27 @@ static void save_loaded() } } +static union __attribute__((packed)) { + pico_unique_board_id_t id; + struct { + uint32_t id32h; + uint32_t id32l; + }; + uint64_t id64; +} board_id; + +uint32_t board_id_32() +{ + pico_get_unique_board_id(&board_id.id); + return board_id.id32h ^ board_id.id32l; +} + +uint64_t board_id_64() +{ + pico_get_unique_board_id(&board_id.id); + return board_id.id64; +} + void save_init(uint32_t magic, mutex_t *locker) { my_magic = magic; diff --git a/firmware/src/save.h b/firmware/src/save.h index 2cf5f1b..cde4229 100644 --- a/firmware/src/save.h +++ b/firmware/src/save.h @@ -12,6 +12,9 @@ #include "pico/multicore.h" +uint32_t board_id_32(); +uint64_t board_id_64(); + /* It's safer to lock other I/O ops during saving, so we need a locker */ typedef void (*io_locker_func)(bool pause); void save_init(uint32_t magic, mutex_t *lock); diff --git a/firmware/src/usb_descriptors.c b/firmware/src/usb_descriptors.c index 90b94f7..67352ab 100644 --- a/firmware/src/usb_descriptors.c +++ b/firmware/src/usb_descriptors.c @@ -175,7 +175,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) if (index == 3) { pico_unique_board_id_t board_id; pico_get_unique_board_id(&board_id); - sprintf(serial_number_str, "%016llx", 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]);