summaryrefslogtreecommitdiff
path: root/quantum/pointing_device_drivers.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/pointing_device_drivers.c')
-rw-r--r--quantum/pointing_device_drivers.c247
1 files changed, 138 insertions, 109 deletions
diff --git a/quantum/pointing_device_drivers.c b/quantum/pointing_device_drivers.c
index 56363c7ac6..b7e98e897e 100644
--- a/quantum/pointing_device_drivers.c
+++ b/quantum/pointing_device_drivers.c
@@ -22,8 +22,8 @@
#include "timer.h"
#include <stddef.h>
-// hid mouse reports cannot exceed -127 to 127, so constrain to that value
-#define constrain_hid(amt) ((amt) < -127 ? -127 : ((amt) > 127 ? 127 : (amt)))
+#define CONSTRAIN_HID(amt) ((amt) < INT8_MIN ? INT8_MIN : ((amt) > INT8_MAX ? INT8_MAX : (amt)))
+#define CONSTRAIN_HID_XY(amt) ((amt) < XY_REPORT_MIN ? XY_REPORT_MIN : ((amt) > XY_REPORT_MAX ? XY_REPORT_MAX : (amt)))
// get_report functions should probably be moved to their respective drivers.
#if defined(POINTING_DEVICE_DRIVER_adns5050)
@@ -35,8 +35,8 @@ report_mouse_t adns5050_get_report(report_mouse_t mouse_report) {
if (debug_mouse) dprintf("Raw ] X: %d, Y: %d\n", data.dx, data.dy);
# endif
- mouse_report.x = data.dx;
- mouse_report.y = data.dy;
+ mouse_report.x = (mouse_xy_report_t)data.dx;
+ mouse_report.y = (mouse_xy_report_t)data.dy;
}
return mouse_report;
@@ -50,16 +50,14 @@ const pointing_device_driver_t pointing_device_driver = {
.get_cpi = adns5050_get_cpi,
};
// clang-format on
+
#elif defined(POINTING_DEVICE_DRIVER_adns9800)
report_mouse_t adns9800_get_report_driver(report_mouse_t mouse_report) {
report_adns9800_t sensor_report = adns9800_get_report();
- int8_t clamped_x = constrain_hid(sensor_report.x);
- int8_t clamped_y = constrain_hid(sensor_report.y);
-
- mouse_report.x = clamped_x;
- mouse_report.y = clamped_y;
+ mouse_report.x = CONSTRAIN_HID_XY(sensor_report.x);
+ mouse_report.y = CONSTRAIN_HID_XY(sensor_report.y);
return mouse_report;
}
@@ -72,6 +70,7 @@ const pointing_device_driver_t pointing_device_driver = {
.get_cpi = adns9800_get_cpi
};
// clang-format on
+
#elif defined(POINTING_DEVICE_DRIVER_analog_joystick)
report_mouse_t analog_joystick_get_report(report_mouse_t mouse_report) {
report_analog_joystick_t data = analog_joystick_read();
@@ -96,72 +95,131 @@ const pointing_device_driver_t pointing_device_driver = {
.get_cpi = NULL
};
// clang-format on
+
#elif defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_i2c) || defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_spi)
-# ifndef CIRQUE_PINNACLE_TAPPING_TERM
-# include "action.h"
-# include "action_tapping.h"
-# define CIRQUE_PINNACLE_TAPPING_TERM GET_TAPPING_TERM(KC_BTN1, &(keyrecord_t){})
-# endif
-# ifndef CIRQUE_PINNACLE_TOUCH_DEBOUNCE
-# define CIRQUE_PINNACLE_TOUCH_DEBOUNCE (CIRQUE_PINNACLE_TAPPING_TERM * 8)
+# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
+static bool cursor_glide_enable = true;
+
+static cursor_glide_context_t glide = {.config = {
+ .coef = 102, /* Good default friction coef */
+ .interval = 10, /* 100sps */
+ .trigger_px = 10, /* Default threshold in case of hover, set to 0 if you'd like */
+ }};
+
+void cirque_pinnacle_enable_cursor_glide(bool enable) {
+ cursor_glide_enable = enable;
+}
+
+void cirque_pinnacle_configure_cursor_glide(float trigger_px) {
+ glide.config.trigger_px = trigger_px;
+}
# endif
report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) {
- pinnacle_data_t touchData = cirque_pinnacle_read_data();
- static uint16_t x = 0, y = 0, mouse_timer = 0;
- int8_t report_x = 0, report_y = 0;
- static bool is_z_down = false;
+ pinnacle_data_t touchData = cirque_pinnacle_read_data();
+ mouse_xy_report_t report_x = 0, report_y = 0;
+ static mouse_xy_report_t x = 0, y = 0;
+# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
+ cursor_glide_t glide_report = {0};
+
+ if (cursor_glide_enable) {
+ glide_report = cursor_glide_check(&glide);
+ }
+# endif
- cirque_pinnacle_scale_data(&touchData, cirque_pinnacle_get_scale(), cirque_pinnacle_get_scale()); // Scale coordinates to arbitrary X, Y resolution
+# if !CIRQUE_PINNACLE_POSITION_MODE
+# error Cirque Pinnacle with relative mode not implemented yet.
+# endif
- if (x && y && touchData.xValue && touchData.yValue) {
- report_x = (int8_t)(touchData.xValue - x);
- report_y = (int8_t)(touchData.yValue - y);
+ if (!touchData.valid) {
+# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
+ if (cursor_glide_enable && glide_report.valid) {
+ report_x = glide_report.dx;
+ report_y = glide_report.dy;
+ goto mouse_report_update;
+ }
+# endif
+ return mouse_report;
}
- x = touchData.xValue;
- y = touchData.yValue;
- if ((bool)touchData.zValue != is_z_down) {
- is_z_down = (bool)touchData.zValue;
- if (!touchData.zValue) {
- if (timer_elapsed(mouse_timer) < CIRQUE_PINNACLE_TAPPING_TERM && mouse_timer != 0) {
- mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, true, POINTING_DEVICE_BUTTON1);
- pointing_device_set_report(mouse_report);
- pointing_device_send();
-# if TAP_CODE_DELAY > 0
- wait_ms(TAP_CODE_DELAY);
+# if CONSOLE_ENABLE
+ if (debug_mouse && touchData.touchDown) {
+ dprintf("cirque_pinnacle touchData x=%4d y=%4d z=%2d\n", touchData.xValue, touchData.yValue, touchData.zValue);
+ }
# endif
- mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, false, POINTING_DEVICE_BUTTON1);
- pointing_device_set_report(mouse_report);
- pointing_device_send();
+
+ // Scale coordinates to arbitrary X, Y resolution
+ cirque_pinnacle_scale_data(&touchData, cirque_pinnacle_get_scale(), cirque_pinnacle_get_scale());
+
+ if (!cirque_pinnacle_gestures(&mouse_report, touchData)) {
+ if (x && y && touchData.xValue && touchData.yValue) {
+ report_x = (mouse_xy_report_t)(touchData.xValue - x);
+ report_y = (mouse_xy_report_t)(touchData.yValue - y);
+ }
+ x = touchData.xValue;
+ y = touchData.yValue;
+
+# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
+ if (cursor_glide_enable) {
+ if (touchData.touchDown) {
+ cursor_glide_update(&glide, report_x, report_y, touchData.zValue);
+ } else if (!glide_report.valid) {
+ glide_report = cursor_glide_start(&glide);
+ if (glide_report.valid) {
+ report_x = glide_report.dx;
+ report_y = glide_report.dy;
+ }
}
}
- mouse_timer = timer_read();
- }
- if (timer_elapsed(mouse_timer) > (CIRQUE_PINNACLE_TOUCH_DEBOUNCE)) {
- mouse_timer = 0;
+# endif
}
+
+# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
+mouse_report_update:
+# endif
mouse_report.x = report_x;
mouse_report.y = report_y;
return mouse_report;
}
+uint16_t cirque_pinnacle_get_cpi(void) {
+ return CIRQUE_PINNACLE_PX_TO_INCH(cirque_pinnacle_get_scale());
+}
+void cirque_pinnacle_set_cpi(uint16_t cpi) {
+ cirque_pinnacle_set_scale(CIRQUE_PINNACLE_INCH_TO_PX(cpi));
+}
+
// clang-format off
const pointing_device_driver_t pointing_device_driver = {
.init = cirque_pinnacle_init,
.get_report = cirque_pinnacle_get_report,
- .set_cpi = cirque_pinnacle_set_scale,
- .get_cpi = cirque_pinnacle_get_scale
+ .set_cpi = cirque_pinnacle_set_cpi,
+ .get_cpi = cirque_pinnacle_get_cpi
};
// clang-format on
#elif defined(POINTING_DEVICE_DRIVER_pimoroni_trackball)
+
+mouse_xy_report_t pimoroni_trackball_adapt_values(clamp_range_t* offset) {
+ if (*offset > XY_REPORT_MAX) {
+ *offset -= XY_REPORT_MAX;
+ return (mouse_xy_report_t)XY_REPORT_MAX;
+ } else if (*offset < XY_REPORT_MIN) {
+ *offset += XY_REPORT_MAX;
+ return (mouse_xy_report_t)XY_REPORT_MIN;
+ } else {
+ mouse_xy_report_t temp_return = *offset;
+ *offset = 0;
+ return temp_return;
+ }
+}
+
report_mouse_t pimoroni_trackball_get_report(report_mouse_t mouse_report) {
- static uint16_t debounce = 0;
- static uint8_t error_count = 0;
- pimoroni_data_t pimoroni_data = {0};
- static int16_t x_offset = 0, y_offset = 0;
+ static uint16_t debounce = 0;
+ static uint8_t error_count = 0;
+ pimoroni_data_t pimoroni_data = {0};
+ static clamp_range_t x_offset = 0, y_offset = 0;
if (error_count < PIMORONI_TRACKBALL_ERROR_COUNT) {
i2c_status_t status = read_pimoroni_trackball(&pimoroni_data);
@@ -174,8 +232,8 @@ report_mouse_t pimoroni_trackball_get_report(report_mouse_t mouse_report) {
if (!debounce) {
x_offset += pimoroni_trackball_get_offsets(pimoroni_data.right, pimoroni_data.left, PIMORONI_TRACKBALL_SCALE);
y_offset += pimoroni_trackball_get_offsets(pimoroni_data.down, pimoroni_data.up, PIMORONI_TRACKBALL_SCALE);
- pimoroni_trackball_adapt_values(&mouse_report.x, &x_offset);
- pimoroni_trackball_adapt_values(&mouse_report.y, &y_offset);
+ mouse_report.x = pimoroni_trackball_adapt_values(&x_offset);
+ mouse_report.y = pimoroni_trackball_adapt_values(&y_offset);
} else {
debounce--;
}
@@ -198,82 +256,52 @@ const pointing_device_driver_t pointing_device_driver = {
.get_cpi = pimoroni_trackball_get_cpi
};
// clang-format on
-#elif defined(POINTING_DEVICE_DRIVER_pmw3360)
-static void pmw3360_device_init(void) {
- pmw3360_init(0);
-}
-
-report_mouse_t pmw3360_get_report(report_mouse_t mouse_report) {
- report_pmw3360_t data = pmw3360_read_burst(0);
- static uint16_t MotionStart = 0; // Timer for accel, 0 is resting state
- if (data.isOnSurface && data.isMotion) {
- // Reset timer if stopped moving
- if (!data.isMotion) {
- if (MotionStart != 0) MotionStart = 0;
- return mouse_report;
- }
-
- // Set timer if new motion
- if ((MotionStart == 0) && data.isMotion) {
-# ifdef CONSOLE_ENABLE
- if (debug_mouse) dprintf("Starting motion.\n");
-# endif
- MotionStart = timer_read();
- }
- mouse_report.x = constrain_hid(data.dx);
- mouse_report.y = constrain_hid(data.dy);
- }
+#elif defined(POINTING_DEVICE_DRIVER_pmw3360) || defined(POINTING_DEVICE_DRIVER_pmw3389)
+static void pmw33xx_init_wrapper(void) {
+ pmw33xx_init(0);
+}
- return mouse_report;
+static void pmw33xx_set_cpi_wrapper(uint16_t cpi) {
+ pmw33xx_set_cpi(0, cpi);
}
-// clang-format off
-const pointing_device_driver_t pointing_device_driver = {
- .init = pmw3360_device_init,
- .get_report = pmw3360_get_report,
- .set_cpi = pmw3360_set_cpi,
- .get_cpi = pmw3360_get_cpi
-};
-// clang-format on
-#elif defined(POINTING_DEVICE_DRIVER_pmw3389)
-static void pmw3389_device_init(void) {
- pmw3389_init();
+static uint16_t pmw33xx_get_cpi_wrapper(void) {
+ return pmw33xx_get_cpi(0);
}
-report_mouse_t pmw3389_get_report(report_mouse_t mouse_report) {
- report_pmw3389_t data = pmw3389_read_burst();
- static uint16_t MotionStart = 0; // Timer for accel, 0 is resting state
+report_mouse_t pmw33xx_get_report(report_mouse_t mouse_report) {
+ pmw33xx_report_t report = pmw33xx_read_burst(0);
+ static bool in_motion = false;
- if (data.isOnSurface && data.isMotion) {
- // Reset timer if stopped moving
- if (!data.isMotion) {
- if (MotionStart != 0) MotionStart = 0;
- return mouse_report;
- }
+ if (report.motion.b.is_lifted) {
+ return mouse_report;
+ }
- // Set timer if new motion
- if ((MotionStart == 0) && data.isMotion) {
-# ifdef CONSOLE_ENABLE
- if (debug_mouse) dprintf("Starting motion.\n");
-# endif
- MotionStart = timer_read();
- }
- mouse_report.x = constrain_hid(data.dx);
- mouse_report.y = constrain_hid(data.dy);
+ if (!report.motion.b.is_motion) {
+ in_motion = false;
+ return mouse_report;
}
+ if (!in_motion) {
+ in_motion = true;
+ dprintf("PWM3360 (0): starting motion\n");
+ }
+
+ mouse_report.x = CONSTRAIN_HID_XY(report.delta_x);
+ mouse_report.y = CONSTRAIN_HID_XY(report.delta_y);
return mouse_report;
}
// clang-format off
const pointing_device_driver_t pointing_device_driver = {
- .init = pmw3389_device_init,
- .get_report = pmw3389_get_report,
- .set_cpi = pmw3389_set_cpi,
- .get_cpi = pmw3389_get_cpi
+ .init = pmw33xx_init_wrapper,
+ .get_report = pmw33xx_get_report,
+ .set_cpi = pmw33xx_set_cpi_wrapper,
+ .get_cpi = pmw33xx_get_cpi_wrapper
};
// clang-format on
+
#else
__attribute__((weak)) void pointing_device_driver_init(void) {}
__attribute__((weak)) report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) {
@@ -292,4 +320,5 @@ const pointing_device_driver_t pointing_device_driver = {
.set_cpi = pointing_device_driver_set_cpi
};
// clang-format on
+
#endif