diff options
Diffstat (limited to 'tmk_core/common')
31 files changed, 552 insertions, 1150 deletions
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index a7432bae59..f53e3c7084 100644 --- a/tmk_core/common/action.c +++ b/tmk_core/common/action.c @@ -47,10 +47,6 @@ int tp_buttons; int retro_tapping_counter = 0; #endif -#ifdef FAUXCLICKY_ENABLE -# include "fauxclicky.h" -#endif - #ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY __attribute__((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { return false; } #endif @@ -80,16 +76,6 @@ void action_exec(keyevent_t event) { #endif } -#ifdef FAUXCLICKY_ENABLE - if (IS_PRESSED(event)) { - FAUXCLICKY_ACTION_PRESS; - } - if (IS_RELEASED(event)) { - FAUXCLICKY_ACTION_RELEASE; - } - fauxclicky_check(); -#endif - #ifdef SWAP_HANDS_ENABLE if (!IS_NOEVENT(event)) { process_hand_swap(&event); @@ -424,56 +410,22 @@ void process_action(keyrecord_t *record, action_t action) { case ACT_MOUSEKEY: if (event.pressed) { mousekey_on(action.key.code); - switch (action.key.code) { -# if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE) - case KC_MS_BTN1: - register_button(true, MOUSE_BTN1); - break; - case KC_MS_BTN2: - register_button(true, MOUSE_BTN2); - break; - case KC_MS_BTN3: - register_button(true, MOUSE_BTN3); - break; -# endif -# ifdef POINTING_DEVICE_ENABLE - case KC_MS_BTN4: - register_button(true, MOUSE_BTN4); - break; - case KC_MS_BTN5: - register_button(true, MOUSE_BTN5); - break; -# endif - default: - mousekey_send(); - break; - } } else { mousekey_off(action.key.code); - switch (action.key.code) { + } + switch (action.key.code) { # if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE) - case KC_MS_BTN1: - register_button(false, MOUSE_BTN1); - break; - case KC_MS_BTN2: - register_button(false, MOUSE_BTN2); - break; - case KC_MS_BTN3: - register_button(false, MOUSE_BTN3); - break; -# endif -# ifdef POINTING_DEVICE_ENABLE - case KC_MS_BTN4: - register_button(false, MOUSE_BTN4); - break; - case KC_MS_BTN5: - register_button(false, MOUSE_BTN5); - break; +# ifdef POINTING_DEVICE_ENABLE + case KC_MS_BTN1 ... KC_MS_BTN8: +# else + case KC_MS_BTN1 ... KC_MS_BTN3: +# endif + register_button(event.pressed, MOUSE_BTN_MASK(action.key.code - KC_MS_BTN1)); + break; # endif - default: - mousekey_send(); - break; - } + default: + mousekey_send(); + break; } break; #endif @@ -936,20 +888,25 @@ void unregister_code(uint8_t code) { #endif } -/** \brief Utilities for actions. (FIXME: Needs better description) +/** \brief Tap a keycode with a delay. * - * FIXME: Needs documentation. + * \param code The basic keycode to tap. + * \param delay The amount of time in milliseconds to leave the keycode registered, before unregistering it. */ -void tap_code(uint8_t code) { +void tap_code_delay(uint8_t code, uint16_t delay) { register_code(code); - if (code == KC_CAPS) { - wait_ms(TAP_HOLD_CAPS_DELAY); - } else { - wait_ms(TAP_CODE_DELAY); + for (uint16_t i = delay; i > 0; i--) { + wait_ms(1); } unregister_code(code); } +/** \brief Tap a keycode with the default delay. + * + * \param code The basic keycode to tap. If `code` is `KC_CAPS`, the delay will be `TAP_HOLD_CAPS_DELAY`, otherwise `TAP_CODE_DELAY`, if defined. + */ +void tap_code(uint8_t code) { tap_code_delay(code, code == KC_CAPS ? TAP_HOLD_CAPS_DELAY : TAP_CODE_DELAY); } + /** \brief Adds the given physically pressed modifiers and sends a keyboard report immediately. * * \param mods A bitfield of modifiers to register. @@ -1017,6 +974,10 @@ void clear_keyboard_but_mods(void) { * FIXME: Needs documentation. */ void clear_keyboard_but_mods_and_keys() { +#ifdef EXTRAKEY_ENABLE + host_system_send(0); + host_consumer_send(0); +#endif clear_weak_mods(); clear_macro_mods(); send_keyboard_report(); @@ -1024,10 +985,6 @@ void clear_keyboard_but_mods_and_keys() { mousekey_clear(); mousekey_send(); #endif -#ifdef EXTRAKEY_ENABLE - host_system_send(0); - host_consumer_send(0); -#endif } /** \brief Utilities for actions. (FIXME: Needs better description) diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h index 81cd54369c..9a991de1c2 100644 --- a/tmk_core/common/action.h +++ b/tmk_core/common/action.h @@ -100,6 +100,7 @@ void process_action(keyrecord_t *record, action_t action); void register_code(uint8_t code); void unregister_code(uint8_t code); void tap_code(uint8_t code); +void tap_code_delay(uint8_t code, uint16_t delay); void register_mods(uint8_t mods); void unregister_mods(uint8_t mods); void register_weak_mods(uint8_t mods); diff --git a/tmk_core/common/print.c b/tmk_core/common/arm_atsam/_print.h index 07aef0b0eb..a774f5d8d2 100644 --- a/tmk_core/common/print.c +++ b/tmk_core/common/arm_atsam/_print.h @@ -1,4 +1,4 @@ -/* Copyright 2012,2013 Jun Wako <wakojun@gmail.com> */ +/* Copyright 2012 Jun Wako <wakojun@gmail.com> */ /* Very basic print functions, intended to be used with usb_debug_only.c * http://www.pjrc.com/teensy/ * Copyright (c) 2008 PJRC.COM, LLC @@ -21,27 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#pragma once -#include <stdint.h> -#include "print.h" +#include "arm_atsam/printf.h" -#ifndef NO_PRINT - -# if defined(__AVR__) - -# define sendchar(c) xputc(c) - -void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) { xdev_out(sendchar_func); } - -# elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */ - -// don't need anything extra - -# elif defined(__arm__) /* __AVR__ */ - -// TODO -// void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) { } - -# endif /* __AVR__ */ - -#endif +// Create user & normal print defines +#define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__) +#define print(s) xprintf(s) +#define println(s) xprintf(s "\r\n") +#define uprint(s) print(s) +#define uprintln(s) println(s) +#define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__) diff --git a/tmk_core/common/arm_atsam/printf.c b/tmk_core/common/arm_atsam/printf.c index cd7cdb52e6..2cb59706a8 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 along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "printf.h" +#include "sendchar.h" + #ifdef CONSOLE_ENABLE # include "samd51j18a.h" # include "arm_atsam_protocol.h" -# include "printf.h" # include <string.h> # include <stdarg.h> @@ -66,3 +68,5 @@ void console_printf(char *fmt, ...) { } #endif // CONSOLE_ENABLE + +void 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 0000000000..f70e02731f --- /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 0000000000..f9b79bdf85 --- /dev/null +++ b/tmk_core/common/avr/_print.h @@ -0,0 +1,33 @@ +/* Copyright 2012 Jun Wako <wakojun@gmail.com> */ +/* Very basic print functions, intended to be used with usb_debug_only.c + * http://www.pjrc.com/teensy/ + * Copyright (c) 2008 PJRC.COM, LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#pragma once + +#include "avr/xprintf.h" + +// Create user & normal print defines +#define print(s) xputs(PSTR(s)) +#define println(s) xputs(PSTR(s "\r\n")) +#define uprint(s) print(s) +#define uprintln(s) println(s) +#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 a1db55da93..c0272903b8 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;"))); * * FIXME: needs doc */ -void bootloader_jump(void) { +__attribute__((weak)) void bootloader_jump(void) { #if !defined(BOOTLOADER_SIZE) uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); diff --git a/tmk_core/common/avr/pin_defs.h b/tmk_core/common/avr/pin_defs.h index dbfed21f48..23d948041d 100644 --- a/tmk_core/common/avr/pin_defs.h +++ b/tmk_core/common/avr/pin_defs.h @@ -29,7 +29,7 @@ # define PIND_ADDRESS 0x9 # define PINE_ADDRESS 0xC # define PINF_ADDRESS 0xF -#elif defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) +#elif defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) # define ADDRESS_BASE 0x00 # define PINB_ADDRESS 0x3 # define PINC_ADDRESS 0x6 @@ -125,4 +125,4 @@ # define F5 PINDEF(F, 5) # define F6 PINDEF(F, 6) # define F7 PINDEF(F, 7) -#endif
\ No newline at end of file +#endif diff --git a/tmk_core/common/avr/printf.c b/tmk_core/common/avr/printf.c new file mode 100644 index 0000000000..9ad7a38693 --- /dev/null +++ b/tmk_core/common/avr/printf.c @@ -0,0 +1,20 @@ +/* +Copyright 2011 Jun Wako <wakojun@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +#include "xprintf.h" +#include "sendchar.h" + +void 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 0000000000..060ad88c57 --- /dev/null +++ b/tmk_core/common/avr/printf.mk @@ -0,0 +1,2 @@ +TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/xprintf.S +TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c index 86c3df040a..b784a0835d 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) { led_set(leds_off); # ifdef AUDIO_ENABLE - // This sometimes disables the start-up noise, so it's been disabled - // stop_all_notes(); + stop_all_notes(); # endif /* AUDIO_ENABLE */ # if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) rgblight_suspend(); # endif - suspend_power_down_kb(); // TODO: more power saving // See PicoPower application note @@ -157,6 +155,7 @@ __attribute__((weak)) void suspend_wakeup_init_user(void) {} * FIXME: needs doc */ __attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); } + /** \brief run immediately after wakeup * * FIXME: needs doc diff --git a/tmk_core/common/chibios/suspend.c b/tmk_core/common/chibios/suspend.c index 796056019f..49e20641fb 100644 --- a/tmk_core/common/chibios/suspend.c +++ b/tmk_core/common/chibios/suspend.c @@ -12,6 +12,10 @@ #include "led.h" #include "wait.h" +#ifdef AUDIO_ENABLE +# include "audio.h" +#endif /* AUDIO_ENABLE */ + #ifdef BACKLIGHT_ENABLE # include "backlight.h" #endif @@ -65,6 +69,9 @@ void suspend_power_down(void) { #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) rgblight_suspend(); #endif +#ifdef AUDIO_ENABLE + stop_all_notes(); +#endif /* AUDIO_ENABLE */ suspend_power_down_kb(); // 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 bea96dfc14..ea62deaa8c 100644 --- a/tmk_core/common/debug.c +++ b/tmk_core/common/debug.c @@ -1,24 +1,25 @@ -#include <stdbool.h> -#include "debug.h" +/* +Copyright 2011 Jun Wako <wakojun@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. -#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +#include "debug.h" debug_config_t debug_config = { -/* GCC Bug 10676 - Using unnamed fields in initializers - * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10676 */ -#if GCC_VERSION >= 40600 - .enable = false, - .matrix = false, - .keyboard = false, - .mouse = false, - .reserved = 0 -#else - { - false, // .enable - false, // .matrix - false, // .keyboard - false, // .mouse - 0 // .reserved - } -#endif + .enable = false, // + .matrix = false, // + .keyboard = false, // + .mouse = false, // + .reserved = 0 // }; diff --git a/tmk_core/common/eeconfig.h b/tmk_core/common/eeconfig.h index c4f0483913..86b9e6f99b 100644 --- a/tmk_core/common/eeconfig.h +++ b/tmk_core/common/eeconfig.h @@ -21,7 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include <stdbool.h> #ifndef EECONFIG_MAGIC_NUMBER -# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEEC +# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEEB // When changing, decrement this value to avoid future re-init issues #endif #define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c index 7120cdacdf..34fed0caba 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/>. #include "led.h" #include "keycode.h" #include "timer.h" +#include "sync_timer.h" #include "print.h" #include "debug.h" #include "command.h" @@ -53,15 +54,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #ifdef RGBLIGHT_ENABLE # include "rgblight.h" #endif +#ifdef RGB_MATRIX_ENABLE +# include "rgb_matrix.h" +#endif #ifdef ENCODER_ENABLE # include "encoder.h" #endif #ifdef STENO_ENABLE # include "process_steno.h" #endif -#ifdef FAUXCLICKY_ENABLE -# include "fauxclicky.h" -#endif #ifdef SERIAL_LINK_ENABLE # include "serial_link/system/serial_link.h" #endif @@ -96,6 +97,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. # include "dip_switch.h" #endif +static uint32_t last_input_modification_time = 0; +uint32_t last_input_activity_time(void) { return last_input_modification_time; } +uint32_t last_input_activity_elapsed(void) { return timer_elapsed32(last_input_modification_time); } + +static uint32_t last_matrix_modification_time = 0; +uint32_t last_matrix_activity_time(void) { return last_matrix_modification_time; } +uint32_t last_matrix_activity_elapsed(void) { return timer_elapsed32(last_matrix_modification_time); } +void last_matrix_activity_trigger(void) { last_matrix_modification_time = last_input_modification_time = timer_read32(); } + +static uint32_t last_encoder_modification_time = 0; +uint32_t last_encoder_activity_time(void) { return last_encoder_modification_time; } +uint32_t last_encoder_activity_elapsed(void) { return timer_elapsed32(last_encoder_modification_time); } +void last_encoder_activity_trigger(void) { last_encoder_modification_time = last_input_modification_time = timer_read32(); } + // Only enable this if console is enabled to print to #if defined(DEBUG_MATRIX_SCAN_RATE) static uint32_t matrix_timer = 0; @@ -217,6 +232,7 @@ void keyboard_setup(void) { #ifndef NO_JTAG_DISABLE disable_jtag(); #endif + print_set_sendchar(sendchar); matrix_setup(); keyboard_pre_init_kb(); } @@ -260,6 +276,7 @@ __attribute__((weak)) void housekeeping_task_user(void) {} */ void keyboard_init(void) { timer_init(); + sync_timer_init(); matrix_init(); #ifdef VIA_ENABLE via_init(); @@ -290,15 +307,15 @@ void keyboard_init(void) { #ifdef RGBLIGHT_ENABLE rgblight_init(); #endif +#ifdef RGB_MATRIX_ENABLE + rgb_matrix_init(); +#endif #ifdef ENCODER_ENABLE encoder_init(); #endif #ifdef STENO_ENABLE steno_init(); #endif -#ifdef FAUXCLICKY_ENABLE - fauxclicky_init(); -#endif #ifdef POINTING_DEVICE_ENABLE pointing_device_init(); #endif @@ -317,6 +334,17 @@ void keyboard_init(void) { keyboard_post_init_kb(); /* Always keep this last */ } +/** \brief key_event_task + * + * This function is responsible for calling into other systems when they need to respond to electrical switch press events. + * This is differnet than keycode events as no layer processing, or filtering occurs. + */ +void switch_events(uint8_t row, uint8_t col, bool pressed) { +#if defined(RGB_MATRIX_ENABLE) + process_rgb_matrix(row, col, pressed); +#endif +} + /** \brief Keyboard task: Do keyboard routine jobs * * Do routine keyboard jobs: @@ -337,42 +365,45 @@ void keyboard_task(void) { #ifdef QMK_KEYS_PER_SCAN uint8_t keys_processed = 0; #endif +#ifdef ENCODER_ENABLE + bool encoders_changed = false; +#endif housekeeping_task_kb(); housekeeping_task_user(); -#if defined(OLED_DRIVER_ENABLE) && !defined(OLED_DISABLE_TIMEOUT) - uint8_t ret = matrix_scan(); -#else - matrix_scan(); -#endif + uint8_t matrix_changed = matrix_scan(); + if (matrix_changed) last_matrix_activity_trigger(); - if (should_process_keypress()) { - for (uint8_t r = 0; r < MATRIX_ROWS; r++) { - matrix_row = matrix_get_row(r); - matrix_change = matrix_row ^ matrix_prev[r]; - if (matrix_change) { + for (uint8_t r = 0; r < MATRIX_ROWS; r++) { + matrix_row = matrix_get_row(r); + matrix_change = matrix_row ^ matrix_prev[r]; + if (matrix_change) { #ifdef MATRIX_HAS_GHOST - if (has_ghost_in_row(r, matrix_row)) { - continue; - } + if (has_ghost_in_row(r, matrix_row)) { + continue; + } #endif - if (debug_matrix) matrix_print(); - matrix_row_t col_mask = 1; - for (uint8_t c = 0; c < MATRIX_COLS; c++, col_mask <<= 1) { - if (matrix_change & col_mask) { + if (debug_matrix) matrix_print(); + matrix_row_t col_mask = 1; + for (uint8_t c = 0; c < MATRIX_COLS; c++, col_mask <<= 1) { + if (matrix_change & col_mask) { + if (should_process_keypress()) { action_exec((keyevent_t){ .key = (keypos_t){.row = r, .col = c}, .pressed = (matrix_row & col_mask), .time = (timer_read() | 1) /* time should not be 0 */ }); - // record a processed key - matrix_prev[r] ^= col_mask; + } + // record a processed key + matrix_prev[r] ^= col_mask; + + switch_events(r, c, (matrix_row & col_mask)); + #ifdef QMK_KEYS_PER_SCAN - // only jump out if we have processed "enough" keys. - if (++keys_processed >= QMK_KEYS_PER_SCAN) + // only jump out if we have processed "enough" keys. + if (++keys_processed >= QMK_KEYS_PER_SCAN) #endif - // process a key per task call - goto MATRIX_LOOP_END; - } + // process a key per task call + goto MATRIX_LOOP_END; } } } @@ -394,6 +425,10 @@ MATRIX_LOOP_END: rgblight_task(); #endif +#ifdef RGB_MATRIX_ENABLE + rgb_matrix_task(); +#endif + #if defined(BACKLIGHT_ENABLE) # if defined(BACKLIGHT_PIN) || defined(BACKLIGHT_PINS) backlight_task(); @@ -401,7 +436,8 @@ MATRIX_LOOP_END: #endif #ifdef ENCODER_ENABLE - encoder_read(); + encoders_changed = encoder_read(); + if (encoders_changed) last_encoder_activity_trigger(); #endif #ifdef QWIIC_ENABLE @@ -411,8 +447,12 @@ MATRIX_LOOP_END: #ifdef OLED_DRIVER_ENABLE oled_task(); # ifndef OLED_DISABLE_TIMEOUT - // Wake up oled if user is using those fabulous keys! - if (ret) oled_on(); + // Wake up oled if user is using those fabulous keys or spinning those encoders! +# ifdef ENCODER_ENABLE + if (matrix_changed || encoders_changed) oled_on(); +# else + if (matrix_changed) oled_on(); +# endif # endif #endif diff --git a/tmk_core/common/keyboard.h b/tmk_core/common/keyboard.h index 70e8f7e2c7..eaf74bac58 100644 --- a/tmk_core/common/keyboard.h +++ b/tmk_core/common/keyboard.h @@ -73,6 +73,15 @@ void keyboard_post_init_user(void); void housekeeping_task_kb(void); void housekeeping_task_user(void); +uint32_t last_input_activity_time(void); // Timestamp of the last matrix or encoder activity +uint32_t last_input_activity_elapsed(void); // Number of milliseconds since the last matrix or encoder activity + +uint32_t last_matrix_activity_time(void); // Timestamp of the last matrix activity +uint32_t last_matrix_activity_elapsed(void); // Number of milliseconds since the last matrix activity + +uint32_t last_encoder_activity_time(void); // Timestamp of the last encoder activity +uint32_t last_encoder_activity_elapsed(void); // Number of milliseconds since the last encoder activity + uint32_t get_matrix_scan_rate(void); #ifdef __cplusplus diff --git a/tmk_core/common/keycode.h b/tmk_core/common/keycode.h index d35e44d8dc..efad92b235 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/>. #define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2) #define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT) -#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN5) +#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN8) #define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT) #define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2) @@ -205,6 +205,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #define KC_BTN3 KC_MS_BTN3 #define KC_BTN4 KC_MS_BTN4 #define KC_BTN5 KC_MS_BTN5 +#define KC_BTN6 KC_MS_BTN6 +#define KC_BTN7 KC_MS_BTN7 +#define KC_BTN8 KC_MS_BTN8 #define KC_WH_U KC_MS_WH_UP #define KC_WH_D KC_MS_WH_DOWN #define KC_WH_L KC_MS_WH_LEFT @@ -521,15 +524,18 @@ enum internal_special_keycodes { enum mouse_keys { /* Mouse Buttons */ - KC_MS_UP = 0xF0, + KC_MS_UP = 0xED, KC_MS_DOWN, KC_MS_LEFT, - KC_MS_RIGHT, + KC_MS_RIGHT, // 0xF0 KC_MS_BTN1, KC_MS_BTN2, KC_MS_BTN3, KC_MS_BTN4, KC_MS_BTN5, + KC_MS_BTN6, + KC_MS_BTN7, + KC_MS_BTN8, /* Mouse Wheel */ KC_MS_WH_UP, @@ -540,5 +546,5 @@ enum mouse_keys { /* Acceleration */ KC_MS_ACCEL0, KC_MS_ACCEL1, - KC_MS_ACCEL2 + KC_MS_ACCEL2 // 0xFF }; diff --git a/tmk_core/common/lib_printf.mk b/tmk_core/common/lib_printf.mk new file mode 100644 index 0000000000..10d2d8468d --- /dev/null +++ b/tmk_core/common/lib_printf.mk @@ -0,0 +1,9 @@ +PRINTF_PATH = $(LIB_PATH)/printf + +TMK_COMMON_SRC += $(PRINTF_PATH)/printf.c +TMK_COMMON_SRC += $(COMMON_DIR)/printf.c +TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_FLOAT +TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_EXPONENTIAL +TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_LONG_LONG +TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_PTRDIFF_T +VPATH += $(PRINTF_PATH) diff --git a/tmk_core/common/mousekey.c b/tmk_core/common/mousekey.c deleted file mode 100644 index ef18bcf1a8..0000000000 --- a/tmk_core/common/mousekey.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright 2011 Jun Wako <wakojun@gmail.com> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <stdint.h> -#include "keycode.h" -#include "host.h" -#include "timer.h" -#include "print.h" -#include "debug.h" -#include "mousekey.h" - -inline int8_t times_inv_sqrt2(int8_t x) { - // 181/256 is pretty close to 1/sqrt(2) - // 0.70703125 0.707106781 - // 1 too small for x=99 and x=198 - // This ends up being a mult and discard lower 8 bits - return (x * 181) >> 8; -} - -static report_mouse_t mouse_report = {0}; -static void mousekey_debug(void); -static uint8_t mousekey_accel = 0; -static uint8_t mousekey_repeat = 0; -static uint8_t mousekey_wheel_repeat = 0; - -#ifndef MK_3_SPEED - -static uint16_t last_timer_c = 0; -static uint16_t last_timer_w = 0; - -/* - * Mouse keys acceleration algorithm - * http://en.wikipedia.org/wiki/Mouse_keys - * - * speed = delta * max_speed * (repeat / time_to_max)**((1000+curve)/1000) - */ -/* milliseconds between the initial key press and first repeated motion event (0-2550) */ -uint8_t mk_delay = MOUSEKEY_DELAY / 10; -/* milliseconds between repeated motion events (0-255) */ -uint8_t mk_interval = MOUSEKEY_INTERVAL; -/* steady speed (in action_delta units) applied each event (0-255) */ -uint8_t mk_max_speed = MOUSEKEY_MAX_SPEED; -/* number of events (count) accelerating to steady speed (0-255) */ -uint8_t mk_time_to_max = MOUSEKEY_TIME_TO_MAX; -/* ramp used to reach maximum pointer speed (NOT SUPPORTED) */ -// int8_t mk_curve = 0; -/* wheel params */ -/* milliseconds between the initial key press and first repeated motion event (0-2550) */ -uint8_t mk_wheel_delay = MOUSEKEY_WHEEL_DELAY / 10; -/* milliseconds between repeated motion events (0-255) */ -uint8_t mk_wheel_interval = MOUSEKEY_WHEEL_INTERVAL; -uint8_t mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED; -uint8_t mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX; - -# ifndef MK_COMBINED - -static uint8_t move_unit(void) { - uint16_t unit; - if (mousekey_accel & (1 << 0)) { - unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 4; - } else if (mousekey_accel & (1 << 1)) { - unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 2; - } else if (mousekey_accel & (1 << 2)) { - unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed); - } else if (mousekey_repeat == 0) { - unit = MOUSEKEY_MOVE_DELTA; - } else if (mousekey_repeat >= mk_time_to_max) { - unit = MOUSEKEY_MOVE_DELTA * mk_max_speed; - } else { - unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed * mousekey_repeat) / mk_time_to_max; - } - return (unit > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : (unit == 0 ? 1 : unit)); -} - -static uint8_t wheel_unit(void) { - uint16_t unit; - if (mousekey_accel & (1 << 0)) { - unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 4; - } else if (mousekey_accel & (1 << 1)) { - unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 2; - } else if (mousekey_accel & (1 << 2)) { - unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed); - } else if (mousekey_wheel_repeat == 0) { - unit = MOUSEKEY_WHEEL_DELTA; - } else if (mousekey_wheel_repeat >= mk_wheel_time_to_max) { - unit = MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed; - } else { - unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed * mousekey_wheel_repeat) / mk_wheel_time_to_max; - } - return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit)); -} - -# else /* #ifndef MK_COMBINED */ - -static uint8_t move_unit(void) { - uint16_t unit; - if (mousekey_accel & (1 << 0)) { - unit = 1; - } else if (mousekey_accel & (1 << 1)) { - unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 2; - } else if (mousekey_accel & (1 << 2)) { - unit = MOUSEKEY_MOVE_MAX; - } else if (mousekey_repeat == 0) { - unit = MOUSEKEY_MOVE_DELTA; - } else if (mousekey_repeat >= mk_time_to_max) { - unit = MOUSEKEY_MOVE_DELTA * mk_max_speed; - } else { - unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed * mousekey_repeat) / mk_time_to_max; - } - return (unit > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : (unit == 0 ? 1 : unit)); -} - -static uint8_t wheel_unit(void) { - uint16_t unit; - if (mousekey_accel & (1 << 0)) { - unit = 1; - } else if (mousekey_accel & (1 << 1)) { - unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 2; - } else if (mousekey_accel & (1 << 2)) { - unit = MOUSEKEY_WHEEL_MAX; - } else if (mousekey_repeat == 0) { - unit = MOUSEKEY_WHEEL_DELTA; - } else if (mousekey_repeat >= mk_wheel_time_to_max) { - unit = MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed; - } else { - unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed * mousekey_repeat) / mk_wheel_time_to_max; - } - return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit)); -} - -# endif /* #ifndef MK_COMBINED */ - -void mousekey_task(void) { - // report cursor and scroll movement independently - report_mouse_t const tmpmr = mouse_report; - - mouse_report.x = 0; - mouse_report.y = 0; - mouse_report.v = 0; - mouse_report.h = 0; - - if ((tmpmr.x || tmpmr.y) && timer_elapsed(last_timer_c) > (mousekey_repeat ? mk_interval : mk_delay * 10)) { - if (mousekey_repeat != UINT8_MAX) mousekey_repeat++; - if (tmpmr.x != 0) mouse_report.x = move_unit() * ((tmpmr.x > 0) ? 1 : -1); - if (tmpmr.y != 0) mouse_report.y = move_unit() * ((tmpmr.y > 0) ? 1 : -1); - - /* diagonal move [1/sqrt(2)] */ - if (mouse_report.x && mouse_report.y) { - mouse_report.x = times_inv_sqrt2(mouse_report.x); - if (mouse_report.x == 0) { - mouse_report.x = 1; - } - mouse_report.y = times_inv_sqrt2(mouse_report.y); - if (mouse_report.y == 0) { - mouse_report.y = 1; - } - } - } - if ((tmpmr.v || tmpmr.h) && timer_elapsed(last_timer_w) > (mousekey_wheel_repeat ? mk_wheel_interval : mk_wheel_delay * 10)) { - if (mousekey_wheel_repeat != UINT8_MAX) mousekey_wheel_repeat++; - if (tmpmr.v != 0) mouse_report.v = wheel_unit() * ((tmpmr.v > 0) ? 1 : -1); - if (tmpmr.h != 0) mouse_report.h = wheel_unit() * ((tmpmr.h > 0) ? 1 : -1); - - /* diagonal move [1/sqrt(2)] */ - if (mouse_report.v && mouse_report.h) { - mouse_report.v = times_inv_sqrt2(mouse_report.v); - if (mouse_report.v == 0) { - mouse_report.v = 1; - } - mouse_report.h = times_inv_sqrt2(mouse_report.h); - if (mouse_report.h == 0) { - mouse_report.h = 1; - } - } - } - - if (mouse_report.x || mouse_report.y || mouse_report.v || mouse_report.h) mousekey_send(); - mouse_report = tmpmr; -} - -void mousekey_on(uint8_t code) { - if (code == KC_MS_UP) - mouse_report.y = move_unit() * -1; - else if (code == KC_MS_DOWN) - mouse_report.y = move_unit(); - else if (code == KC_MS_LEFT) - mouse_report.x = move_unit() * -1; - else if (code == KC_MS_RIGHT) - mouse_report.x = move_unit(); - else if (code == KC_MS_WH_UP) - mouse_report.v = wheel_unit(); - else if (code == KC_MS_WH_DOWN) - mouse_report.v = wheel_unit() * -1; - else if (code == KC_MS_WH_LEFT) - mouse_report.h = wheel_unit() * -1; - else if (code == KC_MS_WH_RIGHT) - mouse_report.h = wheel_unit(); - else if (code == KC_MS_BTN1) - mouse_report.buttons |= MOUSE_BTN1; - else if (code == KC_MS_BTN2) - mouse_report.buttons |= MOUSE_BTN2; - else if (code == KC_MS_BTN3) - mouse_report.buttons |= MOUSE_BTN3; - else if (code == KC_MS_BTN4) - mouse_report.buttons |= MOUSE_BTN4; - else if (code == KC_MS_BTN5) - mouse_report.buttons |= MOUSE_BTN5; - else if (code == KC_MS_ACCEL0) - mousekey_accel |= (1 << 0); - else if (code == KC_MS_ACCEL1) - mousekey_accel |= (1 << 1); - else if (code == KC_MS_ACCEL2) - mousekey_accel |= (1 << 2); -} - -void mousekey_off(uint8_t code) { - if (code == KC_MS_UP && mouse_report.y < 0) - mouse_report.y = 0; - else if (code == KC_MS_DOWN && mouse_report.y > 0) - mouse_report.y = 0; - else if (code == KC_MS_LEFT && mouse_report.x < 0) - mouse_report.x = 0; - else if (code == KC_MS_RIGHT && mouse_report.x > 0) - mouse_report.x = 0; - else if (code == KC_MS_WH_UP && mouse_report.v > 0) - mouse_report.v = 0; - else if (code == KC_MS_WH_DOWN && mouse_report.v < 0) - mouse_report.v = 0; - else if (code == KC_MS_WH_LEFT && mouse_report.h < 0) - mouse_report.h = 0; - else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0) - mouse_report.h = 0; - else if (code == KC_MS_BTN1) - mouse_report.buttons &= ~MOUSE_BTN1; - else if (code == KC_MS_BTN2) - mouse_report.buttons &= ~MOUSE_BTN2; - else if (code == KC_MS_BTN3) - mouse_report.buttons &= ~MOUSE_BTN3; - else if (code == KC_MS_BTN4) - mouse_report.buttons &= ~MOUSE_BTN4; - else if (code == KC_MS_BTN5) - mouse_report.buttons &= ~MOUSE_BTN5; - else if (code == KC_MS_ACCEL0) - mousekey_accel &= ~(1 << 0); - else if (code == KC_MS_ACCEL1) - mousekey_accel &= ~(1 << 1); - else if (code == KC_MS_ACCEL2) - mousekey_accel &= ~(1 << 2); - if (mouse_report.x == 0 && mouse_report.y == 0) mousekey_repeat = 0; - if (mouse_report.v == 0 && mouse_report.h == 0) mousekey_wheel_repeat = 0; -} - -#else /* #ifndef MK_3_SPEED */ - -enum { mkspd_unmod, mkspd_0, mkspd_1, mkspd_2, mkspd_COUNT }; -# ifndef MK_MOMENTARY_ACCEL -static uint8_t mk_speed = mkspd_1; -# else -static uint8_t mk_speed = mkspd_unmod; -static uint8_t mkspd_DEFAULT = mkspd_unmod; -# endif -static uint16_t last_timer_c = 0; -static uint16_t last_timer_w = 0; -uint16_t c_offsets[mkspd_COUNT] = {MK_C_OFFSET_UNMOD, MK_C_OFFSET_0, MK_C_OFFSET_1, MK_C_OFFSET_2}; -uint16_t c_intervals[mkspd_COUNT] = {MK_C_INTERVAL_UNMOD, MK_C_INTERVAL_0, MK_C_INTERVAL_1, MK_C_INTERVAL_2}; -uint16_t w_offsets[mkspd_COUNT] = {MK_W_OFFSET_UNMOD, MK_W_OFFSET_0, MK_W_OFFSET_1, MK_W_OFFSET_2}; -uint16_t w_intervals[mkspd_COUNT] = {MK_W_INTERVAL_UNMOD, MK_W_INTERVAL_0, MK_W_INTERVAL_1, MK_W_INTERVAL_2}; - -void mousekey_task(void) { - // report cursor and scroll movement independently - report_mouse_t const tmpmr = mouse_report; - mouse_report.x = 0; - mouse_report.y = 0; - mouse_report.v = 0; - mouse_report.h = 0; - - if ((tmpmr.x || tmpmr.y) && timer_elapsed(last_timer_c) > c_intervals[mk_speed]) { - mouse_report.x = tmpmr.x; - mouse_report.y = tmpmr.y; - } - if ((tmpmr.h || tmpmr.v) && timer_elapsed(last_timer_w) > w_intervals[mk_speed]) { - mouse_report.v = tmpmr.v; - mouse_report.h = tmpmr.h; - } - - if (mouse_report.x || mouse_report.y || mouse_report.v || mouse_report.h) mousekey_send(); - mouse_report = tmpmr; -} - -void adjust_speed(void) { - uint16_t const c_offset = c_offsets[mk_speed]; - uint16_t const w_offset = w_offsets[mk_speed]; - if (mouse_report.x > 0) mouse_report.x = c_offset; - if (mouse_report.x < 0) mouse_report.x = c_offset * -1; - if (mouse_report.y > 0) mouse_report.y = c_offset; - if (mouse_report.y < 0) mouse_report.y = c_offset * -1; - if (mouse_report.h > 0) mouse_report.h = w_offset; - if (mouse_report.h < 0) mouse_report.h = w_offset * -1; - if (mouse_report.v > 0) mouse_report.v = w_offset; - if (mouse_report.v < 0) mouse_report.v = w_offset * -1; - // adjust for diagonals - if (mouse_report.x && mouse_report.y) { - mouse_report.x = times_inv_sqrt2(mouse_report.x); - if (mouse_report.x == 0) { - mouse_report.x = 1; - } - mouse_report.y = times_inv_sqrt2(mouse_report.y); - if (mouse_report.y == 0) { - mouse_report.y = 1; - } - } - if (mouse_report.h && mouse_report.v) { - mouse_report.h = times_inv_sqrt2(mouse_report.h); - mouse_report.v = times_inv_sqrt2(mouse_report.v); - } -} - -void mousekey_on(uint8_t code) { - uint16_t const c_offset = c_offsets[mk_speed]; - uint16_t const w_offset = w_offsets[mk_speed]; - uint8_t const old_speed = mk_speed; - if (code == KC_MS_UP) - mouse_report.y = c_offset * -1; - else if (code == KC_MS_DOWN) - mouse_report.y = c_offset; - else if (code == KC_MS_LEFT) - mouse_report.x = c_offset * -1; - else if (code == KC_MS_RIGHT) - mouse_report.x = c_offset; - else if (code == KC_MS_WH_UP) - mouse_report.v = w_offset; - else if (code == KC_MS_WH_DOWN) - mouse_report.v = w_offset * -1; - else if (code == KC_MS_WH_LEFT) - mouse_report.h = w_offset * -1; - else if (code == KC_MS_WH_RIGHT) - mouse_report.h = w_offset; - else if (code == KC_MS_BTN1) - mouse_report.buttons |= MOUSE_BTN1; - else if (code == KC_MS_BTN2) - mouse_report.buttons |= MOUSE_BTN2; - else if (code == KC_MS_BTN3) - mouse_report.buttons |= MOUSE_BTN3; - else if (code == KC_MS_BTN4) - mouse_report.buttons |= MOUSE_BTN4; - else if (code == KC_MS_BTN5) - mouse_report.buttons |= MOUSE_BTN5; - else if (code == KC_MS_ACCEL0) - mk_speed = mkspd_0; - else if (code == KC_MS_ACCEL1) - mk_speed = mkspd_1; - else if (code == KC_MS_ACCEL2) - mk_speed = mkspd_2; - if (mk_speed != old_speed) adjust_speed(); -} - -void mousekey_off(uint8_t code) { -# ifdef MK_MOMENTARY_ACCEL - uint8_t const old_speed = mk_speed; -# endif - if (code == KC_MS_UP && mouse_report.y < 0) - mouse_report.y = 0; - else if (code == KC_MS_DOWN && mouse_report.y > 0) - mouse_report.y = 0; - else if (code == KC_MS_LEFT && mouse_report.x < 0) - mouse_report.x = 0; - else if (code == KC_MS_RIGHT && mouse_report.x > 0) - mouse_report.x = 0; - else if (code == KC_MS_WH_UP && mouse_report.v > 0) - mouse_report.v = 0; - else if (code == KC_MS_WH_DOWN && mouse_report.v < 0) - mouse_report.v = 0; - else if (code == KC_MS_WH_LEFT && mouse_report.h < 0) - mouse_report.h = 0; - else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0) - mouse_report.h = 0; - else if (code == KC_MS_BTN1) - mouse_report.buttons &= ~MOUSE_BTN1; - else if (code == KC_MS_BTN2) - mouse_report.buttons &= ~MOUSE_BTN2; - else if (code == KC_MS_BTN3) - mouse_report.buttons &= ~MOUSE_BTN3; - else if (code == KC_MS_BTN4) - mouse_report.buttons &= ~MOUSE_BTN4; - else if (code == KC_MS_BTN5) - mouse_report.buttons &= ~MOUSE_BTN5; -# ifdef MK_MOMENTARY_ACCEL - else if (code == KC_MS_ACCEL0) - mk_speed = mkspd_DEFAULT; - else if (code == KC_MS_ACCEL1) - mk_speed = mkspd_DEFAULT; - else if (code == KC_MS_ACCEL2) - mk_speed = mkspd_DEFAULT; - if (mk_speed != old_speed) adjust_speed(); -# endif -} - -#endif /* #ifndef MK_3_SPEED */ - -void mousekey_send(void) { - mousekey_debug(); - uint16_t time = timer_read(); - if (mouse_report.x || mouse_report.y) last_timer_c = time; - if (mouse_report.v || mouse_report.h) last_timer_w = time; - host_mouse_send(&mouse_report); -} - -void mousekey_clear(void) { - mouse_report = (report_mouse_t){}; - mousekey_repeat = 0; - mousekey_wheel_repeat = 0; - mousekey_accel = 0; -} - -static void mousekey_debug(void) { - if (!debug_mouse) return; - print("mousekey [btn|x y v h](rep/acl): ["); - phex(mouse_report.buttons); - print("|"); - print_decs(mouse_report.x); - print(" "); - print_decs(mouse_report.y); - print(" "); - print_decs(mouse_report.v); - print(" "); - print_decs(mouse_report.h); - print("]("); - print_dec(mousekey_repeat); - print("/"); - print_dec(mousekey_accel); - print(")\n"); -} diff --git a/tmk_core/common/mousekey.h b/tmk_core/common/mousekey.h deleted file mode 100644 index 300d262f5d..0000000000 --- a/tmk_core/common/mousekey.h +++ /dev/null @@ -1,142 +0,0 @@ -/* -Copyright 2011 Jun Wako <wakojun@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#pragma once - -#include <stdbool.h> -#include "host.h" - -#ifndef MK_3_SPEED - -/* max value on report descriptor */ -# ifndef MOUSEKEY_MOVE_MAX -# define MOUSEKEY_MOVE_MAX 127 -# elif MOUSEKEY_MOVE_MAX > 127 -# error MOUSEKEY_MOVE_MAX needs to be smaller than 127 -# endif - -# ifndef MOUSEKEY_WHEEL_MAX -# define MOUSEKEY_WHEEL_MAX 127 -# elif MOUSEKEY_WHEEL_MAX > 127 -# error MOUSEKEY_WHEEL_MAX needs to be smaller than 127 -# endif - -# ifndef MOUSEKEY_MOVE_DELTA -# define MOUSEKEY_MOVE_DELTA 5 -# endif -# ifndef MOUSEKEY_WHEEL_DELTA -# define MOUSEKEY_WHEEL_DELTA 1 -# endif -# ifndef MOUSEKEY_DELAY -# define MOUSEKEY_DELAY 300 -# endif -# ifndef MOUSEKEY_INTERVAL -# define MOUSEKEY_INTERVAL 50 -# endif -# ifndef MOUSEKEY_MAX_SPEED -# define MOUSEKEY_MAX_SPEED 10 -# endif -# ifndef MOUSEKEY_TIME_TO_MAX -# define MOUSEKEY_TIME_TO_MAX 20 -# endif -# ifndef MOUSEKEY_WHEEL_DELAY -# define MOUSEKEY_WHEEL_DELAY 300 -# endif -# ifndef MOUSEKEY_WHEEL_INTERVAL -# define MOUSEKEY_WHEEL_INTERVAL 100 -# endif -# ifndef MOUSEKEY_WHEEL_MAX_SPEED -# define MOUSEKEY_WHEEL_MAX_SPEED 8 -# endif -# ifndef MOUSEKEY_WHEEL_TIME_TO_MAX -# define MOUSEKEY_WHEEL_TIME_TO_MAX 40 -# endif - -#else /* #ifndef MK_3_SPEED */ - -# ifndef MK_C_OFFSET_UNMOD -# define MK_C_OFFSET_UNMOD 16 -# endif -# ifndef MK_C_INTERVAL_UNMOD -# define MK_C_INTERVAL_UNMOD 16 -# endif -# ifndef MK_C_OFFSET_0 -# define MK_C_OFFSET_0 1 -# endif -# ifndef MK_C_INTERVAL_0 -# define MK_C_INTERVAL_0 32 -# endif -# ifndef MK_C_OFFSET_1 -# define MK_C_OFFSET_1 4 -# endif -# ifndef MK_C_INTERVAL_1 -# define MK_C_INTERVAL_1 16 -# endif -# ifndef MK_C_OFFSET_2 -# define MK_C_OFFSET_2 32 -# endif -# ifndef MK_C_INTERVAL_2 -# define MK_C_INTERVAL_2 16 -# endif - -# ifndef MK_W_OFFSET_UNMOD -# define MK_W_OFFSET_UNMOD 1 -# endif -# ifndef MK_W_INTERVAL_UNMOD -# define MK_W_INTERVAL_UNMOD 40 -# endif -# ifndef MK_W_OFFSET_0 -# define MK_W_OFFSET_0 1 -# endif -# ifndef MK_W_INTERVAL_0 -# define MK_W_INTERVAL_0 360 -# endif -# ifndef MK_W_OFFSET_1 -# define MK_W_OFFSET_1 1 -# endif -# ifndef MK_W_INTERVAL_1 -# define MK_W_INTERVAL_1 120 -# endif -# ifndef MK_W_OFFSET_2 -# define MK_W_OFFSET_2 1 -# endif -# ifndef MK_W_INTERVAL_2 -# define MK_W_INTERVAL_2 20 -# endif - -#endif /* #ifndef MK_3_SPEED */ - -#ifdef __cplusplus -extern "C" { -#endif - -extern uint8_t mk_delay; -extern uint8_t mk_interval; -extern uint8_t mk_max_speed; -extern uint8_t mk_time_to_max; -extern uint8_t mk_wheel_max_speed; -extern uint8_t mk_wheel_time_to_max; - -void mousekey_task(void); -void mousekey_on(uint8_t code); -void mousekey_off(uint8_t code); -void mousekey_clear(void); -void mousekey_send(void); - -#ifdef __cplusplus -} -#endif diff --git a/tmk_core/common/print.h b/tmk_core/common/print.h index 647a5aa053..48f91e6342 100644 --- a/tmk_core/common/print.h +++ b/tmk_core/common/print.h @@ -27,104 +27,76 @@ #include <stdint.h> #include <stdbool.h> #include "util.h" +#include "sendchar.h" +#include "progmem.h" -#if defined(PROTOCOL_CHIBIOS) || defined(PROTOCOL_ARM_ATSAM) -# define PSTR(x) x -#endif +void print_set_sendchar(sendchar_func_t func); #ifndef NO_PRINT - -# if defined(__AVR__) /* __AVR__ */ - -# include "avr/xprintf.h" - -# ifdef USER_PRINT /* USER_PRINT */ - -// Remove normal print defines -# define print(s) -# define println(s) -# undef xprintf -# define xprintf(fmt, ...) - -// Create user print defines -# define uprint(s) xputs(PSTR(s)) -# define uprintln(s) xputs(PSTR(s "\r\n")) -# define uprintf(fmt, ...) __xprintf(PSTR(fmt), ##__VA_ARGS__) - -# else /* NORMAL PRINT */ - -// Create user & normal print defines -# define print(s) xputs(PSTR(s)) -# define println(s) xputs(PSTR(s "\r\n")) -# define uprint(s) print(s) -# define uprintln(s) println(s) -# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__) - -# endif /* USER_PRINT / NORMAL PRINT */ - -# ifdef __cplusplus -extern "C" -# endif - - /* function pointer of sendchar to be used by print utility */ - void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t)); - -# elif defined(PROTOCOL_CHIBIOS) /* PROTOCOL_CHIBIOS */ - +# if __has_include_next("_print.h") +# include_next "_print.h" /* Include the platforms print.h */ +# else +// Fall back to lib/printf # include "printf.h" // lib/printf/printf.h -# ifdef USER_PRINT /* USER_PRINT */ - -// Remove normal print defines -# define print(s) -# define println(s) -# define xprintf(fmt, ...) - -// Create user print defines -# define uprint(s) printf(s) -# define uprintln(s) printf(s "\r\n") -# define uprintf printf - -# else /* NORMAL PRINT */ // Create user & normal print defines -# define print(s) printf(s) -# define println(s) printf(s "\r\n") -# define xprintf printf -# define uprint(s) printf(s) -# define uprintln(s) printf(s "\r\n") -# define uprintf printf +# define print(s) printf(s) +# define println(s) printf(s "\r\n") +# define xprintf printf +# define uprint(s) printf(s) +# define uprintln(s) printf(s "\r\n") +# define uprintf printf -# endif /* USER_PRINT / NORMAL PRINT */ - -# elif defined(PROTOCOL_ARM_ATSAM) /* PROTOCOL_ARM_ATSAM */ - -# include "arm_atsam/printf.h" +# endif /* __AVR__ / PROTOCOL_CHIBIOS / PROTOCOL_ARM_ATSAM */ +#else /* NO_PRINT */ +# undef xprintf +// Remove print defines +# define print(s) +# define println(s) +# define xprintf(fmt, ...) +# define uprintf(fmt, ...) +# define uprint(s) +# define uprintln(s) -# ifdef USER_PRINT /* USER_PRINT */ +#endif /* NO_PRINT */ +#ifdef USER_PRINT // Remove normal print defines -# define print(s) -# define println(s) -# define xprintf(fmt, ...) - -// Create user print defines -# define uprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__) -# define uprint(s) xprintf(s) -# define uprintln(s) xprintf(s "\r\n") - -# else /* NORMAL PRINT */ - -// Create user & normal print defines -# define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__) -# define print(s) xprintf(s) -# define println(s) xprintf(s "\r\n") -# define uprint(s) print(s) -# define uprintln(s) println(s) -# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__) - -# endif /* USER_PRINT / NORMAL PRINT */ +# undef print +# undef println +# undef xprintf +# define print(s) +# define println(s) +# define xprintf(fmt, ...) +#endif -# endif /* __AVR__ / PROTOCOL_CHIBIOS / PROTOCOL_ARM_ATSAM */ +#define print_dec(i) xprintf("%u", i) +#define print_decs(i) xprintf("%d", i) +/* hex */ +#define print_hex4(i) xprintf("%X", i) +#define print_hex8(i) xprintf("%02X", i) +#define print_hex16(i) xprintf("%04X", i) +#define print_hex32(i) xprintf("%08lX", i) +/* binary */ +#define print_bin4(i) xprintf("%04b", i) +#define print_bin8(i) xprintf("%08b", i) +#define print_bin16(i) xprintf("%016b", i) +#define print_bin32(i) xprintf("%032lb", i) +#define print_bin_reverse8(i) xprintf("%08b", bitrev(i)) +#define print_bin_reverse16(i) xprintf("%016b", bitrev16(i)) +#define print_bin_reverse32(i) xprintf("%032lb", bitrev32(i)) +/* print value utility */ +#define print_val_dec(v) xprintf(#v ": %u\n", v) +#define print_val_decs(v) xprintf(#v ": %d\n", v) +#define print_val_hex8(v) xprintf(#v ": %X\n", v) +#define print_val_hex16(v) xprintf(#v ": %02X\n", v) +#define print_val_hex32(v) xprintf(#v ": %04lX\n", v) +#define print_val_bin8(v) xprintf(#v ": %08b\n", v) +#define print_val_bin16(v) xprintf(#v ": %016b\n", v) +#define print_val_bin32(v) xprintf(#v ": %032lb\n", v) +#define print_val_bin_reverse8(v) xprintf(#v ": %08b\n", bitrev(v)) +#define print_val_bin_reverse16(v) xprintf(#v ": %016b\n", bitrev16(v)) +#define print_val_bin_reverse32(v) xprintf(#v ": %032lb\n", bitrev32(v)) // User print disables the normal print messages in the body of QMK/TMK code and // is meant as a lightweight alternative to NOPRINT. Use it when you only want to do @@ -132,139 +104,32 @@ extern "C" // print (and store their wasteful strings). // // !!! DO NOT USE USER PRINT CALLS IN THE BODY OF QMK/TMK !!! -// -# ifdef USER_PRINT - -// Disable normal print -# define print_dec(data) -# define print_decs(data) -# define print_hex4(data) -# define print_hex8(data) -# define print_hex16(data) -# define print_hex32(data) -# define print_bin4(data) -# define print_bin8(data) -# define print_bin16(data) -# define print_bin32(data) -# define print_bin_reverse8(data) -# define print_bin_reverse16(data) -# define print_bin_reverse32(data) -# define print_val_dec(v) -# define print_val_decs(v) -# define print_val_hex8(v) -# define print_val_hex16(v) -# define print_val_hex32(v) -# define print_val_bin8(v) -# define print_val_bin16(v) -# define print_val_bin32(v) -# define print_val_bin_reverse8(v) -# define print_val_bin_reverse16(v) -# define print_val_bin_reverse32(v) - -# else /* NORMAL_PRINT */ - -// Enable normal print -/* decimal */ -# define print_dec(i) xprintf("%u", i) -# define print_decs(i) xprintf("%d", i) -/* hex */ -# define print_hex4(i) xprintf("%X", i) -# define print_hex8(i) xprintf("%02X", i) -# define print_hex16(i) xprintf("%04X", i) -# define print_hex32(i) xprintf("%08lX", i) -/* binary */ -# define print_bin4(i) xprintf("%04b", i) -# define print_bin8(i) xprintf("%08b", i) -# define print_bin16(i) xprintf("%016b", i) -# define print_bin32(i) xprintf("%032lb", i) -# define print_bin_reverse8(i) xprintf("%08b", bitrev(i)) -# define print_bin_reverse16(i) xprintf("%016b", bitrev16(i)) -# define print_bin_reverse32(i) xprintf("%032lb", bitrev32(i)) -/* print value utility */ -# define print_val_dec(v) xprintf(# v ": %u\n", v) -# define print_val_decs(v) xprintf(# v ": %d\n", v) -# define print_val_hex8(v) xprintf(# v ": %X\n", v) -# define print_val_hex16(v) xprintf(# v ": %02X\n", v) -# define print_val_hex32(v) xprintf(# v ": %04lX\n", v) -# define print_val_bin8(v) xprintf(# v ": %08b\n", v) -# define print_val_bin16(v) xprintf(# v ": %016b\n", v) -# define print_val_bin32(v) xprintf(# v ": %032lb\n", v) -# define print_val_bin_reverse8(v) xprintf(# v ": %08b\n", bitrev(v)) -# define print_val_bin_reverse16(v) xprintf(# v ": %016b\n", bitrev16(v)) -# define print_val_bin_reverse32(v) xprintf(# v ": %032lb\n", bitrev32(v)) - -# endif /* USER_PRINT / NORMAL_PRINT */ - -// User Print /* decimal */ -# define uprint_dec(i) uprintf("%u", i) -# define uprint_decs(i) uprintf("%d", i) +#define uprint_dec(i) uprintf("%u", i) +#define uprint_decs(i) uprintf("%d", i) /* hex */ -# define uprint_hex4(i) uprintf("%X", i) -# define uprint_hex8(i) uprintf("%02X", i) -# define uprint_hex16(i) uprintf("%04X", i) -# define uprint_hex32(i) uprintf("%08lX", i) +#define uprint_hex4(i) uprintf("%X", i) +#define uprint_hex8(i) uprintf("%02X", i) +#define uprint_hex16(i) uprintf("%04X", i) +#define uprint_hex32(i) uprintf("%08lX", i) /* binary */ -# define uprint_bin4(i) uprintf("%04b", i) -# define uprint_bin8(i) uprintf("%08b", i) -# define uprint_bin16(i) uprintf("%016b", i) -# define uprint_bin32(i) uprintf("%032lb", i) -# define uprint_bin_reverse8(i) uprintf("%08b", bitrev(i)) -# define uprint_bin_reverse16(i) uprintf("%016b", bitrev16(i)) -# define uprint_bin_reverse32(i) uprintf("%032lb", bitrev32(i)) +#define uprint_bin4(i) uprintf("%04b", i) +#define uprint_bin8(i) uprintf("%08b", i) +#define uprint_bin16(i) uprintf("%016b", i) +#define uprint_bin32(i) uprintf("%032lb", i) +#define uprint_bin_reverse8(i) uprintf("%08b", bitrev(i)) +#define uprint_bin_reverse16(i) uprintf("%016b", bitrev16(i)) +#define uprint_bin_reverse32(i) uprintf("%032lb", bitrev32(i)) /* print value utility */ -# define uprint_val_dec(v) uprintf(# v ": %u\n", v) -# define uprint_val_decs(v) uprintf(# v ": %d\n", v) -# define uprint_val_hex8(v) uprintf(# v ": %X\n", v) -# define uprint_val_hex16(v) uprintf(# v ": %02X\n", v) -# define uprint_val_hex32(v) uprintf(# v ": %04lX\n", v) -# define uprint_val_bin8(v) uprintf(# v ": %08b\n", v) -# define uprint_val_bin16(v) uprintf(# v ": %016b\n", v) -# define uprint_val_bin32(v) uprintf(# v ": %032lb\n", v) -# define uprint_val_bin_reverse8(v) uprintf(# v ": %08b\n", bitrev(v)) -# define uprint_val_bin_reverse16(v) uprintf(# v ": %016b\n", bitrev16(v)) -# define uprint_val_bin_reverse32(v) uprintf(# v ": %032lb\n", bitrev32(v)) - -#else /* NO_PRINT */ - -# define xprintf(fmt, ...) -# define print(s) -# define println(s) -# define print_set_sendchar(func) -# define print_dec(data) -# define print_decs(data) -# define print_hex4(data) -# define print_hex8(data) -# define print_hex16(data) -# define print_hex32(data) -# define print_bin4(data) -# define print_bin8(data) -# define print_bin16(data) -# define print_bin32(data) -# define print_bin_reverse8(data) -# define print_bin_reverse16(data) -# define print_bin_reverse32(data) -# define print_val_dec(v) -# define print_val_decs(v) -# define print_val_hex8(v) -# define print_val_hex16(v) -# define print_val_hex32(v) -# define print_val_bin8(v) -# define print_val_bin16(v) -# define print_val_bin32(v) -# define print_val_bin_reverse8(v) -# define print_val_bin_reverse16(v) -# define print_val_bin_reverse32(v) - -#endif /* NO_PRINT */ - -/* Backward compatiblitly for old name */ -#define pdec(data) print_dec(data) -#define pdec16(data) print_dec(data) -#define phex(data) print_hex8(data) -#define phex16(data) print_hex16(data) -#define pbin(data) print_bin8(data) -#define pbin16(data) print_bin16(data) -#define pbin_reverse(data) print_bin_reverse8(data) -#define pbin_reverse16(data) print_bin_reverse16(data) +#define uprint_val_dec(v) uprintf(#v ": %u\n", v) +#define uprint_val_decs(v) uprintf(#v ": %d\n", v) +#define uprint_val_hex8(v) uprintf(#v ": %X\n", v) +#define uprint_val_hex16(v) uprintf(#v ": %02X\n", v) +#define uprint_val_hex32(v) uprintf(#v ": %04lX\n", v) +#define uprint_val_bin8(v) uprintf(#v ": %08b\n", v) +#define uprint_val_bin16(v) uprintf(#v ": %016b\n", v) +#define uprint_val_bin32(v) uprintf(#v ": %032lb\n", v) +#define uprint_val_bin_reverse8(v) uprintf(#v ": %08b\n", bitrev(v)) +#define uprint_val_bin_reverse16(v) uprintf(#v ": %016b\n", bitrev16(v)) +#define uprint_val_bin_reverse32(v) uprintf(#v ": %032lb\n", bitrev32(v)) diff --git a/tmk_core/common/printf.c b/tmk_core/common/printf.c new file mode 100644 index 0000000000..e8440e55ee --- /dev/null +++ b/tmk_core/common/printf.c @@ -0,0 +1,27 @@ +/* +Copyright 2011 Jun Wako <wakojun@gmail.com> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +#include <stddef.h> +#include "sendchar.h" + +// bind lib/printf to console interface - sendchar + +static int8_t null_sendchar_func(uint8_t c) { return 0; } +static sendchar_func_t func = null_sendchar_func; + +void print_set_sendchar(sendchar_func_t send) { func = send; } + +void _putchar(char character) { func(character); } diff --git a/tmk_core/common/progmem.h b/tmk_core/common/progmem.h index c8863d3ad2..4e4771e523 100644 --- a/tmk_core/common/progmem.h +++ b/tmk_core/common/progmem.h @@ -4,6 +4,7 @@ # include <avr/pgmspace.h> #else # define PROGMEM +# define PSTR(x) x # define PGM_P const char* # define memcpy_P(dest, src, n) memcpy(dest, src, n) # 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 5d7c5b3b28..606a259643 100644 --- a/tmk_core/common/report.h +++ b/tmk_core/common/report.h @@ -34,12 +34,16 @@ enum hid_report_ids { }; /* Mouse buttons */ +#define MOUSE_BTN_MASK(n) (1 << (n)) enum mouse_buttons { - MOUSE_BTN1 = (1 << 0), - MOUSE_BTN2 = (1 << 1), - MOUSE_BTN3 = (1 << 2), - MOUSE_BTN4 = (1 << 3), - MOUSE_BTN5 = (1 << 4) + MOUSE_BTN1 = MOUSE_BTN_MASK(0), + MOUSE_BTN2 = MOUSE_BTN_MASK(1), + MOUSE_BTN3 = MOUSE_BTN_MASK(2), + MOUSE_BTN4 = MOUSE_BTN_MASK(3), + MOUSE_BTN5 = MOUSE_BTN_MASK(4), + MOUSE_BTN6 = MOUSE_BTN_MASK(5), + MOUSE_BTN7 = MOUSE_BTN_MASK(6), + MOUSE_BTN8 = MOUSE_BTN_MASK(7) }; /* Consumer Page (0x0C) diff --git a/tmk_core/common/sendchar.h b/tmk_core/common/sendchar.h index b150dd464e..edcddaa6bb 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/>. extern "C" { #endif +typedef int8_t (*sendchar_func_t)(uint8_t c); + /* transmit a character. return 0 on success, -1 on error. */ int8_t sendchar(uint8_t c); diff --git a/tmk_core/common/suspend.h b/tmk_core/common/suspend.h index 766df95aa1..9d17d984ed 100644 --- a/tmk_core/common/suspend.h +++ b/tmk_core/common/suspend.h @@ -12,3 +12,7 @@ void suspend_wakeup_init_user(void); void suspend_wakeup_init_kb(void); void suspend_power_down_user(void); void suspend_power_down_kb(void); + +#ifndef USB_SUSPEND_WAKEUP_DELAY +# define USB_SUSPEND_WAKEUP_DELAY 200 +#endif diff --git a/tmk_core/common/sync_timer.c b/tmk_core/common/sync_timer.c new file mode 100644 index 0000000000..de24b463b6 --- /dev/null +++ b/tmk_core/common/sync_timer.c @@ -0,0 +1,58 @@ +/* +Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +If you happen to meet one of the copyright holders in a bar you are obligated +to buy them one pint of beer. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "sync_timer.h" +#include "keyboard.h" + +#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER) +volatile int32_t sync_timer_ms; + +void sync_timer_init(void) { sync_timer_ms = 0; } + +void sync_timer_update(uint32_t time) { + if (is_keyboard_master()) return; + sync_timer_ms = time - timer_read32(); +} + +uint16_t sync_timer_read(void) { + if (is_keyboard_master()) return timer_read(); + return sync_timer_read32(); +} + +uint32_t sync_timer_read32(void) { + if (is_keyboard_master()) return timer_read32(); + return sync_timer_ms + timer_read32(); +} + +uint16_t sync_timer_elapsed(uint16_t last) { + if (is_keyboard_master()) return timer_elapsed(last); + return TIMER_DIFF_16(sync_timer_read(), last); +} + +uint32_t sync_timer_elapsed32(uint32_t last) { + if (is_keyboard_master()) return timer_elapsed32(last); + return TIMER_DIFF_32(sync_timer_read32(), last); +} +#endif diff --git a/tmk_core/common/sync_timer.h b/tmk_core/common/sync_timer.h new file mode 100644 index 0000000000..9ddef45bb2 --- /dev/null +++ b/tmk_core/common/sync_timer.h @@ -0,0 +1,54 @@ +/* +Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +If you happen to meet one of the copyright holders in a bar you are obligated +to buy them one pint of beer. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#pragma once + +#include <stdint.h> +#include "timer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER) +void sync_timer_init(void); +void sync_timer_update(uint32_t time); +uint16_t sync_timer_read(void); +uint32_t sync_timer_read32(void); +uint16_t sync_timer_elapsed(uint16_t last); +uint32_t sync_timer_elapsed32(uint32_t last); +#else +# define sync_timer_init() +# define sync_timer_clear() +# define sync_timer_update(t) +# define sync_timer_read() timer_read() +# define sync_timer_read32() timer_read32() +# define sync_timer_elapsed(t) timer_elapsed(t) +# define sync_timer_elapsed32(t) timer_elapsed32(t) +#endif + +#ifdef __cplusplus +} +#endif diff --git a/tmk_core/common/uart.c b/tmk_core/common/uart.c deleted file mode 100644 index 150e256c8f..0000000000 --- a/tmk_core/common/uart.c +++ /dev/null @@ -1,172 +0,0 @@ -// TODO: Teensy support(ATMega32u4/AT90USB128) -// Fixed for Arduino Duemilanove ATmega168p by Jun Wako -/* UART Example for Teensy USB Development Board - * http://www.pjrc.com/teensy/ - * Copyright (c) 2009 PJRC.COM, LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// Version 1.0: Initial Release -// Version 1.1: Add support for Teensy 2.0, minor optimizations - -#include <avr/io.h> -#include <avr/interrupt.h> - -#include "uart.h" - -#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) -# define UDRn UDR0 -# define UBRRnL UBRR0L -# define UCSRnA UCSR0A -# define UCSRnB UCSR0B -# define UCSRnC UCSR0C -# define U2Xn U2X0 -# define RXENn RXEN0 -# define TXENn TXEN0 -# define RXCIEn RXCIE0 -# define UCSZn1 UCSZ01 -# define UCSZn0 UCSZ00 -# define UDRIEn UDRIE0 -# define USARTn_UDRE_vect USART_UDRE_vect -# define USARTn_RX_vect USART_RX_vect -#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) -# define UDRn UDR1 -# define UBRRnL UBRR1L -# define UCSRnA UCSR1A -# define UCSRnB UCSR1B -# define UCSRnC UCSR1C -# define U2Xn U2X1 -# define RXENn RXEN1 -# define TXENn TXEN1 -# define RXCIEn RXCIE1 -# define UCSZn1 UCSZ11 -# define UCSZn0 UCSZ10 -# define UDRIEn UDRIE1 -# define USARTn_UDRE_vect USART1_UDRE_vect -# define USARTn_RX_vect USART1_RX_vect -#elif defined(__AVR_ATmega32A__) -# define UDRn UDR -# define UBRRnL UBRRL -# define UCSRnA UCSRA -# define UCSRnB UCSRB -# define UCSRnC UCSRC -# define U2Xn U2X -# define RXENn RXEN -# define TXENn TXEN -# define RXCIEn RXCIE -# define UCSZn1 UCSZ1 -# define UCSZn0 UCSZ0 -# define UDRIEn UDRIE -# define USARTn_UDRE_vect USART_UDRE_vect -# define USARTn_RX_vect USART_RX_vect -#endif - -// These buffers may be any size from 2 to 256 bytes. -#define RX_BUFFER_SIZE 64 -#define TX_BUFFER_SIZE 256 - -static volatile uint8_t tx_buffer[TX_BUFFER_SIZE]; -static volatile uint8_t tx_buffer_head; -static volatile uint8_t tx_buffer_tail; -static volatile uint8_t rx_buffer[RX_BUFFER_SIZE]; -static volatile uint8_t rx_buffer_head; -static volatile uint8_t rx_buffer_tail; - -// Initialize the UART -void uart_init(uint32_t baud) { - cli(); - UBRRnL = (F_CPU / 4 / baud - 1) / 2; - UCSRnA = (1 << U2Xn); - UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn); - UCSRnC = (1 << UCSZn1) | (1 << UCSZn0); - tx_buffer_head = tx_buffer_tail = 0; - rx_buffer_head = rx_buffer_tail = 0; - sei(); -} - -// Transmit a byte -void uart_putchar(uint8_t c) { - uint8_t i; - - i = tx_buffer_head + 1; - if (i >= TX_BUFFER_SIZE) i = 0; - // return immediately to avoid deadlock when interrupt is disabled(called from ISR) - if (tx_buffer_tail == i && (SREG & (1 << SREG_I)) == 0) return; - while (tx_buffer_tail == i) - ; // wait until space in buffer - // cli(); - tx_buffer[i] = c; - tx_buffer_head = i; - UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn) | (1 << UDRIEn); - // sei(); -} - -// Receive a byte -uint8_t uart_getchar(void) { - uint8_t c, i; - - while (rx_buffer_head == rx_buffer_tail) - ; // wait for character - i = rx_buffer_tail + 1; - if (i >= RX_BUFFER_SIZE) i = 0; - c = rx_buffer[i]; - rx_buffer_tail = i; - return c; -} - -// Return the number of bytes waiting in the receive buffer. -// Call this before uart_getchar() to check if it will need -// to wait for a byte to arrive. -uint8_t uart_available(void) { - uint8_t head, tail; - - head = rx_buffer_head; - tail = rx_buffer_tail; - if (head >= tail) return head - tail; - return RX_BUFFER_SIZE + head - tail; -} - -// Transmit Interrupt -ISR(USARTn_UDRE_vect) { - uint8_t i; - - if (tx_buffer_head == tx_buffer_tail) { - // buffer is empty, disable transmit interrupt - UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn); - } else { - i = tx_buffer_tail + 1; - if (i >= TX_BUFFER_SIZE) i = 0; - UDRn = tx_buffer[i]; - tx_buffer_tail = i; - } -} - -// Receive Interrupt -ISR(USARTn_RX_vect) { - uint8_t c, i; - - c = UDRn; - i = rx_buffer_head + 1; - if (i >= RX_BUFFER_SIZE) i = 0; - if (i != rx_buffer_tail) { - rx_buffer[i] = c; - rx_buffer_head = i; - } -} diff --git a/tmk_core/common/uart.h b/tmk_core/common/uart.h deleted file mode 100644 index ea247b17b8..0000000000 --- a/tmk_core/common/uart.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include <stdint.h> - -void uart_init(uint32_t baud); -void uart_putchar(uint8_t c); -uint8_t uart_getchar(void); -uint8_t uart_available(void); diff --git a/tmk_core/common/wait.h b/tmk_core/common/wait.h index 89128e9daf..28224fe3aa 100644 --- a/tmk_core/common/wait.h +++ b/tmk_core/common/wait.h @@ -6,10 +6,89 @@ extern "C" { #endif +#if defined(__ARMEL__) || defined(__ARMEB__) +# ifndef __OPTIMIZE__ +# pragma message "Compiler optimizations disabled; wait_cpuclock() won't work as designed" +# endif + +# define wait_cpuclock(x) wait_cpuclock_allnop(x) + +# 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" + +__attribute__((always_inline)) static inline void wait_cpuclock_allnop(unsigned int n) { /* n: 1..135 */ + /* The argument n must be a constant expression. + * That way, compiler optimization will remove unnecessary code. */ + if (n < 1) { + return; + } + if (n > 8) { + unsigned int n8 = n / 8; + n = n - n8 * 8; + switch (n8) { + case 16: + asm volatile(CLOCK_DELAY_NOP8::: "memory"); + case 15: + asm volatile(CLOCK_DELAY_NOP8::: "memory"); + case 14: + asm volatile(CLOCK_DELAY_NOP8::: "memory"); + case 13: + asm volatile(CLOCK_DELAY_NOP8::: "memory"); + case 12: + asm volatile(CLOCK_DELAY_NOP8::: "memory"); + case 11: + asm volatile(CLOCK_DELAY_NOP8::: "memory"); + case 10: + asm volatile(CLOCK_DELAY_NOP8::: "memory"); + case 9: + asm volatile(CLOCK_DELAY_NOP8::: "memory"); + case 8: + asm volatile(CLOCK_DELAY_NOP8::: "memory"); + case 7: + asm volatile(CLOCK_DELAY_NOP8::: "memory"); + case 6: + asm volatile(CLOCK_DELAY_NOP8::: "memory"); + case 5: + asm volatile(CLOCK_DELAY_NOP8::: "memory"); + case 4: + asm volatile(CLOCK_DELAY_NOP8::: "memory"); + case 3: + asm volatile(CLOCK_DELAY_NOP8::: "memory"); + case 2: + asm volatile(CLOCK_DELAY_NOP8::: "memory"); + case 1: + asm volatile(CLOCK_DELAY_NOP8::: "memory"); + case 0: + break; + } + } + switch (n) { + case 8: + asm volatile("nop" ::: "memory"); + case 7: + asm volatile("nop" ::: "memory"); + case 6: + asm volatile("nop" ::: "memory"); + case 5: + asm volatile("nop" ::: "memory"); + case 4: + asm volatile("nop" ::: "memory"); + case 3: + asm volatile("nop" ::: "memory"); + case 2: + asm volatile("nop" ::: "memory"); + case 1: + asm volatile("nop" ::: "memory"); + case 0: + break; + } +} +#endif + #if defined(__AVR__) # include <util/delay.h> # define wait_ms(ms) _delay_ms(ms) # define wait_us(us) _delay_us(us) +# define wait_cpuclock(x) __builtin_avr_delay_cycles(x) #elif defined PROTOCOL_CHIBIOS # include <ch.h> # define wait_ms(ms) \ |