]> git.friedersdorff.com Git - max/tmk_keyboard.git/commitdiff
Initial version of new code for layer switch is added.
authortmk <nobody@nowhere>
Fri, 5 Oct 2012 17:23:12 +0000 (02:23 +0900)
committertmk <nobody@nowhere>
Wed, 17 Oct 2012 06:55:37 +0000 (15:55 +0900)
19 files changed:
common.mk
common/command.c
common/host.c
common/host.h
common/keyboard.c [changed mode: 0644->0755]
common/keyboard.h [changed mode: 0644->0755]
common/layer.c [deleted file]
common/layer.h [deleted file]
common/matrix.h
common/mousekey.c
common/mousekey.h
common/timer.c
common/usb_keycodes.h
common/util.c
common/util.h
keyboard/hhkb/config.h
keyboard/hhkb/keymap.c
keyboard/hhkb/matrix.c
protocol/lufa/lufa.c

index 26b4bb85962317777df8ee99b23aaa375667e344..66f9fd0999c6cb25f70400f5580d97a0e992d5e7 100644 (file)
--- a/common.mk
+++ b/common.mk
@@ -2,7 +2,6 @@ COMMON_DIR = common
 SRC += $(COMMON_DIR)/host.c \
        $(COMMON_DIR)/keyboard.c \
        $(COMMON_DIR)/command.c \
-       $(COMMON_DIR)/layer.c \
        $(COMMON_DIR)/timer.c \
        $(COMMON_DIR)/print.c \
        $(COMMON_DIR)/debug.c \
index 13d37242d93c60d0440c5a76212991bdcff4980b..0020d8a17cc2c78d74d0726fb42b02d0aaab2f56 100644 (file)
@@ -23,7 +23,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "debug.h"
 #include "util.h"
 #include "timer.h"
-#include "layer.h"
+#include "keyboard.h"
 #include "matrix.h"
 #include "bootloader.h"
 #include "command.h"
index 8dd2abbee8d86048ff21ad9c9cd4c0b42054695e..fddd5b6627fdad4411982bafbd3f70d6b135d5b1 100644 (file)
@@ -56,6 +56,19 @@ uint8_t host_keyboard_leds(void)
     return (*driver->keyboard_leds)();
 }
 
+/* new interface */
+void host_register_key(uint8_t key)
+{
+    host_add_key(key);
+    host_send_keyboard_report();
+}
+
+void host_unregister_key(uint8_t key)
+{
+    host_del_key(key);
+    host_send_keyboard_report();
+}
+
 /* keyboard report operations */
 void host_add_key(uint8_t key)
 {
@@ -158,6 +171,14 @@ void host_send_keyboard_report(void)
 {
     if (!driver) return;
     (*driver->send_keyboard)(keyboard_report);
+
+    if (debug_keyboard) {
+        print("keys: ");
+        for (int i = 0; i < REPORT_KEYS; i++) {
+            phex(keyboard_report->keys[i]); print(" ");
+        }
+        print(" mods: "); phex(keyboard_report->mods); print("\n");
+    }
 }
 
 void host_mouse_send(report_mouse_t *report)
@@ -216,7 +237,6 @@ static inline void del_key_byte(uint8_t code)
     for (; i < REPORT_KEYS; i++) {
         if (keyboard_report->keys[i] == code) {
             keyboard_report->keys[i] = 0;
-            break;
         }
     }
 }
index 26bf3c362f985cec8b70f29c77ac2b9f65792efe..84a6c24773fed65e6cfb77d52abf2f807ffaa9f6 100644 (file)
@@ -39,6 +39,10 @@ void host_set_driver(host_driver_t *driver);
 host_driver_t *host_get_driver(void);
 uint8_t host_keyboard_leds(void);
 
+/* new interface */
+void host_register_key(uint8_t key);
+void host_unregister_key(uint8_t key);
+
 /* keyboard report operations */
 void host_add_key(uint8_t key);
 void host_del_key(uint8_t key);
old mode 100644 (file)
new mode 100755 (executable)
index 25f32eb..9f0c276
@@ -15,15 +15,16 @@ You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "keyboard.h"
-#include "host.h"
-#include "layer.h"
 #include "matrix.h"
+#include "keymap.h"
+#include "host.h"
 #include "led.h"
 #include "usb_keycodes.h"
 #include "timer.h"
 #include "print.h"
 #include "debug.h"
 #include "command.h"
+#include "util.h"
 #ifdef MOUSEKEY_ENABLE
 #include "mousekey.h"
 #endif
@@ -32,162 +33,444 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #endif
 
 
-static uint8_t last_leds = 0;
+#define LAYER_DELAY     250
 
+typedef enum keykind {
+    NONE,
+    FN_DOWN, FN_UP,
+    FNK_DOWN, FNK_UP,
+    KEY_DOWN, KEY_UP,
+    MOD_DOWN, MOD_UP,
+    MOUSEKEY_DOWN, MOUSEKEY_UP,
+    DELAY
+} keykind_t;
 
-void keyboard_init(void)
+typedef enum { IDLE, DELAYING, WAITING, PRESSING } kbdstate_t;
+
+
+uint8_t current_layer = 0;
+uint8_t default_layer = 0;
+
+/* keyboard internal states */
+static kbdstate_t kbdstate = IDLE;
+static uint8_t fn_state_bits = 0;
+static keyrecord_t delayed_fn;
+static keyrecord_t waiting_key;
+
+
+static const char *state_str(kbdstate_t state)
 {
-    timer_init();
-    matrix_init();
-#ifdef PS2_MOUSE_ENABLE
-    ps2_mouse_init();
-#endif
+    if (state == IDLE)      return PSTR("IDLE");
+    if (state == DELAYING)  return PSTR("DELAYING");
+    if (state == WAITING)   return PSTR("WAITING");
+    if (state == PRESSING)  return PSTR("PRESSING");
+    return PSTR("UNKNOWN");
 }
 
-void keyboard_proc(void)
+static inline keykind_t get_keykind(uint8_t code, bool pressed)
 {
-    uint8_t fn_bits = 0;
-#ifdef EXTRAKEY_ENABLE
-    uint16_t consumer_code = 0;
-    uint16_t system_code = 0;
-#endif
-
-    matrix_scan();
+    if IS_KEY(code) return (pressed ? KEY_DOWN      : KEY_UP);
+    if IS_MOD(code) return (pressed ? MOD_DOWN      : MOD_UP);
+    if IS_FN(code) {
+        if (keymap_fn_keycode(FN_INDEX(code)))
+            return (pressed ? FNK_DOWN : FNK_UP);
+        else
+            return (pressed ? FN_DOWN : FN_UP);
+    }
+    if IS_MOUSEKEY(code)    return (pressed ? MOUSEKEY_DOWN : MOUSEKEY_UP);
+    return  NONE;
+}
 
-    if (matrix_is_modified()) {
-        if (debug_matrix) matrix_print();
-#ifdef DEBUG_LED
-        // LED flash for debug
-        DEBUG_LED_CONFIG;
-        DEBUG_LED_ON;
-#endif
+static void layer_switch_on(uint8_t code)
+{
+    if (!IS_FN(code)) return;
+    fn_state_bits |= FN_BIT(code);
+    if (current_layer != keymap_fn_layer(FN_INDEX(code))) {
+        //TODO: clear all key execpt Mod key
+        debug("Layer Switch(on): "); debug_hex(current_layer);
+        current_layer = keymap_fn_layer(FN_INDEX(code));
+        debug(" -> "); debug_hex(current_layer); debug("\n");
     }
+}
 
-    if (matrix_has_ghost()) {
-        // should send error?
-        debug("matrix has ghost!!\n");
-        return;
+static void layer_switch_off(uint8_t code)
+{
+    if (!IS_FN(code)) return;
+    fn_state_bits &= ~FN_BIT(code);
+    if (current_layer != keymap_fn_layer(biton(fn_state_bits))) {
+        //TODO: clear all key execpt Mod key
+        debug("Layer Switch(off): "); debug_hex(current_layer);
+        current_layer = keymap_fn_layer(biton(fn_state_bits));
+        debug(" -> "); debug_hex(current_layer); debug("\n");
     }
+}
 
-    host_swap_keyboard_report();
-    host_clear_keyboard_report();
-    for (int row = 0; row < matrix_rows(); row++) {
-        for (int col = 0; col < matrix_cols(); col++) {
-            if (!matrix_is_on(row, col)) continue;
-
-            uint8_t code = layer_get_keycode(row, col);
-            if (code == KB_NO) {
-                // do nothing
-            } else if (IS_MOD(code)) {
-                host_add_mod_bit(MOD_BIT(code));
-            } else if (IS_FN(code)) {
-                fn_bits |= FN_BIT(code);
-            }
-// TODO: use table or something
-#ifdef EXTRAKEY_ENABLE
-            // System Control
-            else if (code == KB_SYSTEM_POWER) {
-#ifdef HOST_PJRC
-                if (suspend && remote_wakeup) {
-                    usb_remote_wakeup();
+static inline uint8_t get_keycode(key_t key)
+{
+    return keymap_get_keycode(current_layer, key.row, key.col);
+}
+
+// whether any key except modifier is down or not
+static inline bool is_anykey_down(void)
+{
+    for (int r = 0; r < MATRIX_ROWS; r++) {
+        matrix_row_t matrix_row = matrix_get_row(r);
+        for (int c = 0; c < MATRIX_COLS; c++) {
+            if (matrix_row && (1<<c)) {
+                if (IS_KEY(get_keycode((key_t){ .row = r, .col = c }))) {
+                    return true;
                 }
-#endif
-                system_code = SYSTEM_POWER_DOWN;
-            } else if (code == KB_SYSTEM_SLEEP) {
-                system_code = SYSTEM_SLEEP;
-            } else if (code == KB_SYSTEM_WAKE) {
-                system_code = SYSTEM_WAKE_UP;
-            }
-            // Consumer Page
-            else if (code == KB_AUDIO_MUTE) {
-                consumer_code = AUDIO_MUTE;
-            } else if (code == KB_AUDIO_VOL_UP) {
-                consumer_code = AUDIO_VOL_UP;
-            } else if (code == KB_AUDIO_VOL_DOWN) {
-                consumer_code = AUDIO_VOL_DOWN;
             }
-            else if (code == KB_MEDIA_NEXT_TRACK) {
-                consumer_code = TRANSPORT_NEXT_TRACK;
-            } else if (code == KB_MEDIA_PREV_TRACK) {
-                consumer_code = TRANSPORT_PREV_TRACK;
-            } else if (code == KB_MEDIA_STOP) {
-                consumer_code = TRANSPORT_STOP;
-            } else if (code == KB_MEDIA_PLAY_PAUSE) {
-                consumer_code = TRANSPORT_PLAY_PAUSE;
-            } else if (code == KB_MEDIA_SELECT) {
-                consumer_code = AL_CC_CONFIG;
-            }
-            else if (code == KB_MAIL) {
-                consumer_code = AL_EMAIL;
-            } else if (code == KB_CALCULATOR) {
-                consumer_code = AL_CALCULATOR;
-            } else if (code == KB_MY_COMPUTER) {
-                consumer_code = AL_LOCAL_BROWSER;
-            }
-            else if (code == KB_WWW_SEARCH) {
-                consumer_code = AC_SEARCH;
-            } else if (code == KB_WWW_HOME) {
-                consumer_code = AC_HOME;
-            } else if (code == KB_WWW_BACK) {
-                consumer_code = AC_BACK;
-            } else if (code == KB_WWW_FORWARD) {
-                consumer_code = AC_FORWARD;
-            } else if (code == KB_WWW_STOP) {
-                consumer_code = AC_STOP;
-            } else if (code == KB_WWW_REFRESH) {
-                consumer_code = AC_REFRESH;
-            } else if (code == KB_WWW_FAVORITES) {
-                consumer_code = AC_BOOKMARKS;
+        }
+    }
+    return false;
+}
+
+static void register_code(uint8_t code)
+{
+    if IS_KEY(code) {
+        host_add_key(code);
+        host_send_keyboard_report();
+    }
+    else if IS_MOD(code) {
+        host_add_mod_bit(MOD_BIT(code));
+        host_send_keyboard_report();
+    }
+    else if IS_MOUSEKEY(code) {
+        mousekey_on(code);
+        mousekey_send();
+    }
+}
+
+static void unregister_code(uint8_t code)
+{
+    if IS_KEY(code) {
+        host_del_key(code);
+        host_send_keyboard_report();
+    }
+    else if IS_MOD(code) {
+        host_del_mod_bit(MOD_BIT(code));
+        host_send_keyboard_report();
+    }
+    else if IS_MOUSEKEY(code) {
+        mousekey_off(code);
+        mousekey_send();
+    }
+}
+
+/*
+ *
+ * Event/State|IDLE             DELAYING[f]     WAITING[f,k]        PRESSING
+ * -----------+------------------------------------------------------------------
+ * Fn  Down   |IDLE(L+)         WAITING(Sk)     WAITING(Sk)         -
+ *     Up     |IDLE(L-)         IDLE(L-)        IDLE(L-)            IDLE(L-)  
+ * Fnk Down   |DELAYING(Sf)     WAITING(Sk)     WAINTING(Sk)        PRESSING(Rf)
+ *     Up     |IDLE(L-)         IDLE(Rf,Uf)     IDLE(Rf,Ps,Uf)*3    PRESSING(Uf)
+ * Key Down   |PRESSING(Rk)     WAITING(Sk)     WAITING(Sk)         PRESSING(Rk)
+ *     Up     |IDLE(Uk)         DELAYING(Uk)    IDLE(L+,Ps,Uk)      IDLE(Uk)*4
+ * Delay      |-                IDLE(L+)        IDLE(L+,Ps)         -
+ *            |
+ * No key Down|IDLE(Ld)         IDLE(Ld)        IDLE(Ld)            IDLE(Ld)
+ *
+ * *2: register Fnk if any key is pressing
+ * *3: when Fnk == Stored Fnk, if not ignore.
+ * *4: when no registered key any more
+ *
+ * States:
+ *      IDLE:
+ *      DELAYING: delay layer switch after pressing Fn with alt keycode
+ *      WAITING: key is pressed during DELAYING
+ *
+ * Events:
+ *      Fn: Fn key without alternative keycode
+ *      Fnk: Fn key with alternative keycode
+ *      -: ignore
+ *
+ * Actions:
+ *      Rk: register key
+ *      Uk: unregister key
+ *      Rf: register stored Fn(alt keycode)
+ *      Uf: unregister stored Fn(alt keycode)
+ *      Rs: register stored key
+ *      Us: unregister stored key
+ *      Sk: store key
+ *      Sf: store Fn
+ *      Ps: play stored key(Interpret stored key and transit state)
+ *      L+: Switch to new layer(*retain* Modifiers only)
+ *      L-: Switch back to last layer(*clear* stored key/Fn, *unregister* all Modifier/key)
+ *      Ld: Switch back to default layer(*clear* stored key/Fn, *unregister* all Modifier/key)
+ */
+#define NEXT(state)     do { \
+    debug("NEXT: "); print_P(state_str(kbdstate)); \
+    kbdstate = state; \
+    debug(" -> "); print_P(state_str(kbdstate)); debug("\n"); \
+} while (0)
+
+static inline void process_key(keyevent_t event)
+{
+    
+    /* TODO: ring buffer
+    static keyrecord_t waiting_keys[5];
+    static uint8_t waiting_keys_head = 0;
+    static uint8_t waiting_keys_tail = 0;
+    */
+
+    uint8_t code = get_keycode(event.key);
+    keykind_t kind = get_keykind(code, event.pressed);
+
+    uint8_t tmp_mods;
+
+    //debug("kbdstate: "); debug_hex(kbdstate);
+    debug("state: "); print_P(state_str(kbdstate));
+    debug(" kind: "); debug_hex(kind);
+    debug(" code: "); debug_hex(code);
+    if (event.pressed) { debug("d"); } else { debug("u"); }
+    debug("\n");
+    switch (kbdstate) {
+        case IDLE:
+            switch (kind) {
+                case FN_DOWN:
+                    layer_switch_on(code);
+                    break;
+                case FN_UP:
+                    layer_switch_off(code);
+                    break;
+                case FNK_DOWN:
+                    // store event
+                    delayed_fn = (keyrecord_t) { .event = event, .code = code, .mods = keyboard_report->mods, .time = timer_read() };
+                    NEXT(DELAYING);
+                    break;
+                case FNK_UP:
+                    layer_switch_off(code);
+                    break;
+                case KEY_DOWN:
+                case MOUSEKEY_DOWN:
+                    register_code(code);
+                    NEXT(PRESSING);
+                    break;
+                case MOD_DOWN:
+                    register_code(code);
+                    break;
+                case KEY_UP:
+                case MOUSEKEY_UP:
+                case MOD_UP:
+                    unregister_code(code);
+                    break;
+                default:
+                    break;
             }
-#endif
-            else if (IS_KEY(code)) {
-                host_add_key(code);
+            break;
+        case PRESSING:
+            switch (kind) {
+                case FN_DOWN:
+                    // ignored when any key is pressed
+                    break;
+                case FN_UP:
+                    layer_switch_off(code);
+                    NEXT(IDLE);
+                    break;
+                case FNK_DOWN:
+                    register_code(keymap_fn_keycode(FN_INDEX(code)));
+                    break;
+                case FNK_UP:
+                    unregister_code(keymap_fn_keycode(FN_INDEX(code)));
+                    break;
+                case KEY_DOWN:
+                case MOD_DOWN:
+                case MOUSEKEY_DOWN:
+                    register_code(code);
+                    break;
+                case KEY_UP:
+                case MOD_UP:
+                case MOUSEKEY_UP:
+                    unregister_code(code);
+                    // no key registered? mousekey, mediakey, systemkey
+                    if (!host_has_anykey())
+                        NEXT(IDLE);
+                    break;
+                default:
+                    break;
             }
-#ifdef MOUSEKEY_ENABLE
-            else if (IS_MOUSEKEY(code)) {
-                mousekey_decode(code);
+            break;
+        case DELAYING:
+            switch (kind) {
+                case FN_DOWN:
+                case FNK_DOWN:
+                case KEY_DOWN:
+                case MOUSEKEY_DOWN:
+                    waiting_key = (keyrecord_t) { .event = event, .code = code, .mods = keyboard_report->mods, .time = timer_read() };
+                    NEXT(WAITING);
+                    break;
+                case MOD_DOWN:
+                    register_code(code);
+                    break;
+                case FN_UP:
+                    layer_switch_off(code);
+                    NEXT(IDLE);
+                    break;
+                case FNK_UP:
+                    if (code == delayed_fn.code) {
+                        // type Fn with alt keycode
+                        // restore the mod status at the time of pressing Fn key
+                        tmp_mods = keyboard_report->mods;
+                        host_set_mods(delayed_fn.mods);
+                        register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code)));
+                        unregister_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code)));
+                        host_set_mods(tmp_mods);
+                        NEXT(IDLE);
+                    } else {
+                        layer_switch_off(code);
+                        NEXT(IDLE);
+                    }
+                    break;
+                case KEY_UP:
+                case MOUSEKEY_UP:
+                    unregister_code(code);
+                    NEXT(IDLE);
+                    break;
+                case MOD_UP:
+                    unregister_code(code);
+                    break;
+                default:
+                    break;
             }
-#endif
-            else {
-                debug("ignore keycode: "); debug_hex(code); debug("\n");
+            break;
+        case WAITING:
+            switch (kind) {
+                case FN_DOWN:
+                case FNK_DOWN:
+                case KEY_DOWN:
+                case MOUSEKEY_DOWN:
+                    tmp_mods = keyboard_report->mods;
+                    host_set_mods(delayed_fn.mods);
+                    register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code)));
+                    host_set_mods(waiting_key.mods);
+                    register_code(waiting_key.code);
+                    host_set_mods(tmp_mods);
+                    register_code(code);
+                    NEXT(IDLE);
+                    break;
+                case MOD_DOWN:
+                    register_code(code);
+                    break;
+                case FN_UP:
+                    layer_switch_off(code);
+                    NEXT(IDLE);
+                    break;
+                case FNK_UP:
+                    if (code == delayed_fn.code) {
+                        // alt down, key down, alt up
+                        tmp_mods = keyboard_report->mods;
+                        host_set_mods(delayed_fn.mods);
+                        register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code)));
+                        host_set_mods(waiting_key.mods);
+                        register_code(waiting_key.code);
+                        unregister_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code)));
+                        host_set_mods(tmp_mods);
+                        NEXT(IDLE);
+                    } else {
+                        layer_switch_off(code);
+                        NEXT(IDLE);
+                    }
+                    break;
+                case KEY_UP:
+                case MOUSEKEY_UP:
+                    if (code == waiting_key.code) {
+                        layer_switch_on(delayed_fn.code);
+                        NEXT(IDLE);
+                        // process waiting_key
+                        tmp_mods = keyboard_report->mods;
+                        host_set_mods(waiting_key.mods);
+                        process_key(waiting_key.event);
+                        host_set_mods(tmp_mods);
+                        process_key(event);
+                    } else {
+                        unregister_code(code);
+                    }
+                    break;
+                case MOD_UP:
+                    unregister_code(code);
+                    break;
+                default:
+                    break;
             }
-        }
+            break;
     }
 
-    layer_switching(fn_bits);
+    // TODO: FAIL SAFE: unregister all keys when no key down
+}
+
+void keyboard_init(void)
+{
+    debug_keyboard = true;
+
+    timer_init();
+    matrix_init();
+#ifdef PS2_MOUSE_ENABLE
+    ps2_mouse_init();
+#endif
+}
+
+void keyboard_task(void)
+{
+    static matrix_row_t matrix_prev[MATRIX_ROWS];
+    matrix_row_t matrix_row = 0;
+    matrix_row_t matrix_change = 0;
 
+    matrix_scan();
     if (command_proc()) {
+        debug("COMMAND\n");
+        // TODO: clear all keys
+        host_clear_keyboard_report();
+        host_send_keyboard_report();
         return;
     }
+    for (int r = 0; r < MATRIX_ROWS; r++) {
+        matrix_row = matrix_get_row(r);
+        matrix_change = matrix_row ^ matrix_prev[r];
+        if (matrix_change) {
+            // TODO: print once per scan
+            if (debug_matrix) matrix_print();
 
-    // TODO: should send only when changed from last report
-    if (matrix_is_modified()) {
-        host_send_keyboard_report();
-#ifdef EXTRAKEY_ENABLE
-        host_consumer_send(consumer_code);
-        host_system_send(system_code);
-#endif
-#ifdef DEBUG_LED
-        // LED flash for debug
-        DEBUG_LED_CONFIG;
-        DEBUG_LED_OFF;
-#endif
+            for (int c = 0; c < MATRIX_COLS; c++) {
+                if (matrix_change & (1<<c)) {
+                    process_key((keyevent_t){
+                        .key = (key_t){ .row = r, .col = c },
+                        .pressed = (matrix_row & (1<<c))
+                    });
+                    // record a processed key
+                    matrix_prev[r] ^= (1<<c);
+                    // process a key per task call
+                    goto MATRIX_LOOP_END;
+                }
+            }
+        }
     }
+    MATRIX_LOOP_END:
+    // TODO: FAIL SAFE: clear all key if no key down
 
-#ifdef MOUSEKEY_ENABLE
-    mousekey_send();
-#endif
+    // layer switch when delay term elapses
+    if (kbdstate == DELAYING || kbdstate == WAITING) {
+        if (timer_elapsed(delayed_fn.time) > LAYER_DELAY) {
+            if (kbdstate == DELAYING) {
+                layer_switch_on(delayed_fn.code);
+                NEXT(IDLE);
+            }
+            if (kbdstate == WAITING) {
+                layer_switch_on(delayed_fn.code);
+                NEXT(IDLE);
+                uint8_t tmp_mods = keyboard_report->mods;
+                host_set_mods(waiting_key.mods);
+                process_key(waiting_key.event);
+                host_set_mods(tmp_mods);
+            }
+        }
+    }
 
-#ifdef PS2_MOUSE_ENABLE
-    // TODO: should comform new API
-    if (ps2_mouse_read() == 0)
-        ps2_mouse_usb_send();
-#endif
+    // mousekey repeat & acceleration
+    mousekey_task();
 
-    if (last_leds != host_keyboard_leds()) {
-        keyboard_set_leds(host_keyboard_leds());
-        last_leds = host_keyboard_leds();
-    }
+    return;
 }
 
 void keyboard_set_leds(uint8_t leds)
old mode 100644 (file)
new mode 100755 (executable)
index 51bf673..2353805
@@ -18,15 +18,41 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #ifndef KEYBOARD_H
 #define KEYBOARD_H
 
+#include <stdbool.h>
 #include <stdint.h>
 
 
 #ifdef __cplusplus
 extern "C" {
 #endif
+
+typedef struct {
+    uint8_t row;
+    uint8_t col;
+} key_t;
+
+typedef struct {
+    key_t    key;
+    bool     pressed;
+} keyevent_t;
+
+typedef struct {
+    keyevent_t  event;
+    uint8_t     code;
+    uint8_t     mods;
+    uint16_t    time;
+} keyrecord_t;
+
+#define KEYEQ(keya, keyb)     (keya.row == keyb.row && keya.col == keyb.col)
+
+
+extern uint8_t current_layer;
+extern uint8_t default_layer;
+
 void keyboard_init(void);
-void keyboard_proc(void);
+void keyboard_task(void);
 void keyboard_set_leds(uint8_t leds);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/common/layer.c b/common/layer.c
deleted file mode 100644 (file)
index 0854eed..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
-Copyright 2011 Jun Wako <wakojun@gmail.com>
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "keymap.h"
-#include "host.h"
-#include "debug.h"
-#include "timer.h"
-#include "usb_keycodes.h"
-#include "layer.h"
-
-
-/*
- * Parameters:
- *     SWITCH_DELAY        |=======|
- *     SEND_FN_TERM        |================|
- *
- * Fn key processing cases:
- * 1. release Fn after SEND_FN_TERM.
- *     Layer sw         ___________|~~~~~~~~~~~|___
- *     Fn press         ___|~~~~~~~~~~~~~~~~~~~|___
- *     Fn send          ___________________________
- *
- * 2. release Fn during SEND_FN_TERM.(not layer used)
- *     Layer sw         ___________|~~~~~~|________
- *     Fn press         ___|~~~~~~~~~~~~~~|________
- *     Fn key send      __________________|~|______
- *     other key press  ___________________________
- *     other key send   ___________________________
- *
- * 3. release Fn during SEND_FN_TERM.(layer used)
- *     Layer sw         ___________|~~~~~~|________
- *     Fn press         ___|~~~~~~~~~~~~~~|________
- *     Fn key send      ___________________________
- *     Fn send          ___________________________
- *     other key press  _____________|~~|__________
- *     other key send   _____________|~~|__________
- *
- * 4. press other key during SWITCH_DELAY.
- *     Layer sw         ___________________________
- *     Fn key press     ___|~~~~~~~~~|_____________
- *     Fn key send      ______|~~~~~~|_____________
- *     other key press  ______|~~~|________________
- *     other key send   _______|~~|________________
- *
- * 5. press Fn while press other key.
- *     Layer sw         ___________________________
- *     Fn key press     ___|~~~~~~~~~|_____________
- *     Fn key send      ___|~~~~~~~~~|_____________
- *     other key press  ~~~~~~~|___________________
- *     other key send   ~~~~~~~|___________________
- *
- * 6. press Fn twice quickly and keep holding down.(repeat)
- *     Layer sw         ___________________________
- *     Fn key press     ___|~|____|~~~~~~~~~~~~~~~~
- *     Fn key send      _____|~|__|~~~~~~~~~~~~~~~~
- */
-
-// LAYER_SWITCH_DELAY: prevent from moving to new layer
-#ifndef LAYER_SWITCH_DELAY
-#   define LAYER_SWITCH_DELAY 150
-#endif
-
-// LAYER_SEND_FN_TERM: send keycode if release key in this term
-#ifndef LAYER_SEND_FN_TERM
-#   define LAYER_SEND_FN_TERM 500
-#endif
-
-
-uint8_t default_layer = 0;
-uint8_t current_layer = 0;
-
-static bool layer_used = false;
-static uint8_t new_layer(uint8_t fn_bits);
-
-
-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_MOUSEKEY(code))) {
-        layer_used = true;
-    }
-    return code;
-}
-
-// bit substract b from a
-#define BIT_SUBST(a, b) (a&(a^b))
-void layer_switching(uint8_t fn_bits)
-{
-    // layer switching
-    static uint8_t last_fn = 0;
-    static uint8_t last_mods = 0;
-    static uint16_t last_timer = 0; 
-    static uint8_t sent_fn = 0;
-
-    if (fn_bits == last_fn) { // Fn state is not changed
-        if (fn_bits == 0) {
-            // do nothing
-        } else {
-            if (!keymap_fn_keycode(BIT_SUBST(fn_bits, sent_fn)) ||
-                    timer_elapsed(last_timer) > LAYER_SWITCH_DELAY) {
-                uint8_t _layer_to_switch = new_layer(BIT_SUBST(fn_bits, sent_fn));
-                if (current_layer != _layer_to_switch) { // not switch layer yet
-                    debug("Fn case: 1,2,3(LAYER_SWITCH_DELAY passed)\n");
-                    debug("Switch Layer: "); debug_hex(current_layer);
-                    current_layer = _layer_to_switch;
-                    layer_used = false;
-                    debug(" -> "); debug_hex(current_layer); debug("\n");
-                }
-            } else {
-                if (host_has_anykey()) { // other keys is pressed
-                    uint8_t _fn_to_send = BIT_SUBST(fn_bits, sent_fn);
-                    if (_fn_to_send) {
-                        debug("Fn case: 4(press other key during SWITCH_DELAY.)\n");
-                        // send only Fn key first
-                        uint8_t tmp_mods = keyboard_report->mods;
-                        host_add_code(keymap_fn_keycode(_fn_to_send));
-                        host_set_mods(last_mods);
-                        host_send_keyboard_report();
-                        host_set_mods(tmp_mods);
-                        host_del_code(keymap_fn_keycode(_fn_to_send));
-                        sent_fn |= _fn_to_send;
-                    }
-                }
-            }
-            // add Fn keys to send
-            //host_add_code(keymap_fn_keycode(fn_bits&sent_fn));  // TODO: do all Fn keys
-        }
-    } else { // Fn state is changed(edge)
-        uint8_t fn_changed = 0;
-
-        debug("fn_bits: "); debug_bin(fn_bits); debug("\n");
-        debug("sent_fn: "); debug_bin(sent_fn); debug("\n");
-        debug("last_fn: "); debug_bin(last_fn); debug("\n");
-        debug("last_mods: "); debug_hex(last_mods); debug("\n");
-        debug("last_timer: "); debug_hex16(last_timer); debug("\n");
-        debug("timer_count: "); debug_hex16(timer_count); debug("\n");
-
-        // pressed Fn
-        if ((fn_changed = BIT_SUBST(fn_bits, last_fn))) {
-            debug("fn_changed: "); debug_bin(fn_changed); debug("\n");
-            if (host_has_anykey()) {
-                debug("Fn case: 5(pressed Fn with other key)\n");
-                sent_fn |= fn_changed;
-            } else if (fn_changed & sent_fn) { // pressed same Fn in a row
-                if (timer_elapsed(last_timer) > LAYER_SEND_FN_TERM) {
-                    debug("Fn case: 6(not repeat)\n");
-                    // time passed: not repeate
-                    sent_fn &= ~fn_changed;
-                } else {
-                    debug("Fn case: 6(repeat)\n");
-                }
-            }
-        }
-        // released Fn
-        if ((fn_changed = BIT_SUBST(last_fn, fn_bits))) {
-            debug("fn_changed: "); debug_bin(fn_changed); debug("\n");
-            if (timer_elapsed(last_timer) < LAYER_SEND_FN_TERM) {
-                if (!layer_used && BIT_SUBST(fn_changed, sent_fn)) {
-                    debug("Fn case: 2(send Fn one shot: released Fn during LAYER_SEND_FN_TERM)\n");
-                    // send only Fn key first
-                    uint8_t tmp_mods = keyboard_report->mods;
-                    host_add_code(keymap_fn_keycode(fn_changed));
-                    host_set_mods(last_mods);
-                    host_send_keyboard_report();
-                    host_set_mods(tmp_mods);
-                    host_del_code(keymap_fn_keycode(fn_changed));
-                    sent_fn |= fn_changed;
-                }
-            }
-            debug("Switch Layer(released Fn): "); debug_hex(current_layer);
-            current_layer = new_layer(BIT_SUBST(fn_bits, sent_fn));
-            debug(" -> "); debug_hex(current_layer); debug("\n");
-        }
-
-        layer_used = false;
-        last_fn = fn_bits;
-        last_mods = keyboard_report->mods;
-        last_timer = timer_read();
-    }
-    // send Fn keys
-    for (uint8_t i = 0; i < 8; i++) {
-        if ((sent_fn & fn_bits) & (1<<i)) {
-            host_add_code(keymap_fn_keycode(1<<i));
-        }
-    }
-}
-
-inline
-static uint8_t new_layer(uint8_t fn_bits)
-{
-    return (fn_bits ? keymap_fn_layer(fn_bits) : default_layer);
-}
diff --git a/common/layer.h b/common/layer.h
deleted file mode 100644 (file)
index d9e8ceb..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-Copyright 2011 Jun Wako <wakojun@gmail.com>
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef LAYER_H
-#define LAYER_H 1
-
-#include <stdint.h>
-
-extern uint8_t default_layer;
-extern uint8_t current_layer;
-
-/* 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
index c4b2cab51835b8186968187e93b8bf8907acff79..b3332d5ff91ca3132cc5524a4b6485df568d5b0c 100644 (file)
@@ -18,8 +18,23 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #ifndef MATRIX_H
 #define MATRIX_H
 
+#include <stdint.h>
 #include <stdbool.h>
 
+
+#if (MATRIX_COLS <= 8)
+typedef  uint8_t    matrix_row_t;
+#elif (MATRIX_COLS <= 16)
+typedef  uint16_t   matrix_row_t;
+#elif (MATRIX_COLS <= 32)
+typedef  uint32_t   matrix_row_t;
+#else
+#error "MATRIX_COLS: invalid value"
+#endif
+
+#define MATRIX_IS_ON(row, col)  (matrix_get_row(row) && (1<<col))
+
+
 /* number of matrix rows */
 uint8_t matrix_rows(void);
 /* number of matrix columns */
@@ -35,11 +50,7 @@ bool matrix_has_ghost(void);
 /* whether a swtich is on */
 bool matrix_is_on(uint8_t row, uint8_t col);
 /* matrix state on row */
-#if (MATRIX_COLS <= 8)
-uint8_t matrix_get_row(uint8_t row);
-#else
-uint16_t matrix_get_row(uint8_t row);
-#endif
+matrix_row_t  matrix_get_row(uint8_t row);
 /* count keys pressed */
 uint8_t matrix_key_count(void);
 /* print matrix for debug */
index 1d35355b496fe919b65a9a3f49e97bceba65694f..7f8e860aa6d64212acb09fa8fa090cba691bfd9b 100644 (file)
@@ -26,7 +26,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
 static report_mouse_t report;
-static report_mouse_t report_prev;
 
 static uint8_t mousekey_repeat =  0;
 
@@ -38,84 +37,111 @@ static void mousekey_debug(void);
  * see wikipedia http://en.wikipedia.org/wiki/Mouse_keys
  */
 #ifndef MOUSEKEY_DELAY_TIME
-#   define MOUSEKEY_DELAY_TIME 255
+#   define MOUSEKEY_DELAY_TIME 20
 #endif
 
+#define MOUSEKEY_MOVE_INIT      5
+#define MOUSEKEY_WHEEL_INIT     1
+#define MOUSEKEY_MOVE_ACCEL     5
+#define MOUSEKEY_WHEEL_ACCEL    1
+
+static uint16_t last_timer = 0;
+
 // acceleration parameters
-uint8_t mousekey_move_unit = 2;
-uint8_t mousekey_resolution = 5;
+//uint8_t mousekey_move_unit = 2;
+//uint8_t mousekey_resolution = 5;
 
 
 static inline uint8_t move_unit(void)
 {
-    uint16_t unit = 5 + mousekey_repeat*2;
+    uint16_t unit = 5 + mousekey_repeat*4;
     return (unit > 63 ? 63 : unit);
 }
 
-void mousekey_decode(uint8_t code)
-{
-    if      (code == KB_MS_UP)      report.y = -move_unit();
-    else if (code == KB_MS_DOWN)    report.y = move_unit();
-    else if (code == KB_MS_LEFT)    report.x = -move_unit();
-    else if (code == KB_MS_RIGHT)   report.x = move_unit();
-    else if (code == KB_MS_BTN1)    report.buttons |= MOUSE_BTN1;
-    else if (code == KB_MS_BTN2)    report.buttons |= MOUSE_BTN2;
-    else if (code == KB_MS_BTN3)    report.buttons |= MOUSE_BTN3;
-    else if (code == KB_MS_BTN4)    report.buttons |= MOUSE_BTN4;
-    else if (code == KB_MS_BTN5)    report.buttons |= MOUSE_BTN5;
-    else if (code == KB_MS_WH_UP)   report.v += move_unit()/4;
-    else if (code == KB_MS_WH_DOWN) report.v -= move_unit()/4;
-    else if (code == KB_MS_WH_LEFT) report.h -= move_unit()/4;
-    else if (code == KB_MS_WH_RIGHT)report.h += move_unit()/4;
-}
-
-bool mousekey_changed(void)
-{
-    return (report.buttons != report_prev.buttons ||
-            report.x || report.y || report.v || report.h);
-}
-
-void mousekey_send(void)
+void mousekey_task(void)
 {
-    static uint16_t last_timer = 0;
-
-    if (!mousekey_changed()) {
-        mousekey_repeat = 0;
-        mousekey_clear_report();
+    if (timer_elapsed(last_timer) < MOUSEKEY_DELAY_TIME)
         return;
-    }
 
-    // send immediately when buttun state is changed
-    if (report.buttons == report_prev.buttons) {
-        if (timer_elapsed(last_timer) < 100) {
-            mousekey_clear_report();
-            return;
-        }
-    }
+    if (report.x == 0 && report.y == 0 && report.v == 0 && report.h == 0)
+        return;
 
-    if (mousekey_repeat != 0xFF) {
+    if (mousekey_repeat != UINT8_MAX)
         mousekey_repeat++;
-    }
+
+
+    if (report.x > 0) report.x = move_unit();
+    if (report.x < 0) report.x = move_unit() * -1;
+    if (report.y > 0) report.y = move_unit();
+    if (report.y < 0) report.y = move_unit() * -1;
 
     if (report.x && report.y) {
         report.x *= 0.7;
         report.y *= 0.7;
     }
 
+    if (report.v > 0) report.v = move_unit();
+    if (report.v < 0) report.v = move_unit() * -1;
+    if (report.h > 0) report.h = move_unit();
+    if (report.h < 0) report.h = move_unit() * -1;
+
+    mousekey_send();
+}
+
+void mousekey_on(uint8_t code)
+{
+    if      (code == KB_MS_UP)       report.y = MOUSEKEY_MOVE_INIT * -1;
+    else if (code == KB_MS_DOWN)     report.y = MOUSEKEY_MOVE_INIT;
+    else if (code == KB_MS_LEFT)     report.x = MOUSEKEY_MOVE_INIT * -1;
+    else if (code == KB_MS_RIGHT)    report.x = MOUSEKEY_MOVE_INIT;
+    else if (code == KB_MS_WH_UP)    report.v = MOUSEKEY_WHEEL_INIT;
+    else if (code == KB_MS_WH_DOWN)  report.v = MOUSEKEY_WHEEL_INIT * -1;
+    else if (code == KB_MS_WH_LEFT)  report.h = MOUSEKEY_WHEEL_INIT * -1;
+    else if (code == KB_MS_WH_RIGHT) report.h = MOUSEKEY_WHEEL_INIT;
+    else if (code == KB_MS_BTN1)     report.buttons |= MOUSE_BTN1;
+    else if (code == KB_MS_BTN2)     report.buttons |= MOUSE_BTN2;
+    else if (code == KB_MS_BTN3)     report.buttons |= MOUSE_BTN3;
+    else if (code == KB_MS_BTN4)     report.buttons |= MOUSE_BTN4;
+    else if (code == KB_MS_BTN5)     report.buttons |= MOUSE_BTN5;
+}
+
+void mousekey_off(uint8_t code)
+{
+    if      (code == KB_MS_UP    && report.y < 0) report.y = 0;
+    else if (code == KB_MS_DOWN  && report.y > 0) report.y = 0;
+    else if (code == KB_MS_LEFT  && report.x < 0) report.x = 0;
+    else if (code == KB_MS_RIGHT && report.x > 0) report.x = 0;
+    else if (code == KB_MS_WH_UP    && report.v > 0) report.v = 0;
+    else if (code == KB_MS_WH_DOWN  && report.v < 0) report.v = 0;
+    else if (code == KB_MS_WH_LEFT  && report.h < 0) report.h = 0;
+    else if (code == KB_MS_WH_RIGHT && report.h > 0) report.h = 0;
+    else if (code == KB_MS_BTN1) report.buttons &= ~MOUSE_BTN1;
+    else if (code == KB_MS_BTN2) report.buttons &= ~MOUSE_BTN2;
+    else if (code == KB_MS_BTN3) report.buttons &= ~MOUSE_BTN3;
+    else if (code == KB_MS_BTN4) report.buttons &= ~MOUSE_BTN4;
+    else if (code == KB_MS_BTN5) report.buttons &= ~MOUSE_BTN5;
+
+    if (report.x == 0 && report.y == 0 && report.v == 0 && report.h == 0)
+        mousekey_repeat = 0;
+}
+
+void mousekey_send(void)
+{
     mousekey_debug();
     host_mouse_send(&report);
-    report_prev = report;
     last_timer = timer_read();
-    mousekey_clear_report();
 }
 
-void mousekey_clear_report(void)
+void mousekey_clear(void)
 {
+    report = (report_mouse_t){};
+/*
     report.buttons = 0;
     report.x = 0;
     report.y = 0;
     report.v = 0;
     report.h = 0;
+*/
 }
 
 static void mousekey_debug(void)
index c2c24e9fa5d5032eb5540333567cd56ea6dc3c0a..3006c4634f1cff717c1756eccd2e36cd3d798f59 100644 (file)
@@ -21,9 +21,10 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include <stdbool.h>
 #include "host.h"
 
-void mousekey_decode(uint8_t code);
-bool mousekey_changed(void);
+void mousekey_task(void);
+void mousekey_on(uint8_t code);
+void mousekey_off(uint8_t code);
+void mousekey_clear(void);
 void mousekey_send(void);
-void mousekey_clear_report(void);
 
 #endif
index 8b8d37e8b32c47e1a393061e87ee6d0157382779..e0dec6cefcf9d07fef9f25b32f8efcd640e1958e 100644 (file)
@@ -22,6 +22,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
 // counter resolution 1ms
+// NOTE: union { uint32_t timer32; struct { uint16_t dummy; uint16_t timer16; }}
 volatile uint32_t timer_count = 0;
 
 void timer_init(void)
index 04b398fa2a160beef5c8b7d274fc38cfe14daa07..61d6bf002997d223e1183d37d01d45a63ec81b34 100644 (file)
@@ -33,8 +33,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define IS_MOUSEKEY_BUTTON(code) (KB_MS_BTN1   <= (code) && (code) <= KB_MS_BTN5)
 #define IS_MOUSEKEY_WHEEL(code)  (KB_MS_WH_UP  <= (code) && (code) <= KB_MS_WH_RIGHT)
 
-#define MOD_BIT(code) (1<<((code) & 0x07))
-#define FN_BIT(code)  (1<<((code) - KB_FN0))
+#define MOD_BIT(code)   (1<<((code) & 0x07))
+#define FN_BIT(code)    (1<<((code) - KB_FN0))
+#define FN_INDEX(code)  ((code) - KB_FN0)
 
 
 /* Short names */
index 36afdd44706670bf0e4ec79b86d7573703f4b692..644301fe89d6a204a17979125944b3ef0f84a177 100644 (file)
@@ -17,19 +17,23 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #include "util.h"
 
-// bit population
-int bitpop(uint8_t bits)
+// bit population - return number of on-bit
+uint8_t bitpop(uint8_t bits)
 {
-    int c;
+    uint8_t c;
     for (c = 0; bits; c++)
         bits &= bits -1;
     return c;
+/*
+    const uint8_t bit_count[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
+    return bit_count[bits>>4] + bit_count[bits&0x0F]
+*/
 }
 
-// most significant on-bit
-int biton(uint8_t bits)
+// most significant on-bit - return highest location of on-bit
+uint8_t biton(uint8_t bits)
 {
-    int n = 0;
+    uint8_t n = 0;
     if (bits >> 4) { bits >>= 4; n += 4;}
     if (bits >> 2) { bits >>= 2; n += 2;}
     if (bits >> 1) { bits >>= 1; n += 1;}
index 66bccbfa580b8c68005c3a03c78786722acd03cc..87636c9710bbeb2deb38edae736fe5afd5d37e91 100644 (file)
@@ -28,7 +28,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define XSTR(s) #s
 
 
-int bitpop(uint8_t bits);
-int biton(uint8_t bits);
+uint8_t bitpop(uint8_t bits);
+uint8_t biton(uint8_t bits);
 
 #endif
index bf946ac01eb0aed21dbe0c2e73e6a44a1cfa98cb..17a4494065ddee0b3d0434c49beb6db9a18067cf 100644 (file)
@@ -35,8 +35,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 /* matrix size */
 #define MATRIX_ROWS 8
 #define MATRIX_COLS 8
-/* define if matrix has ghost */
-//#define MATRIX_HAS_GHOST
 
 
 /* key combination for command */
index f05962aed6368b997d8a06551c70095bc0d7fb92..43f777c564933ac1ea4a7f2896354102a663c8ba 100644 (file)
@@ -210,12 +210,12 @@ uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col)
     return KEYCODE(layer, row, col);
 }
 
-uint8_t keymap_fn_layer(uint8_t fn_bits)
+uint8_t keymap_fn_layer(uint8_t index)
 {
-    return pgm_read_byte(&fn_layer[biton(fn_bits)]);
+    return pgm_read_byte(&fn_layer[index]);
 }
 
-uint8_t keymap_fn_keycode(uint8_t fn_bits)
+uint8_t keymap_fn_keycode(uint8_t index)
 {
-    return pgm_read_byte(&fn_keycode[(biton(fn_bits))]);
+    return pgm_read_byte(&fn_keycode[index]);
 }
index 79d2d9873157a9db7b304b95114f493bc59846cc..3bd6e73b35a4b00a3599844b0f8c114dee2a593b 100644 (file)
@@ -43,22 +43,10 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
 // matrix state buffer(1:on, 0:off)
-#if (MATRIX_COLS <= 8)
-static uint8_t *matrix;
-static uint8_t *matrix_prev;
-static uint8_t _matrix0[MATRIX_ROWS];
-static uint8_t _matrix1[MATRIX_ROWS];
-#else
-static uint16_t *matrix;
-static uint16_t *matrix_prev;
-static uint16_t _matrix0[MATRIX_ROWS];
-static uint16_t _matrix1[MATRIX_ROWS];
-#endif
-
-// HHKB has no ghost and no bounce.
-#ifdef MATRIX_HAS_GHOST
-static bool matrix_has_ghost_in_row(uint8_t row);
-#endif
+static matrix_row_t *matrix;
+static matrix_row_t *matrix_prev;
+static matrix_row_t _matrix0[MATRIX_ROWS];
+static matrix_row_t _matrix1[MATRIX_ROWS];
 
 
 // Matrix I/O ports
@@ -192,6 +180,8 @@ uint8_t matrix_scan(void)
             }
 
             // Ignore if this code region execution time elapses more than 20us.
+            // MEMO: 20[us] * (TIMER_RAW_FREQ / 1000000)[count per us]
+            // MEMO: then change above using this rule: a/(b/c) = a*1/(b/c) = a*(c/b)
             if (TIMER_DIFF_RAW(TIMER_RAW, last) > 20/(1000000/TIMER_RAW_FREQ)) {
                 matrix[row] = matrix_prev[row];
             }
@@ -219,12 +209,6 @@ bool matrix_is_modified(void)
 inline
 bool matrix_has_ghost(void)
 {
-#ifdef MATRIX_HAS_GHOST
-    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
-        if (matrix_has_ghost_in_row(i))
-            return true;
-    }
-#endif
     return false;
 }
 
@@ -257,11 +241,6 @@ void matrix_print(void)
         pbin_reverse(matrix_get_row(row));
 #else
         pbin_reverse16(matrix_get_row(row));
-#endif
-#ifdef MATRIX_HAS_GHOST
-        if (matrix_has_ghost_in_row(row)) {
-            print(" <ghost");
-        }
 #endif
         print("\n");
     }
@@ -279,20 +258,3 @@ uint8_t matrix_key_count(void)
     }
     return count;
 }
-
-#ifdef MATRIX_HAS_GHOST
-inline
-static bool matrix_has_ghost_in_row(uint8_t row)
-{
-    // no ghost exists in case less than 2 keys on
-    if (((matrix[row] - 1) & matrix[row]) == 0)
-        return false;
-
-    // ghost exists in case same state as other row
-    for (uint8_t i=0; i < MATRIX_ROWS; i++) {
-        if (i != row && (matrix[i] & matrix[row]) == matrix[row])
-            return true;
-    }
-    return false;
-}
-#endif
index ff3413227fd1b25ee3e52d3bda2933231a957ce9..bff1f5e8b28bf5caa0286a80fb05608d1cd48662 100644 (file)
@@ -475,7 +475,7 @@ int main(void)
     keyboard_init();
     host_set_driver(&lufa_driver);
     while (1) {
-        keyboard_proc();
+        keyboard_task();
 
 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
         USB_USBTask();