diff options
Diffstat (limited to 'tmk_core/common')
| -rw-r--r-- | tmk_core/common/action.c | 18 | ||||
| -rw-r--r-- | tmk_core/common/avr/bootloader.c | 10 | ||||
| -rw-r--r-- | tmk_core/common/avr/suspend.c | 5 | ||||
| -rw-r--r-- | tmk_core/common/chibios/suspend.c | 7 | ||||
| -rw-r--r-- | tmk_core/common/keyboard.c | 37 | ||||
| -rw-r--r-- | tmk_core/common/keyboard.h | 9 | ||||
| -rw-r--r-- | tmk_core/common/keycode.h | 14 | ||||
| -rw-r--r-- | tmk_core/common/matrix.h | 3 | ||||
| -rw-r--r-- | tmk_core/common/mousekey.c | 128 | ||||
| -rw-r--r-- | tmk_core/common/mousekey.h | 43 | ||||
| -rw-r--r-- | tmk_core/common/report.h | 5 | ||||
| -rw-r--r-- | tmk_core/common/suspend.h | 4 | ||||
| -rw-r--r-- | tmk_core/common/sync_timer.c | 58 | ||||
| -rw-r--r-- | tmk_core/common/sync_timer.h | 54 | ||||
| -rw-r--r-- | tmk_core/common/uart.c | 172 | ||||
| -rw-r--r-- | tmk_core/common/uart.h | 8 | ||||
| -rw-r--r-- | tmk_core/common/wait.h | 79 | 
17 files changed, 407 insertions, 247 deletions
| diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index a7432bae59..a3830abbff 100644 --- a/tmk_core/common/action.c +++ b/tmk_core/common/action.c @@ -443,6 +443,15 @@ void process_action(keyrecord_t *record, action_t action) {                      case KC_MS_BTN5:                          register_button(true, MOUSE_BTN5);                          break; +                    case KC_MS_BTN6: +                        register_button(true, MOUSE_BTN6); +                        break; +                    case KC_MS_BTN7: +                        register_button(true, MOUSE_BTN7); +                        break; +                    case KC_MS_BTN8: +                        register_button(true, MOUSE_BTN8); +                        break;  #    endif                      default:                          mousekey_send(); @@ -469,6 +478,15 @@ void process_action(keyrecord_t *record, action_t action) {                      case KC_MS_BTN5:                          register_button(false, MOUSE_BTN5);                          break; +                    case KC_MS_BTN6: +                        register_button(false, MOUSE_BTN6); +                        break; +                    case KC_MS_BTN7: +                        register_button(false, MOUSE_BTN7); +                        break; +                    case KC_MS_BTN8: +                        register_button(false, MOUSE_BTN8); +                        break;  #    endif                      default:                          mousekey_send(); diff --git a/tmk_core/common/avr/bootloader.c b/tmk_core/common/avr/bootloader.c index a1db55da93..4e3a27022d 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); @@ -237,13 +237,13 @@ void bootloader_jump(void) {                   "bootloader_startup_loop%=:         \n\t"                   "rjmp bootloader_startup_loop%=     \n\t"                   : -                 : [mcucsrio] "I"(_SFR_IO_ADDR(MCUCSR)), +                 : [ mcucsrio ] "I"(_SFR_IO_ADDR(MCUCSR)),  #    if (FLASHEND > 131071) -                   [ramendhi] "M"(((RAMEND - 2) >> 8) & 0xff), [ramendlo] "M"(((RAMEND - 2) >> 0) & 0xff), [bootaddrhi] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 16) & 0xff), +                   [ ramendhi ] "M"(((RAMEND - 2) >> 8) & 0xff), [ ramendlo ] "M"(((RAMEND - 2) >> 0) & 0xff), [ bootaddrhi ] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 16) & 0xff),  #    else -                   [ramendhi] "M"(((RAMEND - 1) >> 8) & 0xff), [ramendlo] "M"(((RAMEND - 1) >> 0) & 0xff), +                   [ ramendhi ] "M"(((RAMEND - 1) >> 8) & 0xff), [ ramendlo ] "M"(((RAMEND - 1) >> 0) & 0xff),  #    endif -                   [bootaddrme] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 8) & 0xff), [bootaddrlo] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 0) & 0xff)); +                   [ bootaddrme ] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 8) & 0xff), [ bootaddrlo ] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 0) & 0xff));  #else  // Assume remaining boards are DFU, even if the flag isn't set 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/keyboard.c b/tmk_core/common/keyboard.c index 7120cdacdf..40989ca4c6 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" @@ -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; @@ -260,6 +275,7 @@ __attribute__((weak)) void housekeeping_task_user(void) {}   */  void keyboard_init(void) {      timer_init(); +    sync_timer_init();      matrix_init();  #ifdef VIA_ENABLE      via_init(); @@ -337,15 +353,15 @@ 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++) { @@ -401,7 +417,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 +428,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/matrix.h b/tmk_core/common/matrix.h index b570227a31..ce57010a47 100644 --- a/tmk_core/common/matrix.h +++ b/tmk_core/common/matrix.h @@ -55,6 +55,9 @@ matrix_row_t matrix_get_row(uint8_t row);  /* print matrix for debug */  void matrix_print(void);  /* delay between changing matrix pin state and reading values */ +void matrix_output_select_delay(void); +void matrix_output_unselect_delay(void); +/* only for backwards compatibility. delay between changing matrix pin state and reading values */  void matrix_io_delay(void);  /* power control */ diff --git a/tmk_core/common/mousekey.c b/tmk_core/common/mousekey.c index ef18bcf1a8..d8cf63f771 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,65 @@ 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,7 +204,8 @@ static uint8_t wheel_unit(void) {      return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));  } -#    endif /* #ifndef MK_COMBINED */ +#        endif /* #ifndef MK_KINETIC_SPEED */ +#    endif     /* #ifndef MK_COMBINED */  void mousekey_task(void) {      // report cursor and scroll movement independently @@ -193,6 +256,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) @@ -209,16 +278,8 @@ void mousekey_on(uint8_t code) {          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 (IS_MOUSEKEY_BUTTON(code)) +        mouse_report.buttons |= 1 << (code - KC_MS_BTN1);      else if (code == KC_MS_ACCEL0)          mousekey_accel |= (1 << 0);      else if (code == KC_MS_ACCEL1) @@ -244,23 +305,20 @@ void mousekey_off(uint8_t code) {          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 (IS_MOUSEKEY_BUTTON(code)) +        mouse_report.buttons &= ~(1 << (code - KC_MS_BTN1));      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.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;  } @@ -349,16 +407,8 @@ void mousekey_on(uint8_t code) {          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 (IS_MOUSEKEY_BUTTON(code)) +        mouse_report.buttons |= 1 << (code - KC_MS_BTN1);      else if (code == KC_MS_ACCEL0)          mk_speed = mkspd_0;      else if (code == KC_MS_ACCEL1) @@ -388,16 +438,8 @@ void mousekey_off(uint8_t code) {          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 (IS_MOUSEKEY_BUTTON(code)) +        mouse_report.buttons &= ~(1 << (code - KC_MS_BTN1));  #    ifdef MK_MOMENTARY_ACCEL      else if (code == KC_MS_ACCEL0)          mk_speed = mkspd_DEFAULT; diff --git a/tmk_core/common/mousekey.h b/tmk_core/common/mousekey.h index 300d262f5d..52b8fe10e1 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 -#        define MOUSEKEY_MOVE_DELTA 5 +#        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 -#        define MOUSEKEY_DELAY 300 +#        ifndef MK_KINETIC_SPEED +#            define MOUSEKEY_DELAY 300 +#        else +#            define MOUSEKEY_DELAY 8 +#        endif  #    endif  #    ifndef MOUSEKEY_INTERVAL -#        define MOUSEKEY_INTERVAL 50 +#        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/report.h b/tmk_core/common/report.h index 5d7c5b3b28..bcf5cab388 100644 --- a/tmk_core/common/report.h +++ b/tmk_core/common/report.h @@ -39,7 +39,10 @@ enum mouse_buttons {      MOUSE_BTN2 = (1 << 1),      MOUSE_BTN3 = (1 << 2),      MOUSE_BTN4 = (1 << 3), -    MOUSE_BTN5 = (1 << 4) +    MOUSE_BTN5 = (1 << 4), +    MOUSE_BTN6 = (1 << 5), +    MOUSE_BTN7 = (1 << 6), +    MOUSE_BTN8 = (1 << 7)  };  /* Consumer Page (0x0C) 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)                     \ | 
