aboutsummaryrefslogtreecommitdiffstats
path: root/tmk_core
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/common.mk27
-rw-r--r--tmk_core/common/action.c32
-rw-r--r--tmk_core/common/action_tapping.c2
-rw-r--r--tmk_core/common/action_util.c204
-rw-r--r--tmk_core/common/action_util.h16
-rw-r--r--tmk_core/common/backlight.c3
-rw-r--r--tmk_core/common/eeprom.h2
-rw-r--r--tmk_core/common/progmem.h2
-rw-r--r--tmk_core/common/report.c207
-rw-r--r--tmk_core/common/report.h14
-rw-r--r--tmk_core/common/test/bootloader.c19
-rw-r--r--tmk_core/common/test/eeprom.c98
-rw-r--r--tmk_core/common/test/suspend.c17
-rw-r--r--tmk_core/common/test/timer.c30
-rw-r--r--tmk_core/common/wait.h9
-rw-r--r--tmk_core/protocol/lufa/adafruit_ble.cpp20
-rw-r--r--tmk_core/protocol/lufa/adafruit_ble.h2
-rw-r--r--tmk_core/protocol/lufa/lufa.c4
-rw-r--r--tmk_core/protocol/ps2_mouse.c29
19 files changed, 503 insertions, 234 deletions
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index 3e0bd7dbc..75b810d98 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -3,6 +3,8 @@ ifeq ($(PLATFORM),AVR)
PLATFORM_COMMON_DIR = $(COMMON_DIR)/avr
else ifeq ($(PLATFORM),CHIBIOS)
PLATFORM_COMMON_DIR = $(COMMON_DIR)/chibios
+else
+ PLATFORM_COMMON_DIR = $(COMMON_DIR)/test
endif
TMK_COMMON_SRC += $(COMMON_DIR)/host.c \
@@ -16,6 +18,7 @@ TMK_COMMON_SRC += $(COMMON_DIR)/host.c \
$(COMMON_DIR)/debug.c \
$(COMMON_DIR)/util.c \
$(COMMON_DIR)/eeconfig.c \
+ $(COMMON_DIR)/report.c \
$(PLATFORM_COMMON_DIR)/suspend.c \
$(PLATFORM_COMMON_DIR)/timer.c \
$(PLATFORM_COMMON_DIR)/bootloader.c \
@@ -29,6 +32,10 @@ ifeq ($(PLATFORM),CHIBIOS)
TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
endif
+ifeq ($(PLATFORM),TEST)
+ TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
+endif
+
# Option modules
@@ -95,27 +102,35 @@ endif
ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
+ TMK_COMMON_DEFS += -DNO_USB_STARTUP_CHECK
endif
ifeq ($(strip $(BLUETOOTH)), AdafruitBLE)
- TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
- TMK_COMMON_DEFS += -DMODULE_ADAFRUIT_BLE
+ TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
+ TMK_COMMON_DEFS += -DMODULE_ADAFRUIT_BLE
+ TMK_COMMON_DEFS += -DNO_USB_STARTUP_CHECK
endif
ifeq ($(strip $(BLUETOOTH)), AdafruitEZKey)
- TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
- TMK_COMMON_DEFS += -DMODULE_ADAFRUIT_EZKEY
+ TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
+ TMK_COMMON_DEFS += -DMODULE_ADAFRUIT_EZKEY
+ TMK_COMMON_DEFS += -DNO_USB_STARTUP_CHECK
endif
ifeq ($(strip $(BLUETOOTH)), RN42)
- TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
- TMK_COMMON_DEFS += -DMODULE_RN42
+ TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
+ TMK_COMMON_DEFS += -DMODULE_RN42
+ TMK_COMMON_DEFS += -DNO_USB_STARTUP_CHECK
endif
ifeq ($(strip $(ONEHAND_ENABLE)), yes)
TMK_COMMON_DEFS += -DONEHAND_ENABLE
endif
+ifeq ($(strip $(NO_USB_STARTUP_CHECK)), yes)
+ TMK_COMMON_DEFS += -DNO_USB_STARTUP_CHECK
+endif
+
ifeq ($(strip $(KEYMAP_SECTION_ENABLE)), yes)
TMK_COMMON_DEFS += -DKEYMAP_SECTION_ENABLE
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index a534f818e..84e661523 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -34,6 +34,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "nodebug.h"
#endif
+int tp_buttons;
+
#ifdef FAUXCLICKY_ENABLE
#include <fauxclicky.h>
#endif
@@ -65,9 +67,11 @@ void action_exec(keyevent_t 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);
}
+ if (has_oneshot_mods_timed_out()) {
+ clear_oneshot_mods();
+ }
#endif
#ifndef NO_ACTION_TAPPING
@@ -311,9 +315,35 @@ void process_action(keyrecord_t *record, action_t action)
/* Mouse key */
case ACT_MOUSEKEY:
if (event.pressed) {
+ switch (action.key.code) {
+ case KC_MS_BTN1:
+ tp_buttons |= (1<<0);
+ break;
+ case KC_MS_BTN2:
+ tp_buttons |= (1<<1);
+ break;
+ case KC_MS_BTN3:
+ tp_buttons |= (1<<2);
+ break;
+ default:
+ break;
+ }
mousekey_on(action.key.code);
mousekey_send();
} else {
+ switch (action.key.code) {
+ case KC_MS_BTN1:
+ tp_buttons &= ~(1<<0);
+ break;
+ case KC_MS_BTN2:
+ tp_buttons &= ~(1<<1);
+ break;
+ case KC_MS_BTN3:
+ tp_buttons &= ~(1<<2);
+ break;
+ default:
+ break;
+ }
mousekey_off(action.key.code);
mousekey_send();
}
diff --git a/tmk_core/common/action_tapping.c b/tmk_core/common/action_tapping.c
index bd9a69ae0..531a3ca34 100644
--- a/tmk_core/common/action_tapping.c
+++ b/tmk_core/common/action_tapping.c
@@ -96,7 +96,7 @@ bool process_tapping(keyrecord_t *keyp)
// enqueue
return false;
}
-#if TAPPING_TERM >= 500
+#if TAPPING_TERM >= 500 || defined PERMISSIVE_HOLD
/* 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.
diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c
index 77848c092..148162a51 100644
--- a/tmk_core/common/action_util.c
+++ b/tmk_core/common/action_util.c
@@ -25,13 +25,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
extern keymap_config_t keymap_config;
-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;
static uint8_t macro_mods = 0;
@@ -50,6 +43,10 @@ static int8_t cb_count = 0;
//report_keyboard_t keyboard_report = {};
report_keyboard_t *keyboard_report = &(report_keyboard_t){};
+extern inline void add_key(uint8_t key);
+extern inline void del_key(uint8_t key);
+extern inline void clear_keys(void);
+
#ifndef NO_ACTION_ONESHOT
static int8_t oneshot_mods = 0;
static int8_t oneshot_locked_mods = 0;
@@ -134,7 +131,7 @@ void send_keyboard_report(void) {
}
#endif
keyboard_report->mods |= oneshot_mods;
- if (has_anykey()) {
+ if (has_anykey(keyboard_report)) {
clear_oneshot_mods();
}
}
@@ -143,38 +140,6 @@ void send_keyboard_report(void) {
host_keyboard_send(keyboard_report);
}
-/* key */
-void add_key(uint8_t key)
-{
-#ifdef NKRO_ENABLE
- if (keyboard_protocol && keymap_config.nkro) {
- add_key_bit(key);
- return;
- }
-#endif
- add_key_byte(key);
-}
-
-void del_key(uint8_t key)
-{
-#ifdef NKRO_ENABLE
- if (keyboard_protocol && keymap_config.nkro) {
- del_key_bit(key);
- return;
- }
-#endif
- del_key_byte(key);
-}
-
-void clear_keys(void)
-{
- // not clear mods
- for (int8_t i = 1; i < KEYBOARD_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; }
@@ -221,166 +186,7 @@ uint8_t get_oneshot_mods(void)
/*
* inspect keyboard state
*/
-uint8_t has_anykey(void)
-{
- uint8_t cnt = 0;
- for (uint8_t i = 1; i < KEYBOARD_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_protocol && keymap_config.nkro) {
- uint8_t i = 0;
- for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
- ;
- 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
-}
-
-
-
-/* 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 < KEYBOARD_REPORT_KEYS; i++) {
- if (keyboard_report->keys[i] == code) {
- break;
- }
- if (empty == -1 && keyboard_report->keys[i] == 0) {
- empty = i;
- }
- }
- if (i == KEYBOARD_REPORT_KEYS) {
- if (empty != -1) {
- 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 < KEYBOARD_REPORT_KEYS; i++) {
- if (keyboard_report->keys[i] == code) {
- keyboard_report->keys[i] = 0;
- }
- }
-#endif
-}
-
-#ifdef NKRO_ENABLE
-static inline void add_key_bit(uint8_t code)
-{
- if ((code>>3) < KEYBOARD_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) < KEYBOARD_REPORT_BITS) {
- keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
- } else {
- dprintf("del_key_bit: can't del: %02X\n", code);
- }
-}
-#endif
diff --git a/tmk_core/common/action_util.h b/tmk_core/common/action_util.h
index dd0c4c2bf..345893151 100644
--- a/tmk_core/common/action_util.h
+++ b/tmk_core/common/action_util.h
@@ -29,9 +29,17 @@ 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);
+inline void add_key(uint8_t key) {
+ add_key_to_report(keyboard_report, key);
+}
+
+inline void del_key(uint8_t key) {
+ del_key_from_report(keyboard_report, key);
+}
+
+inline void clear_keys(void) {
+ clear_keys_from_report(keyboard_report);
+}
/* modifier */
uint8_t get_mods(void);
@@ -82,9 +90,7 @@ uint8_t get_oneshot_layer_state(void);
bool has_oneshot_layer_timed_out(void);
/* inspect */
-uint8_t has_anykey(void);
uint8_t has_anymod(void);
-uint8_t get_first_key(void);
#ifdef __cplusplus
}
diff --git a/tmk_core/common/backlight.c b/tmk_core/common/backlight.c
index 0e0ad2d15..d03bfe931 100644
--- a/tmk_core/common/backlight.c
+++ b/tmk_core/common/backlight.c
@@ -28,6 +28,9 @@ void backlight_init(void)
eeconfig_init();
}
backlight_config.raw = eeconfig_read_backlight();
+ if (backlight_config.level > BACKLIGHT_LEVELS) {
+ backlight_config.level = BACKLIGHT_LEVELS;
+ }
backlight_set(backlight_config.enable ? backlight_config.level : 0);
}
diff --git a/tmk_core/common/eeprom.h b/tmk_core/common/eeprom.h
index 2cc2ccee3..3696d0df3 100644
--- a/tmk_core/common/eeprom.h
+++ b/tmk_core/common/eeprom.h
@@ -4,6 +4,8 @@
#if defined(__AVR__)
#include <avr/eeprom.h>
#else
+#include <stdint.h>
+
uint8_t eeprom_read_byte (const uint8_t *__p);
uint16_t eeprom_read_word (const uint16_t *__p);
uint32_t eeprom_read_dword (const uint32_t *__p);
diff --git a/tmk_core/common/progmem.h b/tmk_core/common/progmem.h
index 5b2765625..a09f91be8 100644
--- a/tmk_core/common/progmem.h
+++ b/tmk_core/common/progmem.h
@@ -3,7 +3,7 @@
#if defined(__AVR__)
# include <avr/pgmspace.h>
-#elif defined(__arm__)
+#else
# define PROGMEM
# define pgm_read_byte(p) *((unsigned char*)p)
# define pgm_read_word(p) *((uint16_t*)p)
diff --git a/tmk_core/common/report.c b/tmk_core/common/report.c
new file mode 100644
index 000000000..74c6d3fdd
--- /dev/null
+++ b/tmk_core/common/report.c
@@ -0,0 +1,207 @@
+/* Copyright 2017 Fred Sundvik
+ *
+ * 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 "report.h"
+#include "host.h"
+#include "keycode_config.h"
+#include "debug.h"
+#include "util.h"
+
+uint8_t has_anykey(report_keyboard_t* keyboard_report)
+{
+ uint8_t cnt = 0;
+ for (uint8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
+ if (keyboard_report->raw[i])
+ cnt++;
+ }
+ return cnt;
+}
+
+uint8_t get_first_key(report_keyboard_t* keyboard_report)
+{
+#ifdef NKRO_ENABLE
+ if (keyboard_protocol && keymap_config.nkro) {
+ uint8_t i = 0;
+ for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
+ ;
+ 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
+}
+
+void add_key_byte(report_keyboard_t* keyboard_report, 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 < KEYBOARD_REPORT_KEYS; i++) {
+ if (keyboard_report->keys[i] == code) {
+ break;
+ }
+ if (empty == -1 && keyboard_report->keys[i] == 0) {
+ empty = i;
+ }
+ }
+ if (i == KEYBOARD_REPORT_KEYS) {
+ if (empty != -1) {
+ keyboard_report->keys[empty] = code;
+ }
+ }
+#endif
+}
+
+void del_key_byte(report_keyboard_t* keyboard_report, 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 < KEYBOARD_REPORT_KEYS; i++) {
+ if (keyboard_report->keys[i] == code) {
+ keyboard_report->keys[i] = 0;
+ }
+ }
+#endif
+}
+
+#ifdef NKRO_ENABLE
+void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code)
+{
+ if ((code>>3) < KEYBOARD_REPORT_BITS) {
+ keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
+ } else {
+ dprintf("add_key_bit: can't add: %02X\n", code);
+ }
+}
+
+void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code)
+{
+ if ((code>>3) < KEYBOARD_REPORT_BITS) {
+ keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
+ } else {
+ dprintf("del_key_bit: can't del: %02X\n", code);
+ }
+}
+#endif
+
+void add_key_to_report(report_keyboard_t* keyboard_report, int8_t key)
+{
+#ifdef NKRO_ENABLE
+ if (keyboard_protocol && keymap_config.nkro) {
+ add_key_bit(keyboard_report, key);
+ return;
+ }
+#endif
+ add_key_byte(keyboard_report, key);
+}
+
+void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key)
+{
+#ifdef NKRO_ENABLE
+ if (keyboard_protocol && keymap_config.nkro) {
+ del_key_bit(keyboard_report, key);
+ return;
+ }
+#endif
+ del_key_byte(keyboard_report, key);
+}
+
+void clear_keys_from_report(report_keyboard_t* keyboard_report)
+{
+ // not clear mods
+ for (int8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
+ keyboard_report->raw[i] = 0;
+ }
+} \ No newline at end of file
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index 8fb28b6ce..899fc524c 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -174,6 +174,20 @@ typedef struct {
(key == KC_WWW_REFRESH ? AC_REFRESH : \
(key == KC_WWW_FAVORITES ? AC_BOOKMARKS : 0)))))))))))))))))))))
+uint8_t has_anykey(report_keyboard_t* keyboard_report);
+uint8_t get_first_key(report_keyboard_t* keyboard_report);
+
+void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code);
+void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code);
+#ifdef NKRO_ENABLE
+void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code);
+void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code);
+#endif
+
+void add_key_to_report(report_keyboard_t* keyboard_report, int8_t key);
+void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key);
+void clear_keys_from_report(report_keyboard_t* keyboard_report);
+
#ifdef __cplusplus
}
#endif
diff --git a/tmk_core/common/test/bootloader.c b/tmk_core/common/test/bootloader.c
new file mode 100644
index 000000000..5155d9ff0
--- /dev/null
+++ b/tmk_core/common/test/bootloader.c
@@ -0,0 +1,19 @@
+/* Copyright 2017 Fred Sundvik
+ *
+ * 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 "bootloader.h"
+
+void bootloader_jump(void) {}
diff --git a/tmk_core/common/test/eeprom.c b/tmk_core/common/test/eeprom.c
new file mode 100644
index 000000000..61cc039ef
--- /dev/null
+++ b/tmk_core/common/test/eeprom.c
@@ -0,0 +1,98 @@
+/* Copyright 2017 Fred Sundvik
+ *
+ * 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 "eeprom.h"
+
+#define EEPROM_SIZE 32
+
+static uint8_t buffer[EEPROM_SIZE];
+
+uint8_t eeprom_read_byte(const uint8_t *addr) {
+ uintptr_t offset = (uintptr_t)addr;
+ return buffer[offset];
+}
+
+void eeprom_write_byte(uint8_t *addr, uint8_t value) {
+ uintptr_t offset = (uintptr_t)addr;
+ buffer[offset] = value;
+}
+
+uint16_t eeprom_read_word(const uint16_t *addr) {
+ const uint8_t *p = (const uint8_t *)addr;
+ return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8);
+}
+
+uint32_t eeprom_read_dword(const uint32_t *addr) {
+ const uint8_t *p = (const uint8_t *)addr;
+ return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8)
+ | (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24);
+}
+
+void eeprom_read_block(void *buf, const void *addr, uint32_t len) {
+ const uint8_t *p = (const uint8_t *)addr;
+ uint8_t *dest = (uint8_t *)buf;
+ while (len--) {
+ *dest++ = eeprom_read_byte(p++);
+ }
+}
+
+void eeprom_write_word(uint16_t *addr, uint16_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p, value >> 8);
+}
+
+void eeprom_write_dword(uint32_t *addr, uint32_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p++, value >> 8);
+ eeprom_write_byte(p++, value >> 16);
+ eeprom_write_byte(p, value >> 24);
+}
+
+void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
+ uint8_t *p = (uint8_t *)addr;
+ const uint8_t *src = (const uint8_t *)buf;
+ while (len--) {
+ eeprom_write_byte(p++, *src++);
+ }
+}
+
+void eeprom_update_byte(uint8_t *addr, uint8_t value) {
+ eeprom_write_byte(addr, value);
+}
+
+void eeprom_update_word(uint16_t *addr, uint16_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p, value >> 8);
+}
+
+void eeprom_update_dword(uint32_t *addr, uint32_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p++, value >> 8);
+ eeprom_write_byte(p++, value >> 16);
+ eeprom_write_byte(p, value >> 24);
+}
+
+void eeprom_update_block(const void *buf, void *addr, uint32_t len) {
+ uint8_t *p = (uint8_t *)addr;
+ const uint8_t *src = (const uint8_t *)buf;
+ while (len--) {
+ eeprom_write_byte(p++, *src++);
+ }
+}
diff --git a/tmk_core/common/test/suspend.c b/tmk_core/common/test/suspend.c
new file mode 100644
index 000000000..01d1930ea
--- /dev/null
+++ b/tmk_core/common/test/suspend.c
@@ -0,0 +1,17 @@
+/* Copyright 2017 Fred Sundvik
+ *
+ * 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/>.
+ */
+
+
diff --git a/tmk_core/common/test/timer.c b/tmk_core/common/test/timer.c
new file mode 100644
index 000000000..09ea91a89
--- /dev/null
+++ b/tmk_core/common/test/timer.c
@@ -0,0 +1,30 @@
+/* Copyright 2017 Fred Sundvik
+ *
+ * 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 "timer.h"
+
+// TODO: the timer should work, but at a much faster rate than realtime
+// It should also have some kind of integration with the testing system
+
+void timer_init(void) {}
+
+void timer_clear(void) {}
+
+uint16_t timer_read(void) { return 0; }
+uint32_t timer_read32(void) { return 0; }
+uint16_t timer_elapsed(uint16_t last) { return 0; }
+uint32_t timer_elapsed32(uint32_t last) { return 0; }
+
diff --git a/tmk_core/common/wait.h b/tmk_core/common/wait.h
index 82727be01..911c9ddb5 100644
--- a/tmk_core/common/wait.h
+++ b/tmk_core/common/wait.h
@@ -9,13 +9,16 @@ extern "C" {
# include <util/delay.h>
# define wait_ms(ms) _delay_ms(ms)
# define wait_us(us) _delay_us(us)
-#elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */
+#elif defined(PROTOCOL_CHIBIOS)
# include "ch.h"
# define wait_ms(ms) chThdSleepMilliseconds(ms)
# define wait_us(us) chThdSleepMicroseconds(us)
-#elif defined(__arm__) /* __AVR__ */
+#elif defined(__arm__)
# include "wait_api.h"
-#endif /* __AVR__ */
+#else // Unit tests
+#define wait_ms(ms)
+#define wait_us(us)
+#endif
#ifdef __cplusplus
}
diff --git a/tmk_core/protocol/lufa/adafruit_ble.cpp b/tmk_core/protocol/lufa/adafruit_ble.cpp
index fd6edd42c..bee6bb2c1 100644
--- a/tmk_core/protocol/lufa/adafruit_ble.cpp
+++ b/tmk_core/protocol/lufa/adafruit_ble.cpp
@@ -87,6 +87,7 @@ struct queue_item {
uint16_t consumer;
struct __attribute__((packed)) {
int8_t x, y, scroll, pan;
+ uint8_t buttons;
} mousemove;
};
};
@@ -699,6 +700,22 @@ static bool process_queue_item(struct queue_item *item, uint16_t timeout) {
strcpy_P(fmtbuf, PSTR("AT+BLEHIDMOUSEMOVE=%d,%d,%d,%d"));
snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, item->mousemove.x,
item->mousemove.y, item->mousemove.scroll, item->mousemove.pan);
+ if (!at_command(cmdbuf, NULL, 0, true, timeout)) {
+ return false;
+ }
+ strcpy_P(cmdbuf, PSTR("AT+BLEHIDMOUSEBUTTON="));
+ if (item->mousemove.buttons & MOUSE_BTN1) {
+ strcat(cmdbuf, "L");
+ }
+ if (item->mousemove.buttons & MOUSE_BTN2) {
+ strcat(cmdbuf, "R");
+ }
+ if (item->mousemove.buttons & MOUSE_BTN3) {
+ strcat(cmdbuf, "M");
+ }
+ if (item->mousemove.buttons == 0) {
+ strcat(cmdbuf, "0");
+ }
return at_command(cmdbuf, NULL, 0, true, timeout);
#endif
default:
@@ -757,7 +774,7 @@ bool adafruit_ble_send_consumer_key(uint16_t keycode, int hold_duration) {
#ifdef MOUSE_ENABLE
bool adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll,
- int8_t pan) {
+ int8_t pan, uint8_t buttons) {
struct queue_item item;
item.queue_type = QTMouseMove;
@@ -765,6 +782,7 @@ bool adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll,
item.mousemove.y = y;
item.mousemove.scroll = scroll;
item.mousemove.pan = pan;
+ item.mousemove.buttons = buttons;
while (!send_buf.enqueue(item)) {
send_buf_send_one();
diff --git a/tmk_core/protocol/lufa/adafruit_ble.h b/tmk_core/protocol/lufa/adafruit_ble.h
index b3bab3ca0..036b7d14e 100644
--- a/tmk_core/protocol/lufa/adafruit_ble.h
+++ b/tmk_core/protocol/lufa/adafruit_ble.h
@@ -43,7 +43,7 @@ extern bool adafruit_ble_send_consumer_key(uint16_t keycode, int hold_duration);
* The parameters are signed and indicate positive of negative direction
* change. */
extern bool adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll,
- int8_t pan);
+ int8_t pan, uint8_t buttons);
#endif
/* Compute battery voltage by reading an analog pin.
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index ae6129d1a..e3f8724e8 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -669,7 +669,7 @@ static void send_mouse(report_mouse_t *report)
if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
#ifdef MODULE_ADAFRUIT_BLE
// FIXME: mouse buttons
- adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h);
+ adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h, report->buttons);
#else
bluefruit_serial_send(0xFD);
bluefruit_serial_send(0x00);
@@ -1180,7 +1180,7 @@ int main(void)
print("Keyboard start.\n");
while (1) {
- #if !defined(BLUETOOTH_ENABLE)
+ #if !defined(NO_USB_STARTUP_CHECK)
while (USB_DeviceState == DEVICE_STATE_Suspended) {
print("[s]");
suspend_power_down();
diff --git a/tmk_core/protocol/ps2_mouse.c b/tmk_core/protocol/ps2_mouse.c
index d9ccbecb4..4ed3cae1f 100644
--- a/tmk_core/protocol/ps2_mouse.c
+++ b/tmk_core/protocol/ps2_mouse.c
@@ -72,12 +72,13 @@ void ps2_mouse_init_user(void) {
void ps2_mouse_task(void) {
static uint8_t buttons_prev = 0;
+ extern int tp_buttons;
/* receives packet from mouse */
uint8_t rcv;
rcv = ps2_host_send(PS2_MOUSE_READ_DATA);
if (rcv == PS2_ACK) {
- mouse_report.buttons = ps2_host_recv_response();
+ mouse_report.buttons = ps2_host_recv_response() | tp_buttons;
mouse_report.x = ps2_host_recv_response() * PS2_MOUSE_X_MULTIPLIER;
mouse_report.y = ps2_host_recv_response() * PS2_MOUSE_Y_MULTIPLIER;
#ifdef PS2_MOUSE_ENABLE_SCROLLING
@@ -106,34 +107,34 @@ void ps2_mouse_task(void) {
#endif
host_mouse_send(&mouse_report);
}
-
+
ps2_mouse_clear_report(&mouse_report);
}
void ps2_mouse_disable_data_reporting(void) {
- PS2_MOUSE_SEND(PS2_MOUSE_DISABLE_DATA_REPORTING, "ps2 mouse disable data reporting");
+ PS2_MOUSE_SEND(PS2_MOUSE_DISABLE_DATA_REPORTING, "ps2 mouse disable data reporting");
}
void ps2_mouse_enable_data_reporting(void) {
PS2_MOUSE_SEND(PS2_MOUSE_ENABLE_DATA_REPORTING, "ps2 mouse enable data reporting");
}
-void ps2_mouse_set_remote_mode(void) {
- PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_REMOTE_MODE, "ps2 mouse set remote mode");
+void ps2_mouse_set_remote_mode(void) {
+ PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_REMOTE_MODE, "ps2 mouse set remote mode");
ps2_mouse_mode = PS2_MOUSE_REMOTE_MODE;
}
-void ps2_mouse_set_stream_mode(void) {
- PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_STREAM_MODE, "ps2 mouse set stream mode");
+void ps2_mouse_set_stream_mode(void) {
+ PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_STREAM_MODE, "ps2 mouse set stream mode");
ps2_mouse_mode = PS2_MOUSE_STREAM_MODE;
}
void ps2_mouse_set_scaling_2_1(void) {
- PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_SCALING_2_1, "ps2 mouse set scaling 2:1");
+ PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_SCALING_2_1, "ps2 mouse set scaling 2:1");
}
void ps2_mouse_set_scaling_1_1(void) {
- PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_SCALING_1_1, "ps2 mouse set scaling 1:1");
+ PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_SCALING_1_1, "ps2 mouse set scaling 1:1");
}
void ps2_mouse_set_resolution(ps2_mouse_resolution_t resolution) {
@@ -204,9 +205,9 @@ static inline void ps2_mouse_enable_scrolling(void) {
#define PRESS_SCROLL_BUTTONS mouse_report->buttons |= (PS2_MOUSE_SCROLL_BTN_MASK)
#define RELEASE_SCROLL_BUTTONS mouse_report->buttons &= ~(PS2_MOUSE_SCROLL_BTN_MASK)
static inline void ps2_mouse_scroll_button_task(report_mouse_t *mouse_report) {
- static enum {
- SCROLL_NONE,
- SCROLL_BTN,
+ static enum {
+ SCROLL_NONE,
+ SCROLL_BTN,
SCROLL_SENT,
} scroll_state = SCROLL_NONE;
static uint16_t scroll_button_time = 0;
@@ -228,10 +229,10 @@ static inline void ps2_mouse_scroll_button_task(report_mouse_t *mouse_report) {
mouse_report->y = 0;
}
} else if (0 == (PS2_MOUSE_SCROLL_BTN_MASK & mouse_report->buttons)) {
- // None of the scroll buttons are pressed
+ // None of the scroll buttons are pressed
#if PS2_MOUSE_SCROLL_BTN_SEND
- if (scroll_state == SCROLL_BTN
+ if (scroll_state == SCROLL_BTN
&& timer_elapsed(scroll_button_time) < PS2_MOUSE_SCROLL_BTN_SEND) {
PRESS_SCROLL_BUTTONS;
host_mouse_send(mouse_report);