summaryrefslogtreecommitdiffstats
path: root/tmk_core
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/avr.mk42
-rw-r--r--tmk_core/chibios.mk9
-rw-r--r--tmk_core/common.mk19
-rw-r--r--tmk_core/common/action.c50
-rw-r--r--tmk_core/common/action_code.h10
-rw-r--r--tmk_core/common/action_layer.c12
-rw-r--r--tmk_core/common/action_layer.h5
-rw-r--r--tmk_core/common/action_macro.h26
-rw-r--r--tmk_core/common/action_tapping.c11
-rw-r--r--tmk_core/common/action_util.c6
-rw-r--r--tmk_core/common/avr/suspend.c1
-rw-r--r--tmk_core/common/eeconfig.h1
-rw-r--r--tmk_core/common/keyboard.c65
-rw-r--r--tmk_core/common/keyboard.h1
-rw-r--r--tmk_core/common/matrix.h2
-rw-r--r--tmk_core/common/mousekey.h13
-rw-r--r--tmk_core/common/report.h7
-rw-r--r--tmk_core/protocol/lufa.mk20
-rw-r--r--tmk_core/protocol/lufa/adafruit_ble.h4
-rw-r--r--tmk_core/protocol/lufa/bluetooth.h16
-rw-r--r--tmk_core/protocol/lufa/lufa.c177
-rw-r--r--tmk_core/protocol/lufa/lufa.h2
-rw-r--r--tmk_core/protocol/lufa/outputselect.c56
-rw-r--r--tmk_core/protocol/lufa/outputselect.h40
-rw-r--r--tmk_core/protocol/ps2_mouse.h5
-rw-r--r--tmk_core/protocol/vusb/vusb.c4
-rw-r--r--tmk_core/rules.mk6
27 files changed, 439 insertions, 171 deletions
diff --git a/tmk_core/avr.mk b/tmk_core/avr.mk
index 5df539def5..ccecdb1929 100644
--- a/tmk_core/avr.mk
+++ b/tmk_core/avr.mk
@@ -89,9 +89,9 @@ DEBUG_HOST = localhost
#============================================================================
# Autodecct teensy loader
ifneq (, $(shell which teensy-loader-cli 2>/dev/null))
- TEENSY_LOADER_CLI = teensy-loader-cli
+ TEENSY_LOADER_CLI ?= teensy-loader-cli
else
- TEENSY_LOADER_CLI = teensy_loader_cli
+ TEENSY_LOADER_CLI ?= teensy_loader_cli
endif
# Program the device.
@@ -100,43 +100,47 @@ program: $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep
teensy: $(BUILD_DIR)/$(TARGET).hex
$(TEENSY_LOADER_CLI) -mmcu=$(MCU) -w -v $(BUILD_DIR)/$(TARGET).hex
+
+BATCHISP ?= batchisp
flip: $(BUILD_DIR)/$(TARGET).hex
- batchisp -hardware usb -device $(MCU) -operation erase f
- batchisp -hardware usb -device $(MCU) -operation loadbuffer $(BUILD_DIR)/$(TARGET).hex program
- batchisp -hardware usb -device $(MCU) -operation start reset 0
+ $(BATCHISP) -hardware usb -device $(MCU) -operation erase f
+ $(BATCHISP) -hardware usb -device $(MCU) -operation loadbuffer $(BUILD_DIR)/$(TARGET).hex program
+ $(BATCHISP) -hardware usb -device $(MCU) -operation start reset 0
+
+DFU_PROGRAMMER ?= dfu-programmer
dfu: $(BUILD_DIR)/$(TARGET).hex sizeafter
- until dfu-programmer $(MCU) get bootloader-version; do\
+ until $(DFU_PROGRAMMER) $(MCU) get bootloader-version; do\
echo "Error: Bootloader not found. Trying again in 5s." ;\
sleep 5 ;\
done
-ifneq (, $(findstring 0.7, $(shell dfu-programmer --version 2>&1)))
- dfu-programmer $(MCU) erase --force
+ifneq (, $(findstring 0.7, $(shell $(DFU_PROGRAMMER) --version 2>&1)))
+ $(DFU_PROGRAMMER) $(MCU) erase --force
else
- dfu-programmer $(MCU) erase
+ $(DFU_PROGRAMMER) $(MCU) erase
endif
- dfu-programmer $(MCU) flash $(BUILD_DIR)/$(TARGET).hex
- dfu-programmer $(MCU) reset
+ $(DFU_PROGRAMMER) $(MCU) flash $(BUILD_DIR)/$(TARGET).hex
+ $(DFU_PROGRAMMER) $(MCU) reset
dfu-start:
- dfu-programmer $(MCU) reset
- dfu-programmer $(MCU) start
+ $(DFU_PROGRAMMER) $(MCU) reset
+ $(DFU_PROGRAMMER) $(MCU) start
flip-ee: $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep
$(COPY) $(BUILD_DIR)/$(TARGET).eep $(BUILD_DIR)/$(TARGET)eep.hex
- batchisp -hardware usb -device $(MCU) -operation memory EEPROM erase
- batchisp -hardware usb -device $(MCU) -operation memory EEPROM loadbuffer $(BUILD_DIR)/$(TARGET)eep.hex program
- batchisp -hardware usb -device $(MCU) -operation start reset 0
+ $(BATCHISP) -hardware usb -device $(MCU) -operation memory EEPROM erase
+ $(BATCHISP) -hardware usb -device $(MCU) -operation memory EEPROM loadbuffer $(BUILD_DIR)/$(TARGET)eep.hex program
+ $(BATCHISP) -hardware usb -device $(MCU) -operation start reset 0
$(REMOVE) $(BUILD_DIR)/$(TARGET)eep.hex
dfu-ee: $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep
ifneq (, $(findstring 0.7, $(shell dfu-programmer --version 2>&1)))
- dfu-programmer $(MCU) flash --eeprom $(BUILD_DIR)/$(TARGET).eep
+ $(DFU_PROGRAMMER) $(MCU) flash --eeprom $(BUILD_DIR)/$(TARGET).eep
else
- dfu-programmer $(MCU) flash-eeprom $(BUILD_DIR)/$(TARGET).eep
+ $(DFU_PROGRAMMER) $(MCU) flash-eeprom $(BUILD_DIR)/$(TARGET).eep
endif
- dfu-programmer $(MCU) reset
+ $(DFU_PROGRAMMER) $(MCU) reset
# Convert hex to bin.
flashbin: $(BUILD_DIR)/$(TARGET).hex
diff --git a/tmk_core/chibios.mk b/tmk_core/chibios.mk
index 062a712bd1..2a8d32fb99 100644
--- a/tmk_core/chibios.mk
+++ b/tmk_core/chibios.mk
@@ -143,8 +143,15 @@ MCUFLAGS = -mcpu=$(MCU)
DEBUG = gdb
+DFU_ARGS =
+ifneq ("$(SERIAL)","")
+ DFU_ARGS += -S $(SERIAL)
+endif
+
# List any extra directories to look for libraries here.
EXTRALIBDIRS = $(RULESPATH)/ld
+DFU_UTIL ?= dfu-util
+
dfu-util: $(BUILD_DIR)/$(TARGET).bin sizeafter
- dfu-util -D $(BUILD_DIR)/$(TARGET).bin \ No newline at end of file
+ $(DFU_UTIL) $(DFU_ARGS) -D $(BUILD_DIR)/$(TARGET).bin
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index a86dccc616..3e0bd7dbc8 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -93,14 +93,25 @@ ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
TMK_COMMON_DEFS += -DBACKLIGHT_ENABLE
endif
-ifeq ($(strip $(ADAFRUIT_BLE_ENABLE)), yes)
- TMK_COMMON_DEFS += -DADAFRUIT_BLE_ENABLE
-endif
-
ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
endif
+ifeq ($(strip $(BLUETOOTH)), AdafruitBLE)
+ TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
+ TMK_COMMON_DEFS += -DMODULE_ADAFRUIT_BLE
+endif
+
+ifeq ($(strip $(BLUETOOTH)), AdafruitEZKey)
+ TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
+ TMK_COMMON_DEFS += -DMODULE_ADAFRUIT_EZKEY
+endif
+
+ifeq ($(strip $(BLUETOOTH)), RN42)
+ TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
+ TMK_COMMON_DEFS += -DMODULE_RN42
+endif
+
ifeq ($(strip $(ONEHAND_ENABLE)), yes)
TMK_COMMON_DEFS += -DONEHAND_ENABLE
endif
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index d485b46c77..a534f818ec 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -26,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "action_macro.h"
#include "action_util.h"
#include "action.h"
+#include "wait.h"
#ifdef DEBUG_ACTION
#include "debug.h"
@@ -33,6 +34,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "nodebug.h"
#endif
+#ifdef FAUXCLICKY_ENABLE
+#include <fauxclicky.h>
+#endif
void action_exec(keyevent_t event)
{
@@ -41,6 +45,16 @@ void action_exec(keyevent_t event)
dprint("EVENT: "); debug_event(event); dprintln();
}
+#ifdef FAUXCLICKY_ENABLE
+ if (IS_PRESSED(event)) {
+ FAUXCLICKY_ACTION_PRESS;
+ }
+ if (IS_RELEASED(event)) {
+ FAUXCLICKY_ACTION_RELEASE;
+ }
+ fauxclicky_check();
+#endif
+
#ifdef ONEHAND_ENABLE
if (!IS_NOEVENT(event)) {
process_hand_swap(&event);
@@ -49,6 +63,13 @@ void action_exec(keyevent_t event)
keyrecord_t record = { .event = event };
+#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
+ if (has_oneshot_layer_timed_out()) {
+ dprintf("Oneshot layer: timeout\n");
+ clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
+ }
+#endif
+
#ifndef NO_ACTION_TAPPING
action_tapping_process(record);
#else
@@ -100,7 +121,7 @@ bool process_record_quantum(keyrecord_t *record) {
return true;
}
-void process_record(keyrecord_t *record)
+void process_record(keyrecord_t *record)
{
if (IS_NOEVENT(record->event)) { return; }
@@ -120,25 +141,18 @@ void process_record(keyrecord_t *record)
void process_action(keyrecord_t *record, action_t action)
{
- bool do_release_oneshot = false;
keyevent_t event = record->event;
#ifndef NO_ACTION_TAPPING
uint8_t tap_count = record->tap.count;
#endif
-#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
- if (has_oneshot_layer_timed_out()) {
- dprintf("Oneshot layer: timeout\n");
- clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
- }
-#endif
-
if (event.pressed) {
// clear the potential weak mods left by previously pressed keys
clear_weak_mods();
}
#ifndef NO_ACTION_ONESHOT
+ bool do_release_oneshot = false;
// notice we only clear the one shot layer if the pressed key is not a modifier.
if (is_oneshot_layer_active() && event.pressed && !IS_MOD(action.key.code)) {
clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
@@ -425,6 +439,9 @@ void process_action(keyrecord_t *record, action_t action)
} else {
if (tap_count > 0) {
dprint("KEYMAP_TAP_KEY: Tap: unregister_code\n");
+ if (action.layer_tap.code == KC_CAPS) {
+ wait_ms(80);
+ }
unregister_code(action.layer_tap.code);
} else {
dprint("KEYMAP_TAP_KEY: No tap: Off on release\n");
@@ -524,6 +541,21 @@ void process_action(keyrecord_t *record, action_t action)
break;
}
+#ifndef NO_ACTION_LAYER
+ // if this event is a layer action, update the leds
+ switch (action.kind.id) {
+ case ACT_LAYER:
+ #ifndef NO_ACTION_TAPPING
+ case ACT_LAYER_TAP:
+ case ACT_LAYER_TAP_EXT:
+ #endif
+ led_set(host_keyboard_leds());
+ break;
+ default:
+ break;
+ }
+#endif
+
#ifndef NO_ACTION_ONESHOT
/* Because we switch layers after a oneshot event, we need to release the
* key before we leave the layer or no key up event will be generated.
diff --git a/tmk_core/common/action_code.h b/tmk_core/common/action_code.h
index 33da35f35f..b15aaa0eb3 100644
--- a/tmk_core/common/action_code.h
+++ b/tmk_core/common/action_code.h
@@ -47,10 +47,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* 0100|10| usage(10) (reserved)
* 0100|11| usage(10) (reserved)
*
- * ACT_MOUSEKEY(0110): TODO: Not needed?
+ *
+ * ACT_MOUSEKEY(0101): TODO: Merge these two actions to conserve space?
* 0101|xxxx| keycode Mouse key
*
- * 011x|xxxx xxxx xxxx (reseved)
+ * ACT_SWAP_HANDS(0110):
+ * 0110|xxxx| keycode Swap hands (keycode on tap, or options)
+ *
+ *
+ * 0111|xxxx xxxx xxxx (reserved)
*
*
* Layer Actions(10xx)
@@ -67,7 +72,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* ee: on event(01:press, 10:release, 11:both)
*
* 1001|xxxx|xxxx xxxx (reserved)
- * 1001|oopp|BBBB BBBB 8-bit Bitwise Operation???
*
* ACT_LAYER_TAP(101x):
* 101E|LLLL| keycode On/Off with tap key (0x00-DF)[TAP]
diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c
index a3c7579642..58d919a04d 100644
--- a/tmk_core/common/action_layer.c
+++ b/tmk_core/common/action_layer.c
@@ -16,8 +16,14 @@
*/
uint32_t default_layer_state = 0;
+__attribute__((weak))
+uint32_t default_layer_state_set_kb(uint32_t state) {
+ return state;
+}
+
static void default_layer_state_set(uint32_t state)
{
+ state = default_layer_state_set_kb(state);
debug("default_layer_state: ");
default_layer_debug(); debug(" to ");
default_layer_state = state;
@@ -57,8 +63,14 @@ void default_layer_xor(uint32_t state)
*/
uint32_t layer_state = 0;
+__attribute__((weak))
+uint32_t layer_state_set_kb(uint32_t state) {
+ return state;
+}
+
static void layer_state_set(uint32_t state)
{
+ state = layer_state_set_kb(state);
dprint("layer_state: ");
layer_debug(); dprint(" to ");
layer_state = state;
diff --git a/tmk_core/common/action_layer.h b/tmk_core/common/action_layer.h
index 025cf5420f..d89ed6e5ce 100644
--- a/tmk_core/common/action_layer.h
+++ b/tmk_core/common/action_layer.h
@@ -29,6 +29,9 @@ extern uint32_t default_layer_state;
void default_layer_debug(void);
void default_layer_set(uint32_t state);
+__attribute__((weak))
+uint32_t default_layer_state_set_kb(uint32_t state);
+
#ifndef NO_ACTION_LAYER
/* bitwise operation */
void default_layer_or(uint32_t state);
@@ -69,6 +72,8 @@ void layer_xor(uint32_t state);
#define layer_xor(state)
#define layer_debug()
+__attribute__((weak))
+uint32_t layer_state_set_kb(uint32_t state);
#endif
/* pressed actions cache */
diff --git a/tmk_core/common/action_macro.h b/tmk_core/common/action_macro.h
index aedc32ec6b..f373f5068e 100644
--- a/tmk_core/common/action_macro.h
+++ b/tmk_core/common/action_macro.h
@@ -20,11 +20,33 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "progmem.h"
-#define MACRO_NONE 0
+
+typedef uint8_t macro_t;
+
+#define MACRO_NONE (macro_t*)0
#define MACRO(...) ({ static const macro_t __m[] PROGMEM = { __VA_ARGS__ }; &__m[0]; })
#define MACRO_GET(p) pgm_read_byte(p)
-typedef uint8_t macro_t;
+// Sends press when the macro key is pressed, release when release, or tap_macro when the key has been tapped
+#define MACRO_TAP_HOLD(record, press, release, tap_macro) ( ((record)->event.pressed) ? \
+ ( ((record)->tap.count <= 0 || (record)->tap.interrupted) ? (press) : MACRO_NONE ) : \
+ ( ((record)->tap.count > 0 && !((record)->tap.interrupted)) ? (tap_macro) : (release) ) )
+
+// Holds down the modifier mod when the macro key is held, or sends macro instead when tapped
+#define MACRO_TAP_HOLD_MOD(record, macro, mod) MACRO_TAP_HOLD(record, (MACRO(D(mod), END)), MACRO(U(mod), END), macro)
+
+// Holds down the modifier mod when the macro key is held, or pressed a shifted key when tapped (eg: shift+3 for #)
+#define MACRO_TAP_SHFT_KEY_HOLD_MOD(record, key, mod) MACRO_TAP_HOLD_MOD(record, (MACRO(I(10), D(LSFT), T(key), U(LSFT), END)), mod)
+
+
+// Momentary switch layer when held, sends macro if tapped
+#define MACRO_TAP_HOLD_LAYER(record, macro, layer) ( ((record)->event.pressed) ? \
+ ( ((record)->tap.count <= 0 || (record)->tap.interrupted) ? ({layer_on((layer)); MACRO_NONE; }) : MACRO_NONE ) : \
+ ( ((record)->tap.count > 0 && !((record)->tap.interrupted)) ? (macro) : ({layer_off((layer)); MACRO_NONE; }) ) )
+
+// Momentary switch layer when held, presses a shifted key when tapped (eg: shift+3 for #)
+#define MACRO_TAP_SHFT_KEY_HOLD_LAYER(record, key, layer) MACRO_TAP_HOLD_LAYER(record, MACRO(I(10), D(LSFT), T(key), U(LSFT), END), layer)
+
#ifndef NO_ACTION_MACRO
diff --git a/tmk_core/common/action_tapping.c b/tmk_core/common/action_tapping.c
index e16e11be7f..bd9a69ae0a 100644
--- a/tmk_core/common/action_tapping.c
+++ b/tmk_core/common/action_tapping.c
@@ -228,6 +228,7 @@ bool process_tapping(keyrecord_t *keyp)
if (WITHIN_TAPPING_TERM(event)) {
if (event.pressed) {
if (IS_TAPPING_KEY(event.key)) {
+#ifndef TAPPING_FORCE_HOLD
if (!tapping_key.tap.interrupted && tapping_key.tap.count > 0) {
// sequential tap.
keyp->tap = tapping_key.tap;
@@ -237,11 +238,11 @@ bool process_tapping(keyrecord_t *keyp)
tapping_key = *keyp;
debug_tapping_key();
return true;
- } else {
- // FIX: start new tap again
- tapping_key = *keyp;
- return true;
}
+#endif
+ // FIX: start new tap again
+ tapping_key = *keyp;
+ return true;
} else if (is_tap_key(event.key)) {
// Sequential tap can be interfered with other tap key.
debug("Tapping: Start with interfering other tap.\n");
@@ -257,7 +258,7 @@ bool process_tapping(keyrecord_t *keyp)
return true;
}
} else {
- if (!IS_NOEVENT(event)) debug("Tapping: other key just after tap.\n") {};
+ if (!IS_NOEVENT(event)) debug("Tapping: other key just after tap.\n");
process_record(keyp);
return true;
}
diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c
index cb4b252648..77848c0923 100644
--- a/tmk_core/common/action_util.c
+++ b/tmk_core/common/action_util.c
@@ -58,9 +58,13 @@ void set_oneshot_locked_mods(int8_t mods) { oneshot_locked_mods = mods; }
void clear_oneshot_locked_mods(void) { oneshot_locked_mods = 0; }
#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
static int16_t oneshot_time = 0;
-inline bool has_oneshot_mods_timed_out() {
+bool has_oneshot_mods_timed_out(void) {
return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT;
}
+#else
+bool has_oneshot_mods_timed_out(void) {
+ return false;
+}
#endif
#endif
diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c
index 0c81e83612..1c7618ff51 100644
--- a/tmk_core/common/avr/suspend.c
+++ b/tmk_core/common/avr/suspend.c
@@ -9,6 +9,7 @@
#include "suspend.h"
#include "timer.h"
#include "led.h"
+#include "host.h"
#ifdef PROTOCOL_LUFA
#include "lufa.h"
diff --git a/tmk_core/common/eeconfig.h b/tmk_core/common/eeconfig.h
index d8caa346f9..280dc7ab67 100644
--- a/tmk_core/common/eeconfig.h
+++ b/tmk_core/common/eeconfig.h
@@ -33,6 +33,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define EECONFIG_BACKLIGHT (uint8_t *)6
#define EECONFIG_AUDIO (uint8_t *)7
#define EECONFIG_RGBLIGHT (uint32_t *)8
+#define EECONFIG_UNICODEMODE (uint8_t *)12
/* debug bit */
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c
index 7653507928..97a8f1cd8c 100644
--- a/tmk_core/common/keyboard.c
+++ b/tmk_core/common/keyboard.c
@@ -14,6 +14,7 @@ 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 <stdint.h>
#include "keyboard.h"
#include "matrix.h"
@@ -50,6 +51,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef RGBLIGHT_ENABLE
# include "rgblight.h"
#endif
+#ifdef FAUXCLICKY_ENABLE
+# include "fauxclicky.h"
+#endif
#ifdef SERIAL_LINK_ENABLE
# include "serial_link/system/serial_link.h"
#endif
@@ -57,23 +61,51 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# include "visualizer/visualizer.h"
#endif
+#ifdef MATRIX_HAS_GHOST
+extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
+static matrix_row_t get_real_keys(uint8_t row, matrix_row_t rowdata){
+ matrix_row_t out = 0;
+ for (uint8_t col = 0; col < MATRIX_COLS; col++) {
+ //read each key in the row data and check if the keymap defines it as a real key
+ if (pgm_read_byte(&keymaps[0][row][col]) && (rowdata & (1<<col))){
+ //this creates new row data, if a key is defined in the keymap, it will be set here
+ out |= 1<<col;
+ }
+ }
+ return out;
+}
+static inline bool popcount_more_than_one(matrix_row_t rowdata)
+{
+ rowdata &= rowdata-1; //if there are less than two bits (keys) set, rowdata will become zero
+ return rowdata;
+}
-#ifdef MATRIX_HAS_GHOST
-static bool has_ghost_in_row(uint8_t row)
+static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata)
{
- matrix_row_t matrix_row = matrix_get_row(row);
- // No ghost exists when less than 2 keys are down on the row
- if (((matrix_row - 1) & matrix_row) == 0)
+ /* No ghost exists when less than 2 keys are down on the row.
+ If there are "active" blanks in the matrix, the key can't be pressed by the user,
+ there is no doubt as to which keys are really being pressed.
+ The ghosts will be ignored, they are KC_NO. */
+ rowdata = get_real_keys(row, rowdata);
+ if ((popcount_more_than_one(rowdata)) == 0){
return false;
-
- // Ghost occurs when the row shares column line with other row
+ }
+ /* Ghost occurs when the row shares a column line with other row,
+ and two columns are read on each row. Blanks in the matrix don't matter,
+ so they are filtered out.
+ If there are two or more real keys pressed and they match columns with
+ at least two of another row's real keys, the row will be ignored. Keep in mind,
+ we are checking one row at a time, not all of them at once.
+ */
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
- if (i != row && (matrix_get_row(i) & matrix_row))
+ if (i != row && popcount_more_than_one(get_real_keys(i, matrix_get_row(i)) & rowdata)){
return true;
+ }
}
return false;
}
+
#endif
__attribute__ ((weak))
@@ -107,6 +139,9 @@ void keyboard_init(void) {
#ifdef RGBLIGHT_ENABLE
rgblight_init();
#endif
+#ifdef FAUXCLICKY_ENABLE
+ fauxclicky_init();
+#endif
#if defined(NKRO_ENABLE) && defined(FORCE_NKRO)
keymap_config.nkro = 1;
#endif
@@ -120,7 +155,7 @@ void keyboard_task(void)
{
static matrix_row_t matrix_prev[MATRIX_ROWS];
#ifdef MATRIX_HAS_GHOST
- static matrix_row_t matrix_ghost[MATRIX_ROWS];
+ // static matrix_row_t matrix_ghost[MATRIX_ROWS];
#endif
static uint8_t led_status = 0;
matrix_row_t matrix_row = 0;
@@ -132,18 +167,18 @@ void keyboard_task(void)
matrix_change = matrix_row ^ matrix_prev[r];
if (matrix_change) {
#ifdef MATRIX_HAS_GHOST
- if (has_ghost_in_row(r)) {
+ if (has_ghost_in_row(r, matrix_row)) {
/* Keep track of whether ghosted status has changed for
* debugging. But don't update matrix_prev until un-ghosted, or
* the last key would be lost.
*/
- if (debug_matrix && matrix_ghost[r] != matrix_row) {
- matrix_print();
- }
- matrix_ghost[r] = matrix_row;
+ //if (debug_matrix && matrix_ghost[r] != matrix_row) {
+ // matrix_print();
+ //}
+ //matrix_ghost[r] = matrix_row;
continue;
}
- matrix_ghost[r] = matrix_row;
+ //matrix_ghost[r] = matrix_row;
#endif
if (debug_matrix) matrix_print();
for (uint8_t c = 0; c < MATRIX_COLS; c++) {
diff --git a/tmk_core/common/keyboard.h b/tmk_core/common/keyboard.h
index 7738251b64..f17003c2ff 100644
--- a/tmk_core/common/keyboard.h
+++ b/tmk_core/common/keyboard.h
@@ -57,7 +57,6 @@ static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) &&
.time = (timer_read() | 1) \
}
-
/* it runs once at early stage of startup before keyboard_init. */
void keyboard_setup(void);
/* it runs once after initializing host side protocol, debug and MCU peripherals. */
diff --git a/tmk_core/common/matrix.h b/tmk_core/common/matrix.h
index cee3593eee..2543f5abce 100644
--- a/tmk_core/common/matrix.h
+++ b/tmk_core/common/matrix.h
@@ -50,7 +50,7 @@ void matrix_init(void);
uint8_t matrix_scan(void);
/* whether modified from previous scan. used after matrix_scan. */
bool matrix_is_modified(void) __attribute__ ((deprecated));
-/* whether a swtich is on */
+/* whether a switch is on */
bool matrix_is_on(uint8_t row, uint8_t col);
/* matrix state on row */
matrix_row_t matrix_get_row(uint8_t row);
diff --git a/tmk_core/common/mousekey.h b/tmk_core/common/mousekey.h
index 6eede06b44..9338d0af77 100644
--- a/tmk_core/common/mousekey.h
+++ b/tmk_core/common/mousekey.h
@@ -23,8 +23,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* max value on report descriptor */
-#define MOUSEKEY_MOVE_MAX 127
-#define MOUSEKEY_WHEEL_MAX 127
+#ifndef MOUSEKEY_MOVE_MAX
+ #define MOUSEKEY_MOVE_MAX 127
+#elif MOUSEKEY_MOVE_MAX > 127
+ #error MOUSEKEY_MOVE_MAX needs to be smaller than 127
+#endif
+
+#ifndef MOUSEKEY_WHEEL_MAX
+ #define MOUSEKEY_WHEEL_MAX 127
+#elif MOUSEKEY_WHEEL_MAX > 127
+ #error MOUSEKEY_WHEEL_MAX needs to be smaller than 127
+#endif
#ifndef MOUSEKEY_MOVE_DELTA
#define MOUSEKEY_MOVE_DELTA 5
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index 0c799eca39..8fb28b6ce3 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -134,13 +134,6 @@ typedef union {
} nkro;
#endif
} __attribute__ ((packed)) report_keyboard_t;
-/*
-typedef struct {
- uint8_t mods;
- uint8_t reserved;
- uint8_t keys[REPORT_KEYS];
-} __attribute__ ((packed)) report_keyboard_t;
-*/
typedef struct {
uint8_t buttons;
diff --git a/tmk_core/protocol/lufa.mk b/tmk_core/protocol/lufa.mk
index 151d26cbc8..7ce727dab0 100644
--- a/tmk_core/protocol/lufa.mk
+++ b/tmk_core/protocol/lufa.mk
@@ -8,24 +8,35 @@ LUFA_PATH ?= $(LUFA_DIR)/LUFA-git
ifneq (, $(wildcard $(TMK_PATH)/$(LUFA_PATH)/LUFA/Build/lufa_sources.mk))
# New build system from 20120730
LUFA_ROOT_PATH = $(LUFA_PATH)/LUFA
- include $(TMK_PATH)/$(LUFA_PATH)/LUFA/Build/lufa_sources.mk
+ include $(TMK_PATH)/$(LUFA_PATH)/LUFA/Build/lufa_sources.mk
else
include $(TMK_PATH)/$(LUFA_PATH)/LUFA/makefile
endif
LUFA_SRC = lufa.c \
descriptor.c \
+ outputselect.c \
$(LUFA_SRC_USB)
ifeq ($(strip $(MIDI_ENABLE)), yes)
include $(TMK_PATH)/protocol/midi.mk
endif
-ifeq ($(strip $(ADAFRUIT_BLE_ENABLE)), yes)
- LUFA_SRC += $(LUFA_DIR)/adafruit_ble.cpp
+ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
+ LUFA_SRC += $(LUFA_DIR)/bluetooth.c \
+ $(TMK_DIR)/protocol/serial_uart.c
endif
-ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
+ifeq ($(strip $(BLUETOOTH)), AdafruitBLE)
+ LUFA_SRC += $(LUFA_DIR)/adafruit_ble.cpp
+endif
+
+ifeq ($(strip $(BLUETOOTH)), AdafruitEZKey)
+ LUFA_SRC += $(LUFA_DIR)/bluetooth.c \
+ $(TMK_DIR)/protocol/serial_uart.c
+endif
+
+ifeq ($(strip $(BLUETOOTH)), RN42)
LUFA_SRC += $(LUFA_DIR)/bluetooth.c \
$(TMK_DIR)/protocol/serial_uart.c
endif
@@ -53,6 +64,7 @@ LUFA_OPTS += -DUSE_FLASH_DESCRIPTORS
LUFA_OPTS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
#LUFA_OPTS += -DINTERRUPT_CONTROL_ENDPOINT
LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8
+LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -DFIXED_NUM_CONFIGURATIONS=1
# Remote wakeup fix for ATmega32U2 https://github.com/tmk/tmk_keyboard/issues/361
diff --git a/tmk_core/protocol/lufa/adafruit_ble.h b/tmk_core/protocol/lufa/adafruit_ble.h
index 351fd55ae9..b3bab3ca09 100644
--- a/tmk_core/protocol/lufa/adafruit_ble.h
+++ b/tmk_core/protocol/lufa/adafruit_ble.h
@@ -3,7 +3,7 @@
* Supports the Adafruit BLE board built around the nRF51822 chip.
*/
#pragma once
-#ifdef ADAFRUIT_BLE_ENABLE
+#ifdef MODULE_ADAFRUIT_BLE
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
@@ -57,4 +57,4 @@ extern bool adafruit_ble_set_power_level(int8_t level);
}
#endif
-#endif // ADAFRUIT_BLE_ENABLE
+#endif // MODULE_ADAFRUIT_BLE
diff --git a/tmk_core/protocol/lufa/bluetooth.h b/tmk_core/protocol/lufa/bluetooth.h
index 78ece1cd0b..f4b2f6f8b1 100644
--- a/tmk_core/protocol/lufa/bluetooth.h
+++ b/tmk_core/protocol/lufa/bluetooth.h
@@ -62,4 +62,18 @@ void bluefruit_serial_send(uint8_t data);
(usage == AC_REFRESH ? 0x0000 : \
(usage == AC_BOOKMARKS ? 0x0000 : 0)))))))))))))))))))
-#endif \ No newline at end of file
+#define CONSUMER2RN42(usage) \
+ (usage == AUDIO_MUTE ? 0x0040 : \
+ (usage == AUDIO_VOL_UP ? 0x0010 : \
+ (usage == AUDIO_VOL_DOWN ? 0x0020 : \
+ (usage == TRANSPORT_NEXT_TRACK ? 0x0100 : \
+ (usage == TRANSPORT_PREV_TRACK ? 0x0200 : \
+ (usage == TRANSPORT_STOP ? 0x0400 : \
+ (usage == TRANSPORT_STOP_EJECT ? 0x0800 : \
+ (usage == TRANSPORT_PLAY_PAUSE ? 0x0080 : \
+ (usage == AL_EMAIL ? 0x0200 : \
+ (usage == AL_LOCAL_BROWSER ? 0x8000 : \
+ (usage == AC_SEARCH ? 0x0400 : \
+ (usage == AC_HOME ? 0x0100 : 0))))))))))))
+
+ #endif
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index 6dd5959dc4..ae6129d1a2 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -53,6 +53,7 @@
#include "lufa.h"
#include "quantum.h"
#include <util/atomic.h>
+#include "outputselect.h"
#ifdef NKRO_ENABLE
#include "keycode_config.h"
@@ -66,10 +67,11 @@
#endif
#ifdef BLUETOOTH_ENABL