Merge remote-tracking branch 'tmk/master' into cub_layout

This commit is contained in:
Oleg Kostyuk 2013-10-08 10:36:18 +03:00
commit e93188021c
26 changed files with 636 additions and 546 deletions

View file

@ -3,9 +3,9 @@ SRC += $(COMMON_DIR)/host.c \
$(COMMON_DIR)/keyboard.c \
$(COMMON_DIR)/action.c \
$(COMMON_DIR)/action_tapping.c \
$(COMMON_DIR)/action_oneshot.c \
$(COMMON_DIR)/action_macro.c \
$(COMMON_DIR)/action_layer.c \
$(COMMON_DIR)/action_util.c \
$(COMMON_DIR)/keymap.c \
$(COMMON_DIR)/timer.c \
$(COMMON_DIR)/print.c \
@ -74,7 +74,7 @@ ifdef KEYMAP_SECTION_ENABLE
endif
# Version string
OPT_DEFS += -DVERSION=$(shell (git describe --dirty || echo 'unknown') 2> /dev/null)
OPT_DEFS += -DVERSION=$(shell (git describe --always --dirty || echo 'unknown') 2> /dev/null)
# Search Path

View file

@ -23,8 +23,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "backlight.h"
#include "action_layer.h"
#include "action_tapping.h"
#include "action_oneshot.h"
#include "action_macro.h"
#include "action_util.h"
#include "action.h"
#ifdef DEBUG_ACTION
@ -79,15 +79,15 @@ void process_action(keyrecord_t *record)
action.key.mods<<4;
if (event.pressed) {
if (mods) {
host_add_mods(mods);
host_send_keyboard_report();
add_weak_mods(mods);
send_keyboard_report();
}
register_code(action.key.code);
} else {
unregister_code(action.key.code);
if (mods) {
host_del_mods(mods);
host_send_keyboard_report();
del_weak_mods(mods);
send_keyboard_report();
}
}
}
@ -100,43 +100,30 @@ void process_action(keyrecord_t *record)
action.key.mods<<4;
switch (action.layer_tap.code) {
#ifndef NO_ACTION_ONESHOT
case 0x00:
case MODS_ONESHOT:
// Oneshot modifier
if (event.pressed) {
if (tap_count == 0) {
dprint("MODS_TAP: Oneshot: add_mods\n");
add_mods(mods);
register_mods(mods);
}
else if (tap_count == 1) {
dprint("MODS_TAP: Oneshot: start\n");
oneshot_start(mods);
}
else if (tap_count == TAPPING_TOGGLE) {
dprint("MODS_TAP: Oneshot: toggle\n");
oneshot_toggle();
set_oneshot_mods(mods);
}
else {
dprint("MODS_TAP: Oneshot: cancel&add_mods\n");
// double tap cancels oneshot and works as normal modifier.
oneshot_cancel();
add_mods(mods);
register_mods(mods);
}
} else {
if (tap_count == 0) {
dprint("MODS_TAP: Oneshot: cancel/del_mods\n");
// cancel oneshot on hold
oneshot_cancel();
del_mods(mods);
clear_oneshot_mods();
unregister_mods(mods);
}
else if (tap_count == 1) {
dprint("MODS_TAP: Oneshot: del_mods\n");
// retain Oneshot
del_mods(mods);
// Retain Oneshot mods
}
else {
dprint("MODS_TAP: Oneshot: del_mods\n");
// cancel Mods
del_mods(mods);
clear_oneshot_mods();
unregister_mods(mods);
}
}
break;
@ -148,14 +135,14 @@ void process_action(keyrecord_t *record)
dprint("MODS_TAP: Tap: Cancel: add_mods\n");
// ad hoc: set 0 to cancel tap
record->tap.count = 0;
add_mods(mods);
register_mods(mods);
} else {
dprint("MODS_TAP: Tap: register_code\n");
register_code(action.key.code);
}
} else {
dprint("MODS_TAP: No tap: add_mods\n");
add_mods(mods);
register_mods(mods);
}
} else {
if (tap_count > 0) {
@ -163,7 +150,7 @@ void process_action(keyrecord_t *record)
unregister_code(action.key.code);
} else {
dprint("MODS_TAP: No tap: add_mods\n");
del_mods(mods);
unregister_mods(mods);
}
}
break;
@ -343,30 +330,30 @@ void register_code(uint8_t code)
// Resync: ignore if caps lock already is on
if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) return;
#endif
host_add_key(KC_CAPSLOCK);
host_send_keyboard_report();
host_del_key(KC_CAPSLOCK);
host_send_keyboard_report();
add_key(KC_CAPSLOCK);
send_keyboard_report();
del_key(KC_CAPSLOCK);
send_keyboard_report();
}
else if (KC_LOCKING_NUM == code) {
#ifdef LOCKING_RESYNC_ENABLE
if (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) return;
#endif
host_add_key(KC_NUMLOCK);
host_send_keyboard_report();
host_del_key(KC_NUMLOCK);
host_send_keyboard_report();
add_key(KC_NUMLOCK);
send_keyboard_report();
del_key(KC_NUMLOCK);
send_keyboard_report();
}
else if (KC_LOCKING_SCROLL == code) {
#ifdef LOCKING_RESYNC_ENABLE
if (host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) return;
#endif
host_add_key(KC_SCROLLLOCK);
host_send_keyboard_report();
host_del_key(KC_SCROLLLOCK);
host_send_keyboard_report();
add_key(KC_SCROLLLOCK);
send_keyboard_report();
del_key(KC_SCROLLLOCK);
send_keyboard_report();
}
#endif
@ -375,25 +362,28 @@ void register_code(uint8_t code)
if (command_proc(code)) return;
#ifndef NO_ACTION_ONESHOT
/* TODO: remove
if (oneshot_state.mods && !oneshot_state.disabled) {
uint8_t tmp_mods = host_get_mods();
host_add_mods(oneshot_state.mods);
uint8_t tmp_mods = get_mods();
add_mods(oneshot_state.mods);
host_add_key(code);
host_send_keyboard_report();
add_key(code);
send_keyboard_report();
host_set_mods(tmp_mods);
set_mods(tmp_mods);
send_keyboard_report();
oneshot_cancel();
} else
*/
#endif
{
host_add_key(code);
host_send_keyboard_report();
add_key(code);
send_keyboard_report();
}
}
else if IS_MOD(code) {
host_add_mods(MOD_BIT(code));
host_send_keyboard_report();
add_mods(MOD_BIT(code));
send_keyboard_report();
}
else if IS_SYSTEM(code) {
host_system_send(KEYCODE2SYSTEM(code));
@ -415,40 +405,40 @@ void unregister_code(uint8_t code)
// Resync: ignore if caps lock already is off
if (!(host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK))) return;
#endif
host_add_key(KC_CAPSLOCK);
host_send_keyboard_report();
host_del_key(KC_CAPSLOCK);
host_send_keyboard_report();
add_key(KC_CAPSLOCK);
send_keyboard_report();
del_key(KC_CAPSLOCK);
send_keyboard_report();
}
else if (KC_LOCKING_NUM == code) {
#ifdef LOCKING_RESYNC_ENABLE
if (!(host_keyboard_leds() & (1<<USB_LED_NUM_LOCK))) return;
#endif
host_add_key(KC_NUMLOCK);
host_send_keyboard_report();
host_del_key(KC_NUMLOCK);
host_send_keyboard_report();
add_key(KC_NUMLOCK);
send_keyboard_report();
del_key(KC_NUMLOCK);
send_keyboard_report();
}
else if (KC_LOCKING_SCROLL == code) {
#ifdef LOCKING_RESYNC_ENABLE
if (!(host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK))) return;
#endif
host_add_key(KC_SCROLLLOCK);
host_send_keyboard_report();
host_del_key(KC_SCROLLLOCK);
host_send_keyboard_report();
add_key(KC_SCROLLLOCK);
send_keyboard_report();
del_key(KC_SCROLLLOCK);
send_keyboard_report();
}
#endif
else if IS_KEY(code) {
host_del_key(code);
host_send_keyboard_report();
del_key(code);
send_keyboard_report();
}
else if IS_MOD(code) {
host_del_mods(MOD_BIT(code));
host_send_keyboard_report();
del_mods(MOD_BIT(code));
send_keyboard_report();
}
else if IS_SYSTEM(code) {
host_system_send(0);
@ -458,38 +448,33 @@ void unregister_code(uint8_t code)
}
}
void add_mods(uint8_t mods)
void register_mods(uint8_t mods)
{
if (mods) {
host_add_mods(mods);
host_send_keyboard_report();
add_mods(mods);
send_keyboard_report();
}
}
void del_mods(uint8_t mods)
void unregister_mods(uint8_t mods)
{
if (mods) {
host_del_mods(mods);
host_send_keyboard_report();
del_mods(mods);
send_keyboard_report();
}
}
void set_mods(uint8_t mods)
{
host_set_mods(mods);
host_send_keyboard_report();
}
void clear_keyboard(void)
{
host_clear_mods();
clear_mods();
clear_keyboard_but_mods();
}
void clear_keyboard_but_mods(void)
{
host_clear_keys();
host_send_keyboard_report();
clear_weak_mods();
clear_keys();
send_keyboard_report();
#ifdef MOUSEKEY_ENABLE
mousekey_clear();
mousekey_send();
@ -502,7 +487,7 @@ void clear_keyboard_but_mods(void)
bool sending_anykey(void)
{
return (host_has_anykey() || host_mouse_in_use() ||
return (has_anykey() || host_mouse_in_use() ||
host_last_sysytem_report() || host_last_consumer_report());
}

View file

@ -59,9 +59,9 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
void process_action(keyrecord_t *record);
void register_code(uint8_t code);
void unregister_code(uint8_t code);
void add_mods(uint8_t mods);
void del_mods(uint8_t mods);
void set_mods(uint8_t mods);
void register_mods(uint8_t mods);
void unregister_mods(uint8_t mods);
//void set_mods(uint8_t mods);
void clear_keyboard(void);
void clear_keyboard_but_mods(void);
bool sending_anykey(void);

View file

@ -29,13 +29,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* 000r|0000|0000 0001 Transparent code
* 000r|0000| keycode Key
* 000r|mods|0000 0000 Modifiers
* 000r|mods| keycode Key and Modifiers
* 000r|mods| keycode Modifiers+Key(Modified key)
* r: Left/Right flag(Left:0, Right:1)
*
* ACT_MODS_TAP(001r):
* 001r|mods|0000 0000 Modifiers with OneShot
* 001r|mods|0000 00xx (reserved)
* 001r|mods| keycode Modifiers with Tap Key
* 001r|mods| keycode Modifiers with Tap Key(Dual role)
*
*
* Other Keys(01xx)
@ -69,7 +69,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* 1001|oopp|BBBB BBBB 8-bit Bitwise Operation???
*
* ACT_LAYER_TAP(101x):
* 101E|LLLL| keycode Invert with tap key
* 101E|LLLL| keycode On/Off with tap key
* 101E|LLLL|1110 xxxx Reserved(0xE0-EF)
* 101E|LLLL|1111 0000 Invert with tap toggle(0xF0)
* 101E|LLLL|1111 0001 On/Off

View file

@ -1,21 +0,0 @@
#include "action_oneshot.h"
#ifndef NO_ACTION_ONESHOT
oneshot_state_t oneshot_state;
void oneshot_start(uint8_t mods)
{
oneshot_state.mods = mods;
}
void oneshot_cancel(void)
{
oneshot_state.mods = 0;
}
void oneshot_toggle(void)
{
oneshot_state.disabled = !oneshot_state.disabled;
}
#endif

View file

@ -1,52 +0,0 @@
/*
Copyright 2013 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 ACTION_ONESHOT_H
#define ACTION_ONESHOT_H
#include <stdint.h>
#include <stdbool.h>
#ifdef NO_ACTION_TAPPING
#define NO_ACTION_ONESHOT
#endif
#ifndef NO_ACTION_ONESHOT
/* Oneshot modifier
*
* Problem: Want to capitalize like 'The' but the result tends to be 'THe'.
* Solution: Oneshot modifier have its effect on only one key coming next.
* Tap Shift, then type 't', 'h' and 'e'. Not need to hold Shift key.
*
* Hold: works as normal modifier.
* Tap: one shot modifier.
* 2 Tap: cancel one shot modifier.
* 5-Tap: toggles enable/disable oneshot feature.
*/
typedef struct {
uint8_t mods;
bool disabled;
} oneshot_state_t;
oneshot_state_t oneshot_state;
void oneshot_start(uint8_t mods);
void oneshot_cancel(void);
void oneshot_toggle(void);
#endif
#endif

View file

@ -1,7 +1,9 @@
#include <stdint.h>
#include <stdbool.h>
#include "action.h"
#include "action_layer.h"
#include "action_tapping.h"
#include "keycode.h"
#include "timer.h"
#ifdef DEBUG_ACTION
@ -95,22 +97,40 @@ bool process_tapping(keyrecord_t *keyp)
return false;
}
#if TAPPING_TERM >= 500
/* This can settle mod/fn state fast but may prevent from typing fast. */
else if (!event.pressed && waiting_buffer_typed(event)) {
// other key typed. not tap.
/* Process a key typed within TAPPING_TERM
* This can register the key before settlement of tapping,
* useful for long TAPPING_TERM but may prevent fast typing.
*/
else if (IS_RELEASED(event) && waiting_buffer_typed(event)) {
debug("Tapping: End. No tap. Interfered by typing key\n");
process_action(&tapping_key);
tapping_key = (keyrecord_t){};
debug_tapping_key();
// enqueue
return false;
}
#endif
/* release a key pressed before tapping */
else if (!event.pressed && !waiting_buffer_typed(event)) {
/* Unexpected repeating occurs unless this event is processed immedately. */
debug("Tapping: release a key pressed before tapping\n");
/* Process release event of a key pressed before tapping starts
* Without this unexpected repeating will occur with having fast repeating setting
* https://github.com/tmk/tmk_keyboard/issues/60
*/
else if (IS_RELEASED(event) && !waiting_buffer_typed(event)) {
// Modifier should be retained till end of this tapping.
action_t action = layer_switch_get_action(event.key);
switch (action.kind.id) {
case ACT_LMODS:
case ACT_RMODS:
if (action.key.mods && !action.key.code) return false;
if (IS_MOD(action.key.code)) return false;
break;
case ACT_LMODS_TAP:
case ACT_RMODS_TAP:
if (action.key.mods && keyp->tap.count == 0) return false;
if (IS_MOD(action.key.code)) return false;
break;
}
// Release of key should be process immediately.
debug("Tapping: release event of a key pressed before tapping\n");
process_action(keyp);
return true;
}

213
common/action_util.c Normal file
View file

@ -0,0 +1,213 @@
/*
Copyright 2013 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 "host.h"
#include "report.h"
#include "debug.h"
#include "action_util.h"
#include "timer.h"
static inline void add_key_byte(uint8_t code);
static inline void del_key_byte(uint8_t code);
#ifdef NKRO_ENABLE
static inline void add_key_bit(uint8_t code);
static inline void del_key_bit(uint8_t code);
#endif
static uint8_t real_mods = 0;
static uint8_t weak_mods = 0;
// TODO: pointer variable is not needed
//report_keyboard_t keyboard_report = {};
report_keyboard_t *keyboard_report = &(report_keyboard_t){};
#ifndef NO_ACTION_ONESHOT
static int8_t oneshot_mods = 0;
#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
static int16_t oneshot_time = 0;
#endif
#endif
void send_keyboard_report(void) {
keyboard_report->mods = real_mods;
keyboard_report->mods |= weak_mods;
#ifndef NO_ACTION_ONESHOT
if (oneshot_mods) {
#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
if (TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT) {
dprintf("Oneshot: timeout\n");
clear_oneshot_mods();
}
#endif
keyboard_report->mods |= oneshot_mods;
if (has_anykey()) {
clear_oneshot_mods();
}
}
#endif
host_keyboard_send(keyboard_report);
}
/* key */
void add_key(uint8_t key)
{
#ifdef NKRO_ENABLE
if (keyboard_nkro) {
add_key_bit(key);
return;
}
#endif
add_key_byte(key);
}
void del_key(uint8_t key)
{
#ifdef NKRO_ENABLE
if (keyboard_nkro) {
del_key_bit(key);
return;
}
#endif
del_key_byte(key);
}
void clear_keys(void)
{
// not clear mods
for (int8_t i = 1; i < REPORT_SIZE; i++) {
keyboard_report->raw[i] = 0;
}
}
/* modifier */
uint8_t get_mods(void) { return real_mods; }
void add_mods(uint8_t mods) { real_mods |= mods; }
void del_mods(uint8_t mods) { real_mods &= ~mods; }
void set_mods(uint8_t mods) { real_mods = mods; }
void clear_mods(void) { real_mods = 0; }
/* weak modifier */
uint8_t get_weak_mods(void) { return weak_mods; }
void add_weak_mods(uint8_t mods) { weak_mods |= mods; }
void del_weak_mods(uint8_t mods) { weak_mods &= ~mods; }
void set_weak_mods(uint8_t mods) { weak_mods = mods; }
void clear_weak_mods(void) { weak_mods = 0; }
/* Oneshot modifier */
#ifndef NO_ACTION_ONESHOT
void set_oneshot_mods(uint8_t mods)
{
oneshot_mods = mods;
#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_time = timer_read();
#endif
}
void clear_oneshot_mods(void)
{
oneshot_mods = 0;
#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_time = 0;
#endif
}
#endif
/*
* inspect keyboard state
*/
uint8_t has_anykey(void)
{
uint8_t cnt = 0;
for (uint8_t i = 1; i < REPORT_SIZE; i++) {
if (keyboard_report->raw[i])
cnt++;
}
return cnt;
}
uint8_t has_anymod(void)
{
return bitpop(real_mods);
}
uint8_t get_first_key(void)
{
#ifdef NKRO_ENABLE
if (keyboard_nkro) {
uint8_t i = 0;
for (; i < REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
;
return i<<3 | biton(keyboard_report->nkro.bits[i]);
}
#endif
return keyboard_report->keys[0];
}
/* local functions */
static inline void add_key_byte(uint8_t code)
{
int8_t i = 0;
int8_t empty = -1;
for (; i < REPORT_KEYS; i++) {
if (keyboard_report->keys[i] == code) {
break;
}
if (empty == -1 && keyboard_report->keys[i] == 0) {
empty = i;
}
}
if (i == REPORT_KEYS) {
if (empty != -1) {
keyboard_report->keys[empty] = code;
}
}
}
static inline void del_key_byte(uint8_t code)
{
for (uint8_t i = 0; i < REPORT_KEYS; i++) {
if (keyboard_report->keys[i] == code) {
keyboard_report->keys[i] = 0;
}
}
}
#ifdef NKRO_ENABLE
static inline void add_key_bit(uint8_t code)
{
if ((code>>3) < REPORT_BITS) {
keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
} else {
dprintf("add_key_bit: can't add: %02X\n", code);
}
}
static inline void del_key_bit(uint8_t code)
{
if ((code>>3) < REPORT_BITS) {
keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
} else {
dprintf("del_key_bit: can't del: %02X\n", code);
}
}
#endif

56
common/action_util.h Normal file
View file

@ -0,0 +1,56 @@
/*
Copyright 2013 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 ACTION_UTIL_H
#define ACTION_UTIL_H
#include <stdint.h>
extern report_keyboard_t *keyboard_report;
void send_keyboard_report(void);
/* key */
void add_key(uint8_t key);
void del_key(uint8_t key);
void clear_keys(void);
/* modifier */
uint8_t get_mods(void);
void add_mods(uint8_t mods);
void del_mods(uint8_t mods);
void set_mods(uint8_t mods);
void clear_mods(void);
/* weak modifier */
uint8_t get_weak_mods(void);
void add_weak_mods(uint8_t mods);
void del_weak_mods(uint8_t mods);
void set_weak_mods(uint8_t mods);
void clear_weak_mods(void);
/* oneshot modifier */
void set_oneshot_mods(uint8_t mods);
void clear_oneshot_mods(void);
void oneshot_toggle(void);
void oneshot_enable(void);
void oneshot_disable(void);
/* inspect */
uint8_t has_anykey(void);
uint8_t has_anymod(void);
uint8_t get_first_key(void);
#endif

View file

@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "keyboard.h"
#include "bootloader.h"
#include "action_layer.h"
#include "action_util.h"
#include "eeconfig.h"
#include "sleep_led.h"
#include "led.h"

View file

@ -27,7 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
bool keyboard_nkro = false;
#endif
report_keyboard_t *keyboard_report = &(report_keyboard_t){};
report_mouse_t mouse_report = {};
@ -35,13 +34,6 @@ static host_driver_t *driver;
static uint16_t last_system_report = 0;
static uint16_t last_consumer_report = 0;
static inline void add_key_byte(uint8_t code);
static inline void del_key_byte(uint8_t code);
#ifdef NKRO_ENABLE
static inline void add_key_bit(uint8_t code);
static inline void del_key_bit(uint8_t code);
#endif
void host_set_driver(host_driver_t *d)
{
@ -67,7 +59,7 @@ void host_keyboard_send(report_keyboard_t *report)
if (debug_keyboard) {
dprint("keyboard_report: ");
for (uint8_t i = 0; i < REPORT_SIZE; i++) {
dprintf("%02X ", keyboard_report->raw[i]);
dprintf("%02X ", report->raw[i]);
}
dprint("\n");
}
@ -97,98 +89,6 @@ void host_consumer_send(uint16_t report)
(*driver->send_consumer)(report);
}
/* keyboard report utils */
void host_add_key(uint8_t key)
{
#ifdef NKRO_ENABLE
if (keyboard_nkro) {
add_key_bit(key);
return;
}
#endif
add_key_byte(key);
}
void host_del_key(uint8_t key)
{
#ifdef NKRO_ENABLE
if (keyboard_nkro) {
del_key_bit(key);
return;
}
#endif
del_key_byte(key);
}
void host_clear_keys(void)
{
// not clea mods
for (int8_t i = 1; i < REPORT_SIZE; i++) {
keyboard_report->raw[i] = 0;
}
}
uint8_t host_get_mods(void)
{
return keyboard_report->mods;
}
void host_add_mods(uint8_t mods)
{
keyboard_report->mods |= mods;
}
void host_del_mods(uint8_t mods)
{
keyboard_report->mods &= ~mods;
}
void host_set_mods(uint8_t mods)
{
keyboard_report->mods = mods;
}
void host_clear_mods(void)
{
keyboard_report->mods = 0;
}
uint8_t host_has_anykey(void)
{
uint8_t cnt = 0;
for (uint8_t i = 1; i < REPORT_SIZE; i++) {
if (keyboard_report->raw[i])
cnt++;
}
return cnt;
}
uint8_t host_has_anymod(void)
{
return bitpop(keyboard_report->mods);
}
uint8_t host_get_first_key(void)
{
#ifdef NKRO_ENABLE
if (keyboard_nkro) {
uint8_t i = 0;
for (; i < REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
;
return i<<3 | biton(keyboard_report->nkro.bits[i]);
}
#endif
return keyboard_report->keys[0];
}
void host_send_keyboard_report(void)
{
if (!driver) return;
host_keyboard_send(keyboard_report);
}
uint8_t host_mouse_in_use(void)
{
return (mouse_report.buttons | mouse_report.x | mouse_report.y | mouse_report.v | mouse_report.h);
@ -203,51 +103,3 @@ uint16_t host_last_consumer_report(void)
{
return last_consumer_report;
}
static inline void add_key_byte(uint8_t code)
{
int8_t i = 0;
int8_t empty = -1;
for (; i < REPORT_KEYS; i++) {
if (keyboard_report->keys[i] == code) {
break;
}
if (empty == -1 && keyboard_report->keys[i] == 0) {
empty = i;
}
}
if (i == REPORT_KEYS) {
if (empty != -1) {
keyboard_report->keys[empty] = code;
}
}
}
static inline void del_key_byte(uint8_t code)
{
for (uint8_t i = 0; i < REPORT_KEYS; i++) {
if (keyboard_report->keys[i] == code) {
keyboard_report->keys[i] = 0;
}
}
}
#ifdef NKRO_ENABLE
static inline void add_key_bit(uint8_t code)
{
if ((code>>3) < REPORT_BITS) {
keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
} else {
dprintf("add_key_bit: can't add: %02X\n", code);
}
}
static inline void del_key_bit(uint8_t code)
{
if ((code>>3) < REPORT_BITS) {
keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
} else {
dprintf("del_key_bit: can't del: %02X\n", code);
}
}
#endif

View file

@ -33,7 +33,6 @@ extern bool keyboard_nkro;
#endif
/* report */
extern report_keyboard_t *keyboard_report;
extern report_mouse_t mouse_report;
@ -48,22 +47,6 @@ void host_mouse_send(report_mouse_t *report);
void host_system_send(uint16_t data);
void host_consumer_send(uint16_t data);
/* keyboard report utils */
void host_add_key(uint8_t key);
void host_del_key(uint8_t key);
void host_clear_keys(void);
uint8_t host_get_mods(void);
void host_add_mods(uint8_t mods);
void host_del_mods(uint8_t mods);
void host_set_mods(uint8_t mods);
void host_clear_mods(void);
uint8_t host_has_anykey(void);
uint8_t host_has_anymod(void);
uint8_t host_get_first_key(void);
void host_send_keyboard_report(void);
/* mouse report utils */
uint8_t host_mouse_in_use(void);

View file

@ -42,16 +42,15 @@ typedef struct {
/* equivalent test of key_t */
#define KEYEQ(keya, keyb) ((keya).row == (keyb).row && (keya).col == (keyb).col)
/* (time == 0) means no event and assumes matrix has no 255 line. */
#define IS_NOEVENT(event) ((event).time == 0 || ((event).key.row == 255 && (event).key.col == 255))
/* Rules for No Event:
* 1) (time == 0) to handle (keyevent_t){} as empty event
* 2) Matrix(255, 255) to make TICK event available
*/
static inline bool IS_NOEVENT(keyevent_t event) { return event.time == 0 || (event.key.row == 255 && event.key.col == 255); }
static inline bool IS_PRESSED(keyevent_t event) { return (!IS_NOEVENT(event) && event.pressed); }
static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) && !event.pressed); }
#define NOEVENT (keyevent_t){ \
.key = (key_t){ .row = 255, .col = 255 }, \
.pressed = false, \
.time = 0 \
}
/* tick event */
/* Tick event */
#define TICK (keyevent_t){ \
.key = (key_t){ .row = 255, .col = 255 }, \
.pressed = false, \

View file

@ -1,5 +1,45 @@
#----------------------------------------------------------------------------
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device.
# Please customize your programmer settings(PROGRAM_CMD)
#
# make teensy = Download the hex file to the device, using teensy_loader_cli.
# (must have teensy_loader_cli installed).
#
# make dfu = Download the hex file to the device, using dfu-programmer (must
# have dfu-programmer installed).
#
# make flip = Download the hex file to the device, using Atmel FLIP (must
# have Atmel FLIP installed).
#
# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
# (must have dfu-programmer installed).
#
# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
# (must have Atmel FLIP installed).
#
# make debug = Start either simulavr or avarice as specified for debugging,
# with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
# bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------
# Target file name (without extension).
TARGET = adb_usb
TARGET = adb_usb_lufa
# Directory common source filess exist
TOP_DIR = ../..
@ -7,7 +47,7 @@ TOP_DIR = ../..
# Directory keyboard dependent files exist
TARGET_DIR = .
# keyboard dependent files
# project specific files
SRC = keymap.c \
matrix.c \
led.c \
@ -16,22 +56,47 @@ SRC = keymap.c \
CONFIG_H = config.h
# MCU name, you MUST set this to match the board you are using
# type "make clean" after changing this, so all files will be rebuilt
#MCU = at90usb162 # Teensy 1.0
MCU = atmega32u4 # Teensy 2.0
#MCU = at90usb646 # Teensy++ 1.0
#MCU = at90usb1286 # Teensy++ 2.0
# MCU name
#MCU = at90usb1287
MCU = atmega32u4
# Processor frequency.
# Normally the first thing your program should do is set the clock prescaler,
# so your program will run at the correct speed. You should also set this
# variable to same clock speed. The _delay_ms() macro uses this, and many
# examples use this variable to calculate timings. Do not add a "UL" here.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
#OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
@ -44,20 +109,23 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# comment out to disable the options.
#
#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
#MOUSEKEY_ENABLE = yes # Mouse keys(+5000)
#EXTRAKEY_ENABLE = yes # Audio control and System control(+600)
#CONSOLE_ENABLE = yes # Console for debug
#COMMAND_ENABLE = yes # Commands for debug and configuration
BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = yes # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
#NKRO_ENABLE = yes # USB Nkey Rollover(+500)
#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
# Optimize size but this may cause error "relocation truncated to fit"
#EXTRALDFLAGS = -Wl,--relax
# Search Path
VPATH += $(TARGET_DIR)
VPATH += $(TOP_DIR)
include $(TOP_DIR)/protocol/pjrc.mk
include $(TOP_DIR)/protocol/lufa.mk
include $(TOP_DIR)/protocol.mk
include $(TOP_DIR)/common.mk
include $(TOP_DIR)/rules.mk

View file

@ -1,131 +0,0 @@
#----------------------------------------------------------------------------
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device.
# Please customize your programmer settings(PROGRAM_CMD)
#
# make teensy = Download the hex file to the device, using teensy_loader_cli.
# (must have teensy_loader_cli installed).
#
# make dfu = Download the hex file to the device, using dfu-programmer (must
# have dfu-programmer installed).
#
# make flip = Download the hex file to the device, using Atmel FLIP (must
# have Atmel FLIP installed).
#
# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
# (must have dfu-programmer installed).
#
# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
# (must have Atmel FLIP installed).
#
# make debug = Start either simulavr or avarice as specified for debugging,
# with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
# bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------
# Target file name (without extension).
TARGET = adb_usb_lufa
# Directory common source filess exist
TOP_DIR = ../..
# Directory keyboard dependent files exist
TARGET_DIR = .
# project specific files
SRC = keymap.c \
matrix.c \
led.c \
adb.c
CONFIG_H = config.h
# MCU name
#MCU = at90usb1287
MCU = atmega32u4
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
#OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# comment out to disable the options.
#
BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = yes # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
# Optimize size but this may cause error "relocation truncated to fit"
#EXTRALDFLAGS = -Wl,--relax
# Search Path
VPATH += $(TARGET_DIR)
VPATH += $(TOP_DIR)
include $(TOP_DIR)/protocol/lufa.mk
include $(TOP_DIR)/protocol.mk
include $(TOP_DIR)/common.mk
include $(TOP_DIR)/rules.mk

View file

@ -0,0 +1,63 @@
# Target file name (without extension).
TARGET = adb_usb_pjrc
# Directory common source filess exist
TOP_DIR = ../..
# Directory keyboard dependent files exist
TARGET_DIR = .
# keyboard dependent files
SRC = keymap.c \
matrix.c \
led.c \
adb.c
CONFIG_H = config.h
# MCU name, you MUST set this to match the board you are using
# type "make clean" after changing this, so all files will be rebuilt
#MCU = at90usb162 # Teensy 1.0
MCU = atmega32u4 # Teensy 2.0
#MCU = at90usb646 # Teensy++ 1.0
#MCU = at90usb1286 # Teensy++ 2.0
# Processor frequency.
# Normally the first thing your program should do is set the clock prescaler,
# so your program will run at the correct speed. You should also set this
# variable to same clock speed. The _delay_ms() macro uses this, and many
# examples use this variable to calculate timings. Do not add a "UL" here.
F_CPU = 16000000
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# comment out to disable the options.
#
BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+5000)
EXTRAKEY_ENABLE = yes # Audio control and System control(+600)
CONSOLE_ENABLE = yes # Console for debug
COMMAND_ENABLE = yes # Commands for debug and configuration
#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
#NKRO_ENABLE = yes # USB Nkey Rollover(+500)
# Search Path
VPATH += $(TARGET_DIR)
VPATH += $(TOP_DIR)
include $(TOP_DIR)/protocol/pjrc.mk
include $(TOP_DIR)/protocol.mk
include $(TOP_DIR)/common.mk
include $(TOP_DIR)/rules.mk

View file

@ -85,6 +85,7 @@ uint8_t matrix_scan(void)
uint8_t key0, key1;
is_modified = false;
_delay_ms(16); // delay for preventing overload of poor ADB keyboard controller
codes = adb_host_kbd_recv();
key0 = codes>>8;
key1 = codes&0xFF;
@ -100,9 +101,7 @@ uint8_t matrix_scan(void)
} else if (codes == 0xFFFF) { // power key release
register_key(0xFF);
} else if (key0 == 0xFF) { // error
if (debug_matrix) print("adb_host_kbd_recv: ERROR(matrix cleared.)\n");
// clear matrix to unregister all keys
for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
xprintf("adb_host_kbd_recv: ERROR(%02X)\n", codes);
return key1;
} else {
register_key(key0);

View file

@ -78,6 +78,7 @@ CONSOLE_ENABLE = yes # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
KEYMAP_SECTION_ENABLE = yes # fixed address keymap for keymap editor

View file

@ -126,12 +126,12 @@ static const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
* |Ctl |Gui | Space |Alt| \|Lft|Rgt|Dn | | 0| .| |
* `---------------------------------------------------------' `---------------'
*/
KEYMAP(
[0] = KEYMAP(
GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, CLR, EQL, PSLS,PAST,
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, P7, P8, P9, PMNS,
LCAP,A, S, D, F, G, H, J, K, L, SCLN,QUOT, FN1, P4, P5, P6, PPLS,
LCAP,A, S, D, F, G, H, J, K, L, SCLN,QUOT, FN15, P4, P5, P6, PPLS,
LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, UP, P1, P2, P3, PENT,
LCTL,LGUI, FN0, LALT,FN2, LEFT,RGHT,DOWN, P0, PDOT
LCTL,LGUI, FN16, LALT,FN31,LEFT,RGHT,DOWN, P0, PDOT
),
/* Cursor Layer(WASD, IJKL)
* ,---------------------------------------------------------. ,---------------.
@ -146,13 +146,21 @@ static const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
* |Ctl |Gui | Space |Alt | \|Hom|End|PgD| | 0| .| |
* `---------------------------------------------------------' `---------------'
*/
KEYMAP(
[3] = KEYMAP(
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,EQL, PSLS,PAST,
CAPS,HOME,UP, PGUP,NO, NO, NO, NO, PSCR,SLCK,PAUS,UP, INS, P7, P8, P9, PMNS,
LCAP,LEFT,DOWN,RGHT,NO, NO, NO, NO, HOME,PGUP,LEFT,RGHT, FN1, P4, P5, P6, PPLS,
LCAP,LEFT,DOWN,RGHT,NO, NO, NO, NO, HOME,PGUP,LEFT,RGHT, FN15, P4, P5, P6, PPLS,
LSFT,END, NO, PGDN,NO, NO, NO, NO, END, PGDN,DOWN, PGUP, P1, P2, P3, PENT,
LCTL,LGUI, FN0, LALT,FN2, HOME,END, PGDN, P0, PDOT
LCTL,LGUI, FN16, LALT,FN31,HOME,END, PGDN, P0, PDOT
),
[4] = KEYMAP(
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,EQL, PSLS,PAST,
CAPS,HOME,UP, PGUP,NO, NO, NO, NO, PSCR,SLCK,PAUS,UP, INS, P7, P8, P9, PMNS,
LCAP,LEFT,DOWN,RGHT,NO, NO, NO, NO, HOME,PGUP,LEFT,RGHT, FN15, P4, P5, P6, PPLS,
LSFT,END, NO, PGDN,NO, NO, NO, NO, END, PGDN,DOWN, PGUP, P1, P2, P3, PENT,
LCTL,LGUI, FN16, LALT,FN31,HOME,END, PGDN, P0, PDOT
),
[7] = {},
};
@ -164,9 +172,38 @@ const uint16_t fn_actions[] __attribute__ ((section (".keymap.fn_actions"))) = {
#else
static const uint16_t fn_actions[] PROGMEM = {
#endif
[0] = ACTION_LAYER_TAP_KEY(1, KC_SPACE), // Layer switch with Tap key Space
[1] = ACTION_LAYER_TAP_KEY(1, KC_ENTER), // Layer switch with Tap key Enter
[2] = ACTION_MODS_TAP_KEY(MOD_LALT, KC_BSLS), // LALT with Tap key Backslash
[0] = ACTION_LAYER_MOMENTARY(1),
[1] = ACTION_LAYER_MOMENTARY(2),
[2] = ACTION_LAYER_MOMENTARY(3),
[3] = ACTION_LAYER_MOMENTARY(4),
[4] = ACTION_LAYER_MOMENTARY(5),
[5] = ACTION_LAYER_MOMENTARY(6),
[6] = ACTION_LAYER_MOMENTARY(7),
[7] = ACTION_LAYER_TOGGLE(1),
[8] = ACTION_LAYER_TOGGLE(2),
[9] = ACTION_LAYER_TOGGLE(3),
[10] = ACTION_LAYER_TAP_TOGGLE(1),
[11] = ACTION_LAYER_TAP_TOGGLE(2),
[12] = ACTION_LAYER_TAP_TOGGLE(3),
[13] = ACTION_LAYER_TAP_KEY(1, KC_F),
[14] = ACTION_LAYER_TAP_KEY(2, KC_J),
[15] = ACTION_LAYER_TAP_KEY(3, KC_ENTER),
[16] = ACTION_LAYER_TAP_KEY(4, KC_SPACE),
[17] = ACTION_LAYER_TAP_KEY(5, KC_SCOLON),
[18] = ACTION_LAYER_TAP_KEY(6, KC_QUOTE),
[19] = ACTION_LAYER_TAP_KEY(7, KC_SLASH),
[20] = ACTION_MODS_TAP_KEY(MOD_LSFT, KC_SPACE),
[21] = ACTION_MODS_TAP_KEY(MOD_LCTL, KC_SPACE),
[22] = ACTION_MODS_TAP_KEY(MOD_RCTL, KC_QUOTE),
[23] = ACTION_MODS_TAP_KEY(MOD_RCTL, KC_ENTER),
[24] = ACTION_MODS_TAP_KEY(MOD_LCTL, KC_ESC),
[25] = ACTION_MODS_TAP_KEY(MOD_LCTL, KC_BSPACE),
[26] = ACTION_MODS_ONESHOT(MOD_LCTL),
[27] = ACTION_MODS_TAP_KEY(MOD_LSFT, KC_ESC),
[28] = ACTION_MODS_TAP_KEY(MOD_LSFT, KC_BSPACE),
[29] = ACTION_MODS_ONESHOT(MOD_LSFT),
[30] = ACTION_MODS_TAP_KEY(MOD_RSFT, KC_GRAVE),
[31] = ACTION_MODS_TAP_KEY(MOD_RALT, KC_BSLASH),
};

View file

@ -227,7 +227,7 @@ You can define these actions on *'A'* key and *'left shift'* modifier with:
ACTION_KEY(KC_A)
ACTION_KEY(KC_LSFT)
#### 2.1.2 Key with modifiers
#### 2.1.2 Modified key
This action is comprised of strokes of modifiers and a key. `Macro` action is needed if you want more complex key strokes.
Say you want to assign a key to `Shift + 1` to get charactor *'!'* or `Alt + Tab` to switch application windows.
@ -244,7 +244,7 @@ Registers multiple modifiers with pressing a key. To specify multiple modifiers
ACTION_MODS(MOD_ALT | MOD_LSFT)
#### 2.1.3 Modifier with tap key
#### 2.1.3 Modifier with Tap key([Dual role][dual_role])
Works as a modifier key while holding, but registers a key on tap(press and release quickly).
@ -497,7 +497,7 @@ Number of taps can be configured with `TAPPING_TOGGLE` in `config.h`, `5` by def
Tapping is to press and release a key quickly. Tapping speed is determined with setting of `TAPPING_TERM`, which can be defined in `config.h`, 200ms by default.
### 4.1 Tap Key
This is a feature to assign normal key action and modifier including layer switching to just same one physical key. This is a kind of [Dual role modifier][dual_role]. It works as modifier when holding the key but registers normal key when tapping.
This is a feature to assign normal key action and modifier including layer switching to just same one physical key. This is a kind of [Dual role key][dual_role]. It works as modifier when holding the key but registers normal key when tapping.
Modifier with tap key:
@ -507,7 +507,7 @@ Layer switching with tap key:
ACTION_LAYER_TAP_KEY(2, KC_SCLN)
[dual_role]: http://en.wikipedia.org/wiki/Modifier_key#Dual-role_modifier_keys
[dual_role]: http://en.wikipedia.org/wiki/Modifier_key#Dual-role_keys
### 4.2 Tap Toggle
@ -516,13 +516,14 @@ This is a feature to assign both toggle layer and momentary switch layer action
ACTION_LAYER_TAP_TOGGLE(1)
### 4.3 One Shot Modifier
This adds oneshot feature to modifier key. 'One Shot Modifier' is one time modifier which has effect only on following just one key.
It works as normal modifier key when holding but oneshot modifier when tapping.
### 4.3 Oneshot Modifier
This runs onetime effect swhich modify only on just one following key. It works as normal modifier key when holding down while oneshot modifier when tapping.
ACTION_MODS_ONESHOT(MOD_LSFT)
Say you want to type 'The', you have to push and hold Shift before type 't' then release Shift before type 'h' and 'e' or you'll get 'THe'. With One Shot Modifier you can tap Shift then type 't', 'h' and 'e' normally, you don't need to holding Shift key properly here.
Say you want to type 'The', you have to push and hold Shift key before type 't' then release it before type 'h' and 'e', otherwise you'll get 'THe' or 'the' unintentionally. With Oneshot Modifier you can tap Shift then type 't', 'h' and 'e' normally, you don't need to holding Shift key properly here. This mean you can realease Shift before 't' is pressed down.
Oneshot effect is cancel unless following key is pressed down within `ONESHOT_TIMEOUT` of `config.h`. No timeout when it is `0` or not defined.
@ -571,5 +572,5 @@ Top layer has higher precedence than lower layers.
is to press and release a key quickly.
### Fn key
is key which executes a special action like layer switching, mouse key, macro or etc.
### dual role modifier
<http://en.wikipedia.org/wiki/Modifier_key#Dual-role_modifier_keys>
### dual role key
<http://en.wikipedia.org/wiki/Modifier_key#Dual-role_keys>

View file

@ -128,6 +128,8 @@ include $(TOP_DIR)/protocol/lufa.mk
include $(TOP_DIR)/common.mk
include $(TOP_DIR)/rules.mk
debug-on: EXTRAFLAGS += -DDEBUG
#debug-on: EXTRAFLAGS += -DDEBUG -DDEBUG_ACTION
debug-on: EXTRAFLAGS += -DDEBUG -DDEBUG_ACTION
debug-on: all
debug-off: EXTRAFLAGS += -DNO_DEBUG -DNO_PRINT
debug-off: all

View file

@ -40,7 +40,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define TAPPING_TERM 300
/* tap count needed for toggling a feature */
#define TAPPING_TOGGLE 5
/* Oneshot timeout(ms) */
#define ONESHOT_TIMEOUT 300
/* Boot Magic salt key: Space */
#define BOOTMAGIC_KEY_SALT KC_FN6

View file

@ -40,6 +40,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <avr/io.h>
#include <avr/interrupt.h>
#include "adb.h"
#include "debug.h"
static inline void data_lo(void);
@ -82,6 +83,12 @@ bool adb_host_psw(void)
}
#endif
/*
* Don't call this in a row without the delay, otherwise it makes some of poor controllers
* overloaded and misses strokes. Recommended delay is 16ms.
*
* Thanks a lot, blargg! <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919>
*/
uint16_t adb_host_kbd_recv(void)
{
uint16_t data = 0;
@ -93,6 +100,7 @@ uint16_t adb_host_kbd_recv(void)
}
if (!read_bit()) { // Startbit(1)
// Service Request
dprintf("Startbit ERROR\n");
return -2;
}
@ -104,6 +112,7 @@ uint16_t adb_host_kbd_recv(void)
sei();
if (stop) {
dprintf("Stopbit ERROR\n");
return -3;
}
return data;

View file

@ -505,29 +505,29 @@ Scan Code
m0110_recv_key() function returns following scan codes instead of raw key events.
Scan codes are 1 byte long and MSB(bit7) is set when key is released.
M0110
,---------------------------------------------------------.
| `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs|
|---------------------------------------------------------|
|Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \|
|---------------------------------------------------------|
|CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return|
|---------------------------------------------------------|
|Shift | Z| X| C| V| B| N| M| ,| ,| /| |
`---------------------------------------------------------'
|Opt|Mac | Space |Enter|Opt|
`------------------------------------------------'
,---------------------------------------------------------.
| 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33|
|---------------------------------------------------------|
| 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A|
|---------------------------------------------------------|
| 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24|
|---------------------------------------------------------|
| 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38|
`---------------------------------------------------------'
| 3A| 37| 31 | 34| 3A|
`------------------------------------------------'
M0110 M0120
,---------------------------------------------------------. ,---------------.
| `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Clr| -|Lft|Rgt|
|---------------------------------------------------------| |---------------|
|Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | 7| 8| 9|Up |
|---------------------------------------------------------| |---------------|
|CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6|Dn |
|---------------------------------------------------------| |---------------|
|Shift | Z| X| C| V| B| N| M| ,| ,| /| | | 1| 2| 3| |
`---------------------------------------------------------' |-----------|Ent|
|Opt|Mac | Space |Enter|Opt| | 0| .| |
`------------------------------------------------' `---------------'
,---------------------------------------------------------. ,---------------.
| 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | 47| 4E| 46| 42|
|---------------------------------------------------------| |---------------|
| 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A| | 59| 5B| 5C| 4D|
|---------------------------------------------------------| |---------------|
| 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | 56| 57| 58| 48|
|---------------------------------------------------------| |---------------|
| 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| | 53| 54| 55| |
`---------------------------------------------------------' |-----------| 4C|
| 3A| 37| 31 | 34| 3A| | 52| 41| |
`------------------------------------------------' `---------------'
M0110A
,---------------------------------------------------------. ,---------------.

View file

@ -30,6 +30,7 @@
#include "matrix.h"
#include "print.h"
#include "debug.h"
#include "sendchar.h"
#include "util.h"
#include "suspend.h"
#include "host.h"
@ -50,6 +51,8 @@ int main(void)
usb_init();
while (!usb_configured()) /* wait */ ;
print_set_sendchar(sendchar);
keyboard_init();
host_set_driver(pjrc_driver());
#ifdef SLEEP_LED_ENABLE

View file

@ -38,6 +38,7 @@
#include "sleep_led.h"
#endif
#include "suspend.h"
#include "action_util.h"
/**************************************************************************