mirror of
https://github.com/solderparty/i2c_puppet.git
synced 2025-08-16 08:17:47 +02:00
Add functionality to the top buttons, including Ctrl
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 1
|
||||
#define VERSION_MINOR 2
|
||||
|
||||
#define KEY_FIFO_SIZE 31 // number of keys in the public FIFO
|
||||
|
@ -15,9 +15,9 @@
|
||||
|
||||
#define PICO_STDIO_USB_STDOUT_TIMEOUT_US 500000
|
||||
|
||||
static void key_cb(char key, enum key_state state)
|
||||
static void key_cb(char key, enum key_state state, uint32_t mods)
|
||||
{
|
||||
printf("key: 0x%02X/%d/%c, state: %d\r\n", key, key, key, state);
|
||||
printf("key: 0x%02X/%d/%c, state: %d, mods: 0x%08X\r\n", key, key, key, state, mods);
|
||||
}
|
||||
static struct key_callback key_callback = { .func = key_cb };
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include <pico/stdlib.h>
|
||||
|
||||
static void key_cb(char key, enum key_state state)
|
||||
static void key_cb(char key, enum key_state state, uint32_t mods)
|
||||
{
|
||||
(void)key;
|
||||
(void)state;
|
||||
|
@ -40,17 +40,17 @@ static const struct entry kbd_entries[][NUM_OF_COLS] =
|
||||
{
|
||||
{ { KEY_JOY_CENTER }, { 'W', '1' }, { 'G', '/' }, { 'S', '4' }, { 'L', '"' }, { 'H' , ':' } },
|
||||
{ { }, { 'Q', '#' }, { 'R', '3' }, { 'E', '2' }, { 'O', '+' }, { 'U', '_' } },
|
||||
{ { KEY_BTN_LEFT1 }, { '~', '0' }, { 'F', '6' }, { .mod = KEY_MOD_ID_SHL }, { 'K', '\'' }, { 'J', ';' } },
|
||||
{ { .mod = KEY_MOD_ID_CTRL }, { '~', '0' }, { 'F', '6' }, { .mod = KEY_MOD_ID_SHL }, { 'K', '\'' }, { 'J', ';' } },
|
||||
{ { }, { ' ', '\t' }, { 'C', '9' }, { 'Z', '7' }, { 'M', '.' }, { 'N', ',' } },
|
||||
{ { KEY_BTN_LEFT2 }, { .mod = KEY_MOD_ID_SYM }, { 'T', '(' }, { 'D', '5' }, { 'I', '-' }, { 'Y', ')' } },
|
||||
{ { KEY_BTN_RIGHT1 }, { .mod = KEY_MOD_ID_ALT }, { 'V', '?' }, { 'X', '8' }, { '$', '`' }, { 'B', '!' } },
|
||||
{ { '[', '{' }, { .mod = KEY_MOD_ID_SYM }, { 'T', '(' }, { 'D', '5' }, { 'I', '-' }, { 'Y', ')' } },
|
||||
{ { ']', '}' }, { .mod = KEY_MOD_ID_ALT }, { 'V', '?' }, { 'X', '8' }, { '$', '`' }, { 'B', '!' } },
|
||||
{ { }, { 'A', '*' }, { .mod = KEY_MOD_ID_SHR }, { 'P', '@' }, { '\b' }, { '\n', '|' } },
|
||||
};
|
||||
|
||||
#if NUM_OF_BTNS > 0
|
||||
static const struct entry btn_entries[NUM_OF_BTNS] =
|
||||
{
|
||||
BTN_KEYS
|
||||
{ '=', '%' }
|
||||
};
|
||||
|
||||
static const uint8_t btn_pins[NUM_OF_BTNS] =
|
||||
@ -109,11 +109,17 @@ static void transition_to(struct list_item * const p_item, const enum key_state
|
||||
key = KEY_MOD_SYM;
|
||||
break;
|
||||
|
||||
case KEY_MOD_ID_CTRL:
|
||||
if (reg_is_bit_set(REG_ID_CFG, CFG_REPORT_MODS))
|
||||
key = KEY_MOD_CTRL;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
if (reg_is_bit_set(REG_ID_CFG, CFG_USE_MODS)) {
|
||||
const bool shift = (self.mods[KEY_MOD_ID_SHL] || self.mods[KEY_MOD_ID_SHR]) | self.capslock;
|
||||
const bool alt = self.mods[KEY_MOD_ID_ALT] | self.numlock;
|
||||
const bool ctrl = self.mods[KEY_MOD_ID_CTRL];
|
||||
const bool is_button = (key <= KEY_BTN_RIGHT1) || ((key >= KEY_BTN_LEFT2) && (key <= KEY_BTN_RIGHT2));
|
||||
|
||||
if (alt && !is_button) {
|
||||
@ -130,8 +136,9 @@ static void transition_to(struct list_item * const p_item, const enum key_state
|
||||
p_item->effective_key = key;
|
||||
}
|
||||
|
||||
if (p_item->effective_key == '\0')
|
||||
if (p_item->effective_key == '\0') {
|
||||
return;
|
||||
}
|
||||
|
||||
keyboard_inject_event(p_item->effective_key, next_state);
|
||||
}
|
||||
@ -309,9 +316,13 @@ void keyboard_inject_event(char key, enum key_state state)
|
||||
fifo_enqueue_force(item);
|
||||
}
|
||||
|
||||
uint32_t mods = 0;
|
||||
for (size_t i = 0; i < KEY_MOD_ID_LAST; ++i)
|
||||
mods |= (self.mods[i] << i);
|
||||
|
||||
struct key_callback *cb = self.key_callbacks;
|
||||
while (cb) {
|
||||
cb->func(key, state);
|
||||
cb->func(key, state, mods);
|
||||
|
||||
cb = cb->next;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ enum key_mod
|
||||
KEY_MOD_ID_ALT,
|
||||
KEY_MOD_ID_SHL,
|
||||
KEY_MOD_ID_SHR,
|
||||
KEY_MOD_ID_CTRL,
|
||||
|
||||
KEY_MOD_ID_LAST,
|
||||
};
|
||||
@ -40,10 +41,11 @@ enum key_mod
|
||||
#define KEY_MOD_SHL 0x1B // Left Shift
|
||||
#define KEY_MOD_SHR 0x1C // Right Shift
|
||||
#define KEY_MOD_SYM 0x1D
|
||||
#define KEY_MOD_CTRL 0x1E
|
||||
|
||||
struct key_callback
|
||||
{
|
||||
void (*func)(char, enum key_state);
|
||||
void (*func)(char, enum key_state, uint32_t mods);
|
||||
struct key_callback *next;
|
||||
};
|
||||
|
||||
@ -65,3 +67,4 @@ bool keyboard_get_capslock(void);
|
||||
bool keyboard_get_numlock(void);
|
||||
|
||||
void keyboard_init(void);
|
||||
|
||||
|
10
app/usb.c
10
app/usb.c
@ -22,8 +22,6 @@ static struct
|
||||
uint8_t write_len;
|
||||
} self;
|
||||
|
||||
// TODO: What about Ctrl?
|
||||
// TODO: What should L1, L2, R1, R2 do
|
||||
// TODO: Should touch send arrow keys as an option?
|
||||
|
||||
static void low_priority_worker_irq(void)
|
||||
@ -45,13 +43,14 @@ static int64_t timer_task(alarm_id_t id, void *user_data)
|
||||
return USB_TASK_INTERVAL_US;
|
||||
}
|
||||
|
||||
static void key_cb(char key, enum key_state state)
|
||||
static void key_cb(char key, enum key_state state, uint32_t mods)
|
||||
{
|
||||
// Don't send mods over USB
|
||||
if ((key == KEY_MOD_SHL) ||
|
||||
(key == KEY_MOD_SHR) ||
|
||||
(key == KEY_MOD_ALT) ||
|
||||
(key == KEY_MOD_SYM))
|
||||
(key == KEY_MOD_SYM) ||
|
||||
(key == KEY_MOD_CTRL))
|
||||
return;
|
||||
|
||||
if (tud_hid_n_ready(USB_ITF_KEYBOARD) && reg_is_bit_set(REG_ID_CF2, CF2_USB_KEYB_ON)) {
|
||||
@ -69,6 +68,9 @@ static void key_cb(char key, enum key_state state)
|
||||
if (conv_table[(int)key][0])
|
||||
modifier = KEYBOARD_MODIFIER_LEFTSHIFT;
|
||||
|
||||
if (mods & (1 << KEY_MOD_ID_CTRL))
|
||||
modifier |= KEYBOARD_MODIFIER_LEFTCTRL;
|
||||
|
||||
keycode[0] = conv_table[(int)key][1];
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user