mirror of
https://github.com/whowechina/mai_pico.git
synced 2025-02-17 18:08:30 +01:00
HID part optimization
This commit is contained in:
parent
fdfb3975a3
commit
fd174f97cd
@ -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)
|
||||
|
@ -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, \
|
||||
|
@ -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]);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
61
firmware/src/hid.c
Normal 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
11
firmware/src/hid.h
Normal file
@ -0,0 +1,11 @@
|
||||
/*
|
||||
* HID Report Functions
|
||||
* WHowe <github.com/whowechina>
|
||||
*/
|
||||
|
||||
#ifndef HID_H_
|
||||
#define HID_H_
|
||||
|
||||
void hid_update();
|
||||
|
||||
#endif
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user