mirror of
https://github.com/grymoire/i2c_puppet-Linux.git
synced 2024-12-25 13:08:21 +01:00
Added support for Control characters and the characters <escape> and "<>{}[]^&%=\"
This commit is contained in:
parent
c44f9546e3
commit
f27d75ea35
67
LINUX.md
Normal file
67
LINUX.md
Normal file
@ -0,0 +1,67 @@
|
||||
# I2C Puppet mods for Linux systems
|
||||
|
||||
The original version lacked certain characters, such as <ESCAPE>, and the characters "<>{}[]^&%=\"
|
||||
which made it difficult to use on Linux systems
|
||||
|
||||
|
||||
This version of the firmware has been modified to support Linux systems.
|
||||
The following changes have been made
|
||||
1) The backspace key works during the GUI login
|
||||
2) The Sym key not acts as a Control key, so SYM+C is Control-C
|
||||
3) The four top button keys are now used to provide the missing characters.
|
||||
|
||||
The original definiton of the keys were this
|
||||
|
||||
L1 L2 R1 R2 SPKR Mic BS NL SPACE
|
||||
$ ~ \b \n
|
||||
Shift
|
||||
Alt 0
|
||||
Sym | TAB
|
||||
|
||||
|
||||
|
||||
The current definition of the keys are
|
||||
|
||||
L1 L2 R1 R2 SPKR Mic BS NL Spacebar
|
||||
<none> <esc> % = \ $ ~ BS \n <space>
|
||||
Alt > ] } & ` ~ x <tab>
|
||||
Shift < [ { ^ $ ` BS <space>
|
||||
Sym x x x x $ ~ BS | <space>
|
||||
|
||||
|
||||
#Linux Debug tips
|
||||
|
||||
The keyboard was two "outputs" - one is the USB HID interface, the other is the serial port.
|
||||
Any printf() command goes to the serial port.
|
||||
|
||||
When the keyboard is plugged into a Linux system, a new TTY interface will appear. I usually use "ls -lt /dev/tty* | head"
|
||||
to learn the name, as the newest port will appear first. On my system, it's /dev/ttyACM0
|
||||
|
||||
So on one terminal, I type
|
||||
|
||||
cat -v </dev/ttyACM0
|
||||
|
||||
while on a second terminal window, I type
|
||||
|
||||
cat -v
|
||||
|
||||
The first one will print all of the printf output, and the second will show you how the keyboard works normally.
|
||||
|
||||
#Compiling on Linux
|
||||
|
||||
I edit the files in <GIT>/ic2_puppet/all/ using my preferred editor. In my case, I use emacs. I have the keystroke combination "Control-C M" bound to compile, using
|
||||
|
||||
(global-set-key "\C-cm" 'compile)
|
||||
|
||||
And when I press these keys, emacs saves all files, and recompiles the
|
||||
code. I have a small hub with switchable on/off ports, and restart the
|
||||
keyboard into boot mode, and then do a "make install" to load the new
|
||||
firmware
|
||||
|
||||
|
||||
#TODO
|
||||
|
||||
Currently - the SYM+Button keys are defined as the character "x" to indicate it's not been specified.
|
||||
I'l like to make these keys to the 4 arrow keys.
|
||||
|
||||
Also - it might be possible to create key combinations by combining the modified keys, like SYM+Alt+key
|
6
app/Makefile
Normal file
6
app/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# Make it useful for Linux
|
||||
all: keyboard.c keyboard.h usb.c
|
||||
cd ../build;make
|
||||
install: ../build/app/i2c_puppet.uf2
|
||||
cp ../build/app/i2c_puppet.uf2 /media/${USER}/RPI-RP2
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "fifo.h"
|
||||
#include "keyboard.h"
|
||||
#include "reg.h"
|
||||
#include <stdio.h> // BGB
|
||||
|
||||
#include <pico/stdlib.h>
|
||||
|
||||
@ -114,12 +115,76 @@ static void transition_to(struct list_item * const p_item, const enum key_state
|
||||
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 is_button = (key <= KEY_BTN_RIGHT1) || ((key >= KEY_BTN_LEFT2) && (key <= KEY_BTN_RIGHT2));
|
||||
// const bool is_button = (key <= KEY_BTN_RIGHT1) || ((key >= KEY_BTN_LEFT2) && (key <= KEY_BTN_RIGHT2));
|
||||
const bool is_button = ((key == KEY_BTN_RIGHT1)
|
||||
|| (key == KEY_BTN_RIGHT2)
|
||||
|| (key == KEY_BTN_LEFT1)
|
||||
|| (key == KEY_BTN_LEFT2));
|
||||
const bool control = self.mods[KEY_MOD_ID_SYM];
|
||||
|
||||
|
||||
if (alt && !is_button) {
|
||||
if (is_button) {
|
||||
switch (key) {
|
||||
case KEY_BTN_LEFT1:
|
||||
if (alt) {
|
||||
key = '>';
|
||||
} else if (shift) {
|
||||
key = '<';
|
||||
} else if (control) {
|
||||
key = 'x';
|
||||
} else {
|
||||
key =0x1B; // ESC
|
||||
}
|
||||
break;
|
||||
case KEY_BTN_LEFT2:
|
||||
if (alt) {
|
||||
key = ']';
|
||||
} else if (shift) {
|
||||
key = '[';
|
||||
} else if (control) {
|
||||
key ='x';
|
||||
} else {
|
||||
key = '%';
|
||||
}
|
||||
break;
|
||||
case KEY_BTN_RIGHT1:
|
||||
if (alt) {
|
||||
key = '}';
|
||||
} else if (shift) {
|
||||
key = '{';
|
||||
} else if (control) {
|
||||
key = 'x';
|
||||
} else {
|
||||
key = '=';
|
||||
}
|
||||
break;
|
||||
case KEY_BTN_RIGHT2:
|
||||
if (alt) {
|
||||
key = '&';
|
||||
} else if (shift) {
|
||||
key = '^';
|
||||
} else if (control) {
|
||||
key = 'x'; // TODO
|
||||
} else {
|
||||
key = '\\';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// printf(" ERROR: Illegal key: %d\n", key);
|
||||
;
|
||||
}
|
||||
} else if (alt) {
|
||||
printf(" alt \n");
|
||||
key = p_entry->alt;
|
||||
} else if (!shift && (key >= 'A' && key <= 'Z')) {
|
||||
} else if (key >= 'A' && key <= 'Z') {
|
||||
printf(" letter\n");
|
||||
if (control) { // If the SYM key is held down, it's a control key
|
||||
key = key - 0x40;
|
||||
} else if (!shift) { // lower case letter
|
||||
key = (key + ' ');
|
||||
} else {
|
||||
// it's an uppercase letter - do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,24 +22,24 @@ enum key_mod
|
||||
KEY_MOD_ID_LAST,
|
||||
};
|
||||
|
||||
#define KEY_JOY_UP 0x01
|
||||
#define KEY_JOY_DOWN 0x02
|
||||
#define KEY_JOY_LEFT 0x03
|
||||
#define KEY_JOY_RIGHT 0x04
|
||||
#define KEY_JOY_CENTER 0x05
|
||||
#define KEY_BTN_LEFT1 0x06
|
||||
#define KEY_BTN_RIGHT1 0x07
|
||||
#define KEY_JOY_UP 0x81
|
||||
#define KEY_JOY_DOWN 0x82
|
||||
#define KEY_JOY_LEFT 0x83
|
||||
#define KEY_JOY_RIGHT 0x84
|
||||
#define KEY_JOY_CENTER 0x85
|
||||
#define KEY_BTN_LEFT1 0x86
|
||||
#define KEY_BTN_RIGHT1 0x87
|
||||
// 0x08 - BACKSPACE
|
||||
// 0x09 - TAB
|
||||
// 0x0A - NEW LINE
|
||||
// 0x0D - CARRIAGE RETURN
|
||||
#define KEY_BTN_LEFT2 0x11
|
||||
#define KEY_BTN_RIGHT2 0x12
|
||||
#define KEY_BTN_LEFT2 0x91
|
||||
#define KEY_BTN_RIGHT2 0x92
|
||||
|
||||
#define KEY_MOD_ALT 0x1A
|
||||
#define KEY_MOD_SHL 0x1B // Left Shift
|
||||
#define KEY_MOD_SHR 0x1C // Right Shift
|
||||
#define KEY_MOD_SYM 0x1D
|
||||
#define KEY_MOD_ALT 0x9A
|
||||
#define KEY_MOD_SHL 0x9B // Left Shift
|
||||
#define KEY_MOD_SHR 0x9C // Right Shift
|
||||
#define KEY_MOD_SYM 0x9D
|
||||
|
||||
struct key_callback
|
||||
{
|
||||
|
19
app/usb.c
19
app/usb.c
@ -55,8 +55,10 @@ static void key_cb(char key, enum key_state state)
|
||||
return;
|
||||
|
||||
if (tud_hid_n_ready(USB_ITF_KEYBOARD) && reg_is_bit_set(REG_ID_CF2, CF2_USB_KEYB_ON)) {
|
||||
uint8_t conv_table[128][2] = { HID_ASCII_TO_KEYCODE };
|
||||
// conv_table needs to be 256 entries long because the special keys are in range 128-256 (0x80 - 0xFF)
|
||||
uint8_t conv_table[256][2] = { HID_ASCII_TO_KEYCODE };
|
||||
conv_table['\n'][1] = HID_KEY_ENTER; // Fixup: Enter instead of Return
|
||||
conv_table['\b'][1] = HID_KEY_BACKSPACE; // Fixup: HID backspace (0x2A) instead of \b (0x08)
|
||||
conv_table[KEY_JOY_UP][1] = HID_KEY_ARROW_UP;
|
||||
conv_table[KEY_JOY_DOWN][1] = HID_KEY_ARROW_DOWN;
|
||||
conv_table[KEY_JOY_LEFT][1] = HID_KEY_ARROW_LEFT;
|
||||
@ -66,10 +68,21 @@ static void key_cb(char key, enum key_state state)
|
||||
uint8_t modifier = 0;
|
||||
|
||||
if (state == KEY_STATE_PRESSED) {
|
||||
if (conv_table[(int)key][0])
|
||||
printf(" conv_table[%d][0,1]=%d,%d ",key, conv_table[(int)key][0], conv_table[(int)key][1]); // bgb
|
||||
if (conv_table[(int)key][0]) {
|
||||
modifier = KEYBOARD_MODIFIER_LEFTSHIFT;
|
||||
} else if (key < 0x20) { // it's a control key
|
||||
if ((key == '\n') || (key == '\b')) {
|
||||
// leave alone - this is necessary because the Linux graphical login processes the HID equivalent
|
||||
// which is done using conv_table[] below
|
||||
} else {
|
||||
// convert control key, i.e. [Control-A] converts to [modifier=control, key=A]
|
||||
modifier=KEYBOARD_MODIFIER_RIGHTCTRL;
|
||||
key=key + 0x40;
|
||||
}
|
||||
|
||||
keycode[0] = conv_table[(int)key][1];
|
||||
}
|
||||
keycode[0] = conv_table[(int)key][1];
|
||||
}
|
||||
|
||||
if (state != KEY_STATE_HOLD)
|
||||
|
Loading…
Reference in New Issue
Block a user