# List C source files here. (C dependencies are automatically generated.) | # List C source files here. (C dependencies are automatically generated.) | ||||
SRC = tmk.c \ | SRC = tmk.c \ | ||||
layer.c \ | |||||
key_process.c \ | key_process.c \ | ||||
usb_keyboard.c \ | usb_keyboard.c \ | ||||
usb_mouse.c \ | usb_mouse.c \ | ||||
usb.c \ | usb.c \ | ||||
jump_bootloader.c \ | jump_bootloader.c \ | ||||
print.c \ | print.c \ | ||||
timer.c \ | |||||
util.c | util.c | ||||
SRC += $(TARGET_SRC) | SRC += $(TARGET_SRC) | ||||
will be coded when bouncing occurs. | will be coded when bouncing occurs. | ||||
bouncing doesnt occur on my ALPS switch so far. | bouncing doesnt occur on my ALPS switch so far. | ||||
scan rate is too slow?(to be measure) | scan rate is too slow?(to be measure) | ||||
layer switching | |||||
time before switching | |||||
timeout when not used during specific time | |||||
Trackpoint(PS/2) | Trackpoint(PS/2) | ||||
receive PS/2 signal from TrackPoint | receive PS/2 signal from TrackPoint | ||||
key print on/off | key print on/off | ||||
mouse print on/off | mouse print on/off | ||||
2010/10/26 | 2010/10/26 | ||||
layer switching | |||||
time before switching | |||||
timeout when not used during specific time | |||||
2010/10/30 | |||||
EOF | EOF |
#define debug(s) if(debug_enable) print(s) | #define debug(s) if(debug_enable) print(s) | ||||
#define debug_hex(c) if(debug_enable) phex(c) | #define debug_hex(c) if(debug_enable) phex(c) | ||||
#define debug_hex16(i) if(debug_enable) phex(i) | |||||
#define debug_hex16(i) if(debug_enable) phex16(i) | |||||
#define debug_bin(c) if(debug_enable) pbin(c) | #define debug_bin(c) if(debug_enable) pbin(c) | ||||
#define debug_bin_reverse(c) if(debug_enable) pbin_reverse(c) | #define debug_bin_reverse(c) if(debug_enable) pbin_reverse(c) | ||||
#include "controller_teensy.h" | #include "controller_teensy.h" | ||||
/* matrix row size */ | |||||
#define MATRIX_ROWS 8 | |||||
/* matrix column size */ | |||||
#define MATRIX_COLS 8 | |||||
#endif | #endif |
#include <avr/pgmspace.h> | #include <avr/pgmspace.h> | ||||
#include "usb_keyboard.h" | #include "usb_keyboard.h" | ||||
#include "usb_keycodes.h" | #include "usb_keycodes.h" | ||||
#include "matrix.h" | |||||
#include "print.h" | #include "print.h" | ||||
#include "debug.h" | #include "debug.h" | ||||
#include "util.h" | #include "util.h" | ||||
#include "keymap.h" | |||||
#include "controller.h" | |||||
#include "keymap_skel.h" | |||||
#define FN_KEYCODE(fn) (pgm_read_byte(&fn_keycode[(fn)])) | |||||
#define FN_LAYER(fn) (pgm_read_byte(&fn_layer[(fn)])) | |||||
#define KEYCODE(layer, row, col) (pgm_read_byte(&keymaps[(layer)][(row)][(col)])) | |||||
#define KEYMAP( \ | #define KEYMAP( \ | ||||
R3C1, R3C0, R0C0, R1C0, R1C1, R2C0, R2C1, R4C0, R4C1, R6C0, R6C1, R7C0, R7C1, R5C0, R5C1, \ | R3C1, R3C0, R0C0, R1C0, R1C1, R2C0, R2C1, R4C0, R4C1, R6C0, R6C1, R7C0, R7C1, R5C0, R5C1, \ | ||||
R3C2, R0C1, R0C2, R1C3, R1C2, R2C3, R2C2, R4C2, R4C3, R6C2, R6C3, R7C3, R7C2, R5C2, \ | R3C2, R0C1, R0C2, R1C3, R1C2, R2C3, R2C2, R4C2, R4C3, R6C2, R6C3, R7C3, R7C2, R5C2, \ | ||||
{ R7C0, R7C1, R7C2, R7C3, R7C4, R7C5, R7C6, KB_NO } \ | { R7C0, R7C1, R7C2, R7C3, R7C4, R7C5, R7C6, KB_NO } \ | ||||
} | } | ||||
static int current_layer = 0; | |||||
static bool layer_used = false; | |||||
#define KEYCODE(layer, row, col) (pgm_read_byte(&keymaps[(layer)][(row)][(col)])) | |||||
/* layer to change into while Fn key pressed */ | /* layer to change into while Fn key pressed */ | ||||
}; | }; | ||||
uint8_t keymap_get_keycode(int row, int col) | |||||
uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col) | |||||
{ | { | ||||
return keymap_get_keycodel(current_layer, row, col); | |||||
return KEYCODE(layer, row, col); | |||||
} | } | ||||
uint8_t keymap_get_keycodel(int layer, int row, int col) | |||||
int keymap_fn_layer(uint8_t fn_bits) | |||||
{ | { | ||||
uint8_t code = KEYCODE(layer, row, col); | |||||
// normal key or mouse key | |||||
if (IS_KEY(code) || IS_MOUSE(code)) | |||||
layer_used = true; | |||||
return code; | |||||
return pgm_read_byte(&fn_layer[biton(fn_bits)]); | |||||
} | } | ||||
inline | |||||
int keymap_get_layer(void) | |||||
uint8_t keymap_fn_keycode(uint8_t fn_bits) | |||||
{ | { | ||||
return current_layer; | |||||
return pgm_read_byte(&fn_keycode[(biton(fn_bits))]); | |||||
} | } | ||||
inline | |||||
int keymap_set_layer(int layer) | |||||
{ | |||||
current_layer = layer; | |||||
return current_layer; | |||||
} | |||||
inline | |||||
bool keymap_is_special_mode(uint8_t fn_bits) | bool keymap_is_special_mode(uint8_t fn_bits) | ||||
{ | { | ||||
return (keyboard_modifier_keys == (BIT_LCTRL | BIT_LSHIFT | BIT_LALT | BIT_LGUI)); | return (keyboard_modifier_keys == (BIT_LCTRL | BIT_LSHIFT | BIT_LALT | BIT_LGUI)); | ||||
} | } | ||||
void keymap_fn_proc(uint8_t fn_bits) | |||||
{ | |||||
// layer switching | |||||
static uint8_t last_bits = 0; | |||||
static uint8_t last_mod = 0; | |||||
if (usb_keyboard_has_key() || fn_bits == last_bits) { | |||||
// do nothing during press other than Fn key | |||||
return; | |||||
} else if (fn_bits == 0) { | |||||
// send key when Fn key is released without using the layer | |||||
if (!layer_used) { | |||||
uint8_t code = FN_KEYCODE(biton(last_bits)); | |||||
if (code != KB_NO) { | |||||
if (IS_MOD(code)) { | |||||
keyboard_modifier_keys = last_mod | 1<<(code & 0x07); | |||||
} else { | |||||
keyboard_keys[0] = code; | |||||
keyboard_modifier_keys = last_mod; | |||||
} | |||||
usb_keyboard_send(); | |||||
usb_keyboard_print(); | |||||
usb_keyboard_clear(); | |||||
} | |||||
} | |||||
last_bits = 0; | |||||
last_mod = 0; | |||||
layer_used = false; | |||||
keymap_set_layer(0); // default layer | |||||
} else if ((fn_bits & (fn_bits - 1)) == 0) { | |||||
// switch layer when just one Fn Key is pressed | |||||
last_bits = fn_bits; | |||||
last_mod = keyboard_modifier_keys; | |||||
layer_used = false; | |||||
keymap_set_layer(FN_LAYER(biton(fn_bits))); | |||||
debug("layer: "); phex(current_layer); debug("("); | |||||
debug_bin(last_bits); debug(")\n"); | |||||
debug("last_mod: "); debug_hex(last_mod); debug("\n"); | |||||
} | |||||
} |
#ifndef KEYMAP_H | |||||
#define KEYMAP_H 1 | |||||
#include "usb_keycodes.h" | |||||
#include "keymap_skel.h" | |||||
#endif |
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <avr/io.h> | #include <avr/io.h> | ||||
#include <util/delay.h> | #include <util/delay.h> | ||||
#include "matrix.h" | |||||
#include "print.h" | #include "print.h" | ||||
#include "util.h" | #include "util.h" | ||||
#include "controller.h" | |||||
#include "matrix_skel.h" | |||||
// matrix is active low. (key on: 0/key off: 1) | // matrix is active low. (key on: 0/key off: 1) | ||||
// | // | ||||
#define KEY_ON ((PINE&(1<<6)) ? false : true) | #define KEY_ON ((PINE&(1<<6)) ? false : true) | ||||
// matrix state buffer | // matrix state buffer | ||||
uint8_t *matrix; | |||||
uint8_t *matrix_prev; | |||||
static uint8_t *matrix; | |||||
static uint8_t *matrix_prev; | |||||
static uint8_t _matrix0[MATRIX_ROWS]; | static uint8_t _matrix0[MATRIX_ROWS]; | ||||
static uint8_t _matrix1[MATRIX_ROWS]; | static uint8_t _matrix1[MATRIX_ROWS]; | ||||
#ifndef MATRIX_H | |||||
#define MATRIX_H 1 | |||||
#include <stdbool.h> | |||||
#include "matrix_skel.h" | |||||
#define MATRIX_ROWS 8 | |||||
#define MATRIX_COLS 8 | |||||
extern uint8_t *matrix; | |||||
extern uint8_t *matrix_prev; | |||||
#endif |
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <avr/io.h> | #include <avr/io.h> | ||||
#include <util/delay.h> | #include <util/delay.h> | ||||
#include "usb_keyboard.h" | |||||
#include "usb_mouse.h" | |||||
#include "usb_keycodes.h" | |||||
#include "print.h" | #include "print.h" | ||||
#include "debug.h" | #include "debug.h" | ||||
#include "timer.h" | |||||
#include "util.h" | #include "util.h" | ||||
#include "jump_bootloader.h" | #include "jump_bootloader.h" | ||||
#include "usb_keyboard.h" | |||||
#include "usb_mouse.h" | |||||
#include "usb_keycodes.h" | |||||
#include "layer.h" | |||||
#include "matrix_skel.h" | #include "matrix_skel.h" | ||||
#include "keymap_skel.h" | #include "keymap_skel.h" | ||||
#include "controller.h" | #include "controller.h" | ||||
#include "key_process.h" | #include "key_process.h" | ||||
for (int col = 0; col < matrix_cols(); col++) { | for (int col = 0; col < matrix_cols(); col++) { | ||||
if (!matrix_is_on(row, col)) continue; | if (!matrix_is_on(row, col)) continue; | ||||
uint8_t code = keymap_get_keycode(row, col); | |||||
uint8_t code = layer_get_keycode(row, col); | |||||
if (code == KB_NO) { | if (code == KB_NO) { | ||||
// do nothing | // do nothing | ||||
} else if (IS_MOD(code)) { | } else if (IS_MOD(code)) { | ||||
} | } | ||||
} | } | ||||
} | } | ||||
keymap_fn_proc(fn_bits); | |||||
layer_switching(fn_bits); | |||||
// when 4 left modifier keys down | // when 4 left modifier keys down | ||||
if (keymap_is_special_mode(fn_bits)) { | if (keymap_is_special_mode(fn_bits)) { | ||||
switch (keyboard_keys[0]) { | switch (keyboard_keys[0]) { | ||||
case KB_B: // bootloader | |||||
case KB_H: // help | |||||
print_enable = true; | |||||
print("b: jump to bootloader\n"); | |||||
print("d: debug print toggle\n"); | |||||
print("k: keyboard debug toggle\n"); | |||||
print("m: mouse debug toggle\n"); | |||||
print("x: matrix debug toggle\n"); | |||||
print("v: print version\n"); | |||||
print("t: print timer count\n"); | |||||
print("p: print enable toggle\n"); | |||||
_delay_ms(500); | |||||
print_enable = false; | |||||
break; | |||||
case KB_B: // bootloader | |||||
usb_keyboard_clear(); | usb_keyboard_clear(); | ||||
usb_keyboard_send(); | usb_keyboard_send(); | ||||
print_enable = true; | print_enable = true; | ||||
usb_keyboard_send(); | usb_keyboard_send(); | ||||
debug_enable = !debug_enable; | debug_enable = !debug_enable; | ||||
if (debug_enable) { | if (debug_enable) { | ||||
print("debug enabled.\n"); | |||||
print_enable = true; | print_enable = true; | ||||
print("debug enabled.\n"); | |||||
debug_matrix = true; | debug_matrix = true; | ||||
debug_keyboard = true; | debug_keyboard = true; | ||||
debug_mouse = true; | debug_mouse = true; | ||||
case KB_V: // print version & information | case KB_V: // print version & information | ||||
usb_keyboard_clear(); | usb_keyboard_clear(); | ||||
usb_keyboard_send(); | usb_keyboard_send(); | ||||
print_enable = true; | |||||
print(STR(DESCRIPTION) "\n"); | print(STR(DESCRIPTION) "\n"); | ||||
_delay_ms(1000); | _delay_ms(1000); | ||||
break; | break; | ||||
case KB_T: // print timer | |||||
usb_keyboard_clear(); | |||||
usb_keyboard_send(); | |||||
print_enable = true; | |||||
print("timer: "); phex16(timer_count); print("\n"); | |||||
_delay_ms(500); | |||||
break; | |||||
case KB_P: // print toggle | |||||
usb_keyboard_clear(); | |||||
usb_keyboard_send(); | |||||
if (print_enable) { | |||||
print("print disabled.\n"); | |||||
print_enable = false; | |||||
} else { | |||||
print_enable = true; | |||||
print("print enabled.\n"); | |||||
} | |||||
_delay_ms(1000); | |||||
break; | |||||
} | } | ||||
} | } | ||||
#include "usb_keycodes.h" | #include "usb_keycodes.h" | ||||
uint8_t keymap_get_keycode(int row, int col); | |||||
uint8_t keymap_get_keycodel(int layer, int row, int col); | |||||
int keymap_get_layer(void); | |||||
int keymap_set_layer(int layer); | |||||
/* keycode in specific layer */ | |||||
uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col); | |||||
/* layer to move during press Fn key */ | |||||
int keymap_fn_layer(uint8_t fn_bits); | |||||
/* keycode to send when release Fn key without using */ | |||||
uint8_t keymap_fn_keycode(uint8_t fn_bits); | |||||
/* whether special key combination */ | |||||
bool keymap_is_special_mode(uint8_t fn_bits); | bool keymap_is_special_mode(uint8_t fn_bits); | ||||
/* process Fn keys. This.should be called every scan. */ | |||||
void keymap_fn_proc(uint8_t fn_bits); | |||||
#endif | #endif |
#include "keymap_skel.h" | |||||
#include "usb_keyboard.h" | |||||
#include "debug.h" | |||||
#include "timer.h" | |||||
#include "layer.h" | |||||
/* | |||||
* LAYER_ENTER_DELAY: prevent from moving new layer | |||||
* press release | |||||
* Fn key sate ____|~~~~~~~~~~~~~~~~~~~|_______________ | |||||
* | |||||
* enter_delay |======| | |||||
* new layer | |||||
* Layer sw ___________|~~~~~~~~~~~~|_______________ | |||||
*/ | |||||
#define LAYER_ENTER_DELAY 10 | |||||
/* | |||||
* LAYER_SEND_FN_TERM: send keycode if release key in this term | |||||
* press release(send) | |||||
* Fn key state ____|~~~~~~~~~~~~~|_______________ | |||||
* press | release(not send) | |||||
* Fn key state ____|~~~~~~~~~~~~~|~~~~~~|__________ | |||||
* | | | |||||
* send_fn_term |=============o==| x | |||||
*/ | |||||
#define LAYER_SEND_FN_TERM 30 | |||||
static uint8_t current_layer = 0; | |||||
static bool layer_used = false; | |||||
uint8_t layer_get_keycode(uint8_t row, uint8_t col) | |||||
{ | |||||
uint8_t code = keymap_get_keycode(current_layer, row, col); | |||||
// normal key or mouse key | |||||
if ((IS_KEY(code) || IS_MOUSE(code))) | |||||
layer_used = true; | |||||
return code; | |||||
} | |||||
void layer_switching(uint8_t fn_bits) | |||||
{ | |||||
// layer switching | |||||
static uint8_t last_bits = 0; | |||||
static uint8_t last_mod = 0; | |||||
static uint16_t last_timer = 0; | |||||
//uint16_t now_timer; | |||||
if (fn_bits == last_bits) { | |||||
// switch layer when specific time elapsed | |||||
if (current_layer != keymap_fn_layer(fn_bits) && | |||||
timer_elapsed(last_timer) > LAYER_ENTER_DELAY) { | |||||
current_layer = keymap_fn_layer(fn_bits); | |||||
debug("time_elapsed: "); debug_hex16(timer_elapsed(last_timer)); debug("\n"); | |||||
debug("switch layer: "); debug_hex(current_layer); debug("\n"); | |||||
} | |||||
} else if (fn_bits == 0) { | |||||
// send key when Fn key is released without using the layer and within specific time | |||||
if ((!layer_used || current_layer != keymap_fn_layer(last_bits)) && | |||||
timer_elapsed(last_timer) < LAYER_SEND_FN_TERM) { | |||||
uint8_t code = keymap_fn_keycode(last_bits); | |||||
if (code != KB_NO) { | |||||
if (IS_MOD(code)) { | |||||
keyboard_modifier_keys = last_mod | MOD_BIT(code); | |||||
} else { | |||||
keyboard_keys[0] = code; | |||||
keyboard_modifier_keys = last_mod; | |||||
} | |||||
usb_keyboard_send(); | |||||
usb_keyboard_print(); | |||||
usb_keyboard_clear(); | |||||
} | |||||
} | |||||
last_bits = 0; | |||||
last_mod = 0; | |||||
layer_used = false; | |||||
current_layer = 0; // default layer | |||||
} else if ((fn_bits & (fn_bits - 1)) == 0) { | |||||
// switch layer when just one Fn Key is pressed | |||||
if (!usb_keyboard_has_key()) { | |||||
last_bits = fn_bits; | |||||
last_mod = keyboard_modifier_keys; | |||||
last_timer = timer_read(); | |||||
debug("last_bits: "); debug_bin(last_bits); debug("\n"); | |||||
debug("last_mod: "); debug_hex(last_mod); debug("\n"); | |||||
debug("last_timer: "); debug_hex16(last_timer); debug("\n"); | |||||
} | |||||
} | |||||
} |
#ifndef LAYER_H | |||||
#define LAYER_H 1 | |||||
#include <stdint.h> | |||||
/* return keycode for switch */ | |||||
uint8_t layer_get_keycode(uint8_t row, uint8_t col); | |||||
/* process layer switching */ | |||||
void layer_switching(uint8_t fn_bits); | |||||
#endif |
#include "controller_teensy.h" | #include "controller_teensy.h" | ||||
/* matrix row size */ | |||||
#define MATRIX_ROWS 9 | |||||
/* matrix column size */ | |||||
#define MATRIX_COLS 8 | |||||
#endif | #endif |
#include <stdint.h> | #include <stdint.h> | ||||
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <avr/pgmspace.h> | #include <avr/pgmspace.h> | ||||
#include <avr/interrupt.h> | |||||
#include "usb_keyboard.h" | #include "usb_keyboard.h" | ||||
#include "usb_keycodes.h" | #include "usb_keycodes.h" | ||||
#include "matrix.h" | |||||
#include "print.h" | #include "print.h" | ||||
#include "debug.h" | #include "debug.h" | ||||
#include "util.h" | #include "util.h" | ||||
#include "keymap.h" | |||||
#include "controller.h" | |||||
#include "keymap_skel.h" | |||||
#define FN_KEYCODE(fn) (pgm_read_byte(&fn_keycode[(fn)])) | |||||
#define FN_LAYER(fn) (pgm_read_byte(&fn_layer[(fn)])) | |||||
#define KEYCODE(layer, row, col) (pgm_read_byte(&keymaps[(layer)][(row)][(col)])) | |||||
#define KEYMAP( \ | #define KEYMAP( \ | ||||
R1C1, R1C0, R2C0, R3C0, R4C0, R4C1, R5C1, R5C0, R6C0, R7C0, R8C0, R8C1, R6C1, R0C2, \ | R1C1, R1C0, R2C0, R3C0, R4C0, R4C1, R5C1, R5C0, R6C0, R7C0, R8C0, R8C1, R6C1, R0C2, \ | ||||
R1C2, R1C3, R2C3, R3C3, R4C3, R4C2, R5C2, R5C3, R6C3, R7C3, R8C3, R8C2, R6C2, \ | R1C2, R1C3, R2C3, R3C3, R4C3, R4C2, R5C2, R5C3, R6C3, R7C3, R8C3, R8C2, R6C2, \ | ||||
{ R8C0, R8C1, R8C2, R8C3, R8C4, R8C5, KB_NO, R8C7 } \ | { R8C0, R8C1, R8C2, R8C3, R8C4, R8C5, KB_NO, R8C7 } \ | ||||
} | } | ||||
#define KEYCODE(layer, row, col) (pgm_read_byte(&keymaps[(layer)][(row)][(col)])) | |||||
static int current_layer = 0; | |||||
static bool layer_used = false; | |||||
/* layer to change into while Fn key pressed */ | |||||
static const int PROGMEM fn_layer[] = { 0, 1, 2, 3, 4, 0, 2, 3 }; | |||||
static const uint8_t PROGMEM fn_layer[] = { 0, 1, 2, 3, 4, 0, 2, 3 }; | |||||
/* keycode to sent when Fn key released without using layer keys. */ | |||||
static const uint8_t PROGMEM fn_keycode[] = { | static const uint8_t PROGMEM fn_keycode[] = { | ||||
KB_NO, // FN_0 [NOT USED] | KB_NO, // FN_0 [NOT USED] | ||||
KB_NO, // FN_1 layer 1 | KB_NO, // FN_1 layer 1 | ||||
KB_LSFT,KB_Z, KB_X, KB_C, KB_V, KB_B, KB_N, KB_M, KB_COMM,KB_DOT, KB_SLSH,KB_RSFT,FN_1, \ | KB_LSFT,KB_Z, KB_X, KB_C, KB_V, KB_B, KB_N, KB_M, KB_COMM,KB_DOT, KB_SLSH,KB_RSFT,FN_1, \ | ||||
FN_7, KB_LGUI,KB_LALT,KB_SPC, FN_6, KB_BSLS,KB_GRV, KB_NO, KB_NO), | FN_7, KB_LGUI,KB_LALT,KB_SPC, FN_6, KB_BSLS,KB_GRV, KB_NO, KB_NO), | ||||
/* Layer 1: HHKB mode (HHKB Fn) | /* Layer 1: HHKB mode (HHKB Fn) | ||||
* ,-----------------------------------------------------------. | * ,-----------------------------------------------------------. | ||||
* |Pow| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete | | * |Pow| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete | | ||||
KB_LSFT,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KP_PLUS,KP_MINS,KB_END, KB_PGDN,KB_DOWN,KB_RSFT,FN_1, \ | KB_LSFT,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KP_PLUS,KP_MINS,KB_END, KB_PGDN,KB_DOWN,KB_RSFT,FN_1, \ | ||||
KB_NO, KB_LGUI,KB_LALT,KB_SPC, KB_RALT,KB_NO, KB_NO, KB_NO, KB_NO), | KB_NO, KB_LGUI,KB_LALT,KB_SPC, KB_RALT,KB_NO, KB_NO, KB_NO, KB_NO), | ||||
/* Layer 2: Vi mode (Quote/Rmeta) | /* Layer 2: Vi mode (Quote/Rmeta) | ||||
* ,-----------------------------------------------------------. | * ,-----------------------------------------------------------. | ||||
* | `| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12| ` | | * | `| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12| ` | | ||||
KB_LSFT,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_RSFT,KB_NO, \ | KB_LSFT,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_RSFT,KB_NO, \ | ||||
KB_NO, KB_LGUI,KB_LALT,KB_SPC, FN_6, KB_NO, KB_NO, KB_NO, KB_NO), | KB_NO, KB_LGUI,KB_LALT,KB_SPC, FN_6, KB_NO, KB_NO, KB_NO, KB_NO), | ||||
/* Layer 3: Mouse mode (Semicolon) | /* Layer 3: Mouse mode (Semicolon) | ||||
* ,-------------------------------------------------------- --. | * ,-------------------------------------------------------- --. | ||||
* |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete | | * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete | | ||||
KB_LSFT,KB_NO, MS_DOWN,KB_NO, KB_NO, KB_NO, MS_BTN2,MS_BTN1,MS_BTN2,MS_BTN3,KB_NO, KB_RSFT,KB_NO, \ | KB_LSFT,KB_NO, MS_DOWN,KB_NO, KB_NO, KB_NO, MS_BTN2,MS_BTN1,MS_BTN2,MS_BTN3,KB_NO, KB_RSFT,KB_NO, \ | ||||
FN_7, KB_LGUI,KB_LALT,MS_BTN1,KB_RALT,KB_NO, KB_NO, KB_NO, KB_NO), | FN_7, KB_LGUI,KB_LALT,MS_BTN1,KB_RALT,KB_NO, KB_NO, KB_NO, KB_NO), | ||||
/* Layer 4: Matias half keyboard style (Space) | /* Layer 4: Matias half keyboard style (Space) | ||||
* ,-----------------------------------------------------------. | * ,-----------------------------------------------------------. | ||||
* |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete | | * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete | | ||||
}; | }; | ||||
uint8_t keymap_get_keycode(int row, int col) | |||||
uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col) | |||||
{ | { | ||||
return keymap_get_keycodel(current_layer, row, col); | |||||
return KEYCODE(layer, row, col); | |||||
} | } | ||||
uint8_t keymap_get_keycodel(int layer, int row, int col) | |||||
int keymap_fn_layer(uint8_t fn_bits) | |||||
{ | { | ||||
uint8_t code = KEYCODE(layer, row, col); | |||||
// normal key or mouse key | |||||
if (IS_KEY(code) || IS_MOUSE(code)) | |||||
layer_used = true; | |||||
return code; | |||||
return pgm_read_byte(&fn_layer[biton(fn_bits)]); | |||||
} | } | ||||
inline | |||||
int keymap_get_layer(void) | |||||
uint8_t keymap_fn_keycode(uint8_t fn_bits) | |||||
{ | { | ||||
return current_layer; | |||||
return pgm_read_byte(&fn_keycode[(biton(fn_bits))]); | |||||
} | } | ||||
inline | |||||
int keymap_set_layer(int layer) | |||||
{ | |||||
current_layer = layer; | |||||
return current_layer; | |||||
} | |||||
inline | |||||
bool keymap_is_special_mode(uint8_t fn_bits) | bool keymap_is_special_mode(uint8_t fn_bits) | ||||
{ | { | ||||
return (keyboard_modifier_keys == (BIT_LCTRL | BIT_LSHIFT | BIT_LALT | BIT_LGUI)); | return (keyboard_modifier_keys == (BIT_LCTRL | BIT_LSHIFT | BIT_LALT | BIT_LGUI)); | ||||
} | } | ||||
void keymap_fn_proc(uint8_t fn_bits) | |||||
{ | |||||
// layer switching | |||||
static int last_bits = 0; | |||||
static uint8_t last_mod = 0; | |||||
if (usb_keyboard_has_key() || fn_bits == last_bits) { | |||||
// do nothing during press other than Fn key | |||||
return; | |||||
} else if (fn_bits == 0) { | |||||
// send key when Fn key is released without using the layer | |||||
if (!layer_used) { | |||||
uint8_t code = FN_KEYCODE(biton(last_bits)); | |||||
if (code != KB_NO) { | |||||
if (IS_MOD(code)) { | |||||
keyboard_modifier_keys = last_mod | 1<<(code & 0x07); | |||||
} else { | |||||
keyboard_keys[0] = code; | |||||
keyboard_modifier_keys = last_mod; | |||||
} | |||||
usb_keyboard_send(); | |||||
usb_keyboard_print(); | |||||
usb_keyboard_clear(); | |||||
} | |||||
} | |||||
last_bits = 0; | |||||
last_mod = 0; | |||||
layer_used = false; | |||||
keymap_set_layer(0); // default layer | |||||
} else if ((fn_bits & (fn_bits - 1)) == 0) { | |||||
// switch layer when just one Fn Key is pressed | |||||
last_bits = fn_bits; | |||||
last_mod = keyboard_modifier_keys; | |||||
layer_used = false; | |||||
keymap_set_layer(FN_LAYER(biton(fn_bits))); | |||||
debug("layer: "); phex(current_layer); debug("("); | |||||
debug_bin(last_bits); debug(")\n"); | |||||
debug("last_mod: "); debug_hex(last_mod); debug("\n"); | |||||
} | |||||
} |
#ifndef KEYMAP_H | |||||
#define KEYMAP_H 1 | |||||
#include "usb_keycodes.h" | |||||
#include "keymap_skel.h" | |||||
#endif |
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <avr/io.h> | #include <avr/io.h> | ||||
#include <util/delay.h> | #include <util/delay.h> | ||||
#include "matrix.h" | |||||
#include "print.h" | #include "print.h" | ||||
#include "util.h" | #include "util.h" | ||||
#include "controller.h" | |||||
#include "matrix_skel.h" | |||||
// matrix is active low. (key on: 0/key off: 1) | // matrix is active low. (key on: 0/key off: 1) | ||||
// row: Hi-Z(unselected)/low output(selected) | // row: Hi-Z(unselected)/low output(selected) | ||||
// PB0-PB7 | // PB0-PB7 | ||||
// matrix state buffer | // matrix state buffer | ||||
uint8_t *matrix; | |||||
uint8_t *matrix_prev; | |||||
static uint8_t *matrix; | |||||
static uint8_t *matrix_prev; | |||||
static uint8_t _matrix0[MATRIX_ROWS]; | static uint8_t _matrix0[MATRIX_ROWS]; | ||||
static uint8_t _matrix1[MATRIX_ROWS]; | static uint8_t _matrix1[MATRIX_ROWS]; | ||||
#ifndef MATRIX_H | |||||
#define MATRIX_H 1 | |||||
#include <stdint.h> | |||||
#include "matrix_skel.h" | |||||
#define MATRIX_ROWS 9 | |||||
#define MATRIX_COLS 8 | |||||
extern uint8_t *matrix; | |||||
extern uint8_t *matrix_prev; | |||||
#endif |
#ifndef MATRIX_SKEL_H | #ifndef MATRIX_SKEL_H | ||||
#define MATRIX_SKEL_H 1 | |||||
#define MATRIX_SKEL_H 1 | |||||
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <avr/io.h> | |||||
#include <avr/interrupt.h> | |||||
#include <stdint.h> | |||||
#include "timer.h" | |||||
uint16_t timer_count = 0; | |||||
// Configure timer 0 to generate a timer overflow interrupt every | |||||
// 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock | |||||
// This demonstrates how to use interrupts to implement a simple | |||||
// inactivity timeout. | |||||
void timer_init(void) | |||||
{ | |||||
TCCR0A = 0x00; | |||||
TCCR0B = 0x05; | |||||
TIMSK0 = (1<<TOIE0); | |||||
} | |||||
inline | |||||
void timer_clear(void) | |||||
{ | |||||
cli(); | |||||
timer_count = 0; | |||||
sei(); | |||||
} | |||||
inline | |||||
uint16_t timer_read(void) | |||||
{ | |||||
uint8_t _sreg = SREG; | |||||
uint16_t t; | |||||
cli(); | |||||
t = timer_count; | |||||
SREG = _sreg; | |||||
return t; | |||||
} | |||||
inline | |||||
uint16_t timer_elapsed(uint16_t last) | |||||
{ | |||||
uint8_t _sreg = SREG; | |||||
uint16_t t; | |||||
cli(); | |||||
t = timer_count; | |||||
SREG = _sreg; | |||||
return TIMER_DIFF(t, last); | |||||
} | |||||
// This interrupt routine is run approx 61 times per second. | |||||
// A very simple inactivity timeout is implemented, where we | |||||
// will send a space character and print a message to the | |||||
// hid_listen debug message window. | |||||
ISR(TIMER0_OVF_vect) | |||||
{ | |||||
timer_count++; | |||||
} | |||||
#ifndef TIMER_H | |||||
#define TIMER_H 1 | |||||
#include <stdint.h> | |||||
#define TIMER_DIFF(a, b) ((a) >= (b) ? (a) - (b) : UINT16_MAX - (b) + (a)) | |||||
extern uint16_t timer_count; | |||||
void timer_init(void); | |||||
void timer_clear(void); | |||||
uint16_t timer_read(void); | |||||
uint16_t timer_elapsed(uint16_t last); | |||||
#endif |
#include "debug.h" | #include "debug.h" | ||||
#include "util.h" | #include "util.h" | ||||
#include "controller.h" | #include "controller.h" | ||||
#include "timer.h" | |||||
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) | #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) | ||||
bool debug_enable = false; | bool debug_enable = false; | ||||
bool debug_matrix = false; | bool debug_matrix = false; | ||||
bool debug_keyboard = false; | bool debug_keyboard = false; | ||||
bool debug_mouse = false; | bool debug_mouse = false; | ||||
uint16_t idle_count=0; | |||||
int main(void) | int main(void) | ||||
{ | { | ||||
usb_init(); | usb_init(); | ||||
while (!usb_configured()) /* wait */ ; | while (!usb_configured()) /* wait */ ; | ||||
// Configure timer 0 to generate a timer overflow interrupt every | |||||
// 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock | |||||
// This demonstrates how to use interrupts to implement a simple | |||||
// inactivity timeout. | |||||
TCCR0A = 0x00; | |||||
TCCR0B = 0x05; | |||||
TIMSK0 = (1<<TOIE0); | |||||
timer_init(); | |||||
matrix_init(); | matrix_init(); | ||||
matrix_scan(); | matrix_scan(); | ||||
_delay_ms(2); | _delay_ms(2); | ||||
} | } | ||||
} | } | ||||
// This interrupt routine is run approx 61 times per second. | |||||
// A very simple inactivity timeout is implemented, where we | |||||
// will send a space character and print a message to the | |||||
// hid_listen debug message window. | |||||
ISR(TIMER0_OVF_vect) | |||||
{ | |||||
idle_count++; | |||||
} |