diff options
Diffstat (limited to 'tmk_core/common')
| -rw-r--r-- | tmk_core/common/avr/bootloader.c | 2 | ||||
| -rw-r--r-- | tmk_core/common/keyboard.c | 2 | ||||
| -rw-r--r-- | tmk_core/common/mousekey.c | 82 | ||||
| -rw-r--r-- | tmk_core/common/mousekey.h | 37 | ||||
| -rw-r--r-- | tmk_core/common/sync_timer.c | 58 | ||||
| -rw-r--r-- | tmk_core/common/sync_timer.h | 54 | 
6 files changed, 232 insertions, 3 deletions
| 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/keyboard.c b/tmk_core/common/keyboard.c index 8c7bdc8b55..a1fbc01da6 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" @@ -255,6 +256,7 @@ __attribute__((weak)) void housekeeping_task_user(void) {}   */  void keyboard_init(void) {      timer_init(); +    sync_timer_init();      matrix_init();  #ifdef VIA_ENABLE      via_init(); diff --git a/tmk_core/common/mousekey.c b/tmk_core/common/mousekey.c index ef18bcf1a8..697e0692c0 100644 --- a/tmk_core/common/mousekey.c +++ b/tmk_core/common/mousekey.c @@ -36,6 +36,9 @@ static void           mousekey_debug(void);  static uint8_t        mousekey_accel        = 0;  static uint8_t        mousekey_repeat       = 0;  static uint8_t        mousekey_wheel_repeat = 0; +#ifdef MK_KINETIC_SPEED +static uint16_t       mouse_timer     = 0; +#endif  #ifndef MK_3_SPEED @@ -43,7 +46,7 @@ static uint16_t last_timer_c = 0;  static uint16_t last_timer_w = 0;  /* - * Mouse keys  acceleration algorithm + * Mouse keys acceleration algorithm   *  http://en.wikipedia.org/wiki/Mouse_keys   *   *  speed = delta * max_speed * (repeat / time_to_max)**((1000+curve)/1000) @@ -105,6 +108,69 @@ static uint8_t wheel_unit(void) {  }  #    else /* #ifndef MK_COMBINED */ +#        ifndef MK_KINETIC_SPEED + +/* + * Kinetic movement  acceleration algorithm + * + *  current speed = I + A * T/50 + A * 0.5 * T^2 | maximum B + * + * T: time since the mouse movement started + * E: mouse events per second (set through MOUSEKEY_INTERVAL, UHK sends 250, the + *    pro micro on my Signum 3.0 sends only 125!) + * I: initial speed at time 0 + * A: acceleration + * B: base mouse travel speed + */ +const uint16_t mk_accelerated_speed = MOUSEKEY_ACCELERATED_SPEED; +const uint16_t mk_base_speed = MOUSEKEY_BASE_SPEED; +const uint16_t mk_decelerated_speed = MOUSEKEY_DECELERATED_SPEED; +const uint16_t mk_initial_speed = MOUSEKEY_INITIAL_SPEED; + +static uint8_t move_unit(void) { +    float speed = mk_initial_speed; + +    if (mousekey_accel & ((1<<0) | (1<<2))) { +        speed = mousekey_accel & (1<<2) ? mk_accelerated_speed : mk_decelerated_speed; +    } else if (mousekey_repeat && mouse_timer) { +        const float time_elapsed = timer_elapsed(mouse_timer) / 50; +        speed = mk_initial_speed + +            MOUSEKEY_MOVE_DELTA * time_elapsed + +            MOUSEKEY_MOVE_DELTA * 0.5 * time_elapsed * time_elapsed; + +        speed = speed > mk_base_speed ? mk_base_speed : speed; +    } + +    /* convert speed to USB mouse speed 1 to 127 */ +    speed = (uint8_t)(speed / (1000.0f / mk_interval)); +    speed = speed < 1 ? 1 : speed; + +    return speed > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : speed; +} + +float mk_wheel_interval = 1000.0f / MOUSEKEY_WHEEL_INITIAL_MOVEMENTS; + +static uint8_t wheel_unit(void) { +    float speed = MOUSEKEY_WHEEL_INITIAL_MOVEMENTS; + +    if (mousekey_accel & ((1<<0) | (1<<2))) { +        speed = mousekey_accel & (1<<2) ? MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS : MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS; +    } else if (mousekey_repeat && mouse_timer) { +        if (mk_wheel_interval != MOUSEKEY_WHEEL_BASE_MOVEMENTS) { +            const float time_elapsed = timer_elapsed(mouse_timer) / 50; +            speed = MOUSEKEY_WHEEL_INITIAL_MOVEMENTS + +                1 * time_elapsed + +                1 * 0.5 * time_elapsed * time_elapsed; +        } +        speed = speed > MOUSEKEY_WHEEL_BASE_MOVEMENTS ? MOUSEKEY_WHEEL_BASE_MOVEMENTS : speed; +    } + +    mk_wheel_interval = 1000.0f / speed; + +    return 1; +} + +#        else /* #ifndef MK_KINETIC_SPEED */  static uint8_t move_unit(void) {      uint16_t unit; @@ -142,6 +208,7 @@ static uint8_t wheel_unit(void) {      return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));  } +#        endif /* #ifndef MK_KINETIC_SPEED */  #    endif /* #ifndef MK_COMBINED */  void mousekey_task(void) { @@ -193,6 +260,12 @@ void mousekey_task(void) {  }  void mousekey_on(uint8_t code) { +#ifdef MK_KINETIC_SPEED +    if (mouse_timer == 0) { +        mouse_timer = timer_read(); +    } +#endif /* #ifdef MK_KINETIC_SPEED */ +      if (code == KC_MS_UP)          mouse_report.y = move_unit() * -1;      else if (code == KC_MS_DOWN) @@ -260,7 +333,12 @@ void mousekey_off(uint8_t code) {          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.x == 0 && mouse_report.y == 0) { +        mousekey_repeat = 0; +#ifdef MK_KINETIC_SPEED +        mouse_timer = 0; +#endif /* #ifdef MK_KINETIC_SPEED */ +    }      if (mouse_report.v == 0 && mouse_report.h == 0) mousekey_wheel_repeat = 0;  } diff --git a/tmk_core/common/mousekey.h b/tmk_core/common/mousekey.h index 300d262f5d..911d11eeb9 100644 --- a/tmk_core/common/mousekey.h +++ b/tmk_core/common/mousekey.h @@ -36,16 +36,28 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #    endif  #    ifndef MOUSEKEY_MOVE_DELTA +#ifndef MK_KINETIC_SPEED  #        define MOUSEKEY_MOVE_DELTA 5 +#else +#        define MOUSEKEY_MOVE_DELTA 25 +#endif  #    endif  #    ifndef MOUSEKEY_WHEEL_DELTA  #        define MOUSEKEY_WHEEL_DELTA 1  #    endif  #    ifndef MOUSEKEY_DELAY +#ifndef MK_KINETIC_SPEED  #        define MOUSEKEY_DELAY 300 +#else +#        define MOUSEKEY_DELAY 8 +#endif  #    endif  #    ifndef MOUSEKEY_INTERVAL +#ifndef MK_KINETIC_SPEED  #        define MOUSEKEY_INTERVAL 50 +#else +#        define MOUSEKEY_INTERVAL 8 +#endif  #    endif  #    ifndef MOUSEKEY_MAX_SPEED  #        define MOUSEKEY_MAX_SPEED 10 @@ -66,6 +78,31 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #        define MOUSEKEY_WHEEL_TIME_TO_MAX 40  #    endif +#ifndef MOUSEKEY_INITIAL_SPEED +#define MOUSEKEY_INITIAL_SPEED  100 +#endif +#ifndef MOUSEKEY_BASE_SPEED +#define MOUSEKEY_BASE_SPEED 1000 +#endif +#ifndef MOUSEKEY_DECELERATED_SPEED +#define MOUSEKEY_DECELERATED_SPEED 400 +#endif +#ifndef MOUSEKEY_ACCELERATED_SPEED +#define MOUSEKEY_ACCELERATED_SPEED 3000 +#endif +#ifndef MOUSEKEY_WHEEL_INITIAL_MOVEMENTS +#define MOUSEKEY_WHEEL_INITIAL_MOVEMENTS  16 +#endif +#ifndef MOUSEKEY_WHEEL_BASE_MOVEMENTS +#define MOUSEKEY_WHEEL_BASE_MOVEMENTS  32 +#endif +#ifndef MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS +#define MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS  48 +#endif +#ifndef MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS +#define MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS  8 +#endif +  #else /* #ifndef MK_3_SPEED */  #    ifndef MK_C_OFFSET_UNMOD 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 | 
