aboutsummaryrefslogtreecommitdiff
path: root/tmk_core
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/chibios.mk4
-rw-r--r--tmk_core/common.mk24
-rw-r--r--tmk_core/common/action.c40
-rw-r--r--tmk_core/common/arm_atsam/_print.h (renamed from tmk_core/common/print.c)33
-rw-r--r--tmk_core/common/arm_atsam/printf.c6
-rw-r--r--tmk_core/common/arm_atsam/printf.mk1
-rw-r--r--tmk_core/common/avr/_print.h33
-rw-r--r--tmk_core/common/avr/bootloader.c2
-rw-r--r--tmk_core/common/avr/pin_defs.h4
-rw-r--r--tmk_core/common/avr/printf.c20
-rw-r--r--tmk_core/common/avr/printf.mk2
-rw-r--r--tmk_core/common/avr/suspend.c5
-rw-r--r--tmk_core/common/chibios/suspend.c7
-rw-r--r--tmk_core/common/debug.c41
-rw-r--r--tmk_core/common/keyboard.c44
-rw-r--r--tmk_core/common/keyboard.h9
-rw-r--r--tmk_core/common/keycode.h14
-rw-r--r--tmk_core/common/lib_printf.mk9
-rw-r--r--tmk_core/common/mousekey.c446
-rw-r--r--tmk_core/common/mousekey.h142
-rw-r--r--tmk_core/common/print.h301
-rw-r--r--tmk_core/common/printf.c27
-rw-r--r--tmk_core/common/progmem.h1
-rw-r--r--tmk_core/common/report.h5
-rw-r--r--tmk_core/common/sendchar.h2
-rw-r--r--tmk_core/common/suspend.h4
-rw-r--r--tmk_core/common/sync_timer.c58
-rw-r--r--tmk_core/common/sync_timer.h54
-rw-r--r--tmk_core/common/uart.c172
-rw-r--r--tmk_core/common/uart.h8
-rw-r--r--tmk_core/common/wait.h79
-rw-r--r--tmk_core/protocol/adb.c256
-rw-r--r--tmk_core/protocol/adb.h58
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.c3
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.h4
-rw-r--r--tmk_core/protocol/arm_atsam/main_arm_atsam.c4
-rw-r--r--tmk_core/protocol/chibios/main.c3
-rw-r--r--tmk_core/protocol/chibios/usb_main.c95
-rw-r--r--tmk_core/protocol/chibios/usb_main.h11
-rw-r--r--tmk_core/protocol/lufa/lufa.c25
-rw-r--r--tmk_core/protocol/m0110.c8
-rw-r--r--tmk_core/protocol/ps2_mouse.c2
-rw-r--r--tmk_core/protocol/usb_descriptor.c12
-rw-r--r--tmk_core/protocol/vusb/main.c7
-rw-r--r--tmk_core/protocol/vusb/vusb.c10
45 files changed, 865 insertions, 1230 deletions
diff --git a/tmk_core/chibios.mk b/tmk_core/chibios.mk
index e94e935eb..40595a1e3 100644
--- a/tmk_core/chibios.mk
+++ b/tmk_core/chibios.mk
@@ -71,6 +71,9 @@ else ifneq ("$(wildcard $(TOP_DIR)/platforms/chibios/$(BOARD)/board/board.mk)","
71 BOARD_PATH = $(TOP_DIR)/platforms/chibios/$(BOARD) 71 BOARD_PATH = $(TOP_DIR)/platforms/chibios/$(BOARD)
72 BOARD_MK += $(TOP_DIR)/platforms/chibios/$(BOARD)/board/board.mk 72 BOARD_MK += $(TOP_DIR)/platforms/chibios/$(BOARD)/board/board.mk
73 KEYBOARD_PATHS += $(BOARD_PATH)/configs 73 KEYBOARD_PATHS += $(BOARD_PATH)/configs
74 ifneq ("$(wildcard $(BOARD_PATH)/rules.mk)","")
75 include $(BOARD_PATH)/rules.mk
76 endif
74endif 77endif
75 78
76ifeq ("$(wildcard $(BOARD_MK))","") 79ifeq ("$(wildcard $(BOARD_MK))","")
@@ -309,6 +312,7 @@ LDFLAGS += -mno-thumb-interwork -mthumb
309LDSYMBOLS =,--defsym=__process_stack_size__=$(USE_PROCESS_STACKSIZE) 312LDSYMBOLS =,--defsym=__process_stack_size__=$(USE_PROCESS_STACKSIZE)
310LDSYMBOLS :=$(LDSYMBOLS),--defsym=__main_stack_size__=$(USE_EXCEPTIONS_STACKSIZE) 313LDSYMBOLS :=$(LDSYMBOLS),--defsym=__main_stack_size__=$(USE_EXCEPTIONS_STACKSIZE)
311LDFLAGS += -Wl,--script=$(LDSCRIPT)$(LDSYMBOLS) 314LDFLAGS += -Wl,--script=$(LDSCRIPT)$(LDSYMBOLS)
315LDFLAGS += --specs=nano.specs
312 316
313OPT_DEFS += -DPROTOCOL_CHIBIOS 317OPT_DEFS += -DPROTOCOL_CHIBIOS
314 318
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index 55af71ed6..238b3c69f 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -1,5 +1,3 @@
1PRINTF_PATH = $(LIB_PATH)/printf
2
3COMMON_DIR = common 1COMMON_DIR = common
4PLATFORM_COMMON_DIR = $(COMMON_DIR)/$(PLATFORM_KEY) 2PLATFORM_COMMON_DIR = $(COMMON_DIR)/$(PLATFORM_KEY)
5 3
@@ -10,26 +8,20 @@ TMK_COMMON_SRC += $(COMMON_DIR)/host.c \
10 $(COMMON_DIR)/action_macro.c \ 8 $(COMMON_DIR)/action_macro.c \
11 $(COMMON_DIR)/action_layer.c \ 9 $(COMMON_DIR)/action_layer.c \
12 $(COMMON_DIR)/action_util.c \ 10 $(COMMON_DIR)/action_util.c \
13 $(COMMON_DIR)/print.c \
14 $(COMMON_DIR)/debug.c \ 11 $(COMMON_DIR)/debug.c \
15 $(COMMON_DIR)/sendchar_null.c \ 12 $(COMMON_DIR)/sendchar_null.c \
16 $(COMMON_DIR)/eeconfig.c \ 13 $(COMMON_DIR)/eeconfig.c \
17 $(COMMON_DIR)/report.c \ 14 $(COMMON_DIR)/report.c \
18 $(PLATFORM_COMMON_DIR)/suspend.c \ 15 $(PLATFORM_COMMON_DIR)/suspend.c \
19 $(PLATFORM_COMMON_DIR)/timer.c \ 16 $(PLATFORM_COMMON_DIR)/timer.c \
17 $(COMMON_DIR)/sync_timer.c \
20 $(PLATFORM_COMMON_DIR)/bootloader.c \ 18 $(PLATFORM_COMMON_DIR)/bootloader.c \
21 19
22ifeq ($(PLATFORM),AVR) 20# Use platform provided print - fall back to lib/printf
23 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/xprintf.S 21ifneq ("$(wildcard $(TMK_PATH)/$(PLATFORM_COMMON_DIR)/printf.mk)","")
24else ifeq ($(PLATFORM),CHIBIOS) 22 include $(TMK_PATH)/$(PLATFORM_COMMON_DIR)/printf.mk
25 TMK_COMMON_SRC += $(PRINTF_PATH)/printf.c 23else
26 TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_FLOAT 24 include $(TMK_PATH)/$(COMMON_DIR)/lib_printf.mk
27 TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_EXPONENTIAL
28 TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_LONG_LONG
29 TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_PTRDIFF_T
30 VPATH += $(PRINTF_PATH)
31else ifeq ($(PLATFORM),ARM_ATSAM)
32 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c
33endif 25endif
34 26
35# Option modules 27# Option modules
@@ -66,10 +58,6 @@ ifeq ($(strip $(KEYBOARD_SHARED_EP)), yes)
66endif 58endif
67 59
68ifeq ($(strip $(MOUSEKEY_ENABLE)), yes) 60ifeq ($(strip $(MOUSEKEY_ENABLE)), yes)
69 TMK_COMMON_SRC += $(COMMON_DIR)/mousekey.c
70 TMK_COMMON_DEFS += -DMOUSEKEY_ENABLE
71 TMK_COMMON_DEFS += -DMOUSE_ENABLE
72
73 ifeq ($(strip $(MOUSE_SHARED_EP)), yes) 61 ifeq ($(strip $(MOUSE_SHARED_EP)), yes)
74 TMK_COMMON_DEFS += -DMOUSE_SHARED_EP 62 TMK_COMMON_DEFS += -DMOUSE_SHARED_EP
75 SHARED_EP_ENABLE = yes 63 SHARED_EP_ENABLE = yes
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index a7432bae5..e4a97e0bc 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -47,10 +47,6 @@ int tp_buttons;
47int retro_tapping_counter = 0; 47int retro_tapping_counter = 0;
48#endif 48#endif
49 49
50#ifdef FAUXCLICKY_ENABLE
51# include "fauxclicky.h"
52#endif
53
54#ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY 50#ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY
55__attribute__((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { return false; } 51__attribute__((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { return false; }
56#endif 52#endif
@@ -80,16 +76,6 @@ void action_exec(keyevent_t event) {
80#endif 76#endif
81 } 77 }
82 78
83#ifdef FAUXCLICKY_ENABLE
84 if (IS_PRESSED(event)) {
85 FAUXCLICKY_ACTION_PRESS;
86 }
87 if (IS_RELEASED(event)) {
88 FAUXCLICKY_ACTION_RELEASE;
89 }
90 fauxclicky_check();
91#endif
92
93#ifdef SWAP_HANDS_ENABLE 79#ifdef SWAP_HANDS_ENABLE
94 if (!IS_NOEVENT(event)) { 80 if (!IS_NOEVENT(event)) {
95 process_hand_swap(&event); 81 process_hand_swap(&event);
@@ -443,6 +429,15 @@ void process_action(keyrecord_t *record, action_t action) {
443 case KC_MS_BTN5: 429 case KC_MS_BTN5:
444 register_button(true, MOUSE_BTN5); 430 register_button(true, MOUSE_BTN5);
445 break; 431 break;
432 case KC_MS_BTN6:
433 register_button(true, MOUSE_BTN6);
434 break;
435 case KC_MS_BTN7:
436 register_button(true, MOUSE_BTN7);
437 break;
438 case KC_MS_BTN8:
439 register_button(true, MOUSE_BTN8);
440 break;
446# endif 441# endif
447 default: 442 default:
448 mousekey_send(); 443 mousekey_send();
@@ -469,6 +464,15 @@ void process_action(keyrecord_t *record, action_t action) {
469 case KC_MS_BTN5: 464 case KC_MS_BTN5:
470 register_button(false, MOUSE_BTN5); 465 register_button(false, MOUSE_BTN5);
471 break; 466 break;
467 case KC_MS_BTN6:
468 register_button(false, MOUSE_BTN6);
469 break;
470 case KC_MS_BTN7:
471 register_button(false, MOUSE_BTN7);
472 break;
473 case KC_MS_BTN8:
474 register_button(false, MOUSE_BTN8);
475 break;
472# endif 476# endif
473 default: 477 default:
474 mousekey_send(); 478 mousekey_send();
@@ -1017,6 +1021,10 @@ void clear_keyboard_but_mods(void) {
1017 * FIXME: Needs documentation. 1021 * FIXME: Needs documentation.
1018 */ 1022 */
1019void clear_keyboard_but_mods_and_keys() { 1023void clear_keyboard_but_mods_and_keys() {
1024#ifdef EXTRAKEY_ENABLE
1025 host_system_send(0);
1026 host_consumer_send(0);
1027#endif
1020 clear_weak_mods(); 1028 clear_weak_mods();
1021 clear_macro_mods(); 1029 clear_macro_mods();
1022 send_keyboard_report(); 1030 send_keyboard_report();
@@ -1024,10 +1032,6 @@ void clear_keyboard_but_mods_and_keys() {
1024 mousekey_clear(); 1032 mousekey_clear();
1025 mousekey_send(); 1033 mousekey_send();
1026#endif 1034#endif
1027#ifdef EXTRAKEY_ENABLE
1028 host_system_send(0);
1029 host_consumer_send(0);
1030#endif
1031} 1035}
1032 1036
1033/** \brief Utilities for actions. (FIXME: Needs better description) 1037/** \brief Utilities for actions. (FIXME: Needs better description)
diff --git a/tmk_core/common/print.c b/tmk_core/common/arm_atsam/_print.h
index 07aef0b0e..a774f5d8d 100644
--- a/tmk_core/common/print.c
+++ b/tmk_core/common/arm_atsam/_print.h
@@ -1,4 +1,4 @@
1/* Copyright 2012,2013 Jun Wako <wakojun@gmail.com> */ 1/* Copyright 2012 Jun Wako <wakojun@gmail.com> */
2/* Very basic print functions, intended to be used with usb_debug_only.c 2/* Very basic print functions, intended to be used with usb_debug_only.c
3 * http://www.pjrc.com/teensy/ 3 * http://www.pjrc.com/teensy/
4 * Copyright (c) 2008 PJRC.COM, LLC 4 * Copyright (c) 2008 PJRC.COM, LLC
@@ -21,27 +21,14 @@
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE. 22 * THE SOFTWARE.
23 */ 23 */
24#pragma once
24 25
25#include <stdint.h> 26#include "arm_atsam/printf.h"
26#include "print.h"
27 27
28#ifndef NO_PRINT 28// Create user & normal print defines
29 29#define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
30# if defined(__AVR__) 30#define print(s) xprintf(s)
31 31#define println(s) xprintf(s "\r\n")
32# define sendchar(c) xputc(c) 32#define uprint(s) print(s)
33 33#define uprintln(s) println(s)
34void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) { xdev_out(sendchar_func); } 34#define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
35
36# elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */
37
38// don't need anything extra
39
40# elif defined(__arm__) /* __AVR__ */
41
42// TODO
43// void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) { }
44
45# endif /* __AVR__ */
46
47#endif
diff --git a/tmk_core/common/arm_atsam/printf.c b/tmk_core/common/arm_atsam/printf.c
index cd7cdb52e..2cb59706a 100644
--- a/tmk_core/common/arm_atsam/printf.c
+++ b/tmk_core/common/arm_atsam/printf.c
@@ -15,11 +15,13 @@ You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>. 15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17 17
18#include "printf.h"
19#include "sendchar.h"
20
18#ifdef CONSOLE_ENABLE 21#ifdef CONSOLE_ENABLE
19 22
20# include "samd51j18a.h" 23# include "samd51j18a.h"
21# include "arm_atsam_protocol.h" 24# include "arm_atsam_protocol.h"
22# include "printf.h"
23# include <string.h> 25# include <string.h>
24# include <stdarg.h> 26# include <stdarg.h>
25 27
@@ -66,3 +68,5 @@ void console_printf(char *fmt, ...) {
66} 68}
67 69
68#endif // CONSOLE_ENABLE 70#endif // CONSOLE_ENABLE
71
72void print_set_sendchar(sendchar_func_t send) {} \ No newline at end of file
diff --git a/tmk_core/common/arm_atsam/printf.mk b/tmk_core/common/arm_atsam/printf.mk
new file mode 100644
index 000000000..f70e02731
--- /dev/null
+++ b/tmk_core/common/arm_atsam/printf.mk
@@ -0,0 +1 @@
TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c
diff --git a/tmk_core/common/avr/_print.h b/tmk_core/common/avr/_print.h
new file mode 100644
index 000000000..f9b79bdf8
--- /dev/null
+++ b/tmk_core/common/avr/_print.h
@@ -0,0 +1,33 @@
1/* Copyright 2012 Jun Wako <wakojun@gmail.com> */
2/* Very basic print functions, intended to be used with usb_debug_only.c
3 * http://www.pjrc.com/teensy/
4 * Copyright (c) 2008 PJRC.COM, LLC
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#pragma once
25
26#include "avr/xprintf.h"
27
28// Create user & normal print defines
29#define print(s) xputs(PSTR(s))
30#define println(s) xputs(PSTR(s "\r\n"))
31#define uprint(s) print(s)
32#define uprintln(s) println(s)
33#define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__) \ No newline at end of file
diff --git a/tmk_core/common/avr/bootloader.c b/tmk_core/common/avr/bootloader.c
index a1db55da9..c0272903b 100644
--- a/tmk_core/common/avr/bootloader.c
+++ b/tmk_core/common/avr/bootloader.c
@@ -77,7 +77,7 @@ uint32_t reset_key __attribute__((section(".noinit,\"aw\",@nobits;")));
77 * 77 *
78 * FIXME: needs doc 78 * FIXME: needs doc
79 */ 79 */
80void bootloader_jump(void) { 80__attribute__((weak)) void bootloader_jump(void) {
81#if !defined(BOOTLOADER_SIZE) 81#if !defined(BOOTLOADER_SIZE)
82 uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); 82 uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
83 83
diff --git a/tmk_core/common/avr/pin_defs.h b/tmk_core/common/avr/pin_defs.h
index dbfed21f4..23d948041 100644
--- a/tmk_core/common/avr/pin_defs.h
+++ b/tmk_core/common/avr/pin_defs.h
@@ -29,7 +29,7 @@
29# define PIND_ADDRESS 0x9 29# define PIND_ADDRESS 0x9
30# define PINE_ADDRESS 0xC 30# define PINE_ADDRESS 0xC
31# define PINF_ADDRESS 0xF 31# define PINF_ADDRESS 0xF
32#elif defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) 32#elif defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
33# define ADDRESS_BASE 0x00 33# define ADDRESS_BASE 0x00
34# define PINB_ADDRESS 0x3 34# define PINB_ADDRESS 0x3
35# define PINC_ADDRESS 0x6 35# define PINC_ADDRESS 0x6
@@ -125,4 +125,4 @@
125# define F5 PINDEF(F, 5) 125# define F5 PINDEF(F, 5)
126# define F6 PINDEF(F, 6) 126# define F6 PINDEF(F, 6)
127# define F7 PINDEF(F, 7) 127# define F7 PINDEF(F, 7)
128#endif \ No newline at end of file 128#endif
diff --git a/tmk_core/common/avr/printf.c b/tmk_core/common/avr/printf.c
new file mode 100644
index 000000000..9ad7a3869
--- /dev/null
+++ b/tmk_core/common/avr/printf.c
@@ -0,0 +1,20 @@
1/*
2Copyright 2011 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include "xprintf.h"
18#include "sendchar.h"
19
20void print_set_sendchar(sendchar_func_t func) { xdev_out(func); }
diff --git a/tmk_core/common/avr/printf.mk b/tmk_core/common/avr/printf.mk
new file mode 100644
index 000000000..060ad88c5
--- /dev/null
+++ b/tmk_core/common/avr/printf.mk
@@ -0,0 +1,2 @@
1TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/xprintf.S
2TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c
diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c
index 86c3df040..b784a0835 100644
--- a/tmk_core/common/avr/suspend.c
+++ b/tmk_core/common/avr/suspend.c
@@ -97,13 +97,11 @@ static void power_down(uint8_t wdto) {
97 led_set(leds_off); 97 led_set(leds_off);
98 98
99# ifdef AUDIO_ENABLE 99# ifdef AUDIO_ENABLE
100 // This sometimes disables the start-up noise, so it's been disabled 100 stop_all_notes();
101 // stop_all_notes();
102# endif /* AUDIO_ENABLE */ 101# endif /* AUDIO_ENABLE */
103# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) 102# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
104 rgblight_suspend(); 103 rgblight_suspend();
105# endif 104# endif
106 suspend_power_down_kb();
107 105
108 // TODO: more power saving 106 // TODO: more power saving
109 // See PicoPower application note 107 // See PicoPower application note
@@ -157,6 +155,7 @@ __attribute__((weak)) void suspend_wakeup_init_user(void) {}
157 * FIXME: needs doc 155 * FIXME: needs doc
158 */ 156 */
159__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); } 157__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); }
158
160/** \brief run immediately after wakeup 159/** \brief run immediately after wakeup
161 * 160 *
162 * FIXME: needs doc 161 * FIXME: needs doc
diff --git a/tmk_core/common/chibios/suspend.c b/tmk_core/common/chibios/suspend.c
index 796056019..49e20641f 100644
--- a/tmk_core/common/chibios/suspend.c
+++ b/tmk_core/common/chibios/suspend.c
@@ -12,6 +12,10 @@
12#include "led.h" 12#include "led.h"
13#include "wait.h" 13#include "wait.h"
14 14
15#ifdef AUDIO_ENABLE
16# include "audio.h"
17#endif /* AUDIO_ENABLE */
18
15#ifdef BACKLIGHT_ENABLE 19#ifdef BACKLIGHT_ENABLE
16# include "backlight.h" 20# include "backlight.h"
17#endif 21#endif
@@ -65,6 +69,9 @@ void suspend_power_down(void) {
65#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) 69#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
66 rgblight_suspend(); 70 rgblight_suspend();
67#endif 71#endif
72#ifdef AUDIO_ENABLE
73 stop_all_notes();
74#endif /* AUDIO_ENABLE */
68 75
69 suspend_power_down_kb(); 76 suspend_power_down_kb();
70 // on AVR, this enables the watchdog for 15ms (max), and goes to 77 // on AVR, this enables the watchdog for 15ms (max), and goes to
diff --git a/tmk_core/common/debug.c b/tmk_core/common/debug.c
index bea96dfc1..ea62deaa8 100644
--- a/tmk_core/common/debug.c
+++ b/tmk_core/common/debug.c
@@ -1,24 +1,25 @@
1#include <stdbool.h> 1/*
2#include "debug.h" 2Copyright 2011 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
3 8
4#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include "debug.h"
5 18
6debug_config_t debug_config = { 19debug_config_t debug_config = {
7/* GCC Bug 10676 - Using unnamed fields in initializers 20 .enable = false, //
8 * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10676 */ 21 .matrix = false, //
9#if GCC_VERSION >= 40600 22 .keyboard = false, //
10 .enable = false, 23 .mouse = false, //
11 .matrix = false, 24 .reserved = 0 //
12 .keyboard = false,
13 .mouse = false,
14 .reserved = 0
15#else
16 {
17 false, // .enable
18 false, // .matrix
19 false, // .keyboard
20 false, // .mouse
21 0 // .reserved
22 }
23#endif
24}; 25};
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c
index 7120cdacd..299bda2c1 100644
--- a/tmk_core/common/keyboard.c
+++ b/tmk_core/common/keyboard.c
@@ -23,6 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
23#include "led.h" 23#include "led.h"
24#include "keycode.h" 24#include "keycode.h"
25#include "timer.h" 25#include "timer.h"
26#include "sync_timer.h"
26#include "print.h" 27#include "print.h"
27#include "debug.h" 28#include "debug.h"
28#include "command.h" 29#include "command.h"
@@ -59,9 +60,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
59#ifdef STENO_ENABLE 60#ifdef STENO_ENABLE
60# include "process_steno.h" 61# include "process_steno.h"
61#endif 62#endif
62#ifdef FAUXCLICKY_ENABLE
63# include "fauxclicky.h"
64#endif
65#ifdef SERIAL_LINK_ENABLE 63#ifdef SERIAL_LINK_ENABLE
66# include "serial_link/system/serial_link.h" 64# include "serial_link/system/serial_link.h"
67#endif 65#endif
@@ -96,6 +94,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
96# include "dip_switch.h" 94# include "dip_switch.h"
97#endif 95#endif
98 96
97static uint32_t last_input_modification_time = 0;
98uint32_t last_input_activity_time(void) { return last_input_modification_time; }
99uint32_t last_input_activity_elapsed(void) { return timer_elapsed32(last_input_modification_time); }
100
101static uint32_t last_matrix_modification_time = 0;
102uint32_t last_matrix_activity_time(void) { return last_matrix_modification_time; }
103uint32_t last_matrix_activity_elapsed(void) { return timer_elapsed32(last_matrix_modification_time); }
104void last_matrix_activity_trigger(void) { last_matrix_modification_time = last_input_modification_time = timer_read32(); }
105
106static uint32_t last_encoder_modification_time = 0;
107uint32_t last_encoder_activity_time(void) { return last_encoder_modification_time; }
108uint32_t last_encoder_activity_elapsed(void) { return timer_elapsed32(last_encoder_modification_time); }
109void last_encoder_activity_trigger(void) { last_encoder_modification_time = last_input_modification_time = timer_read32(); }
110
99// Only enable this if console is enabled to print to 111// Only enable this if console is enabled to print to
100#if defined(DEBUG_MATRIX_SCAN_RATE) 112#if defined(DEBUG_MATRIX_SCAN_RATE)
101static uint32_t matrix_timer = 0; 113static uint32_t matrix_timer = 0;
@@ -217,6 +229,7 @@ void keyboard_setup(void) {
217#ifndef NO_JTAG_DISABLE 229#ifndef NO_JTAG_DISABLE
218 disable_jtag(); 230 disable_jtag();
219#endif 231#endif
232 print_set_sendchar(sendchar);
220 matrix_setup(); 233 matrix_setup();
221 keyboard_pre_init_kb(); 234 keyboard_pre_init_kb();
222} 235}
@@ -260,6 +273,7 @@ __attribute__((weak)) void housekeeping_task_user(void) {}
260 */ 273 */
261void keyboard_init(void) { 274void keyboard_init(void) {
262 timer_init(); 275 timer_init();
276 sync_timer_init();
263 matrix_init(); 277 matrix_init();
264#ifdef VIA_ENABLE 278#ifdef VIA_ENABLE
265 via_init(); 279 via_init();
@@ -296,9 +310,6 @@ void keyboard_init(void) {
296#ifdef STENO_ENABLE 310#ifdef STENO_ENABLE
297 steno_init(); 311 steno_init();
298#endif 312#endif
299#ifdef FAUXCLICKY_ENABLE
300 fauxclicky_init();
301#endif
302#ifdef POINTING_DEVICE_ENABLE 313#ifdef POINTING_DEVICE_ENABLE
303 pointing_device_init(); 314 pointing_device_init();
304#endif 315#endif
@@ -337,15 +348,15 @@ void keyboard_task(void) {
337#ifdef QMK_KEYS_PER_SCAN 348#ifdef QMK_KEYS_PER_SCAN
338 uint8_t keys_processed = 0; 349 uint8_t keys_processed = 0;
339#endif 350#endif
351#ifdef ENCODER_ENABLE
352 bool encoders_changed = false;
353#endif
340 354
341 housekeeping_task_kb(); 355 housekeeping_task_kb();
342 housekeeping_task_user(); 356 housekeeping_task_user();
343 357
344#if defined(OLED_DRIVER_ENABLE) && !defined(OLED_DISABLE_TIMEOUT) 358 uint8_t matrix_changed = matrix_scan();
345 uint8_t ret = matrix_scan(); 359 if (matrix_changed) last_matrix_activity_trigger();
346#else
347 matrix_scan();
348#endif
349 360
350 if (should_process_keypress()) { 361 if (should_process_keypress()) {
351 for (uint8_t r = 0; r < MATRIX_ROWS; r++) { 362 for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
@@ -401,7 +412,8 @@ MATRIX_LOOP_END:
401#endif 412#endif
402 413
403#ifdef ENCODER_ENABLE 414#ifdef ENCODER_ENABLE
404 encoder_read(); 415 encoders_changed = encoder_read();
416 if (encoders_changed) last_encoder_activity_trigger();
405#endif 417#endif
406 418
407#ifdef QWIIC_ENABLE 419#ifdef QWIIC_ENABLE
@@ -411,8 +423,12 @@ MATRIX_LOOP_END:
411#ifdef OLED_DRIVER_ENABLE 423#ifdef OLED_DRIVER_ENABLE
412 oled_task(); 424 oled_task();
413# ifndef OLED_DISABLE_TIMEOUT 425# ifndef OLED_DISABLE_TIMEOUT
414 // Wake up oled if user is using those fabulous keys! 426 // Wake up oled if user is using those fabulous keys or spinning those encoders!
415 if (ret) oled_on(); 427# ifdef ENCODER_ENABLE
428 if (matrix_changed || encoders_changed) oled_on();
429# else
430 if (matrix_changed) oled_on();
431# endif
416# endif 432# endif
417#endif 433#endif
418 434
diff --git a/tmk_core/common/keyboard.h b/tmk_core/common/keyboard.h
index 70e8f7e2c..eaf74bac5 100644
--- a/tmk_core/common/keyboard.h
+++ b/tmk_core/common/keyboard.h
@@ -73,6 +73,15 @@ void keyboard_post_init_user(void);
73void housekeeping_task_kb(void); 73void housekeeping_task_kb(void);
74void housekeeping_task_user(void); 74void housekeeping_task_user(void);
75 75
76uint32_t last_input_activity_time(void); // Timestamp of the last matrix or encoder activity
77uint32_t last_input_activity_elapsed(void); // Number of milliseconds since the last matrix or encoder activity
78
79uint32_t last_matrix_activity_time(void); // Timestamp of the last matrix activity
80uint32_t last_matrix_activity_elapsed(void); // Number of milliseconds since the last matrix activity
81
82uint32_t last_encoder_activity_time(void); // Timestamp of the last encoder activity
83uint32_t last_encoder_activity_elapsed(void); // Number of milliseconds since the last encoder activity
84
76uint32_t get_matrix_scan_rate(void); 85uint32_t get_matrix_scan_rate(void);
77 86
78#ifdef __cplusplus 87#ifdef __cplusplus
diff --git a/tmk_core/common/keycode.h b/tmk_core/common/keycode.h
index d35e44d8d..efad92b23 100644
--- a/tmk_core/common/keycode.h
+++ b/tmk_core/common/keycode.h
@@ -39,7 +39,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
39 39
40#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2) 40#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2)
41#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT) 41#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT)
42#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN5) 42#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN8)
43#define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT) 43#define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT)
44#define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2) 44#define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2)
45 45
@@ -205,6 +205,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
205#define KC_BTN3 KC_MS_BTN3 205#define KC_BTN3 KC_MS_BTN3
206#define KC_BTN4 KC_MS_BTN4 206#define KC_BTN4 KC_MS_BTN4
207#define KC_BTN5 KC_MS_BTN5 207#define KC_BTN5 KC_MS_BTN5
208#define KC_BTN6 KC_MS_BTN6
209#define KC_BTN7 KC_MS_BTN7
210#define KC_BTN8 KC_MS_BTN8
208#define KC_WH_U KC_MS_WH_UP 211#define KC_WH_U KC_MS_WH_UP
209#define KC_WH_D KC_MS_WH_DOWN 212#define KC_WH_D KC_MS_WH_DOWN
210#define KC_WH_L KC_MS_WH_LEFT 213#define KC_WH_L KC_MS_WH_LEFT
@@ -521,15 +524,18 @@ enum internal_special_keycodes {
521 524
522enum mouse_keys { 525enum mouse_keys {
523 /* Mouse Buttons */ 526 /* Mouse Buttons */
524 KC_MS_UP = 0xF0, 527 KC_MS_UP = 0xED,
525 KC_MS_DOWN, 528 KC_MS_DOWN,
526 KC_MS_LEFT, 529 KC_MS_LEFT,
527 KC_MS_RIGHT, 530 KC_MS_RIGHT, // 0xF0
528 KC_MS_BTN1, 531 KC_MS_BTN1,
529 KC_MS_BTN2, 532 KC_MS_BTN2,
530 KC_MS_BTN3, 533 KC_MS_BTN3,
531 KC_MS_BTN4, 534 KC_MS_BTN4,
532 KC_MS_BTN5, 535 KC_MS_BTN5,
536 KC_MS_BTN6,
537 KC_MS_BTN7,
538 KC_MS_BTN8,
533 539
534 /* Mouse Wheel */ 540 /* Mouse Wheel */
535 KC_MS_WH_UP, 541 KC_MS_WH_UP,
@@ -540,5 +546,5 @@ enum mouse_keys {
540 /* Acceleration */ 546 /* Acceleration */
541 KC_MS_ACCEL0, 547 KC_MS_ACCEL0,
542 KC_MS_ACCEL1, 548 KC_MS_ACCEL1,
543 KC_MS_ACCEL2 549 KC_MS_ACCEL2 // 0xFF
544}; 550};
diff --git a/tmk_core/common/lib_printf.mk b/tmk_core/common/lib_printf.mk
new file mode 100644
index 000000000..10d2d8468
--- /dev/null
+++ b/tmk_core/common/lib_printf.mk
@@ -0,0 +1,9 @@
1PRINTF_PATH = $(LIB_PATH)/printf
2
3TMK_COMMON_SRC += $(PRINTF_PATH)/printf.c
4TMK_COMMON_SRC += $(COMMON_DIR)/printf.c
5TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_FLOAT
6TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_EXPONENTIAL
7TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_LONG_LONG
8TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_PTRDIFF_T
9VPATH += $(PRINTF_PATH)
diff --git a/tmk_core/common/mousekey.c b/tmk_core/common/mousekey.c
deleted file mode 100644
index ef18bcf1a..000000000
--- a/tmk_core/common/mousekey.c
+++ /dev/null
@@ -1,446 +0,0 @@
1/*
2 * Copyright 2011 Jun Wako <wakojun@gmail.com>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <stdint.h>
19#include "keycode.h"
20#include "host.h"
21#include "timer.h"
22#include "print.h"
23#include "debug.h"
24#include "mousekey.h"
25
26inline int8_t times_inv_sqrt2(int8_t x) {
27 // 181/256 is pretty close to 1/sqrt(2)
28 // 0.70703125 0.707106781
29 // 1 too small for x=99 and x=198
30 // This ends up being a mult and discard lower 8 bits
31 return (x * 181) >> 8;
32}
33
34static report_mouse_t mouse_report = {0};
35static void mousekey_debug(void);
36static uint8_t mousekey_accel = 0;
37static uint8_t mousekey_repeat = 0;
38static uint8_t mousekey_wheel_repeat = 0;
39
40#ifndef MK_3_SPEED
41
42static uint16_t last_timer_c = 0;
43static uint16_t last_timer_w = 0;
44
45/*
46 * Mouse keys acceleration algorithm
47 * http://en.wikipedia.org/wiki/Mouse_keys
48 *
49 * speed = delta * max_speed * (repeat / time_to_max)**((1000+curve)/1000)
50 */
51/* milliseconds between the initial key press and first repeated motion event (0-2550) */
52uint8_t mk_delay = MOUSEKEY_DELAY / 10;
53/* milliseconds between repeated motion events (0-255) */
54uint8_t mk_interval = MOUSEKEY_INTERVAL;
55/* steady speed (in action_delta units) applied each event (0-255) */
56uint8_t mk_max_speed = MOUSEKEY_MAX_SPEED;
57/* number of events (count) accelerating to steady speed (0-255) */
58uint8_t mk_time_to_max = MOUSEKEY_TIME_TO_MAX;
59/* ramp used to reach maximum pointer speed (NOT SUPPORTED) */
60// int8_t mk_curve = 0;
61/* wheel params */
62/* milliseconds between the initial key press and first repeated motion event (0-2550) */
63uint8_t mk_wheel_delay = MOUSEKEY_WHEEL_DELAY / 10;
64/* milliseconds between repeated motion events (0-255) */
65uint8_t mk_wheel_interval = MOUSEKEY_WHEEL_INTERVAL;
66uint8_t mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED;
67uint8_t mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX;
68
69# ifndef MK_COMBINED
70
71static uint8_t move_unit(void) {
72 uint16_t unit;
73 if (mousekey_accel & (1 << 0)) {
74 unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 4;
75 } else if (mousekey_accel & (1 << 1)) {
76 unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 2;
77 } else if (mousekey_accel & (1 << 2)) {
78 unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed);
79 } else if (mousekey_repeat == 0) {
80 unit = MOUSEKEY_MOVE_DELTA;
81 } else if (mousekey_repeat >= mk_time_to_max) {
82 unit = MOUSEKEY_MOVE_DELTA * mk_max_speed;
83 } else {
84 unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed * mousekey_repeat) / mk_time_to_max;
85 }
86 return (unit > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : (unit == 0 ? 1 : unit));
87}
88
89static uint8_t wheel_unit(void) {
90 uint16_t unit;
91 if (mousekey_accel & (1 << 0)) {
92 unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 4;
93 } else if (mousekey_accel & (1 << 1)) {
94 unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 2;
95 } else if (mousekey_accel & (1 << 2)) {
96 unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed);
97 } else if (mousekey_wheel_repeat == 0) {
98 unit = MOUSEKEY_WHEEL_DELTA;
99 } else if (mousekey_wheel_repeat >= mk_wheel_time_to_max) {
100 unit = MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed;
101 } else {
102 unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed * mousekey_wheel_repeat) / mk_wheel_time_to_max;
103 }
104 return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));
105}
106
107# else /* #ifndef MK_COMBINED */
108
109static uint8_t move_unit(void) {
110 uint16_t unit;
111 if (mousekey_accel & (1 << 0)) {
112 unit = 1;
113 } else if (mousekey_accel & (1 << 1)) {
114 unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 2;
115 } else if (mousekey_accel & (1 << 2)) {
116 unit = MOUSEKEY_MOVE_MAX;
117 } else if (mousekey_repeat == 0) {
118 unit = MOUSEKEY_MOVE_DELTA;
119 } else if (mousekey_repeat >= mk_time_to_max) {
120 unit = MOUSEKEY_MOVE_DELTA * mk_max_speed;
121 } else {
122 unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed * mousekey_repeat) / mk_time_to_max;
123 }
124 return (unit > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : (unit == 0 ? 1 : unit));
125}
126
127static uint8_t wheel_unit(void) {
128 uint16_t unit;
129 if (mousekey_accel & (1 << 0)) {
130 unit = 1;
131 } else if (mousekey_accel & (1 << 1)) {
132 unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 2;
133 } else if (mousekey_accel & (1 << 2)) {
134 unit = MOUSEKEY_WHEEL_MAX;
135 } else if (mousekey_repeat == 0) {
136 unit = MOUSEKEY_WHEEL_DELTA;
137 } else if (mousekey_repeat >= mk_wheel_time_to_max) {
138 unit = MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed;
139 } else {
140 unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed * mousekey_repeat) / mk_wheel_time_to_max;
141 }
142 return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));
143}
144
145# endif /* #ifndef MK_COMBINED */
146
147void mousekey_task(void) {
148 // report cursor and scroll movement independently
149 report_mouse_t const tmpmr = mouse_report;
150
151 mouse_report.x = 0;
152 mouse_report.y = 0;
153 mouse_report.v = 0;
154 mouse_report.h = 0;
155
156 if ((tmpmr.x || tmpmr.y) && timer_elapsed(last_timer_c) > (mousekey_repeat ? mk_interval : mk_delay * 10)) {
157 if (mousekey_repeat != UINT8_MAX) mousekey_repeat++;
158 if (tmpmr.x != 0) mouse_report.x = move_unit() * ((tmpmr.x > 0) ? 1 : -1);
159 if (tmpmr.y != 0) mouse_report.y = move_unit() * ((tmpmr.y > 0) ? 1 : -1);
160
161 /* diagonal move [1/sqrt(2)] */
162 if (mouse_report.x && mouse_report.y) {
163 mouse_report.x = times_inv_sqrt2(mouse_report.x);
164 if (mouse_report.x == 0) {
165 mouse_report.x = 1;
166 }
167 mouse_report.y = times_inv_sqrt2(mouse_report.y);
168 if (mouse_report.y == 0) {
169 mouse_report.y = 1;
170 }
171 }
172 }
173 if ((tmpmr.v || tmpmr.h) && timer_elapsed(last_timer_w) > (mousekey_wheel_repeat ? mk_wheel_interval : mk_wheel_delay * 10)) {
174 if (mousekey_wheel_repeat != UINT8_MAX) mousekey_wheel_repeat++;
175 if (tmpmr.v != 0) mouse_report.v = wheel_unit() * ((tmpmr.v > 0) ? 1 : -1);
176 if (tmpmr.h != 0) mouse_report.h = wheel_unit() * ((tmpmr.h > 0) ? 1 : -1);
177
178 /* diagonal move [1/sqrt(2)] */
179 if (mouse_report.v && mouse_report.h) {
180 mouse_report.v = times_inv_sqrt2(mouse_report.v);
181 if (mouse_report.v == 0) {
182 mouse_report.v = 1;
183 }
184 mouse_report.h = times_inv_sqrt2(mouse_report.h);
185 if (mouse_report.h == 0) {
186 mouse_report.h = 1;
187 }
188 }
189 }
190
191 if (mouse_report.x || mouse_report.y || mouse_report.v || mouse_report.h) mousekey_send();
192 mouse_report = tmpmr;
193}
194
195void mousekey_on(uint8_t code) {
196 if (code == KC_MS_UP)
197 mouse_report.y = move_unit() * -1;
198 else if (code == KC_MS_DOWN)
199 mouse_report.y = move_unit();
200 else if (code == KC_MS_LEFT)
201 mouse_report.x = move_unit() * -1;
202 else if (code == KC_MS_RIGHT)
203 mouse_report.x = move_unit();
204 else if (code == KC_MS_WH_UP)
205 mouse_report.v = wheel_unit();
206 else if (code == KC_MS_WH_DOWN)
207 mouse_report.v = wheel_unit() * -1;
208 else if (code == KC_MS_WH_LEFT)
209 mouse_report.h = wheel_unit() * -1;
210 else if (code == KC_MS_WH_RIGHT)
211 mouse_report.h = wheel_unit();
212 else if (code == KC_MS_BTN1)
213 mouse_report.buttons |= MOUSE_BTN1;
214 else if (code == KC_MS_BTN2)
215 mouse_report.buttons |= MOUSE_BTN2;
216 else if (code == KC_MS_BTN3)
217 mouse_report.buttons |= MOUSE_BTN3;
218 else if (code == KC_MS_BTN4)
219 mouse_report.buttons |= MOUSE_BTN4;
220 else if (code == KC_MS_BTN5)
221 mouse_report.buttons |= MOUSE_BTN5;
222 else if (code == KC_MS_ACCEL0)
223 mousekey_accel |= (1 << 0);
224 else if (code == KC_MS_ACCEL1)
225 mousekey_accel |= (1 << 1);
226 else if (code == KC_MS_ACCEL2)
227 mousekey_accel |= (1 << 2);
228}
229
230void mousekey_off(uint8_t code) {
231 if (code == KC_MS_UP && mouse_report.y < 0)
232 mouse_report.y = 0;
233 else if (code == KC_MS_DOWN && mouse_report.y > 0)
234 mouse_report.y = 0;
235 else if (code == KC_MS_LEFT && mouse_report.x < 0)
236 mouse_report.x = 0;
237 else if (code == KC_MS_RIGHT && mouse_report.x > 0)
238 mouse_report.x = 0;
239 else if (code == KC_MS_WH_UP && mouse_report.v > 0)
240 mouse_report.v = 0;
241 else if (code == KC_MS_WH_DOWN && mouse_report.v < 0)
242 mouse_report.v = 0;
243 else if (code == KC_MS_WH_LEFT && mouse_report.h < 0)
244 mouse_report.h = 0;
245 else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0)
246 mouse_report.h = 0;
247 else if (code == KC_MS_BTN1)
248 mouse_report.buttons &= ~MOUSE_BTN1;
249 else if (code == KC_MS_BTN2)
250 mouse_report.buttons &= ~MOUSE_BTN2;
251 else if (code == KC_MS_BTN3)
252 mouse_report.buttons &= ~MOUSE_BTN3;
253 else if (code == KC_MS_BTN4)
254 mouse_report.buttons &= ~MOUSE_BTN4;
255 else if (code == KC_MS_BTN5)
256 mouse_report.buttons &= ~MOUSE_BTN5;
257 else if (code == KC_MS_ACCEL0)
258 mousekey_accel &= ~(1 << 0);
259 else if (code == KC_MS_ACCEL1)
260 mousekey_accel &= ~(1 << 1);
261 else if (code == KC_MS_ACCEL2)
262 mousekey_accel &= ~(1 << 2);
263 if (mouse_report.x == 0 && mouse_report.y == 0) mousekey_repeat = 0;
264 if (mouse_report.v == 0 && mouse_report.h == 0) mousekey_wheel_repeat = 0;
265}
266
267#else /* #ifndef MK_3_SPEED */
268
269enum { mkspd_unmod, mkspd_0, mkspd_1, mkspd_2, mkspd_COUNT };
270# ifndef MK_MOMENTARY_ACCEL
271static uint8_t mk_speed = mkspd_1;
272# else
273static uint8_t mk_speed = mkspd_unmod;
274static uint8_t mkspd_DEFAULT = mkspd_unmod;
275# endif
276static uint16_t last_timer_c = 0;
277static uint16_t last_timer_w = 0;
278uint16_t c_offsets[mkspd_COUNT] = {MK_C_OFFSET_UNMOD, MK_C_OFFSET_0, MK_C_OFFSET_1, MK_C_OFFSET_2};
279uint16_t c_intervals[mkspd_COUNT] = {MK_C_INTERVAL_UNMOD, MK_C_INTERVAL_0, MK_C_INTERVAL_1, MK_C_INTERVAL_2};
280uint16_t w_offsets[mkspd_COUNT] = {MK_W_OFFSET_UNMOD, MK_W_OFFSET_0, MK_W_OFFSET_1, MK_W_OFFSET_2};
281uint16_t w_intervals[mkspd_COUNT] = {MK_W_INTERVAL_UNMOD, MK_W_INTERVAL_0, MK_W_INTERVAL_1, MK_W_INTERVAL_2};
282
283void mousekey_task(void) {
284 // report cursor and scroll movement independently
285 report_mouse_t const tmpmr = mouse_report;
286 mouse_report.x = 0;
287 mouse_report.y = 0;
288 mouse_report.v = 0;
289 mouse_report.h = 0;
290
291 if ((tmpmr.x || tmpmr.y) && timer_elapsed(last_timer_c) > c_intervals[mk_speed]) {
292 mouse_report.x = tmpmr.x;
293 mouse_report.y = tmpmr.y;
294 }
295 if ((tmpmr.h || tmpmr.v) && timer_elapsed(last_timer_w) > w_intervals[mk_speed]) {
296 mouse_report.v = tmpmr.v;
297 mouse_report.h = tmpmr.h;
298 }
299
300 if (mouse_report.x || mouse_report.y || mouse_report.v || mouse_report.h) mousekey_send();
301 mouse_report = tmpmr;
302}
303
304void adjust_speed(void) {
305 uint16_t const c_offset = c_offsets[mk_speed];
306 uint16_t const w_offset = w_offsets[mk_speed];
307 if (mouse_report.x > 0) mouse_report.x = c_offset;
308 if (mouse_report.x < 0) mouse_report.x = c_offset * -1;
309 if (mouse_report.y > 0) mouse_report.y = c_offset;
310 if (mouse_report.y < 0) mouse_report.y = c_offset * -1;
311 if (mouse_report.h > 0) mouse_report.h = w_offset;
312 if (mouse_report.h < 0) mouse_report.h = w_offset * -1;
313 if (mouse_report.v > 0) mouse_report.v = w_offset;
314 if (mouse_report.v < 0) mouse_report.v = w_offset * -1;
315 // adjust for diagonals
316 if (mouse_report.x && mouse_report.y) {
317 mouse_report.x = times_inv_sqrt2(mouse_report.x);
318 if (mouse_report.x == 0) {
319 mouse_report.x = 1;
320 }
321 mouse_report.y = times_inv_sqrt2(mouse_report.y);
322 if (mouse_report.y == 0) {
323 mouse_report.y = 1;
324 }
325 }
326 if (mouse_report.h && mouse_report.v) {
327 mouse_report.h = times_inv_sqrt2(mouse_report.h);
328 mouse_report.v = times_inv_sqrt2(mouse_report.v);
329 }
330}
331
332void mousekey_on(uint8_t code) {
333 uint16_t const c_offset = c_offsets[mk_speed];
334 uint16_t const w_offset = w_offsets[mk_speed];
335 uint8_t const old_speed = mk_speed;
336 if (code == KC_MS_UP)
337 mouse_report.y = c_offset * -1;
338 else if (code == KC_MS_DOWN)
339 mouse_report.y = c_offset;
340 else if (code == KC_MS_LEFT)
341 mouse_report.x = c_offset * -1;
342 else if (code == KC_MS_RIGHT)
343 mouse_report.x = c_offset;
344 else if (code == KC_MS_WH_UP)
345 mouse_report.v = w_offset;
346 else if (code == KC_MS_WH_DOWN)
347 mouse_report.v = w_offset * -1;
348 else if (code == KC_MS_WH_LEFT)
349 mouse_report.h = w_offset * -1;
350 else if (code == KC_MS_WH_RIGHT)
351 mouse_report.h = w_offset;
352 else if (code == KC_MS_BTN1)
353 mouse_report.buttons |= MOUSE_BTN1;
354 else if (code == KC_MS_BTN2)
355 mouse_report.buttons |= MOUSE_BTN2;
356 else if (code == KC_MS_BTN3)
357 mouse_report.buttons |= MOUSE_BTN3;
358 else if (code == KC_MS_BTN4)
359 mouse_report.buttons |= MOUSE_BTN4;
360 else if (code == KC_MS_BTN5)
361 mouse_report.buttons |= MOUSE_BTN5;
362 else if (code == KC_MS_ACCEL0)
363 mk_speed = mkspd_0;
364 else if (code == KC_MS_ACCEL1)
365 mk_speed = mkspd_1;
366 else if (code == KC_MS_ACCEL2)
367 mk_speed = mkspd_2;
368 if (mk_speed != old_speed) adjust_speed();
369}
370
371void mousekey_off(uint8_t code) {
372# ifdef MK_MOMENTARY_ACCEL
373 uint8_t const old_speed = mk_speed;
374# endif
375 if (code == KC_MS_UP && mouse_report.y < 0)
376 mouse_report.y = 0;
377 else if (code == KC_MS_DOWN && mouse_report.y > 0)
378 mouse_report.y = 0;
379 else if (code == KC_MS_LEFT && mouse_report.x < 0)
380 mouse_report.x = 0;
381 else if (code == KC_MS_RIGHT && mouse_report.x > 0)
382 mouse_report.x = 0;
383 else if (code == KC_MS_WH_UP && mouse_report.v > 0)
384 mouse_report.v = 0;
385 else if (code == KC_MS_WH_DOWN && mouse_report.v < 0)
386 mouse_report.v = 0;
387 else if (code == KC_MS_WH_LEFT && mouse_report.h < 0)
388 mouse_report.h = 0;
389 else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0)
390 mouse_report.h = 0;
391 else if (code == KC_MS_BTN1)
392 mouse_report.buttons &= ~MOUSE_BTN1;
393 else if (code == KC_MS_BTN2)
394 mouse_report.buttons &= ~MOUSE_BTN2;
395 else if (code == KC_MS_BTN3)
396 mouse_report.buttons &= ~MOUSE_BTN3;
397 else if (code == KC_MS_BTN4)
398 mouse_report.buttons &= ~MOUSE_BTN4;
399 else if (code == KC_MS_BTN5)
400 mouse_report.buttons &= ~MOUSE_BTN5;
401# ifdef MK_MOMENTARY_ACCEL
402 else if (code == KC_MS_ACCEL0)
403 mk_speed = mkspd_DEFAULT;
404 else if (code == KC_MS_ACCEL1)
405 mk_speed = mkspd_DEFAULT;
406 else if (code == KC_MS_ACCEL2)
407 mk_speed = mkspd_DEFAULT;
408 if (mk_speed != old_speed) adjust_speed();
409# endif
410}
411
412#endif /* #ifndef MK_3_SPEED */
413
414void mousekey_send(void) {
415 mousekey_debug();
416 uint16_t time = timer_read();
417 if (mouse_report.x || mouse_report.y) last_timer_c = time;
418 if (mouse_report.v || mouse_report.h) last_timer_w = time;
419 host_mouse_send(&mouse_report);
420}
421
422void mousekey_clear(void) {
423 mouse_report = (report_mouse_t){};
424 mousekey_repeat = 0;
425 mousekey_wheel_repeat = 0;
426 mousekey_accel = 0;
427}
428
429static void mousekey_debug(void) {
430 if (!debug_mouse) return;
431 print("mousekey [btn|x y v h](rep/acl): [");
432 phex(mouse_report.buttons);
433 print("|");
434 print_decs(mouse_report.x);
435 print(" ");
436 print_decs(mouse_report.y);
437 print(" ");
438 print_decs(mouse_report.v);
439 print(" ");
440 print_decs(mouse_report.h);
441 print("](");
442 print_dec(mousekey_repeat);
443 print("/");
444 print_dec(mousekey_accel);
445 print(")\n");
446}
diff --git a/tmk_core/common/mousekey.h b/tmk_core/common/mousekey.h
deleted file mode 100644
index 300d262f5..000000000
--- a/tmk_core/common/mousekey.h
+++ /dev/null
@@ -1,142 +0,0 @@
1/*
2Copyright 2011 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include <stdbool.h>
21#include "host.h"
22
23#ifndef MK_3_SPEED
24
25/* max value on report descriptor */
26# ifndef MOUSEKEY_MOVE_MAX
27# define MOUSEKEY_MOVE_MAX 127
28# elif MOUSEKEY_MOVE_MAX > 127
29# error MOUSEKEY_MOVE_MAX needs to be smaller than 127
30# endif
31
32# ifndef MOUSEKEY_WHEEL_MAX
33# define MOUSEKEY_WHEEL_MAX 127
34# elif MOUSEKEY_WHEEL_MAX > 127
35# error MOUSEKEY_WHEEL_MAX needs to be smaller than 127
36# endif
37
38# ifndef MOUSEKEY_MOVE_DELTA
39# define MOUSEKEY_MOVE_DELTA 5
40# endif
41# ifndef MOUSEKEY_WHEEL_DELTA
42# define MOUSEKEY_WHEEL_DELTA 1
43# endif
44# ifndef MOUSEKEY_DELAY
45# define MOUSEKEY_DELAY 300
46# endif
47# ifndef MOUSEKEY_INTERVAL
48# define MOUSEKEY_INTERVAL 50
49# endif
50# ifndef MOUSEKEY_MAX_SPEED
51# define MOUSEKEY_MAX_SPEED 10
52# endif
53# ifndef MOUSEKEY_TIME_TO_MAX
54# define MOUSEKEY_TIME_TO_MAX 20
55# endif
56# ifndef MOUSEKEY_WHEEL_DELAY
57# define MOUSEKEY_WHEEL_DELAY 300
58# endif
59# ifndef MOUSEKEY_WHEEL_INTERVAL
60# define MOUSEKEY_WHEEL_INTERVAL 100
61# endif
62# ifndef MOUSEKEY_WHEEL_MAX_SPEED
63# define MOUSEKEY_WHEEL_MAX_SPEED 8
64# endif
65# ifndef MOUSEKEY_WHEEL_TIME_TO_MAX
66# define MOUSEKEY_WHEEL_TIME_TO_MAX 40
67# endif
68
69#else /* #ifndef MK_3_SPEED */
70
71# ifndef MK_C_OFFSET_UNMOD
72# define MK_C_OFFSET_UNMOD 16
73# endif
74# ifndef MK_C_INTERVAL_UNMOD
75# define MK_C_INTERVAL_UNMOD 16
76# endif
77# ifndef MK_C_OFFSET_0
78# define MK_C_OFFSET_0 1
79# endif
80# ifndef MK_C_INTERVAL_0
81# define MK_C_INTERVAL_0 32
82# endif
83# ifndef MK_C_OFFSET_1
84# define MK_C_OFFSET_1 4
85# endif
86# ifndef MK_C_INTERVAL_1
87# define MK_C_INTERVAL_1 16
88# endif
89# ifndef MK_C_OFFSET_2
90# define MK_C_OFFSET_2 32
91# endif
92# ifndef MK_C_INTERVAL_2
93# define MK_C_INTERVAL_2 16
94# endif
95
96# ifndef MK_W_OFFSET_UNMOD
97# define MK_W_OFFSET_UNMOD 1
98# endif
99# ifndef MK_W_INTERVAL_UNMOD
100# define MK_W_INTERVAL_UNMOD 40
101# endif
102# ifndef MK_W_OFFSET_0
103# define MK_W_OFFSET_0 1
104# endif
105# ifndef MK_W_INTERVAL_0
106# define MK_W_INTERVAL_0 360
107# endif
108# ifndef MK_W_OFFSET_1
109# define MK_W_OFFSET_1 1
110# endif
111# ifndef MK_W_INTERVAL_1
112# define MK_W_INTERVAL_1 120
113# endif
114# ifndef MK_W_OFFSET_2
115# define MK_W_OFFSET_2 1
116# endif
117# ifndef MK_W_INTERVAL_2
118# define MK_W_INTERVAL_2 20
119# endif
120
121#endif /* #ifndef MK_3_SPEED */
122
123#ifdef __cplusplus
124extern "C" {
125#endif
126
127extern uint8_t mk_delay;
128extern uint8_t mk_interval;
129extern uint8_t mk_max_speed;
130extern uint8_t mk_time_to_max;
131extern uint8_t mk_wheel_max_speed;
132extern uint8_t mk_wheel_time_to_max;
133
134void mousekey_task(void);
135void mousekey_on(uint8_t code);
136void mousekey_off(uint8_t code);
137void mousekey_clear(void);
138void mousekey_send(void);
139
140#ifdef __cplusplus
141}
142#endif
diff --git a/tmk_core/common/print.h b/tmk_core/common/print.h
index 647a5aa05..48f91e634 100644
--- a/tmk_core/common/print.h
+++ b/tmk_core/common/print.h
@@ -27,104 +27,76 @@
27#include <stdint.h> 27#include <stdint.h>
28#include <stdbool.h> 28#include <stdbool.h>
29#include "util.h" 29#include "util.h"
30#include "sendchar.h"
31#include "progmem.h"
30 32
31#if defined(PROTOCOL_CHIBIOS) || defined(PROTOCOL_ARM_ATSAM) 33void print_set_sendchar(sendchar_func_t func);
32# define PSTR(x) x
33#endif
34 34
35#ifndef NO_PRINT 35#ifndef NO_PRINT
36 36# if __has_include_next("_print.h")
37# if defined(__AVR__) /* __AVR__ */ 37# include_next "_print.h" /* Include the platforms print.h */
38 38# else
39# include "avr/xprintf.h" 39// Fall back to lib/printf
40
41# ifdef USER_PRINT /* USER_PRINT */
42
43// Remove normal print defines
44# define print(s)
45# define println(s)
46# undef xprintf
47# define xprintf(fmt, ...)
48
49// Create user print defines
50# define uprint(s) xputs(PSTR(s))
51# define uprintln(s) xputs(PSTR(s "\r\n"))
52# define uprintf(fmt, ...) __xprintf(PSTR(fmt), ##__VA_ARGS__)
53
54# else /* NORMAL PRINT */
55
56// Create user & normal print defines
57# define print(s) xputs(PSTR(s))
58# define println(s) xputs(PSTR(s "\r\n"))
59# define uprint(s) print(s)
60# define uprintln(s) println(s)
61# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
62
63# endif /* USER_PRINT / NORMAL PRINT */
64
65# ifdef __cplusplus
66extern "C"
67# endif
68
69 /* function pointer of sendchar to be used by print utility */
70 void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
71
72# elif defined(PROTOCOL_CHIBIOS) /* PROTOCOL_CHIBIOS */
73
74# include "printf.h" // lib/printf/printf.h 40# include "printf.h" // lib/printf/printf.h
75 41
76# ifdef USER_PRINT /* USER_PRINT */
77
78// Remove normal print defines
79# define print(s)
80# define println(s)
81# define xprintf(fmt, ...)
82
83// Create user print defines
84# define uprint(s) printf(s)
85# define uprintln(s) printf(s "\r\n")
86# define uprintf printf
87
88# else /* NORMAL PRINT */
89// Create user & normal print defines 42// Create user & normal print defines
90# define print(s) printf(s) 43# define print(s) printf(s)
91# define println(s) printf(s "\r\n") 44# define println(s) printf(s "\r\n")
92# define xprintf printf 45# define xprintf printf
93# define uprint(s) printf(s) 46# define uprint(s) printf(s)
94# define uprintln(s) printf(s "\r\n") 47# define uprintln(s) printf(s "\r\n")
95# define uprintf printf 48# define uprintf printf
96 49
97# endif /* USER_PRINT / NORMAL PRINT */ 50# endif /* __AVR__ / PROTOCOL_CHIBIOS / PROTOCOL_ARM_ATSAM */
98 51#else /* NO_PRINT */
99# elif defined(PROTOCOL_ARM_ATSAM) /* PROTOCOL_ARM_ATSAM */ 52# undef xprintf
100 53// Remove print defines
101# include "arm_atsam/printf.h" 54# define print(s)
55# define println(s)
56# define xprintf(fmt, ...)
57# define uprintf(fmt, ...)
58# define uprint(s)
59# define uprintln(s)
102 60
103# ifdef USER_PRINT /* USER_PRINT */ 61#endif /* NO_PRINT */
104 62
63#ifdef USER_PRINT
105// Remove normal print defines 64// Remove normal print defines
106# define print(s) 65# undef print
107# define println(s) 66# undef println
108# define xprintf(fmt, ...) 67# undef xprintf
109 68# define print(s)
110// Create user print defines 69# define println(s)
111# define uprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__) 70# define xprintf(fmt, ...)
112# define uprint(s) xprintf(s) 71#endif
113# define uprintln(s) xprintf(s "\r\n")
114
115# else /* NORMAL PRINT */
116
117// Create user & normal print defines
118# define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
119# define print(s) xprintf(s)
120# define println(s) xprintf(s "\r\n")
121# define uprint(s) print(s)
122# define uprintln(s) println(s)
123# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
124
125# endif /* USER_PRINT / NORMAL PRINT */
126 72
127# endif /* __AVR__ / PROTOCOL_CHIBIOS / PROTOCOL_ARM_ATSAM */ 73#define print_dec(i) xprintf("%u", i)
74#define print_decs(i) xprintf("%d", i)
75/* hex */
76#define print_hex4(i) xprintf("%X", i)
77#define print_hex8(i) xprintf("%02X", i)
78#define print_hex16(i) xprintf("%04X", i)
79#define print_hex32(i) xprintf("%08lX", i)
80/* binary */
81#define print_bin4(i) xprintf("%04b", i)
82#define print_bin8(i) xprintf("%08b", i)
83#define print_bin16(i) xprintf("%016b", i)
84#define print_bin32(i) xprintf("%032lb", i)
85#define print_bin_reverse8(i) xprintf("%08b", bitrev(i))
86#define print_bin_reverse16(i) xprintf("%016b", bitrev16(i))
87#define print_bin_reverse32(i) xprintf("%032lb", bitrev32(i))
88/* print value utility */
89#define print_val_dec(v) xprintf(#v ": %u\n", v)
90#define print_val_decs(v) xprintf(#v ": %d\n", v)
91#define print_val_hex8(v) xprintf(#v ": %X\n", v)
92#define print_val_hex16(v) xprintf(#v ": %02X\n", v)
93#define print_val_hex32(v) xprintf(#v ": %04lX\n", v)
94#define print_val_bin8(v) xprintf(#v ": %08b\n", v)
95#define print_val_bin16(v) xprintf(#v ": %016b\n", v)
96#define print_val_bin32(v) xprintf(#v ": %032lb\n", v)
97#define print_val_bin_reverse8(v) xprintf(#v ": %08b\n", bitrev(v))
98#define print_val_bin_reverse16(v) xprintf(#v ": %016b\n", bitrev16(v))
99#define print_val_bin_reverse32(v) xprintf(#v ": %032lb\n", bitrev32(v))
128 100
129// User print disables the normal print messages in the body of QMK/TMK code and 101// User print disables the normal print messages in the body of QMK/TMK code and
130// is meant as a lightweight alternative to NOPRINT. Use it when you only want to do 102// is meant as a lightweight alternative to NOPRINT. Use it when you only want to do
@@ -132,139 +104,32 @@ extern "C"
132// print (and store their wasteful strings). 104// print (and store their wasteful strings).
133// 105//
134// !!! DO NOT USE USER PRINT CALLS IN THE BODY OF QMK/TMK !!! 106// !!! DO NOT USE USER PRINT CALLS IN THE BODY OF QMK/TMK !!!
135//
136# ifdef USER_PRINT
137
138// Disable normal print
139# define print_dec(data)
140# define print_decs(data)
141# define print_hex4(data)
142# define print_hex8(data)
143# define print_hex16(data)
144# define print_hex32(data)
145# define print_bin4(data)
146# define print_bin8(data)
147# define print_bin16(data)
148# define print_bin32(data)
149# define print_bin_reverse8(data)
150# define print_bin_reverse16(data)
151# define print_bin_reverse32(data)
152# define print_val_dec(v)
153# define print_val_decs(v)
154# define print_val_hex8(v)
155# define print_val_hex16(v)
156# define print_val_hex32(v)
157# define print_val_bin8(v)
158# define print_val_bin16(v)
159# define print_val_bin32(v)
160# define print_val_bin_reverse8(v)
161# define print_val_bin_reverse16(v)
162# define print_val_bin_reverse32(v)
163
164# else /* NORMAL_PRINT */
165
166// Enable normal print
167/* decimal */
168# define print_dec(i) xprintf("%u", i)
169# define print_decs(i) xprintf("%d", i)
170/* hex */
171# define print_hex4(i) xprintf("%X", i)
172# define print_hex8(i) xprintf("%02X", i)
173# define print_hex16(i) xprintf("%04X", i)
174# define print_hex32(i) xprintf("%08lX", i)
175/* binary */
176# define print_bin4(i) xprintf("%04b", i)
177# define print_bin8(i) xprintf("%08b", i)
178# define print_bin16(i) xprintf("%016b", i)
179# define print_bin32(i) xprintf("%032lb", i)
180# define print_bin_reverse8(i) xprintf("%08b", bitrev(i))
181# define print_bin_reverse16(i) xprintf("%016b", bitrev16(i))
182# define print_bin_reverse32(i) xprintf("%032lb", bitrev32(i))
183/* print value utility */
184# define print_val_dec(v) xprintf(# v ": %u\n", v)
185# define print_val_decs(v) xprintf(# v ": %d\n", v)
186# define print_val_hex8(v) xprintf(# v ": %X\n", v)
187# define print_val_hex16(v) xprintf(# v ": %02X\n", v)
188# define print_val_hex32(v) xprintf(# v ": %04lX\n", v)
189# define print_val_bin8(v) xprintf(# v ": %08b\n", v)
190# define print_val_bin16(v) xprintf(# v ": %016b\n", v)
191# define print_val_bin32(v) xprintf(# v ": %032lb\n", v)
192# define print_val_bin_reverse8(v) xprintf(# v ": %08b\n", bitrev(v))
193# define print_val_bin_reverse16(v) xprintf(# v ": %016b\n", bitrev16(v))
194# define print_val_bin_reverse32(v) xprintf(# v ": %032lb\n", bitrev32(v))
195
196# endif /* USER_PRINT / NORMAL_PRINT */
197
198// User Print
199 107
200/* decimal */ 108/* decimal */
201# define uprint_dec(i) uprintf("%u", i) 109#define uprint_dec(i) uprintf("%u", i)
202# define uprint_decs(i) uprintf("%d", i) 110#define uprint_decs(i) uprintf("%d", i)
203/* hex */ 111/* hex */
204# define uprint_hex4(i) uprintf("%X", i) 112#define uprint_hex4(i) uprintf("%X", i)
205# define uprint_hex8(i) uprintf("%02X", i) 113#define uprint_hex8(i) uprintf("%02X", i)
206# define uprint_hex16(i) uprintf("%04X", i) 114#define uprint_hex16(i) uprintf("%04X", i)
207# define uprint_hex32(i) uprintf("%08lX", i) 115#define uprint_hex32(i) uprintf("%08lX", i)
208/* binary */ 116/* binary */
209# define uprint_bin4(i) uprintf("%04b", i) 117#define uprint_bin4(i) uprintf("%04b", i)
210# define uprint_bin8(i) uprintf("%08b", i) 118#define uprint_bin8(i) uprintf("%08b", i)
211# define uprint_bin16(i) uprintf("%016b", i) 119#define uprint_bin16(i) uprintf("%016b", i)
212# define uprint_bin32(i) uprintf("%032lb", i) 120#define uprint_bin32(i) uprintf("%032lb", i)
213# define uprint_bin_reverse8(i) uprintf("%08b", bitrev(i)) 121#define uprint_bin_reverse8(i) uprintf("%08b", bitrev(i))
214# define uprint_bin_reverse16(i) uprintf("%016b", bitrev16(i)) 122#define uprint_bin_reverse16(i) uprintf("%016b", bitrev16(i))
215# define uprint_bin_reverse32(i) uprintf("%032lb", bitrev32(i)) 123#define uprint_bin_reverse32(i) uprintf("%032lb", bitrev32(i))
216/* print value utility */ 124/* print value utility */
217# define uprint_val_dec(v) uprintf(# v ": %u\n", v) 125#define uprint_val_dec(v) uprintf(#v ": %u\n", v)
218# define uprint_val_decs(v) uprintf(# v ": %d\n", v) 126#define uprint_val_decs(v) uprintf(#v ": %d\n", v)
219# define uprint_val_hex8(v) uprintf(# v ": %X\n", v) 127#define uprint_val_hex8(v) uprintf(#v ": %X\n", v)
220# define uprint_val_hex16(v) uprintf(# v ": %02X\n", v) 128#define uprint_val_hex16(v) uprintf(#v ": %02X\n", v)
221# define uprint_val_hex32(v) uprintf(# v ": %04lX\n", v) 129#define uprint_val_hex32(v) uprintf(#v ": %04lX\n", v)
222# define uprint_val_bin8(v) uprintf(# v ": %08b\n", v) 130#define uprint_val_bin8(v) uprintf(#v ": %08b\n", v)
223# define uprint_val_bin16(v) uprintf(# v ": %016b\n", v) 131#define uprint_val_bin16(v) uprintf(#v ": %016b\n", v)
224# define uprint_val_bin32(v) uprintf(# v ": %032lb\n", v) 132#define uprint_val_bin32(v) uprintf(#v ": %032lb\n", v)
225# define uprint_val_bin_reverse8(v) uprintf(# v ": %08b\n", bitrev(v)) 133#define uprint_val_bin_reverse8(v) uprintf(#v ": %08b\n", bitrev(v))
226# define uprint_val_bin_reverse16(v) uprintf(# v ": %016b\n", bitrev16(v)) 134#define uprint_val_bin_reverse16(v) uprintf(#v ": %016b\n", bitrev16(v))
227# define uprint_val_bin_reverse32(v) uprintf(# v ": %032lb\n", bitrev32(v)) 135#define uprint_val_bin_reverse32(v) uprintf(#v ": %032lb\n", bitrev32(v))
228
229#else /* NO_PRINT */
230
231# define xprintf(fmt, ...)
232# define print(s)
233# define println(s)
234# define print_set_sendchar(func)
235# define print_dec(data)
236# define print_decs(data)
237# define print_hex4(data)
238# define print_hex8(data)
239# define print_hex16(data)
240# define print_hex32(data)
241# define print_bin4(data)
242# define print_bin8(data)
243# define print_bin16(data)
244# define print_bin32(data)
245# define print_bin_reverse8(data)
246# define print_bin_reverse16(data)
247# define print_bin_reverse32(data)
248# define print_val_dec(v)
249# define print_val_decs(v)
250# define print_val_hex8(v)
251# define print_val_hex16(v)
252# define print_val_hex32(v)
253# define print_val_bin8(v)
254# define print_val_bin16(v)
255# define print_val_bin32(v)
256# define print_val_bin_reverse8(v)
257# define print_val_bin_reverse16(v)
258# define print_val_bin_reverse32(v)
259
260#endif /* NO_PRINT */
261
262/* Backward compatiblitly for old name */
263#define pdec(data) print_dec(data)
264#define pdec16(data) print_dec(data)
265#define phex(data) print_hex8(data)
266#define phex16(data) print_hex16(data)
267#define pbin(data) print_bin8(data)
268#define pbin16(data) print_bin16(data)
269#define pbin_reverse(data) print_bin_reverse8(data)
270#define pbin_reverse16(data) print_bin_reverse16(data)
diff --git a/tmk_core/common/printf.c b/tmk_core/common/printf.c
new file mode 100644
index 000000000..e8440e55e
--- /dev/null
+++ b/tmk_core/common/printf.c
@@ -0,0 +1,27 @@
1/*
2Copyright 2011 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include <stddef.h>
18#include "sendchar.h"
19
20// bind lib/printf to console interface - sendchar
21
22static int8_t null_sendchar_func(uint8_t c) { return 0; }
23static sendchar_func_t func = null_sendchar_func;
24
25void print_set_sendchar(sendchar_func_t send) { func = send; }
26
27void _putchar(char character) { func(character); }
diff --git a/tmk_core/common/progmem.h b/tmk_core/common/progmem.h
index c8863d3ad..4e4771e52 100644
--- a/tmk_core/common/progmem.h
+++ b/tmk_core/common/progmem.h
@@ -4,6 +4,7 @@
4# include <avr/pgmspace.h> 4# include <avr/pgmspace.h>
5#else 5#else
6# define PROGMEM 6# define PROGMEM
7# define PSTR(x) x
7# define PGM_P const char* 8# define PGM_P const char*
8# define memcpy_P(dest, src, n) memcpy(dest, src, n) 9# define memcpy_P(dest, src, n) memcpy(dest, src, n)
9# define pgm_read_byte(address_short) *((uint8_t*)(address_short)) 10# define pgm_read_byte(address_short) *((uint8_t*)(address_short))
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index 5d7c5b3b2..bcf5cab38 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -39,7 +39,10 @@ enum mouse_buttons {
39 MOUSE_BTN2 = (1 << 1), 39 MOUSE_BTN2 = (1 << 1),
40 MOUSE_BTN3 = (1 << 2), 40 MOUSE_BTN3 = (1 << 2),
41 MOUSE_BTN4 = (1 << 3), 41 MOUSE_BTN4 = (1 << 3),
42 MOUSE_BTN5 = (1 << 4) 42 MOUSE_BTN5 = (1 << 4),
43 MOUSE_BTN6 = (1 << 5),
44 MOUSE_BTN7 = (1 << 6),
45 MOUSE_BTN8 = (1 << 7)
43}; 46};
44 47
45/* Consumer Page (0x0C) 48/* Consumer Page (0x0C)
diff --git a/tmk_core/common/sendchar.h b/tmk_core/common/sendchar.h
index b150dd464..edcddaa6b 100644
--- a/tmk_core/common/sendchar.h
+++ b/tmk_core/common/sendchar.h
@@ -23,6 +23,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
23extern "C" { 23extern "C" {
24#endif 24#endif
25 25
26typedef int8_t (*sendchar_func_t)(uint8_t c);
27
26/* transmit a character. return 0 on success, -1 on error. */ 28/* transmit a character. return 0 on success, -1 on error. */
27int8_t sendchar(uint8_t c); 29int8_t sendchar(uint8_t c);
28 30
diff --git a/tmk_core/common/suspend.h b/tmk_core/common/suspend.h
index 766df95aa..9d17d984e 100644
--- a/tmk_core/common/suspend.h
+++ b/tmk_core/common/suspend.h
@@ -12,3 +12,7 @@ void suspend_wakeup_init_user(void);
12void suspend_wakeup_init_kb(void); 12void suspend_wakeup_init_kb(void);
13void suspend_power_down_user(void); 13void suspend_power_down_user(void);
14void suspend_power_down_kb(void); 14void suspend_power_down_kb(void);
15
16#ifndef USB_SUSPEND_WAKEUP_DELAY
17# define USB_SUSPEND_WAKEUP_DELAY 200
18#endif
diff --git a/tmk_core/common/sync_timer.c b/tmk_core/common/sync_timer.c
new file mode 100644
index 000000000..de24b463b
--- /dev/null
+++ b/tmk_core/common/sync_timer.c
@@ -0,0 +1,58 @@
1/*
2Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2>
3
4Permission is hereby granted, free of charge, to any person obtaining a copy of
5this software and associated documentation files (the "Software"), to deal in
6the Software without restriction, including without limitation the rights to
7use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8of the Software, and to permit persons to whom the Software is furnished to do
9so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all
12copies or substantial portions of the Software.
13
14If you happen to meet one of the copyright holders in a bar you are obligated
15to buy them one pint of beer.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24*/
25
26#include "sync_timer.h"
27#include "keyboard.h"
28
29#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)
30volatile int32_t sync_timer_ms;
31
32void sync_timer_init(void) { sync_timer_ms = 0; }
33
34void sync_timer_update(uint32_t time) {
35 if (is_keyboard_master()) return;
36 sync_timer_ms = time - timer_read32();
37}
38
39uint16_t sync_timer_read(void) {
40 if (is_keyboard_master()) return timer_read();
41 return sync_timer_read32();
42}
43
44uint32_t sync_timer_read32(void) {
45 if (is_keyboard_master()) return timer_read32();
46 return sync_timer_ms + timer_read32();
47}
48
49uint16_t sync_timer_elapsed(uint16_t last) {
50 if (is_keyboard_master()) return timer_elapsed(last);
51 return TIMER_DIFF_16(sync_timer_read(), last);
52}
53
54uint32_t sync_timer_elapsed32(uint32_t last) {
55 if (is_keyboard_master()) return timer_elapsed32(last);
56 return TIMER_DIFF_32(sync_timer_read32(), last);
57}
58#endif
diff --git a/tmk_core/common/sync_timer.h b/tmk_core/common/sync_timer.h
new file mode 100644
index 000000000..9ddef45bb
--- /dev/null
+++ b/tmk_core/common/sync_timer.h
@@ -0,0 +1,54 @@
1/*
2Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2>
3
4Permission is hereby granted, free of charge, to any person obtaining a copy of
5this software and associated documentation files (the "Software"), to deal in
6the Software without restriction, including without limitation the rights to
7use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8of the Software, and to permit persons to whom the Software is furnished to do
9so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all
12copies or substantial portions of the Software.
13
14If you happen to meet one of the copyright holders in a bar you are obligated
15to buy them one pint of beer.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24*/
25
26#pragma once
27
28#include <stdint.h>
29#include "timer.h"
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)
36void sync_timer_init(void);
37void sync_timer_update(uint32_t time);
38uint16_t sync_timer_read(void);
39uint32_t sync_timer_read32(void);
40uint16_t sync_timer_elapsed(uint16_t last);
41uint32_t sync_timer_elapsed32(uint32_t last);
42#else
43# define sync_timer_init()
44# define sync_timer_clear()
45# define sync_timer_update(t)
46# define sync_timer_read() timer_read()
47# define sync_timer_read32() timer_read32()
48# define sync_timer_elapsed(t) timer_elapsed(t)
49# define sync_timer_elapsed32(t) timer_elapsed32(t)
50#endif
51
52#ifdef __cplusplus
53}
54#endif
diff --git a/tmk_core/common/uart.c b/tmk_core/common/uart.c
deleted file mode 100644
index 150e256c8..000000000
--- a/tmk_core/common/uart.c
+++ /dev/null
@@ -1,172 +0,0 @@
1// TODO: Teensy support(ATMega32u4/AT90USB128)
2// Fixed for Arduino Duemilanove ATmega168p by Jun Wako
3/* UART Example for Teensy USB Development Board
4 * http://www.pjrc.com/teensy/
5 * Copyright (c) 2009 PJRC.COM, LLC
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
26// Version 1.0: Initial Release
27// Version 1.1: Add support for Teensy 2.0, minor optimizations
28
29#include <avr/io.h>
30#include <avr/interrupt.h>
31
32#include "uart.h"
33
34#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
35# define UDRn UDR0
36# define UBRRnL UBRR0L
37# define UCSRnA UCSR0A
38# define UCSRnB UCSR0B
39# define UCSRnC UCSR0C
40# define U2Xn U2X0
41# define RXENn RXEN0
42# define TXENn TXEN0
43# define RXCIEn RXCIE0
44# define UCSZn1 UCSZ01
45# define UCSZn0 UCSZ00
46# define UDRIEn UDRIE0
47# define USARTn_UDRE_vect USART_UDRE_vect
48# define USARTn_RX_vect USART_RX_vect
49#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
50# define UDRn UDR1
51# define UBRRnL UBRR1L
52# define UCSRnA UCSR1A
53# define UCSRnB UCSR1B
54# define UCSRnC UCSR1C
55# define U2Xn U2X1
56# define RXENn RXEN1
57# define TXENn TXEN1
58# define RXCIEn RXCIE1
59# define UCSZn1 UCSZ11
60# define UCSZn0 UCSZ10
61# define UDRIEn UDRIE1
62# define USARTn_UDRE_vect USART1_UDRE_vect
63# define USARTn_RX_vect USART1_RX_vect
64#elif defined(__AVR_ATmega32A__)
65# define UDRn UDR
66# define UBRRnL UBRRL
67# define UCSRnA UCSRA
68# define UCSRnB UCSRB
69# define UCSRnC UCSRC
70# define U2Xn U2X
71# define RXENn RXEN
72# define TXENn TXEN
73# define RXCIEn RXCIE
74# define UCSZn1 UCSZ1
75# define UCSZn0 UCSZ0
76# define UDRIEn UDRIE
77# define USARTn_UDRE_vect USART_UDRE_vect
78# define USARTn_RX_vect USART_RX_vect
79#endif
80
81// These buffers may be any size from 2 to 256 bytes.
82#define RX_BUFFER_SIZE 64
83#define TX_BUFFER_SIZE 256
84
85static volatile uint8_t tx_buffer[TX_BUFFER_SIZE];
86static volatile uint8_t tx_buffer_head;
87static volatile uint8_t tx_buffer_tail;
88static volatile uint8_t rx_buffer[RX_BUFFER_SIZE];
89static volatile uint8_t rx_buffer_head;
90static volatile uint8_t rx_buffer_tail;
91
92// Initialize the UART
93void uart_init(uint32_t baud) {
94 cli();
95 UBRRnL = (F_CPU / 4 / baud - 1) / 2;
96 UCSRnA = (1 << U2Xn);
97 UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn);
98 UCSRnC = (1 << UCSZn1) | (1 << UCSZn0);
99 tx_buffer_head = tx_buffer_tail = 0;
100 rx_buffer_head = rx_buffer_tail = 0;
101 sei();
102}
103
104// Transmit a byte
105void uart_putchar(uint8_t c) {
106 uint8_t i;
107
108 i = tx_buffer_head + 1;
109 if (i >= TX_BUFFER_SIZE) i = 0;
110 // return immediately to avoid deadlock when interrupt is disabled(called from ISR)
111 if (tx_buffer_tail == i && (SREG & (1 << SREG_I)) == 0) return;
112 while (tx_buffer_tail == i)
113 ; // wait until space in buffer
114 // cli();
115 tx_buffer[i] = c;
116 tx_buffer_head = i;
117 UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn) | (1 << UDRIEn);
118 // sei();
119}
120
121// Receive a byte
122uint8_t uart_getchar(void) {
123 uint8_t c, i;
124
125 while (rx_buffer_head == rx_buffer_tail)
126 ; // wait for character
127 i = rx_buffer_tail + 1;
128 if (i >= RX_BUFFER_SIZE) i = 0;
129 c = rx_buffer[i];
130 rx_buffer_tail = i;
131 return c;
132}
133
134// Return the number of bytes waiting in the receive buffer.
135// Call this before uart_getchar() to check if it will need
136// to wait for a byte to arrive.
137uint8_t uart_available(void) {
138 uint8_t head, tail;
139
140 head = rx_buffer_head;
141 tail = rx_buffer_tail;
142 if (head >= tail) return head - tail;
143 return RX_BUFFER_SIZE + head - tail;
144}
145
146// Transmit Interrupt
147ISR(USARTn_UDRE_vect) {
148 uint8_t i;
149
150 if (tx_buffer_head == tx_buffer_tail) {
151 // buffer is empty, disable transmit interrupt
152 UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn);
153 } else {
154 i = tx_buffer_tail + 1;
155 if (i >= TX_BUFFER_SIZE) i = 0;
156 UDRn = tx_buffer[i];
157 tx_buffer_tail = i;
158 }
159}
160
161// Receive Interrupt
162ISR(USARTn_RX_vect) {
163 uint8_t c, i;
164
165 c = UDRn;
166 i = rx_buffer_head + 1;
167 if (i >= RX_BUFFER_SIZE) i = 0;
168 if (i != rx_buffer_tail) {
169 rx_buffer[i] = c;
170 rx_buffer_head = i;
171 }
172}
diff --git a/tmk_core/common/uart.h b/tmk_core/common/uart.h
deleted file mode 100644
index ea247b17b..000000000
--- a/tmk_core/common/uart.h
+++ /dev/null
@@ -1,8 +0,0 @@
1#pragma once
2
3#include <stdint.h>
4
5void uart_init(uint32_t baud);
6void uart_putchar(uint8_t c);
7uint8_t uart_getchar(void);
8uint8_t uart_available(void);
diff --git a/tmk_core/common/wait.h b/tmk_core/common/wait.h
index 89128e9da..28224fe3a 100644
--- a/tmk_core/common/wait.h
+++ b/tmk_core/common/wait.h
@@ -6,10 +6,89 @@
6extern "C" { 6extern "C" {
7#endif 7#endif
8 8
9#if defined(__ARMEL__) || defined(__ARMEB__)
10# ifndef __OPTIMIZE__
11# pragma message "Compiler optimizations disabled; wait_cpuclock() won't work as designed"
12# endif
13
14# define wait_cpuclock(x) wait_cpuclock_allnop(x)
15
16# define CLOCK_DELAY_NOP8 "nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t"
17
18__attribute__((always_inline)) static inline void wait_cpuclock_allnop(unsigned int n) { /* n: 1..135 */
19 /* The argument n must be a constant expression.
20 * That way, compiler optimization will remove unnecessary code. */
21 if (n < 1) {
22 return;
23 }
24 if (n > 8) {
25 unsigned int n8 = n / 8;
26 n = n - n8 * 8;
27 switch (n8) {
28 case 16:
29 asm volatile(CLOCK_DELAY_NOP8::: "memory");
30 case 15:
31 asm volatile(CLOCK_DELAY_NOP8::: "memory");
32 case 14:
33 asm volatile(CLOCK_DELAY_NOP8::: "memory");
34 case 13:
35 asm volatile(CLOCK_DELAY_NOP8::: "memory");
36 case 12:
37 asm volatile(CLOCK_DELAY_NOP8::: "memory");
38 case 11:
39 asm volatile(CLOCK_DELAY_NOP8::: "memory");
40 case 10:
41 asm volatile(CLOCK_DELAY_NOP8::: "memory");
42 case 9:
43 asm volatile(CLOCK_DELAY_NOP8::: "memory");
44 case 8:
45 asm volatile(CLOCK_DELAY_NOP8::: "memory");
46 case 7:
47 asm volatile(CLOCK_DELAY_NOP8::: "memory");
48 case 6:
49 asm volatile(CLOCK_DELAY_NOP8::: "memory");
50 case 5:
51 asm volatile(CLOCK_DELAY_NOP8::: "memory");
52 case 4:
53 asm volatile(CLOCK_DELAY_NOP8::: "memory");
54 case 3:
55 asm volatile(CLOCK_DELAY_NOP8::: "memory");
56 case 2:
57 asm volatile(CLOCK_DELAY_NOP8::: "memory");
58 case 1:
59 asm volatile(CLOCK_DELAY_NOP8::: "memory");
60 case 0:
61 break;
62 }
63 }
64 switch (n) {
65 case 8:
66 asm volatile("nop" ::: "memory");
67 case 7:
68 asm volatile("nop" ::: "memory");
69 case 6:
70 asm volatile("nop" ::: "memory");
71 case 5:
72 asm volatile("nop" ::: "memory");
73 case 4:
74 asm volatile("nop" ::: "memory");
75 case 3:
76 asm volatile("nop" ::: "memory");
77 case 2:
78 asm volatile("nop" ::: "memory");
79 case 1:
80 asm volatile("nop" ::: "memory");
81 case 0:
82 break;
83 }
84}
85#endif
86
9#if defined(__AVR__) 87#if defined(__AVR__)
10# include <util/delay.h> 88# include <util/delay.h>
11# define wait_ms(ms) _delay_ms(ms) 89# define wait_ms(ms) _delay_ms(ms)
12# define wait_us(us) _delay_us(us) 90# define wait_us(us) _delay_us(us)
91# define wait_cpuclock(x) __builtin_avr_delay_cycles(x)
13#elif defined PROTOCOL_CHIBIOS 92#elif defined PROTOCOL_CHIBIOS
14# include <ch.h> 93# include <ch.h>
15# define wait_ms(ms) \ 94# define wait_ms(ms) \
diff --git a/tmk_core/protocol/adb.c b/tmk_core/protocol/adb.c
index a23c91961..367f1b09f 100644
--- a/tmk_core/protocol/adb.c
+++ b/tmk_core/protocol/adb.c
@@ -1,5 +1,5 @@
1/* 1/*
2Copyright 2011 Jun WAKO <wakojun@gmail.com> 2Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
3Copyright 2013 Shay Green <gblargg@gmail.com> 3Copyright 2013 Shay Green <gblargg@gmail.com>
4 4
5This software is licensed with a Modified BSD License. 5This software is licensed with a Modified BSD License.
@@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
41#include <avr/io.h> 41#include <avr/io.h>
42#include <avr/interrupt.h> 42#include <avr/interrupt.h>
43#include "adb.h" 43#include "adb.h"
44#include "print.h"
44 45
45// GCC doesn't inline functions normally 46// GCC doesn't inline functions normally
46#define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT)) 47#define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT))
@@ -59,7 +60,6 @@ static inline void place_bit1(void);
59static inline void send_byte(uint8_t data); 60static inline void send_byte(uint8_t data);
60static inline uint16_t wait_data_lo(uint16_t us); 61static inline uint16_t wait_data_lo(uint16_t us);
61static inline uint16_t wait_data_hi(uint16_t us); 62static inline uint16_t wait_data_hi(uint16_t us);
62static inline uint16_t adb_host_dev_recv(uint8_t device);
63 63
64void adb_host_init(void) { 64void adb_host_init(void) {
65 ADB_PORT &= ~(1 << ADB_DATA_BIT); 65 ADB_PORT &= ~(1 << ADB_DATA_BIT);
@@ -81,119 +81,164 @@ bool adb_host_psw(void) { return psw_in(); }
81 * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919> 81 * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919>
82 * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139> 82 * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139>
83 */ 83 */
84 84uint16_t adb_host_kbd_recv(void) { return adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_0); }
85// ADB Bit Cells
86//
87// bit cell time: 70-130us
88// low part of bit0: 60-70% of bit cell
89// low part of bit1: 30-40% of bit cell
90//
91// bit cell time 70us 130us
92// --------------------------------------------
93// low part of bit0 42-49 78-91
94// high part of bit0 21-28 39-52
95// low part of bit1 21-28 39-52
96// high part of bit1 42-49 78-91
97//
98//
99// bit0:
100// 70us bit cell:
101// ____________~~~~~~
102// 42-49 21-28
103//
104// 130us bit cell:
105// ____________~~~~~~
106// 78-91 39-52
107//
108// bit1:
109// 70us bit cell:
110// ______~~~~~~~~~~~~
111// 21-28 42-49
112//
113// 130us bit cell:
114// ______~~~~~~~~~~~~
115// 39-52 78-91
116//
117// [from Apple IIgs Hardware Reference Second Edition]
118
119enum { ADDR_KEYB = 0x20, ADDR_MOUSE = 0x30 };
120
121uint16_t adb_host_kbd_recv(void) { return adb_host_dev_recv(ADDR_KEYB); }
122 85
123#ifdef ADB_MOUSE_ENABLE 86#ifdef ADB_MOUSE_ENABLE
124void adb_mouse_init(void) { return; } 87__attribute__((weak)) void adb_mouse_init(void) { return; }
88
89__attribute__((weak)) void adb_mouse_task(void) { return; }
125 90
126uint16_t adb_host_mouse_recv(void) { return adb_host_dev_recv(ADDR_MOUSE); } 91uint16_t adb_host_mouse_recv(void) { return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); }
127#endif 92#endif
128 93
129static inline uint16_t adb_host_dev_recv(uint8_t device) { 94// This sends Talk command to read data from register and returns length of the data.
130 uint16_t data = 0; 95uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {
96 for (int8_t i = 0; i < len; i++) buf[i] = 0;
97
131 cli(); 98 cli();
132 attention(); 99 attention();
133 send_byte(device | 0x0C); // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00) 100 send_byte((addr << 4) | ADB_CMD_TALK | reg);
134 place_bit0(); // Stopbit(0) 101 place_bit0(); // Stopbit(0)
102 // TODO: Service Request(Srq):
103 // Device holds low part of comannd stopbit for 140-260us
104 //
105 // Command:
106 // ......._ ______________________ ___ ............_ -------
107 // | | | | | | |
108 // Command | | | | | Data bytes | |
109 // ........|___| | 140-260 |__| |_............|___|
110 // |stop0 | Tlt Stop-to-Start |start1| |stop0 |
111 //
112 // Command without data:
113 // ......._ __________________________
114 // | |
115 // Command | |
116 // ........|___| | 140-260 |
117 // |stop0 | Tlt Stop-to-Start |
118 //
119 // Service Request:
120 // ......._ ______ ___ ............_ -------
121 // | 140-260 | | | | | |
122 // Command | Service Request | | | | Data bytes | |
123 // ........|___________________| |__| |_............|___|
124 // |stop0 | |start1| |stop0 |
125 // ......._ __________
126 // | 140-260 |
127 // Command | Service Request |
128 // ........|___________________|
129 // |stop0 |
130 // This can be happened?
131 // ......._ ______________________ ___ ............_ -----
132 // | | | | | | 140-260 |
133 // Command | | | | | Data bytes | Service Request |
134 // ........|___| | 140-260 |__| |_............|_________________|
135 // |stop0 | Tlt Stop-to-Start |start1| |stop0 |
136 //
137 // "Service requests are issued by the devices during a very specific time at the
138 // end of the reception of the command packet.
139 // If a device in need of service issues a service request, it must do so within
140 // the 65 µs of the Stop Bit’s low time and maintain the line low for a total of 300 µs."
141 //
142 // "A device sends a Service Request signal by holding the bus low during the low
143 // portion of the stop bit of any command or data transaction. The device must lengthen
144 // the stop by a minimum of 140 J.lS beyond its normal duration, as shown in Figure 8-15."
145 // http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf
135 if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored 146 if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored
147 xprintf("R");
136 sei(); 148 sei();
137 return -30; // something wrong 149 return 0;
138 } 150 }
139 if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us) 151 if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us)
140 sei(); 152 sei();
141 return 0; // No data to send 153 return 0; // No data from device(not error);
154 }
155
156 // start bit(1)
157 if (!wait_data_hi(40)) {
158 xprintf("S");
159 sei();
160 return 0;
161 }
162 if (!wait_data_lo(100)) {
163 xprintf("s");
164 sei();
165 return 0;
142 } 166 }
143 167
144 uint8_t n = 17; // start bit + 16 data bits 168 uint8_t n = 0; // bit count
145 do { 169 do {
170 //
171 // |<- bit_cell_max(130) ->|
172 // | |<- lo ->|
173 // | | |<-hi->|
174 // _______
175 // | | |
176 // | 130-lo | lo-hi |
177 // |________| |
178 //
146 uint8_t lo = (uint8_t)wait_data_hi(130); 179 uint8_t lo = (uint8_t)wait_data_hi(130);
147 if (!lo) goto error; 180 if (!lo) goto error; // no more bit or after stop bit
148 181
149 uint8_t hi = (uint8_t)wait_data_lo(lo); 182 uint8_t hi = (uint8_t)wait_data_lo(lo);
150 if (!hi) goto error; 183 if (!hi) goto error; // stop bit extedned by Srq?
151 184
152 hi = lo - hi; 185 if (n / 8 >= len) continue; // can't store in buf
153 lo = 130 - lo;
154 186
155 data <<= 1; 187 buf[n / 8] <<= 1;
156 if (lo < hi) { 188 if ((130 - lo) < (lo - hi)) {
157 data |= 1; 189 buf[n / 8] |= 1;
158 } else if (n == 17) {
159 sei();
160 return -20;
161 } 190 }
162 } while (--n); 191 } while (++n);
163
164 // Stop bit can't be checked normally since it could have service request lenghtening
165 // and its high state never goes low.
166 if (!wait_data_hi(351) || wait_data_lo(91)) {
167 sei();
168 return -21;
169 }
170 sei();
171 return data;
172 192
173error: 193error:
174 sei(); 194 sei();
175 return -n; 195 return n / 8;
176} 196}
177 197
178void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) { 198uint16_t adb_host_talk(uint8_t addr, uint8_t reg) {
199 uint8_t len;
200 uint8_t buf[8];
201 len = adb_host_talk_buf(addr, reg, buf, 8);
202 if (len != 2) return 0;
203 return (buf[0] << 8 | buf[1]);
204}
205
206void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {
179 cli(); 207 cli();
180 attention(); 208 attention();
181 send_byte(cmd); 209 send_byte((addr << 4) | ADB_CMD_LISTEN | reg);
182 place_bit0(); // Stopbit(0) 210 place_bit0(); // Stopbit(0)
211 // TODO: Service Request
183 _delay_us(200); // Tlt/Stop to Start 212 _delay_us(200); // Tlt/Stop to Start
184 place_bit1(); // Startbit(1) 213 place_bit1(); // Startbit(1)
185 send_byte(data_h); 214 for (int8_t i = 0; i < len; i++) {
186 send_byte(data_l); 215 send_byte(buf[i]);
216 // xprintf("%02X ", buf[i]);
217 }
187 place_bit0(); // Stopbit(0); 218 place_bit0(); // Stopbit(0);
188 sei(); 219 sei();
189} 220}
190 221
222void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) {
223 uint8_t buf[2] = {data_h, data_l};
224 adb_host_listen_buf(addr, reg, buf, 2);
225}
226
227void adb_host_flush(uint8_t addr) {
228 cli();
229 attention();
230 send_byte((addr << 4) | ADB_CMD_FLUSH);
231 place_bit0(); // Stopbit(0)
232 _delay_us(200); // Tlt/Stop to Start
233 sei();
234}
235
191// send state of LEDs 236// send state of LEDs
192void adb_host_kbd_led(uint8_t led) { 237void adb_host_kbd_led(uint8_t led) {
193 // Addr:Keyboard(0010), Cmd:Listen(10), Register2(10) 238 // Listen Register2
194 // send upper byte (not used) 239 // upper byte: not used
195 // send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0: 240 // lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock
196 adb_host_listen(0x2A, 0, led & 0x07); 241 adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_2, 0, led & 0x07);
197} 242}
198 243
199#ifdef ADB_PSW_BIT 244#ifdef ADB_PSW_BIT
@@ -327,7 +372,7 @@ Commands
327 372
328 bits commands 373 bits commands
329 ------------------------------------------------------ 374 ------------------------------------------------------
330 - - - - 0 0 0 0 Send Request(reset all devices) 375 - - - - 0 0 0 0 Send Reset(reset all devices)
331 A A A A 0 0 0 1 Flush(reset a device) 376 A A A A 0 0 0 1 Flush(reset a device)
332 - - - - 0 0 1 0 Reserved 377 - - - - 0 0 1 0 Reserved
333 - - - - 0 0 1 1 Reserved 378 - - - - 0 0 1 1 Reserved
@@ -435,5 +480,56 @@ Keyboard LEDs & state of keys(Register2)
435 | +----------------------------- Delete 480 | +----------------------------- Delete
436 +------------------------------- Reserved 481 +------------------------------- Reserved
437 482
483Address, Handler ID and bits(Register3)
484 1514131211 . . 8 7 . . . . . . 0
485 | | | | | | | | | | | | | | | |
486 | | | | | | | | +-+-+-+-+-+-+-+- Handler ID
487 | | | | +-+-+-+----------------- Address
488 | | | +------------------------- 0
489 | | +--------------------------- Service request enable(1 = enabled)
490 | +----------------------------- Exceptional event(alwyas 1 if not used)
491 +------------------------------- 0
492
493ADB Bit Cells
494 bit cell time: 70-130us
495 low part of bit0: 60-70% of bit cell
496 low part of bit1: 30-40% of bit cell
497
498 bit cell time 70us 130us
499 --------------------------------------------
500 low part of bit0 42-49 78-91
501 high part of bit0 21-28 39-52
502 low part of bit1 21-28 39-52
503 high part of bit1 42-49 78-91
504
505
506 bit0:
507 70us bit cell:
508 ____________~~~~~~
509 42-49 21-28
510
511 130us bit cell:
512 ____________~~~~~~
513 78-91 39-52
514
515 bit1:
516 70us bit cell:
517 ______~~~~~~~~~~~~
518 21-28 42-49
519
520 130us bit cell:
521 ______~~~~~~~~~~~~
522 39-52 78-91
523
524 [from Apple IIgs Hardware Reference Second Edition]
525
526Keyboard Handle ID
527 Apple Standard Keyboard M0116: 0x01
528 Apple Extended Keyboard M0115: 0x02
529 Apple Extended Keyboard II M3501: 0x02
530 Apple Adjustable Keybaord: 0x10
531
532 http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802
533
438END_OF_ADB 534END_OF_ADB
439*/ 535*/
diff --git a/tmk_core/protocol/adb.h b/tmk_core/protocol/adb.h
index 34cbcf769..fe8becc2d 100644
--- a/tmk_core/protocol/adb.h
+++ b/tmk_core/protocol/adb.h
@@ -1,5 +1,5 @@
1/* 1/*
2Copyright 2011 Jun WAKO <wakojun@gmail.com> 2Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
3 3
4This software is licensed with a Modified BSD License. 4This software is licensed with a Modified BSD License.
5All of this is supposed to be Free Software, Open Source, DFSG-free, 5All of this is supposed to be Free Software, Open Source, DFSG-free,
@@ -47,12 +47,60 @@ POSSIBILITY OF SUCH DAMAGE.
47#define ADB_POWER 0x7F 47#define ADB_POWER 0x7F
48#define ADB_CAPS 0x39 48#define ADB_CAPS 0x39
49 49
50/* ADB commands */
51// Default Address
52#define ADB_ADDR_0 0
53#define ADB_ADDR_DONGLE 1
54#define ADB_ADDR_KEYBOARD 2
55#define ADB_ADDR_MOUSE 3
56#define ADB_ADDR_TABLET 4
57#define ADB_ADDR_APPLIANCE 7
58#define ADB_ADDR_8 8
59#define ADB_ADDR_9 9
60#define ADB_ADDR_10 10
61#define ADB_ADDR_11 11
62#define ADB_ADDR_12 12
63#define ADB_ADDR_13 13
64#define ADB_ADDR_14 14
65#define ADB_ADDR_15 15
66// for temporary purpose, do not use for polling
67#define ADB_ADDR_TMP 15
68#define ADB_ADDR_MOUSE_POLL 10
69// Command Type
70#define ADB_CMD_RESET 0
71#define ADB_CMD_FLUSH 1
72#define ADB_CMD_LISTEN 8
73#define ADB_CMD_TALK 12
74// Register
75#define ADB_REG_0 0
76#define ADB_REG_1 1
77#define ADB_REG_2 2
78#define ADB_REG_3 3
79
80/* ADB keyboard handler id */
81#define ADB_HANDLER_STD 0x01 /* IIGS, M0116 */
82#define ADB_HANDLER_AEK 0x02 /* M0115, M3501 */
83#define ADB_HANDLER_AEK_RMOD 0x03 /* M0115, M3501, alternate mode enableing right modifiers */
84#define ADB_HANDLER_STD_ISO 0x04 /* M0118, ISO swapping keys */
85#define ADB_HANDLER_AEK_ISO 0x05 /* M0115, M3501, ISO swapping keys */
86#define ADB_HANDLER_M1242_ANSI 0x10 /* Adjustable keyboard */
87#define ADB_HANDLER_CLASSIC1_MOUSE 0x01
88#define ADB_HANDLER_CLASSIC2_MOUSE 0x02
89#define ADB_HANDLER_EXTENDED_MOUSE 0x04
90#define ADB_HANDLER_TURBO_MOUSE 0x32
91
50// ADB host 92// ADB host
51void adb_host_init(void); 93void adb_host_init(void);
52bool adb_host_psw(void); 94bool adb_host_psw(void);
95uint16_t adb_host_talk(uint8_t addr, uint8_t reg);
96uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
97void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l);
98void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
99void adb_host_flush(uint8_t addr);
100void adb_host_kbd_led(uint8_t led);
53uint16_t adb_host_kbd_recv(void); 101uint16_t adb_host_kbd_recv(void);
54uint16_t adb_host_mouse_recv(void); 102uint16_t adb_host_mouse_recv(void);
55void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l); 103
56void adb_host_kbd_led(uint8_t led); 104// ADB Mouse
57void adb_mouse_task(void); 105void adb_mouse_task(void);
58void adb_mouse_init(void); 106void adb_mouse_init(void);
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.c b/tmk_core/protocol/arm_atsam/i2c_master.c
index d3319ab44..dda2f85b0 100644
--- a/tmk_core/protocol/arm_atsam/i2c_master.c
+++ b/tmk_core/protocol/arm_atsam/i2c_master.c
@@ -28,6 +28,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
28 28
29# define I2C_LED_USE_DMA 1 // Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers 29# define I2C_LED_USE_DMA 1 // Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers
30 30
31DmacDescriptor dmac_desc;
32DmacDescriptor dmac_desc_wb;
33
31static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer 34static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer
32static uint8_t i2c_led_q_s; // Start of circular buffer 35static uint8_t i2c_led_q_s; // Start of circular buffer
33static uint8_t i2c_led_q_e; // End of circular buffer 36static uint8_t i2c_led_q_e; // End of circular buffer
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.h b/tmk_core/protocol/arm_atsam/i2c_master.h
index 44dbdfbff..68773f213 100644
--- a/tmk_core/protocol/arm_atsam/i2c_master.h
+++ b/tmk_core/protocol/arm_atsam/i2c_master.h
@@ -24,8 +24,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
24# include "issi3733_driver.h" 24# include "issi3733_driver.h"
25# include "config.h" 25# include "config.h"
26 26
27__attribute__((__aligned__(16))) DmacDescriptor dmac_desc; 27extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc;
28__attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb; 28extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb;
29 29
30uint8_t I2C3733_Init_Control(void); 30uint8_t I2C3733_Init_Control(void);
31uint8_t I2C3733_Init_Drivers(void); 31uint8_t I2C3733_Init_Drivers(void);
diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
index e10be52fb..e4e79d351 100644
--- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c
+++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
@@ -305,10 +305,6 @@ int main(void) {
305 // dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n", v_5v, v_5v_avg, v_5v_avg - V5_LOW, v_5v_avg - V5_HIGH, gcr_actual, gcr_desired); 305 // dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n", v_5v, v_5v_avg, v_5v_avg - V5_LOW, v_5v_avg - V5_HIGH, gcr_actual, gcr_desired);
306 } 306 }
307#endif // CONSOLE_ENABLE 307#endif // CONSOLE_ENABLE
308
309 // Run housekeeping
310 housekeeping_task_kb();
311 housekeeping_task_user();
312 } 308 }
313 309
314 return 1; 310 return 1;
diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c
index e07c181fc..63e4c99d2 100644
--- a/tmk_core/protocol/chibios/main.c
+++ b/tmk_core/protocol/chibios/main.c
@@ -163,6 +163,7 @@ int main(void) {
163 keyboard_setup(); 163 keyboard_setup();
164 164
165 /* Init USB */ 165 /* Init USB */
166 usb_event_queue_init();
166 init_usb_driver(&USB_DRIVER); 167 init_usb_driver(&USB_DRIVER);
167 168
168#ifdef MIDI_ENABLE 169#ifdef MIDI_ENABLE
@@ -221,6 +222,8 @@ int main(void) {
221 222
222 /* Main loop */ 223 /* Main loop */
223 while (true) { 224 while (true) {
225 usb_event_queue_task();
226
224#if !defined(NO_USB_STARTUP_CHECK) 227#if !defined(NO_USB_STARTUP_CHECK)
225 if (USB_DRIVER.state == USB_SUSPENDED) { 228 if (USB_DRIVER.state == USB_SUSPENDED) {
226 print("[s]"); 229 print("[s]");
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index ad489fb91..8adecfa71 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -27,6 +27,7 @@
27 27
28#include <ch.h> 28#include <ch.h>
29#include <hal.h> 29#include <hal.h>
30#include <string.h>
30 31
31#include "usb_main.h" 32#include "usb_main.h"
32 33
@@ -368,6 +369,69 @@ static usb_driver_configs_t drivers = {
368 * --------------------------------------------------------- 369 * ---------------------------------------------------------
369 */ 370 */
370 371
372#define USB_EVENT_QUEUE_SIZE 16
373usbevent_t event_queue[USB_EVENT_QUEUE_SIZE];
374uint8_t event_queue_head;
375uint8_t event_queue_tail;
376
377void usb_event_queue_init(void) {
378 // Initialise the event queue
379 memset(&event_queue, 0, sizeof(event_queue));
380 event_queue_head = 0;
381 event_queue_tail = 0;
382}
383
384static inline bool usb_event_queue_enqueue(usbevent_t event) {
385 uint8_t next = (event_queue_head + 1) % USB_EVENT_QUEUE_SIZE;
386 if (next == event_queue_tail) {
387 return false;
388 }
389 event_queue[event_queue_head] = event;
390 event_queue_head = next;
391 return true;
392}
393
394static inline bool usb_event_queue_dequeue(usbevent_t *event) {
395 if (event_queue_head == event_queue_tail) {
396 return false;
397 }
398 *event = event_queue[event_queue_tail];
399 event_queue_tail = (event_queue_tail + 1) % USB_EVENT_QUEUE_SIZE;
400 return true;
401}
402
403static inline void usb_event_suspend_handler(void) {
404#ifdef SLEEP_LED_ENABLE
405 sleep_led_enable();
406#endif /* SLEEP_LED_ENABLE */
407}
408
409static inline void usb_event_wakeup_handler(void) {
410 suspend_wakeup_init();
411#ifdef SLEEP_LED_ENABLE
412 sleep_led_disable();
413 // NOTE: converters may not accept this
414 led_set(host_keyboard_leds());
415#endif /* SLEEP_LED_ENABLE */
416}
417
418void usb_event_queue_task(void) {
419 usbevent_t event;
420 while (usb_event_queue_dequeue(&event)) {
421 switch (event) {
422 case USB_EVENT_SUSPEND:
423 usb_event_suspend_handler();
424 break;
425 case USB_EVENT_WAKEUP:
426 usb_event_wakeup_handler();
427 break;
428 default:
429 // Nothing to do, we don't handle it.
430 break;
431 }
432 }
433}
434
371/* Handles the USB driver global events 435/* Handles the USB driver global events
372 * TODO: maybe disable some things when connection is lost? */ 436 * TODO: maybe disable some things when connection is lost? */
373static void usb_event_cb(USBDriver *usbp, usbevent_t event) { 437static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
@@ -402,9 +466,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
402 osalSysUnlockFromISR(); 466 osalSysUnlockFromISR();
403 return; 467 return;
404 case USB_EVENT_SUSPEND: 468 case USB_EVENT_SUSPEND:
405#ifdef SLEEP_LED_ENABLE 469 usb_event_queue_enqueue(USB_EVENT_SUSPEND);
406 sleep_led_enable();
407#endif /* SLEEP_LED_ENABLE */
408 /* Falls into.*/ 470 /* Falls into.*/
409 case USB_EVENT_UNCONFIGURED: 471 case USB_EVENT_UNCONFIGURED:
410 /* Falls into.*/ 472 /* Falls into.*/
@@ -425,12 +487,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
425 qmkusbWakeupHookI(&drivers.array[i].driver); 487 qmkusbWakeupHookI(&drivers.array[i].driver);
426 chSysUnlockFromISR(); 488 chSysUnlockFromISR();
427 } 489 }
428 suspend_wakeup_init(); 490 usb_event_queue_enqueue(USB_EVENT_WAKEUP);
429#ifdef SLEEP_LED_ENABLE
430 sleep_led_disable();
431 // NOTE: converters may not accept this
432 led_set(host_keyboard_leds());
433#endif /* SLEEP_LED_ENABLE */
434 return; 491 return;
435 492
436 case USB_EVENT_STALLED: 493 case USB_EVENT_STALLED:
@@ -651,6 +708,17 @@ void init_usb_driver(USBDriver *usbp) {
651void restart_usb_driver(USBDriver *usbp) { 708void restart_usb_driver(USBDriver *usbp) {
652 usbStop(usbp); 709 usbStop(usbp);
653 usbDisconnectBus(usbp); 710 usbDisconnectBus(usbp);
711
712#if USB_SUSPEND_WAKEUP_DELAY > 0
713 // Some hubs, kvm switches, and monitors do
714 // weird things, with USB device state bouncing
715 // around wildly on wakeup, yielding race
716 // conditions that can corrupt the keyboard state.
717 //
718 // Pause for a while to let things settle...
719 wait_ms(USB_SUSPEND_WAKEUP_DELAY);
720#endif
721
654 usbStart(usbp, &usbcfg); 722 usbStart(usbp, &usbcfg);
655 usbConnectBus(usbp); 723 usbConnectBus(usbp);
656} 724}
@@ -806,7 +874,7 @@ void send_mouse(report_mouse_t *report) {
806} 874}
807 875
808#else /* MOUSE_ENABLE */ 876#else /* MOUSE_ENABLE */
809void send_mouse(report_mouse_t *report) { (void)report; } 877void send_mouse(report_mouse_t *report) { (void)report; }
810#endif /* MOUSE_ENABLE */ 878#endif /* MOUSE_ENABLE */
811 879
812/* --------------------------------------------------------- 880/* ---------------------------------------------------------
@@ -885,15 +953,8 @@ void console_task(void) {
885 } while (size > 0); 953 } while (size > 0);
886} 954}
887 955
888#else /* CONSOLE_ENABLE */
889int8_t sendchar(uint8_t c) {
890 (void)c;
891 return 0;
892}
893#endif /* CONSOLE_ENABLE */ 956#endif /* CONSOLE_ENABLE */
894 957
895void _putchar(char character) { sendchar(character); }
896
897#ifdef RAW_ENABLE 958#ifdef RAW_ENABLE
898void raw_hid_send(uint8_t *data, uint8_t length) { 959void raw_hid_send(uint8_t *data, uint8_t length) {
899 // TODO: implement variable size packet 960 // TODO: implement variable size packet
diff --git a/tmk_core/protocol/chibios/usb_main.h b/tmk_core/protocol/chibios/usb_main.h
index eaa08d8f7..fb33c8cd0 100644
--- a/tmk_core/protocol/chibios/usb_main.h
+++ b/tmk_core/protocol/chibios/usb_main.h
@@ -38,6 +38,17 @@ void init_usb_driver(USBDriver *usbp);
38void restart_usb_driver(USBDriver *usbp); 38void restart_usb_driver(USBDriver *usbp);
39 39
40/* --------------- 40/* ---------------
41 * USB Event queue
42 * ---------------
43 */
44
45/* Initialisation of the FIFO */
46void usb_event_queue_init(void);
47
48/* Task to dequeue and execute any handlers for the USB events on the main thread */
49void usb_event_queue_task(void);
50
51/* ---------------
41 * Keyboard header 52 * Keyboard header
42 * --------------- 53 * ---------------
43 */ 54 */
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index 623aa33ff..bd9daaac9 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -435,7 +435,9 @@ void EVENT_USB_Device_Suspend() {
435 */ 435 */
436void EVENT_USB_Device_WakeUp() { 436void EVENT_USB_Device_WakeUp() {
437 print("[W]"); 437 print("[W]");
438#if defined(NO_USB_STARTUP_CHECK)
438 suspend_wakeup_init(); 439 suspend_wakeup_init();
440#endif
439 441
440#ifdef SLEEP_LED_ENABLE 442#ifdef SLEEP_LED_ENABLE
441 sleep_led_disable(); 443 sleep_led_disable();
@@ -1023,7 +1025,6 @@ static void setup_usb(void) {
1023 1025
1024 // for Console_Task 1026 // for Console_Task
1025 USB_Device_EnableSOFEvents(); 1027 USB_Device_EnableSOFEvents();
1026 print_set_sendchar(sendchar);
1027} 1028}
1028 1029
1029/** \brief Main 1030/** \brief Main
@@ -1073,12 +1074,26 @@ int main(void) {
1073 print("Keyboard start.\n"); 1074 print("Keyboard start.\n");
1074 while (1) { 1075 while (1) {
1075#if !defined(NO_USB_STARTUP_CHECK) 1076#if !defined(NO_USB_STARTUP_CHECK)
1076 while (USB_DeviceState == DEVICE_STATE_Suspended) { 1077 if (USB_DeviceState == DEVICE_STATE_Suspended) {
1077 print("[s]"); 1078 print("[s]");
1078 suspend_power_down(); 1079 while (USB_DeviceState == DEVICE_STATE_Suspended) {
1079 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { 1080 suspend_power_down();
1080 USB_Device_SendRemoteWakeup(); 1081 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
1082 USB_Device_SendRemoteWakeup();
1083 clear_keyboard();
1084
1085# if USB_SUSPEND_WAKEUP_DELAY > 0
1086 // Some hubs, kvm switches, and monitors do
1087 // weird things, with USB device state bouncing
1088 // around wildly on wakeup, yielding race
1089 // conditions that can corrupt the keyboard state.
1090 //
1091 // Pause for a while to let things settle...
1092 wait_ms(USB_SUSPEND_WAKEUP_DELAY);
1093# endif
1094 }
1081 } 1095 }
1096 suspend_wakeup_init();
1082 } 1097 }
1083#endif 1098#endif
1084 1099
diff --git a/tmk_core/protocol/m0110.c b/tmk_core/protocol/m0110.c
index b02a6933d..64f2fa50a 100644
--- a/tmk_core/protocol/m0110.c
+++ b/tmk_core/protocol/m0110.c
@@ -95,11 +95,11 @@ void m0110_init(void) {
95 uint8_t data; 95 uint8_t data;
96 m0110_send(M0110_MODEL); 96 m0110_send(M0110_MODEL);
97 data = m0110_recv(); 97 data = m0110_recv();
98 print("m0110_init model: "); phex(data); print("\n"); 98 print("m0110_init model: "); print_hex8(data); print("\n");
99 99
100 m0110_send(M0110_TEST); 100 m0110_send(M0110_TEST);
101 data = m0110_recv(); 101 data = m0110_recv();
102 print("m0110_init test: "); phex(data); print("\n"); 102 print("m0110_init test: "); print_hex8(data); print("\n");
103 */ 103 */
104} 104}
105 105
@@ -122,7 +122,7 @@ uint8_t m0110_send(uint8_t data) {
122 return 1; 122 return 1;
123ERROR: 123ERROR:
124 print("m0110_send err: "); 124 print("m0110_send err: ");
125 phex(m0110_error); 125 print_hex8(m0110_error);
126 print("\n"); 126 print("\n");
127 _delay_ms(500); 127 _delay_ms(500);
128 idle(); 128 idle();
@@ -146,7 +146,7 @@ uint8_t m0110_recv(void) {
146 return data; 146 return data;
147ERROR: 147ERROR:
148 print("m0110_recv err: "); 148 print("m0110_recv err: ");
149 phex(m0110_error); 149 print_hex8(m0110_error);
150 print("\n"); 150 print("\n");
151 _delay_ms(500); 151 _delay_ms(500);
152 idle(); 152 idle();
diff --git a/tmk_core/protocol/ps2_mouse.c b/tmk_core/protocol/ps2_mouse.c
index 8df465026..5415453a0 100644
--- a/tmk_core/protocol/ps2_mouse.c
+++ b/tmk_core/protocol/ps2_mouse.c
@@ -190,7 +190,7 @@ static inline void ps2_mouse_clear_report(report_mouse_t *mouse_report) {
190static inline void ps2_mouse_print_report(report_mouse_t *mouse_report) { 190static inline void ps2_mouse_print_report(report_mouse_t *mouse_report) {
191 if (!debug_mouse) return; 191 if (!debug_mouse) return;
192 print("ps2_mouse: ["); 192 print("ps2_mouse: [");
193 phex(mouse_report->buttons); 193 print_hex8(mouse_report->buttons);
194 print("|"); 194 print("|");
195 print_hex8((uint8_t)mouse_report->x); 195 print_hex8((uint8_t)mouse_report->x);
196 print(" "); 196 print(" ");
diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c
index 7ea4b2e37..ba7760f28 100644
--- a/tmk_core/protocol/usb_descriptor.c
+++ b/tmk_core/protocol/usb_descriptor.c
@@ -116,19 +116,15 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
116# endif 116# endif
117 HID_RI_USAGE(8, 0x01), // Pointer 117 HID_RI_USAGE(8, 0x01), // Pointer
118 HID_RI_COLLECTION(8, 0x00), // Physical 118 HID_RI_COLLECTION(8, 0x00), // Physical
119 // Buttons (5 bits) 119 // Buttons (8 bits)
120 HID_RI_USAGE_PAGE(8, 0x09), // Button 120 HID_RI_USAGE_PAGE(8, 0x09), // Button
121 HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1 121 HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1
122 HID_RI_USAGE_MAXIMUM(8, 0x05), // Button 5 122 HID_RI_USAGE_MAXIMUM(8, 0x08), // Button 8
123 HID_RI_LOGICAL_MINIMUM(8, 0x00), 123 HID_RI_LOGICAL_MINIMUM(8, 0x00),
124 HID_RI_LOGICAL_MAXIMUM(8, 0x01), 124 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
125 HID_RI_REPORT_COUNT(8, 0x05), 125 HID_RI_REPORT_COUNT(8, 0x08),
126 HID_RI_REPORT_SIZE(8, 0x01), 126 HID_RI_REPORT_SIZE(8, 0x01),
127 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), 127 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
128 // Button padding (3 bits)
129 HID_RI_REPORT_COUNT(8, 0x01),
130 HID_RI_REPORT_SIZE(8, 0x03),
131 HID_RI_INPUT(8, HID_IOF_CONSTANT),
132 128
133 // X/Y position (2 bytes) 129 // X/Y position (2 bytes)
134 HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop 130 HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
@@ -356,7 +352,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = {
356 .Type = DTYPE_Device 352 .Type = DTYPE_Device
357 }, 353 },
358 .USBSpecification = VERSION_BCD(1, 1, 0), 354 .USBSpecification = VERSION_BCD(1, 1, 0),
359 355
360#if VIRTSER_ENABLE 356#if VIRTSER_ENABLE
361 .Class = USB_CSCP_IADDeviceClass, 357 .Class = USB_CSCP_IADDeviceClass,
362 .SubClass = USB_CSCP_IADDeviceSubclass, 358 .SubClass = USB_CSCP_IADDeviceSubclass,
diff --git a/tmk_core/protocol/vusb/main.c b/tmk_core/protocol/vusb/main.c
index 2e8bb2fbb..3f93ef6d2 100644
--- a/tmk_core/protocol/vusb/main.c
+++ b/tmk_core/protocol/vusb/main.c
@@ -74,12 +74,7 @@ static void usb_remote_wakeup(void) {
74 * 74 *
75 * FIXME: Needs doc 75 * FIXME: Needs doc
76 */ 76 */
77static void setup_usb(void) { 77static void setup_usb(void) { initForUsbConnectivity(); }
78 initForUsbConnectivity();
79
80 // for Console_Task
81 print_set_sendchar(sendchar);
82}
83 78
84/** \brief Main 79/** \brief Main
85 * 80 *
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c
index a422903cc..9362fbde7 100644
--- a/tmk_core/protocol/vusb/vusb.c
+++ b/tmk_core/protocol/vusb/vusb.c
@@ -444,19 +444,15 @@ const PROGMEM uchar shared_hid_report[] = {
444 0x85, REPORT_ID_MOUSE, // Report ID 444 0x85, REPORT_ID_MOUSE, // Report ID
445 0x09, 0x01, // Usage (Pointer) 445 0x09, 0x01, // Usage (Pointer)
446 0xA1, 0x00, // Collection (Physical) 446 0xA1, 0x00, // Collection (Physical)
447 // Buttons (5 bits) 447 // Buttons (8 bits)
448 0x05, 0x09, // Usage Page (Button) 448 0x05, 0x09, // Usage Page (Button)
449 0x19, 0x01, // Usage Minimum (Button 1) 449 0x19, 0x01, // Usage Minimum (Button 1)
450 0x29, 0x05, // Usage Maximum (Button 5) 450 0x29, 0x08, // Usage Maximum (Button 8)
451 0x15, 0x00, // Logical Minimum (0) 451 0x15, 0x00, // Logical Minimum (0)
452 0x25, 0x01, // Logical Maximum (1) 452 0x25, 0x01, // Logical Maximum (1)
453 0x95, 0x05, // Report Count (5) 453 0x95, 0x08, // Report Count (8)
454 0x75, 0x01, // Report Size (1) 454 0x75, 0x01, // Report Size (1)
455 0x81, 0x02, // Input (Data, Variable, Absolute) 455 0x81, 0x02, // Input (Data, Variable, Absolute)
456 // Button padding (3 bits)
457 0x95, 0x01, // Report Count (1)
458 0x75, 0x03, // Report Size (3)
459 0x81, 0x03, // Input (Constant)
460 456
461 // X/Y position (2 bytes) 457 // X/Y position (2 bytes)
462 0x05, 0x01, // Usage Page (Generic Desktop) 458 0x05, 0x01, // Usage Page (Generic Desktop)