[Keyboard] Kinesis + Pro Micro (#9944)
* [Keyboard] Kinesis + Pro Micro init - docs for DIY - custom matrix = lite - a near-factory dvorak mapping - optimized debouncing for lower latency * chore: reformatting * chore: update doc * chore: cleanups according to PR feedback * chore: PR feedback * fix: compile error * chore: add include * fix: LEDs hanging after USB disconnect * chore: enable QMK goodies by default * chore: use semantic write pinmaster
parent
e071206c58
commit
194dc0984e
|
@ -130,14 +130,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
//#define NO_ACTION_MACRO
|
||||
//#define NO_ACTION_FUNCTION
|
||||
|
||||
#ifdef SUBPROJECT_alvicstep
|
||||
#include "alvicstep/config.h"
|
||||
#endif
|
||||
#ifdef SUBPROJECT_stapelberg
|
||||
#include "stapelberg/config.h"
|
||||
#endif
|
||||
#ifdef SUBPROJECT_kint2pp
|
||||
#include "kint2pp/config.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
#include QMK_KEYBOARD_H
|
||||
|
||||
#define DVORAK_MAC_MODE 0 // Base Dvorak in Kinesis's Mac Mode with (Cmd, Option, Ctrl, Cmd) thumbkeys
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[DVORAK_MAC_MODE] = LAYOUT(
|
||||
// left hand
|
||||
KC_CAPS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8,
|
||||
KC_EQL, KC_1, KC_2, KC_3, KC_4, KC_5,
|
||||
KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y,
|
||||
KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I,
|
||||
KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X,
|
||||
KC_GRV, KC_INS, KC_LEFT, KC_RIGHT,
|
||||
// left thumb
|
||||
KC_LGUI, KC_LALT,
|
||||
KC_HOME,
|
||||
KC_BSPC, KC_DEL, KC_END,
|
||||
// right hand
|
||||
KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS, KC_NLCK, KC_POWER,
|
||||
KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
|
||||
KC_F, KC_G, KC_C, KC_R, KC_L, KC_SLSH,
|
||||
KC_D, KC_H, KC_T, KC_N, KC_S, KC_BSLS,
|
||||
KC_B, KC_M, KC_W, KC_V, KC_Z, KC_RSFT,
|
||||
KC_UP, KC_DOWN, KC_LBRC, KC_RBRC,
|
||||
// right thumb
|
||||
KC_RCTL, KC_RGUI,
|
||||
KC_PGUP,
|
||||
KC_PGDN, KC_ENT, KC_SPC
|
||||
)
|
||||
};
|
|
@ -10,6 +10,9 @@
|
|||
#ifdef KEYBOARD_kinesis_kint2pp
|
||||
#include "kint2pp.h"
|
||||
#endif
|
||||
#ifdef KEYBOARD_kinesis_nguyenvietyen
|
||||
#include "nguyenvietyen.h"
|
||||
#endif
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
# Viet's Kinesis + Pro Micro
|
||||
|
||||
July 2020
|
||||
|
||||
This work is inspired by `alvicstep`'s solution. Instead of hooking up the Kinesis to a Teensy 2, this one hooks it up to a Pro Micro.
|
||||
|
||||
## Kinesis Board Layout
|
||||
The following is a reinterpretation of [@chrisandreae](https://github.com/chrisandreae/keyboard-firmware/blob/public/hardware/kinesis.h)'s work.
|
||||
|
||||
### Used Pins
|
||||
* 8 columns mapped to output pins 21 - 28
|
||||
* 16 rows mapped to 4 input pins: pin 39 - 36. Rows are traversed by iterating and setting 16 values from 0000 to 1111.
|
||||
* 4 leds (e.g. capslock) mapped to input pin 1 - 4
|
||||
* keypad key mapped to pin 5
|
||||
* program key mapped to pin 6
|
||||
* `VCC` mapped to pin 40
|
||||
|
||||
### Matrix Configuration
|
||||
The matrix configuration of the columns and rows on my Advantage is as follows:
|
||||
|
||||
| | row 0 | row 1 | row 2 | row 3 | row 4 | row 5 | row 6 | row 7 | row 8 | row 9 | row A | row B | row C | row D | row E | row F |
|
||||
| ----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- |
|
||||
| col0 | F6 | F8 | F7 | 5% | 4$ | 3# | 2@ | 1! | =+ | | | | | | | |
|
||||
| col1 | F3 | F5 | F4 | T | R | E | W | Q | Tab | | | | | | | |
|
||||
| col2 | Esc | F2 | F1 | G | F | D | S | A | CapsLk | | | | | | | |
|
||||
| col3 | F9 | F11 | F10 | B | V | C | X | Z | LShift | Up | | Down | | [{ | ]} | |
|
||||
| col4 | F12 | ScrLk | PrtSc | Right | | Left | Insert | ~ | | 6^ | 7& | 8* | | 9( | 0) | -_ |
|
||||
| col5 | Pause | | | LAlt | | Home | | End | | Y | U | I | | O | P | `\|` |
|
||||
| col6 | | | | LCtrl | Delete | Bksp | RCtrl | Enter | Space | H | J | K | | L | ;: | '" |
|
||||
| col7 | | | | | RGUI | | PageUp | | PageDn | N | M | ,< | | .> | /? | RShift |
|
||||
|
||||
(this is a modified copy from [@alvicstep](https://github.com/qmk/qmk_firmware/blob/master/keyboards/kinesis/alvicstep/alvicstep.h))
|
||||
|
||||
In the code, keypad and program keys are mapped respectively to col0 and col1 of row C, the 12th row.
|
||||
|
||||
### Omitted Pins
|
||||
There are pins that we currently omit:
|
||||
* serial eeprom clock line mapped to pin 7
|
||||
* serial eeprom data line mapped to pin 8
|
||||
* EEPROM write protect mapped to pin 10.
|
||||
* foot switch 1 mapped to pin 11
|
||||
* PS/2 clock mapped to pin 12
|
||||
* PS/2 data mapped to pin 13
|
||||
* foot switch 2 mapped to pin 17
|
||||
* foot switch 3 mapped to pin 15
|
||||
* audio mapped to pin 32
|
||||
|
||||
### DIP Socket
|
||||
Here's an ASCII drawing of the 40 pin DIP socket.
|
||||
```
|
||||
DL2 1 40 VCC
|
||||
DR1 2 39 A
|
||||
DR2 3 38 B
|
||||
DL1 4 37 C
|
||||
KPD 5 36 G
|
||||
PGM 6 35
|
||||
SCL 7 34
|
||||
SDA 8 33
|
||||
RST 9 32 BUZZ
|
||||
WP 10 31 EA
|
||||
FS1 11 30 ALE
|
||||
CLOCK 12 29 PSEN
|
||||
DATA 13 28 r8
|
||||
14 27 r7
|
||||
FS3 15 26 r6
|
||||
16 25 r5
|
||||
FS2 17 24 r4
|
||||
XTAL1 18 23 r3
|
||||
XTAL2 19 22 r2
|
||||
GND 20 21 r1
|
||||
```
|
||||
(this is copied from [@wjanssens](https://raw.githubusercontent.com/wjanssens/tmk_keyboard/master/keyboard/kinesis/doc/readme.txt))
|
||||
|
||||
## Pin Mapping to Pro Micro
|
||||
|
||||
The following table is ordered by physical Arduino pin order.
|
||||
|
||||
| Arduino | Kinesis | Meaning |
|
||||
| ------- | ------- | ------- |
|
||||
| D3 | 36 | G |
|
||||
| D2 | 37 | C |
|
||||
| GND | | |
|
||||
| GND | | |
|
||||
| D1 | 38 | B |
|
||||
| D0 | 39 | A |
|
||||
| D4 | 1 | DL2 |
|
||||
| C6 | 2 | DR1 |
|
||||
| D7 | 3 | DR2 |
|
||||
| E6 | 4 | DL1 |
|
||||
| B4 | 5 | KPD |
|
||||
| B5 | 6 | PGM |
|
||||
| B6 | 21 | r1 |
|
||||
| B2 | 22 | r2 |
|
||||
| B3 | 23 | r3 |
|
||||
| B1 | 24 | r4 |
|
||||
| F7 | 25 | r5 |
|
||||
| F6 | 26 | r6 |
|
||||
| F5 | 27 | r7 |
|
||||
| F4 | 28 | r8 |
|
||||
| VCC | 40 | |
|
||||
| RESET | | |
|
||||
| GND | 20 | |
|
||||
| RAW | | |
|
||||
|
||||
## Notes
|
||||
|
||||
* The rows are multiplexed. Instead of reading them out, one sets the row value and corresponding column values are returned through r1-r8.
|
||||
* On my keyboard, the keypad and program key have dedicated pins. Since row 12 had no mapping in the physical matrix, there's a code override injects the keypad and program pins to the first two bits in the matrix.
|
||||
* I've experimented with debouncing approaches. The current setting delivers a snappier feeling than Kinesis's factory default for me.
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define PRODUCT_ID 0x6060
|
||||
#define DEVICE_VER 0x0003
|
||||
|
||||
/* key matrix size */
|
||||
#define MATRIX_ROWS 16
|
||||
#define MATRIX_COLS 8
|
||||
|
||||
/*
|
||||
* Keyboard Matrix Assignments
|
||||
*
|
||||
* Change this to how you wired your keyboard
|
||||
* COLS: AVR pins used for columns, left to right
|
||||
* ROWS: AVR pins used for rows, top to bottom
|
||||
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
|
||||
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
|
||||
*
|
||||
*/
|
||||
// Passed through the port multipler, so 4 pins =16
|
||||
#define MATRIX_ROW_PINS { D0, D1, D2, D3 }
|
||||
#define MATRIX_COL_PINS { B6, B2, B3, B1, F7, F6, F5, F4 }
|
||||
#define UNUSED_PINS
|
||||
|
||||
/* COL2ROW or ROW2COL */
|
||||
#define DIODE_DIRECTION COL2ROW
|
|
@ -0,0 +1,64 @@
|
|||
#include "matrix.h"
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
static matrix_row_t read_row(uint8_t row) {
|
||||
matrix_io_delay(); // without this wait read unstable value.
|
||||
|
||||
// keypad and program buttons
|
||||
if (row == 12) {
|
||||
return ~(readPin(B4) | (readPin(B5) << 1) | 0b11111100);
|
||||
}
|
||||
|
||||
return ~(readPin(B6) | readPin(B2) << 1 | readPin(B3) << 2 | readPin(B1) << 3 | readPin(F7) << 4 | readPin(F6) << 5 | readPin(F5) << 6 | readPin(F4) << 7);
|
||||
}
|
||||
|
||||
static void unselect_rows(void) {
|
||||
// set A,B,C,G to 0
|
||||
PORTD &= 0xF0;
|
||||
}
|
||||
|
||||
static void select_rows(uint8_t row) {
|
||||
// set A,B,C,G to row value
|
||||
PORTD |= (0x0F & row);
|
||||
}
|
||||
|
||||
void matrix_init_custom(void) {
|
||||
// output low (multiplexers)
|
||||
setPinOutput(D0);
|
||||
setPinOutput(D1);
|
||||
setPinOutput(D2);
|
||||
setPinOutput(D3);
|
||||
|
||||
// input with pullup (matrix)
|
||||
setPinInputHigh(B6);
|
||||
setPinInputHigh(B2);
|
||||
setPinInputHigh(B3);
|
||||
setPinInputHigh(B1);
|
||||
setPinInputHigh(F7);
|
||||
setPinInputHigh(F6);
|
||||
setPinInputHigh(F5);
|
||||
setPinInputHigh(F4);
|
||||
|
||||
// input with pullup (program and keypad buttons)
|
||||
setPinInputHigh(B4);
|
||||
setPinInputHigh(B5);
|
||||
|
||||
// initialize row and col
|
||||
unselect_rows();
|
||||
}
|
||||
|
||||
bool matrix_scan_custom(matrix_row_t current_matrix[]) {
|
||||
bool matrix_has_changed = false;
|
||||
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
select_rows(i);
|
||||
matrix_row_t row = read_row(i);
|
||||
unselect_rows();
|
||||
bool row_has_changed = current_matrix[i] != row;
|
||||
matrix_has_changed |= row_has_changed;
|
||||
current_matrix[i] = row;
|
||||
}
|
||||
|
||||
return matrix_has_changed;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#include "nguyenvietyen.h"
|
||||
|
||||
void matrix_init_kb(void) {
|
||||
led_init_ports();
|
||||
matrix_init_user();
|
||||
}
|
||||
|
||||
void led_init_ports() {
|
||||
// * Set our LED pins as output
|
||||
setPinOutput(D7); // Keypad LED
|
||||
setPinOutput(C6); // ScrLock LED
|
||||
setPinOutput(D4); // NumLock LED
|
||||
setPinOutput(E6); // CapsLock LED
|
||||
|
||||
// turn all LEDs off by default
|
||||
writePinHigh(D7);
|
||||
writePinHigh(C6);
|
||||
writePinHigh(D4);
|
||||
writePinHigh(E6);
|
||||
}
|
||||
|
||||
bool led_update_kb(led_t led_state) {
|
||||
bool res = led_update_user(led_state);
|
||||
if (res) {
|
||||
writePin(D7, !led_state.compose);
|
||||
writePin(C6, !led_state.scroll_lock);
|
||||
writePin(D4, !led_state.num_lock);
|
||||
writePin(E6, !led_state.caps_lock);
|
||||
}
|
||||
return res;
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
#define ___ KC_NO
|
||||
|
||||
#define LAYOUT( \
|
||||
k02, k22, k12, k01, k21, k11, k00, k20, k10, \
|
||||
k80, k70, k60, k50, k40, k30, \
|
||||
k81, k71, k61, k51, k41, k31, \
|
||||
k82, k72, k62, k52, k42, k32, \
|
||||
k83, k73, k63, k53, k43, k33, \
|
||||
k74, k64, k54, k34, \
|
||||
k36, k35, \
|
||||
k55, \
|
||||
k56, k46, k75, \
|
||||
\
|
||||
k03, k23, k13, k04, k24, k14, k05, kC0, kC1, \
|
||||
k94, kA4, kB4, kD4, kE4, kF4, \
|
||||
k95, kA5, kB5, kD5, kE5, kF5, \
|
||||
k96, kA6, kB6, kD6, kE6, kF6, \
|
||||
k97, kA7, kB7, kD7, kE7, kF7, \
|
||||
k93, kB3, kD3, kE3, \
|
||||
k47, k66, \
|
||||
k67, \
|
||||
k87, k76, k86 \
|
||||
) { \
|
||||
{ k00, k01, k02, k03, k04, k05, ___, ___ }, \
|
||||
{ k10, k11, k12, k13, k14, ___, ___, ___ }, \
|
||||
{ k20, k21, k22, k23, k24, ___, ___, ___ }, \
|
||||
{ k30, k31, k32, k33, k34, k35, k36, ___ }, \
|
||||
{ k40, k41, k42, k43, ___, ___, k46, k47 }, \
|
||||
{ k50, k51, k52, k53, k54, k55, k56, ___ }, \
|
||||
{ k60, k61, k62, k63, k64, ___, k66, k67 }, \
|
||||
{ k70, k71, k72, k73, k74, k75, k76, ___ }, \
|
||||
{ k80, k81, k82, k83, ___, ___, k86, k87 }, \
|
||||
{ ___, ___, ___, k93, k94, k95, k96, k97 }, \
|
||||
{ ___, ___, ___, ___, kA4, kA5, kA6, kA7 }, \
|
||||
{ ___, ___, ___, kB3, kB4, kB5, kB6, kB7 }, \
|
||||
{ kC0, kC1, ___, ___, ___, ___, ___, ___ }, \
|
||||
{ ___, ___, ___, kD3, kD4, kD5, kD6, kD7 }, \
|
||||
{ ___, ___, ___, kE3, kE4, kE5, kE6, kE7 }, \
|
||||
{ ___, ___, ___, ___, kF4, kF5, kF6, kF7 } \
|
||||
}
|
||||
|
||||
/* ---------------- LEFT HAND ----------------- ---------------- RIGHT HAND ---------------- */
|
||||
#define LAYOUT_pretty( \
|
||||
k02, k22, k12, k01, k21, k11, k00, k20, k10, k03, k23, k13, k04, k24, k14, k05, kC0, kC1, \
|
||||
k80, k70, k60, k50, k40, k30, k94, kA4, kB4, kD4, kE4, kF4, \
|
||||
k81, k71, k61, k51, k41, k31, k95, kA5, kB5, kD5, kE5, kF5, \
|
||||
k82, k72, k62, k52, k42, k32, k96, kA6, kB6, kD6, kE6, kF6, \
|
||||
k83, k73, k63, k53, k43, k33, k97, kA7, kB7, kD7, kE7, kF7, \
|
||||
k74, k64, k54, k34, k93, kB3, kD3, kE3, \
|
||||
k36, k35, k47, k66, \
|
||||
k55, k67, \
|
||||
k56, k46, k75, k87, k76, k86 \
|
||||
) { \
|
||||
{ k00, k01, k02, k03, k04, k05, ___, ___ }, \
|
||||
{ k10, k11, k12, k13, k14, ___, ___, ___ }, \
|
||||
{ k20, k21, k22, k23, k24, ___, ___, ___ }, \
|
||||
{ k30, k31, k32, k33, k34, k35, k36, ___ }, \
|
||||
{ k40, k41, k42, k43, ___, ___, k46, k47 }, \
|
||||
{ k50, k51, k52, k53, k54, k55, k56, ___ }, \
|
||||
{ k60, k61, k62, k63, k64, ___, k66, k67 }, \
|
||||
{ k70, k71, k72, k73, k74, k75, k76, ___ }, \
|
||||
{ k80, k81, k82, k83, ___, ___, k86, k87 }, \
|
||||
{ ___, ___, ___, k93, k94, k95, k96, k97 }, \
|
||||
{ ___, ___, ___, ___, kA4, kA5, kA6, kA7 }, \
|
||||
{ ___, ___, ___, kB3, kB4, kB5, kB6, kB7 }, \
|
||||
{ kC0, kC1, ___, ___, ___, ___, ___, ___ }, \
|
||||
{ ___, ___, ___, kD3, kD4, kD5, kD6, kD7 }, \
|
||||
{ ___, ___, ___, kE3, kE4, kE5, kE6, kE7 }, \
|
||||
{ ___, ___, ___, ___, kF4, kF5, kF6, kF7 } \
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
# MCU name
|
||||
MCU = atmega32u4
|
||||
|
||||
# Bootloader selection
|
||||
BOOTLOADER = caterina
|
||||
|
||||
# Build Options
|
||||
# change yes to no to disable
|
||||
#
|
||||
BOOTMAGIC_ENABLE = yes
|
||||
MOUSEKEY_ENABLE = yes
|
||||
EXTRAKEY_ENABLE = yes
|
||||
COMMAND_ENABLE = yes
|
||||
NKRO_ENABLE = yes
|
||||
SLEEP_LED_ENABLE = yes
|
||||
CUSTOM_MATRIX = lite
|
||||
SRC += matrix.c
|
||||
|
||||
# experimentally determined to be sufficient :)
|
||||
DEBOUNCE=1
|
Loading…
Reference in New Issue