Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for hall effect mouse keys. #340

Open
wants to merge 2 commits into
base: hall_effect_playground
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions keyboards/keychron/common/analog_matrix/analog_matrix_scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "debounce.h"
#include "lpm.h"

#include <keychron_common.h>

#ifndef HC164_DS
# define HC164_DS B3
#endif
Expand Down Expand Up @@ -161,6 +163,34 @@ void matrix_read_rows_on_col(uint8_t current_col, matrix_row_t row_shifter) {
if ((analog_raw_matrix[row_index] & row_mask) == 0)
changed = true;

uint16_t mouse_keycode = is_mouse_key(current_col, row_index);
if (mouse_keycode>0) {
uint8_t travel = analog_matrix_get_travel(row_index, current_col)/TRAVEL_SCALE;
uint8_t mouse_speed = ((travel * travel + travel) * 4) / 100;
if (mouse_speed == 0)
mouse_speed = 1;
if (mouse_speed > 200)
mouse_speed = 200;
switch (mouse_keycode) {
case KC_MS_UP:
case KC_MS_DOWN:
mousekey_set_speed_y(mouse_speed);
break;
case KC_MS_LEFT:
case KC_MS_RIGHT:
mousekey_set_speed_x(mouse_speed);
break;
case KC_MS_WH_UP:
case KC_MS_WH_DOWN:
mousekey_set_speed_v(mouse_speed);
break;
case KC_MS_WH_LEFT:
case KC_MS_WH_RIGHT:
mousekey_set_speed_h(mouse_speed);
break;
}
}

if (debouce_times == ANALOG_DEBOUCE_TIME) {
row_value |= (0x01 << row_index);
} else {
Expand Down
58 changes: 57 additions & 1 deletion keyboards/keychron/common/keychron_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,39 @@ static key_combination_t key_comb_list[4] = {
{2, {KC_LWIN, KC_C}},
};

// A struct that stores col and row
typedef struct {
uint8_t col;
uint8_t row;
uint16_t keycode;
} key_pos_t;

key_pos_t mouse_keys_pos[8] = {
{255, 255, KC_MS_UP},
{255, 255, KC_MS_DOWN},
{255, 255, KC_MS_LEFT},
{255, 255, KC_MS_RIGHT},
{255, 255, KC_MS_WH_UP},
{255, 255, KC_MS_WH_DOWN},
{255, 255, KC_MS_WH_LEFT},
{255, 255, KC_MS_WH_RIGHT},
};

void set_mouse_key_last_key_pos(uint8_t pos, uint8_t col, uint8_t row) {
if (pos>7) return;
mouse_keys_pos[pos].col = col;
mouse_keys_pos[pos].row = row;
}

uint16_t is_mouse_key(uint8_t col, uint8_t row) {
for (uint8_t i = 0; i < 8; i++) {
if (mouse_keys_pos[i].col == col && mouse_keys_pos[i].row == row) {
return mouse_keys_pos[i].keycode;
}
}
return 0;
}

bool process_record_keychron_common(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case KC_MCTRL:
Expand Down Expand Up @@ -100,7 +133,30 @@ bool process_record_keychron_common(uint16_t keycode, keyrecord_t *record) {
}
}
return false; // Skip all further processing of this key

case KC_MS_UP:
set_mouse_key_last_key_pos(0, record->event.key.col, record->event.key.row);
break;
case KC_MS_DOWN:
set_mouse_key_last_key_pos(1, record->event.key.col, record->event.key.row);
break;
case KC_MS_LEFT:
set_mouse_key_last_key_pos(2, record->event.key.col, record->event.key.row);
break;
case KC_MS_RIGHT:
set_mouse_key_last_key_pos(3, record->event.key.col, record->event.key.row);
break;
case KC_MS_WH_UP:
set_mouse_key_last_key_pos(4, record->event.key.col, record->event.key.row);
break;
case KC_MS_WH_DOWN:
set_mouse_key_last_key_pos(5, record->event.key.col, record->event.key.row);
break;
case KC_MS_WH_LEFT:
set_mouse_key_last_key_pos(6, record->event.key.col, record->event.key.row);
break;
case KC_MS_WH_RIGHT:
set_mouse_key_last_key_pos(7, record->event.key.col, record->event.key.row);
break;
default:
#ifdef ANANLOG_MATRIX
return process_record_profile( keycode, record);
Expand Down
12 changes: 12 additions & 0 deletions keyboards/keychron/common/keychron_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ enum {
PROF1,
PROF2,
PROF3,
HE_M_UP,
HE_M_DOWN,
HE_M_LEFT,
HE_M_RIGHT,
#endif
NEW_SAFE_RANGE,
};
Expand All @@ -57,6 +61,10 @@ enum {
#define PROF1 KC_TRANS
#define PROF2 KC_TRANS
#define PROF3 KC_TRANS
#define HE_M_UP KC_TRANS
#define HE_M_DOWN KC_TRANS
#define HE_M_LEFT KC_TRANS
#define HE_M_RIGHT KC_TRANS
#endif

#define KC_TASK KC_TASK_VIEW
Expand All @@ -79,6 +87,10 @@ typedef struct PACKED {

bool process_record_keychron_common(uint16_t keycode, keyrecord_t *record);
void keychron_common_task(void);
void set_mouse_vertical_last_key_pos(uint8_t col, uint8_t row);
void set_mouse_horizontal_last_key_pos(uint8_t col, uint8_t row);
void set_mouse_key_last_key_pos(uint8_t pos, uint8_t col, uint8_t row);
uint16_t is_mouse_key(uint8_t col, uint8_t row);

#ifdef ENCODER_ENABLE
void encoder_cb_init(void);
Expand Down
1 change: 1 addition & 0 deletions keyboards/keychron/k2_he/ansi_rgb/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
/* RGB Matrix driver configuration */
# define DRIVER_COUNT 2
# define RGB_MATRIX_LED_COUNT 84
# define MOUSEKEY_VARIABLE 1

# define SPI_SCK_PIN A5
# define SPI_MISO_PIN A6
Expand Down
68 changes: 52 additions & 16 deletions quantum/mousekey.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ static void mousekey_debug(void);
static uint8_t mousekey_accel = 0;
static uint8_t mousekey_repeat = 0;
static uint8_t mousekey_wheel_repeat = 0;
static uint8_t mousekey_variable = MOUSEKEY_VARIABLE;
static uint8_t mousekey_speed_x = 1;
static uint8_t mousekey_speed_y = 1;
static uint8_t mousekey_speed_h = 1;
static uint8_t mousekey_speed_v = 1;
#
#ifdef MOUSEKEY_INERTIA
static uint8_t mousekey_frame = 0; // track whether gesture is inactive, first frame, or repeating
static int8_t mousekey_x_dir = 0; // -1 / 0 / 1 = left / neutral / right
Expand Down Expand Up @@ -92,9 +98,15 @@ uint8_t mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX;

/* Default accelerated mode */

static uint8_t move_unit(void) {
static uint8_t move_unit(uint8_t axis) {
uint16_t unit;
if (mousekey_accel & (1 << 0)) {
if (mousekey_variable) {
if (axis) {
unit = mousekey_speed_x;
} else {
unit = mousekey_speed_y;
}
} else 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;
Expand All @@ -110,6 +122,24 @@ static uint8_t move_unit(void) {
return (unit > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : (unit == 0 ? 1 : unit));
}

/* Used to set acceleration from other means such as hall effect */

void mousekey_set_speed_x(uint8_t speed) {
mousekey_speed_x = speed;
}

void mousekey_set_speed_y(uint8_t speed) {
mousekey_speed_y = speed;
}

void mousekey_set_speed_h(uint8_t speed) {
mousekey_speed_h = speed;
}

void mousekey_set_speed_v(uint8_t speed) {
mousekey_speed_v = speed;
}

# else // MOUSEKEY_INERTIA mode

static int8_t move_unit(uint8_t axis) {
Expand Down Expand Up @@ -157,9 +187,15 @@ static int8_t move_unit(uint8_t axis) {

# endif // end MOUSEKEY_INERTIA mode

static uint8_t wheel_unit(void) {
static uint8_t wheel_unit(uint8_t axis) {
uint16_t unit;
if (mousekey_accel & (1 << 0)) {
if (mousekey_variable) {
if (axis) {
unit = mousekey_speed_h;
} else {
unit = mousekey_speed_v;
}
} else 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;
Expand Down Expand Up @@ -341,8 +377,8 @@ void mousekey_task(void) {

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);
if (tmpmr.x != 0) mouse_report.x = move_unit(1) * ((tmpmr.x > 0) ? 1 : -1);
if (tmpmr.y != 0) mouse_report.y = move_unit(0) * ((tmpmr.y > 0) ? 1 : -1);

/* diagonal move [1/sqrt(2)] */
if (mouse_report.x && mouse_report.y) {
Expand All @@ -361,8 +397,8 @@ void mousekey_task(void) {

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);
if (tmpmr.v != 0) mouse_report.v = wheel_unit(0) * ((tmpmr.v > 0) ? 1 : -1);
if (tmpmr.h != 0) mouse_report.h = wheel_unit(1) * ((tmpmr.h > 0) ? 1 : -1);

/* diagonal move [1/sqrt(2)] */
if (mouse_report.v && mouse_report.h) {
Expand Down Expand Up @@ -418,24 +454,24 @@ void mousekey_on(uint8_t code) {
# else // no inertia

if (code == KC_MS_UP)
mouse_report.y = move_unit() * -1;
mouse_report.y = move_unit(0) * -1;
else if (code == KC_MS_DOWN)
mouse_report.y = move_unit();
mouse_report.y = move_unit(0);
else if (code == KC_MS_LEFT)
mouse_report.x = move_unit() * -1;
mouse_report.x = move_unit(1) * -1;
else if (code == KC_MS_RIGHT)
mouse_report.x = move_unit();
mouse_report.x = move_unit(1);

# endif // inertia or not

else if (code == KC_MS_WH_UP)
mouse_report.v = wheel_unit();
mouse_report.v = wheel_unit(0);
else if (code == KC_MS_WH_DOWN)
mouse_report.v = wheel_unit() * -1;
mouse_report.v = wheel_unit(0) * -1;
else if (code == KC_MS_WH_LEFT)
mouse_report.h = wheel_unit() * -1;
mouse_report.h = wheel_unit(1) * -1;
else if (code == KC_MS_WH_RIGHT)
mouse_report.h = wheel_unit();
mouse_report.h = wheel_unit(1);
else if (IS_MOUSEKEY_BUTTON(code))
mouse_report.buttons |= 1 << (code - KC_MS_BTN1);
else if (code == KC_MS_ACCEL0)
Expand Down
8 changes: 8 additions & 0 deletions quantum/mousekey.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# define MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS 8
# endif

#ifndef MOUSEKEY_VARIABLE
# define MOUSEKEY_VARIABLE 0
#endif

#else /* #ifndef MK_3_SPEED */

# ifndef MK_C_OFFSET_UNMOD
Expand Down Expand Up @@ -190,6 +194,10 @@ void mousekey_on(uint8_t code);
void mousekey_off(uint8_t code);
void mousekey_clear(void);
void mousekey_send(void);
void mousekey_set_speed_x(uint8_t);
void mousekey_set_speed_y(uint8_t);
void mousekey_set_speed_h(uint8_t);
void mousekey_set_speed_v(uint8_t);
report_mouse_t mousekey_get_report(void);
bool should_mousekey_report_send(report_mouse_t *mouse_report);

Expand Down
Loading