diff --git a/app/app_config.h b/app/app_config.h index 9d54d39..c60e7e1 100644 --- a/app/app_config.h +++ b/app/app_config.h @@ -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 diff --git a/app/debug.c b/app/debug.c index f5fe97e..1de0a1e 100644 --- a/app/debug.c +++ b/app/debug.c @@ -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 }; diff --git a/app/interrupt.c b/app/interrupt.c index e46a0eb..2d477a3 100644 --- a/app/interrupt.c +++ b/app/interrupt.c @@ -8,7 +8,7 @@ #include -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; diff --git a/app/keyboard.c b/app/keyboard.c index 5b624cc..5e48e5e 100644 --- a/app/keyboard.c +++ b/app/keyboard.c @@ -38,19 +38,19 @@ static const uint8_t col_pins[NUM_OF_COLS] = 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', ';' } }, - { { }, { ' ', '\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', '!' } }, - { { }, { 'A', '*' }, { .mod = KEY_MOD_ID_SHR }, { 'P', '@' }, { '\b' }, { '\n', '|' } }, + { { KEY_JOY_CENTER }, { 'W', '1' }, { 'G', '/' }, { 'S', '4' }, { 'L', '"' }, { 'H' , ':' } }, + { { }, { 'Q', '#' }, { 'R', '3' }, { 'E', '2' }, { 'O', '+' }, { 'U', '_' } }, + { { .mod = KEY_MOD_ID_CTRL }, { '~', '0' }, { 'F', '6' }, { .mod = KEY_MOD_ID_SHL }, { 'K', '\'' }, { 'J', ';' } }, + { { }, { ' ', '\t' }, { 'C', '9' }, { 'Z', '7' }, { 'M', '.' }, { 'N', ',' } }, + { { '[', '{' }, { .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; } diff --git a/app/keyboard.h b/app/keyboard.h index fbe9531..858dd3b 100644 --- a/app/keyboard.h +++ b/app/keyboard.h @@ -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); + diff --git a/app/usb.c b/app/usb.c index 25cf769..595da99 100644 --- a/app/usb.c +++ b/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]; }