HID part optimization

This commit is contained in:
whowechina 2023-10-14 12:31:54 +08:00
parent fdfb3975a3
commit fd174f97cd
13 changed files with 154 additions and 136 deletions

View File

@ -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)

View File

@ -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, \

View File

@ -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]);

View File

@ -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 <joy|nkro|both>\n";
const char *usage = "Usage: hid <joy|key1|key2\n";
if (argc != 1) {
printf(usage);
return;
}
const char *choices[] = {"joy", "nkro", "both"};
const char *choices[] = {"joy", "key1", "key2"};
int match = cli_match_prefix(choices, 3, argv[0]);
if (match < 0) {
printf(usage);
return;
}
mai_cfg->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();
}

View File

@ -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;

View File

@ -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;

61
firmware/src/hid.c Normal file
View File

@ -0,0 +1,61 @@
#include <stdint.h>
#include <stdbool.h>
#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();
}

11
firmware/src/hid.h Normal file
View File

@ -0,0 +1,11 @@
/*
* HID Report Functions
* WHowe <github.com/whowechina>
*/
#ifndef HID_H_
#define HID_H_
void hid_update();
#endif

View File

@ -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();

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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]);