~ruther/qmk_firmware

ac570686b6bde1e5066ea68636ae780392739cb4 — Kai Ryu 11 years ago abe5edc
New branch for 6KRO feature
2 files changed, 98 insertions(+), 0 deletions(-)

M common.mk
M common/action_util.c
M common.mk => common.mk +4 -0
@@ 48,6 48,10 @@ ifdef NKRO_ENABLE
    OPT_DEFS += -DNKRO_ENABLE
endif

ifdef USB_6KRO_ENABLE
    OPT_DEFS += -DUSB_6KRO_ENABLE
endif

ifdef SLEEP_LED_ENABLE
    SRC += $(COMMON_DIR)/sleep_led.c
    OPT_DEFS += -DSLEEP_LED_ENABLE

M common/action_util.c => common/action_util.c +94 -0
@@ 30,6 30,15 @@ static inline void del_key_bit(uint8_t code);
static uint8_t real_mods = 0;
static uint8_t weak_mods = 0;

#ifdef USB_6KRO_ENABLE
#define RO_ADD(a, b) ((a + b) % REPORT_KEYS)
#define RO_SUB(a, b) ((a - b + REPORT_KEYS) % REPORT_KEYS)
#define RO_INC(a) RO_ADD(a, 1)
#define RO_DEC(a) RO_SUB(a, 1)
static int8_t cb_head = 0;
static int8_t cb_tail = 0;
static int8_t cb_count = 0;
#endif

// TODO: pointer variable is not needed
//report_keyboard_t keyboard_report = {};


@@ 158,7 167,18 @@ uint8_t get_first_key(void)
        return i<<3 | biton(keyboard_report->nkro.bits[i]);
    }
#endif
#ifdef USB_6KRO_ENABLE
    uint8_t i = cb_head;
    do {
        if (keyboard_report->keys[i] != 0) {
            break;
        }
        i = RO_INC(i);
    } while (i != cb_tail);
    return keyboard_report->keys[i];
#else
    return keyboard_report->keys[0];
#endif
}




@@ 166,6 186,52 @@ uint8_t get_first_key(void)
/* local functions */
static inline void add_key_byte(uint8_t code)
{
#ifdef USB_6KRO_ENABLE
    int8_t i = cb_head;
    int8_t empty = -1;
    if (cb_count) {
        do {
            if (keyboard_report->keys[i] == code) {
                return;
            }
            if (empty == -1 && keyboard_report->keys[i] == 0) {
                empty = i;
            }
            i = RO_INC(i);
        } while (i != cb_tail);
        if (i == cb_tail) {
            if (cb_tail == cb_head) {
                // buffer is full
                if (empty == -1) {
                    // pop head when has no empty space
                    cb_head = RO_INC(cb_head);
                    cb_count--;
                }
                else {
                    // left shift when has empty space
                    uint8_t offset = 1;
                    i = RO_INC(empty);
                    do {
                        if (keyboard_report->keys[i] != 0) {
                            keyboard_report->keys[empty] = keyboard_report->keys[i];
                            keyboard_report->keys[i] = 0;
                            empty = RO_INC(empty);
                        }
                        else {
                            offset++;
                        }
                        i = RO_INC(i);
                    } while (i != cb_tail);
                    cb_tail = RO_SUB(cb_tail, offset);
                }
            }
        }
    }
    // add to tail
    keyboard_report->keys[cb_tail] = code;
    cb_tail = RO_INC(cb_tail);
    cb_count++;
#else
    int8_t i = 0;
    int8_t empty = -1;
    for (; i < REPORT_KEYS; i++) {


@@ 181,15 247,43 @@ static inline void add_key_byte(uint8_t code)
            keyboard_report->keys[empty] = code;
        }
    }
#endif
}

static inline void del_key_byte(uint8_t code)
{
#ifdef USB_6KRO_ENABLE
    uint8_t i = cb_head;
    if (cb_count) {
        do {
            if (keyboard_report->keys[i] == code) {
                keyboard_report->keys[i] = 0;
                cb_count--;
                if (cb_count == 0) {
                    // reset head and tail
                    cb_tail = cb_head = 0;
                }
                if (i == RO_DEC(cb_tail)) {
                    // left shift when next to tail
                    do {
                        cb_tail = RO_DEC(cb_tail);
                        if (keyboard_report->keys[RO_DEC(cb_tail)] != 0) {
                            break;
                        }
                    } while (cb_tail != cb_head);
                }
                break;
            }
            i = RO_INC(i);
        } while (i != cb_tail);
    }
#else
    for (uint8_t i = 0; i < REPORT_KEYS; i++) {
        if (keyboard_report->keys[i] == code) {
            keyboard_report->keys[i] = 0;
        }
    }
#endif
}

#ifdef NKRO_ENABLE