mirror of
https://github.com/grymoire/i2c_puppet-Linux.git
synced 2025-04-08 18:06:46 +02:00
Compare commits
No commits in common. "main" and "v1.1" have entirely different histories.
103
LINUX.md
103
LINUX.md
@ -1,103 +0,0 @@
|
|||||||
# I2C Puppet mods for Linux systems
|
|
||||||
|
|
||||||
|
|
||||||
This is a modification to the <a href="https:README.md" target="_blank">standard firmware</a>
|
|
||||||
|
|
||||||
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
|
|
||||||
- The backspace key works during the GUI login
|
|
||||||
- The Sym key now acts as a Control key, so SYM+C is Control-C
|
|
||||||
- The four top button keys are now used to provide the missing characters.
|
|
||||||
|
|
||||||
The original definiton of the keys were this. I'm including the
|
|
||||||
spacebar, newline/enter, backspace, Microphone and Spkeaer keys
|
|
||||||
because they provide characters not indicated on the key. For
|
|
||||||
instance, ALT + spacebar provides TAB, and ALT+NewLine is the pipe character.
|
|
||||||
|
|
||||||
|
|
||||||
| | L1 | L2 | R1 | R2 | SPKR | Mic| BS | NL | SPACE |
|
|
||||||
| ------|-------|-------|-------|-------|------|----|---|----|---------|
|
|
||||||
| none | | | | | $ | ~ | \b| \n | SPACE |
|
|
||||||
| Alt | | | | | \` | 0 | | \| | TAB |
|
|
||||||
| Shift | | | | | $ | | | | |
|
|
||||||
| Sym | | | | | $ | | | | |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
This firmware adds the following mappings
|
|
||||||
|
|
||||||
|
|
||||||
| | L1 | L2 | R1 | R2 | SPKR | Mic| BS| NL | SPACE |
|
|
||||||
| ------|--------|-------|-------|-------|------|----|---|----|---------|
|
|
||||||
| none | ESCAPE | % | = | \\ | $ | ~ | \b| \n | SPACE |
|
|
||||||
| Alt | > | ] | } | & | \` | 0 | | \| | TAB |
|
|
||||||
| Shift | < | [ | { | ^ | $ | ~ | \b| | |
|
|
||||||
| Sym | x | x | x | x | $ | ~ | \b| | |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
I tried to make the bracket characters easierr to remember by using
|
|
||||||
Shift+ to indicate the left-pointing brackets, and Alt+ corresponds to
|
|
||||||
the same right-pointing bracket. You can redefine these keys if you
|
|
||||||
prefer a different arraingment.
|
|
||||||
|
|
||||||
Currently, SYM+<top button keys> produces an 'x' to indicate some value can be inserted.
|
|
||||||
I'm considering mapping these to the 4 arrow keys
|
|
||||||
|
|
||||||
|
|
||||||
## Linux Debug tips
|
|
||||||
|
|
||||||
The keyboard has two "outputs" - one is the USB HID interface, the
|
|
||||||
other is the serial port. Any printf() command goes to the serial
|
|
||||||
port, but not the USB HID keyboard. For instance, when using an
|
|
||||||
Arduino sketch, print() 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 window, 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 and what gets sent to the USB
|
|
||||||
keyboard when a key is pressed..
|
|
||||||
|
|
||||||
## Compiling firmware on Linux
|
|
||||||
|
|
||||||
I edit the files in <GIT>/ic2_puppet/all/ using emacs.
|
|
||||||
I have the keystroke combination
|
|
||||||
"Control-C M" bound to compile, using
|
|
||||||
|
|
||||||
(global-set-key "\C-cm" 'compile)
|
|
||||||
|
|
||||||
And when I press "Control-c M", 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. But you can also use vim. The makefile assumes the compiled version is in ../build.
|
|
||||||
|
|
||||||
## GUI Login
|
|
||||||
|
|
||||||
I found that I had to handle the backspace differently, as arturo did
|
|
||||||
for enter. This was necessary so that the backspace key would delete
|
|
||||||
the username or password characters.
|
|
||||||
|
|
||||||
## 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
|
|
@ -1,6 +0,0 @@
|
|||||||
# 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,7 +2,6 @@
|
|||||||
#include "fifo.h"
|
#include "fifo.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "reg.h"
|
#include "reg.h"
|
||||||
#include <stdio.h> // BGB
|
|
||||||
|
|
||||||
#include <pico/stdlib.h>
|
#include <pico/stdlib.h>
|
||||||
|
|
||||||
@ -115,76 +114,12 @@ 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)) {
|
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 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 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 (is_button) {
|
if (alt && !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;
|
key = p_entry->alt;
|
||||||
} else if (key >= 'A' && key <= 'Z') {
|
} else if (!shift && (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 + ' ');
|
key = (key + ' ');
|
||||||
} else {
|
|
||||||
// it's an uppercase letter - do nothing
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,24 +22,24 @@ enum key_mod
|
|||||||
KEY_MOD_ID_LAST,
|
KEY_MOD_ID_LAST,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define KEY_JOY_UP 0x81
|
#define KEY_JOY_UP 0x01
|
||||||
#define KEY_JOY_DOWN 0x82
|
#define KEY_JOY_DOWN 0x02
|
||||||
#define KEY_JOY_LEFT 0x83
|
#define KEY_JOY_LEFT 0x03
|
||||||
#define KEY_JOY_RIGHT 0x84
|
#define KEY_JOY_RIGHT 0x04
|
||||||
#define KEY_JOY_CENTER 0x85
|
#define KEY_JOY_CENTER 0x05
|
||||||
#define KEY_BTN_LEFT1 0x86
|
#define KEY_BTN_LEFT1 0x06
|
||||||
#define KEY_BTN_RIGHT1 0x87
|
#define KEY_BTN_RIGHT1 0x07
|
||||||
// 0x08 - BACKSPACE
|
// 0x08 - BACKSPACE
|
||||||
// 0x09 - TAB
|
// 0x09 - TAB
|
||||||
// 0x0A - NEW LINE
|
// 0x0A - NEW LINE
|
||||||
// 0x0D - CARRIAGE RETURN
|
// 0x0D - CARRIAGE RETURN
|
||||||
#define KEY_BTN_LEFT2 0x91
|
#define KEY_BTN_LEFT2 0x11
|
||||||
#define KEY_BTN_RIGHT2 0x92
|
#define KEY_BTN_RIGHT2 0x12
|
||||||
|
|
||||||
#define KEY_MOD_ALT 0x9A
|
#define KEY_MOD_ALT 0x1A
|
||||||
#define KEY_MOD_SHL 0x9B // Left Shift
|
#define KEY_MOD_SHL 0x1B // Left Shift
|
||||||
#define KEY_MOD_SHR 0x9C // Right Shift
|
#define KEY_MOD_SHR 0x1C // Right Shift
|
||||||
#define KEY_MOD_SYM 0x9D
|
#define KEY_MOD_SYM 0x1D
|
||||||
|
|
||||||
struct key_callback
|
struct key_callback
|
||||||
{
|
{
|
||||||
|
19
app/usb.c
19
app/usb.c
@ -55,10 +55,8 @@ static void key_cb(char key, enum key_state state)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (tud_hid_n_ready(USB_ITF_KEYBOARD) && reg_is_bit_set(REG_ID_CF2, CF2_USB_KEYB_ON)) {
|
if (tud_hid_n_ready(USB_ITF_KEYBOARD) && reg_is_bit_set(REG_ID_CF2, CF2_USB_KEYB_ON)) {
|
||||||
// conv_table needs to be 256 entries long because the special keys are in range 128-256 (0x80 - 0xFF)
|
uint8_t conv_table[128][2] = { HID_ASCII_TO_KEYCODE };
|
||||||
uint8_t conv_table[256][2] = { HID_ASCII_TO_KEYCODE };
|
|
||||||
conv_table['\n'][1] = HID_KEY_ENTER; // Fixup: Enter instead of Return
|
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_UP][1] = HID_KEY_ARROW_UP;
|
||||||
conv_table[KEY_JOY_DOWN][1] = HID_KEY_ARROW_DOWN;
|
conv_table[KEY_JOY_DOWN][1] = HID_KEY_ARROW_DOWN;
|
||||||
conv_table[KEY_JOY_LEFT][1] = HID_KEY_ARROW_LEFT;
|
conv_table[KEY_JOY_LEFT][1] = HID_KEY_ARROW_LEFT;
|
||||||
@ -68,21 +66,10 @@ static void key_cb(char key, enum key_state state)
|
|||||||
uint8_t modifier = 0;
|
uint8_t modifier = 0;
|
||||||
|
|
||||||
if (state == KEY_STATE_PRESSED) {
|
if (state == KEY_STATE_PRESSED) {
|
||||||
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])
|
||||||
if (conv_table[(int)key][0]) {
|
|
||||||
modifier = KEYBOARD_MODIFIER_LEFTSHIFT;
|
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)
|
if (state != KEY_STATE_HOLD)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user