From 0b726a437b8906fb52662504ccb6e4f052890f3c Mon Sep 17 00:00:00 2001 From: Drzony Date: Sat, 30 Jul 2022 06:20:34 +0200 Subject: [PATCH] Implement relative mode for Cirque trackpad (#17760) --- docs/feature_pointing_device.md | 75 +++++++++++------ drivers/sensors/cirque_pinnacle.c | 83 ++++++++++++++++--- drivers/sensors/cirque_pinnacle.h | 51 +++++++----- drivers/sensors/cirque_pinnacle_gestures.c | 12 ++- drivers/sensors/cirque_pinnacle_gestures.h | 5 +- drivers/sensors/cirque_pinnacle_regdefs.h | 2 +- .../pointing_device/pointing_device_drivers.c | 51 ++++++++---- 7 files changed, 202 insertions(+), 77 deletions(-) diff --git a/docs/feature_pointing_device.md b/docs/feature_pointing_device.md index f8a55c1c86..17acc15ff0 100644 --- a/docs/feature_pointing_device.md +++ b/docs/feature_pointing_device.md @@ -89,17 +89,16 @@ POINTING_DEVICE_DRIVER = cirque_pinnacle_spi This supports the Cirque Pinnacle 1CA027 Touch Controller, which is used in the TM040040, TM035035 and the TM023023 trackpads. These are I2C or SPI compatible, and both configurations are supported. +#### Common settings + | Setting | Description | Default | | -------------------------------- | ---------------------------------------------------------- | ------------------ | -| `CIRQUE_PINNACLE_X_LOWER` | (Optional) The minimum reachable X value on the sensor. | `127` | -| `CIRQUE_PINNACLE_X_UPPER` | (Optional) The maximum reachable X value on the sensor. | `1919` | -| `CIRQUE_PINNACLE_Y_LOWER` | (Optional) The minimum reachable Y value on the sensor. | `63` | -| `CIRQUE_PINNACLE_Y_UPPER` | (Optional) The maximum reachable Y value on the sensor. | `1471` | | `CIRQUE_PINNACLE_DIAMETER_MM` | (Optional) Diameter of the trackpad sensor in millimeters. | `40` | | `CIRQUE_PINNACLE_ATTENUATION` | (Optional) Sets the attenuation of the sensor data. | `ADC_ATTENUATE_4X` | | `CIRQUE_PINNACLE_CURVED_OVERLAY` | (Optional) Applies settings tuned for curved overlay. | _not defined_ | +| `CIRQUE_PINNACLE_POSITION_MODE` | (Optional) Mode of operation. | _not defined_ | -**`CIRQUE_PINNACLE_ATTENUATION`** is a measure of how much data is suppressed in regards to sensitivity. The higher the attenuation, the less sensitive the touchpad will be. +**`CIRQUE_PINNACLE_ATTENUATION`** is a measure of how much data is suppressed in regards to sensitivity. The higher the attenuation, the less sensitive the touchpad will be. Default attenuation is set to 4X, although if you are using a thicker overlay (such as the curved overlay) you will want a lower attenuation such as 2X. The possible values are: * `ADC_ATTENUATE_4X`: Least sensitive @@ -107,6 +106,11 @@ Default attenuation is set to 4X, although if you are using a thicker overlay (s * `ADC_ATTENUATE_2X` * `ADC_ATTENUATE_1X`: Most sensitive +**`CIRQUE_PINNACLE_POSITION_MODE`** can be `CIRQUE_PINNACLE_ABSOLUTE_MODE` or `CIRQUE_PINNACLE_RELATIVE_MODE`. Modes differ in supported features/gestures. + +* `CIRQUE_PINNACLE_ABSOLUTE_MODE`: Reports absolute x, y, z (touch pressure) coordinates and up to 5 hw buttons connected to the trackpad +* `CIRQUE_PINNACLE_RELATIVE_MODE`: Reports x/y deltas, scroll and up to 3 buttons (2 of them can be from taps, see gestures) connected to trackpad. Supports taps on secondary side of split. Saves about 2k of flash compared to absolute mode with all features. + | I2C Setting | Description | Default | | ------------------------- | ------------------------------------------------------------------------------- | ------- | | `CIRQUE_PINNACLE_ADDR` | (Required) Sets the I2C Address for the Cirque Trackpad | `0x2A` | @@ -124,16 +128,37 @@ Default Scaling is 1024. Actual CPI depends on trackpad diameter. Also see the `POINTING_DEVICE_TASK_THROTTLE_MS`, which defaults to 10ms when using Cirque Pinnacle, which matches the internal update rate of the position registers (in standard configuration). Advanced configuration for pen/stylus usage might require lower values. -#### Cirque Trackpad gestures +#### Absolute mode settings -| Gesture Setting | Description | Default | -| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | -| `CIRQUE_PINNACLE_CIRCULAR_SCROLL_ENABLE` | (Optional) Enable circular scroll. Touch originating in outer ring can trigger scroll by moving along the perimeter. Near side triggers vertical scroll and far side triggers horizontal scroll. | _not defined_ | -| `CIRQUE_PINNACLE_TAP_ENABLE` | (Optional) Enable tap to click. This currently only works on the master side. | _not defined_ | -| `CIRQUE_PINNACLE_TAPPING_TERM` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` | -| `CIRQUE_PINNACLE_TOUCH_DEBOUNCE` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` | +| Setting | Description | Default | +| -------------------------------- | ---------------------------------------------------------- | ------------------ | +| `CIRQUE_PINNACLE_X_LOWER` | (Optional) The minimum reachable X value on the sensor. | `127` | +| `CIRQUE_PINNACLE_X_UPPER` | (Optional) The maximum reachable X value on the sensor. | `1919` | +| `CIRQUE_PINNACLE_Y_LOWER` | (Optional) The minimum reachable Y value on the sensor. | `63` | +| `CIRQUE_PINNACLE_Y_UPPER` | (Optional) The maximum reachable Y value on the sensor. | `1471` | -Additionally, `POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE` is supported on the Cirque. +#### Absolute mode gestures + +| Gesture Setting | Description | Default | +| ---------------------------------------------- | ------------------------------------------------------------------------------ | -------------------- | +| `CIRQUE_PINNACLE_TAP_ENABLE` | (Optional) Enable tap to click. This currently only works on the master side. | _not defined_ | +| `CIRQUE_PINNACLE_TAPPING_TERM` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` | +| `CIRQUE_PINNACLE_TOUCH_DEBOUNCE` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` | + +`POINTING_DEVICE_GESTURES_SCROLL_ENABLE` in this mode enables circular scroll. Touch originating in outer ring can trigger scroll by moving along the perimeter. Near side triggers vertical scroll and far side triggers horizontal scroll. + +Additionally, `POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE` is supported in this mode. + +#### Relative mode gestures + +| Gesture Setting | Description | Default | +| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| `CIRQUE_PINNACLE_TAP_ENABLE` | (Optional) Enable tap to "left click". Works on both sides of a split keyboard. | _not defined_ | +| `CIRQUE_PINNACLE_SECONDARY_TAP_ENABLE` | (Optional) Tap in upper right corner (half of the finger needs to be outside of the trackpad) of the trackpad will result in "right click". `CIRQUE_PINNACLE_TAP_ENABLE` must be enabled. | _not defined_ | + +Tapping term and debounce are not configurable in this mode since it's handled by trackpad internally. + +`POINTING_DEVICE_GESTURES_SCROLL_ENABLE` in this mode enables side scroll. Touch originating on the right side can trigger vertical scroll (IntelliSense trackpad style). ### PAW 3204 Sensor @@ -152,7 +177,6 @@ The paw 3204 sensor uses a serial type protocol for communication, and requires The CPI range is 400-1600, with supported values of (400, 500, 600, 800, 1000, 1200 and 1600). Defaults to 1000 CPI. - ### Pimoroni Trackball To use the Pimoroni Trackball module, add this to your `rules.mk`: @@ -254,17 +278,18 @@ void pointing_device_driver_set_cpi(uint16_t cpi) {} ## Common Configuration -| Setting | Description | Default | -| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------- | -| `MOUSE_EXTENDED_REPORT` | (Optional) Enables support for extended mouse reports. (-32767 to 32767, instead of just -127 to 127). | _not defined_ | -| `POINTING_DEVICE_ROTATION_90` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ | -| `POINTING_DEVICE_ROTATION_180` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ | -| `POINTING_DEVICE_ROTATION_270` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ | -| `POINTING_DEVICE_INVERT_X` | (Optional) Inverts the X axis report. | _not defined_ | -| `POINTING_DEVICE_INVERT_Y` | (Optional) Inverts the Y axis report. | _not defined_ | -| `POINTING_DEVICE_MOTION_PIN` | (Optional) If supported, will only read from sensor if pin is active. | _not defined_ | -| `POINTING_DEVICE_TASK_THROTTLE_MS` | (Optional) Limits the frequency that the sensor is polled for motion. | _not defined_ | -| `POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE` | (Optional) Enable inertial cursor. Cursor continues moving after a flick gesture and slows down by kinetic friction. | _not defined_ | +| Setting | Description | Default | +| ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| `MOUSE_EXTENDED_REPORT` | (Optional) Enables support for extended mouse reports. (-32767 to 32767, instead of just -127 to 127). | _not defined_ | +| `POINTING_DEVICE_ROTATION_90` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ | +| `POINTING_DEVICE_ROTATION_180` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ | +| `POINTING_DEVICE_ROTATION_270` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ | +| `POINTING_DEVICE_INVERT_X` | (Optional) Inverts the X axis report. | _not defined_ | +| `POINTING_DEVICE_INVERT_Y` | (Optional) Inverts the Y axis report. | _not defined_ | +| `POINTING_DEVICE_MOTION_PIN` | (Optional) If supported, will only read from sensor if pin is active. | _not defined_ | +| `POINTING_DEVICE_TASK_THROTTLE_MS` | (Optional) Limits the frequency that the sensor is polled for motion. | _not defined_ | +| `POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE` | (Optional) Enable inertial cursor. Cursor continues moving after a flick gesture and slows down by kinetic friction. | _not defined_ | +| `POINTING_DEVICE_GESTURES_SCROLL_ENABLE` | (Optional) Enable scroll gesture. The gesture that activates the scroll is device dependent. | _not defined_ | !> When using `SPLIT_POINTING_ENABLE` the `POINTING_DEVICE_MOTION_PIN` functionality is not supported and `POINTING_DEVICE_TASK_THROTTLE_MS` will default to `1`. Increasing this value will increase transport performance at the cost of possible mouse responsiveness. diff --git a/drivers/sensors/cirque_pinnacle.c b/drivers/sensors/cirque_pinnacle.c index c50d5a2525..8bd4eb736e 100644 --- a/drivers/sensors/cirque_pinnacle.c +++ b/drivers/sensors/cirque_pinnacle.c @@ -9,6 +9,8 @@ #include "wait.h" #include "timer.h" +#include + #ifndef CIRQUE_PINNACLE_ATTENUATION # ifdef CIRQUE_PINNACLE_CURVED_OVERLAY # define CIRQUE_PINNACLE_ATTENUATION EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_2X @@ -31,6 +33,7 @@ void print_byte(uint8_t byte) { } #endif +#if CIRQUE_PINNACLE_POSITION_MODE /* Logical Scaling Functions */ // Clips raw coordinates to "reachable" window of sensor // NOTE: values outside this window can only appear as a result of noise @@ -46,6 +49,7 @@ void ClipCoordinates(pinnacle_data_t* coordinates) { coordinates->yValue = CIRQUE_PINNACLE_Y_UPPER; } } +#endif uint16_t cirque_pinnacle_get_scale(void) { return scale_data; @@ -56,6 +60,7 @@ void cirque_pinnacle_set_scale(uint16_t scale) { // Scales data to desired X & Y resolution void cirque_pinnacle_scale_data(pinnacle_data_t* coordinates, uint16_t xResolution, uint16_t yResolution) { +#if CIRQUE_PINNACLE_POSITION_MODE uint32_t xTemp = 0; uint32_t yTemp = 0; @@ -71,6 +76,22 @@ void cirque_pinnacle_scale_data(pinnacle_data_t* coordinates, uint16_t xResoluti // scale coordinates to (xResolution, yResolution) range coordinates->xValue = (uint16_t)(xTemp * xResolution / CIRQUE_PINNACLE_X_RANGE); coordinates->yValue = (uint16_t)(yTemp * yResolution / CIRQUE_PINNACLE_Y_RANGE); +#else + int32_t xTemp = 0, yTemp = 0; + ldiv_t temp; + static int32_t xRemainder, yRemainder; + + temp = ldiv(((int32_t)coordinates->xDelta) * (int32_t)xResolution + xRemainder, (int32_t)CIRQUE_PINNACLE_X_RANGE); + xTemp = temp.quot; + xRemainder = temp.rem; + + temp = ldiv(((int32_t)coordinates->yDelta) * (int32_t)yResolution + yRemainder, (int32_t)CIRQUE_PINNACLE_Y_RANGE); + yTemp = temp.quot; + yRemainder = temp.rem; + + coordinates->xDelta = (int16_t)xTemp; + coordinates->yDelta = (int16_t)yTemp; +#endif } // Clears Status1 register flags (SW_CC and SW_DR) @@ -142,14 +163,20 @@ void ERA_WriteByte(uint16_t address, uint8_t data) { cirque_pinnacle_clear_flags(); } -void cirque_pinnacle_set_adc_attenuation(uint8_t adcGain) { +bool cirque_pinnacle_set_adc_attenuation(uint8_t adcGain) { uint8_t adcconfig = 0x00; ERA_ReadBytes(EXTREG__TRACK_ADCCONFIG, &adcconfig, 1); - adcconfig &= EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_MASK; + adcGain &= EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_MASK; + if (adcGain == (adcconfig & EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_MASK)) { + return false; + } + adcconfig &= ~EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_MASK; adcconfig |= adcGain; ERA_WriteByte(EXTREG__TRACK_ADCCONFIG, adcconfig); ERA_ReadBytes(EXTREG__TRACK_ADCCONFIG, &adcconfig, 1); + + return true; } // Changes thresholds to improve detection of fingers @@ -207,30 +234,52 @@ void cirque_pinnacle_init(void) { touchpad_init = true; - // Host clears SW_CC flag - cirque_pinnacle_clear_flags(); - // send a RESET command now, in case QMK had a soft-reset without a power cycle RAP_Write(HOSTREG__SYSCONFIG1, HOSTREG__SYSCONFIG1__RESET); wait_ms(30); // Pinnacle needs 10-15ms to boot, so wait long enough before configuring RAP_Write(HOSTREG__SYSCONFIG1, HOSTREG__SYSCONFIG1_DEFVAL); wait_us(50); - // FeedConfig2 (Feature flags for Relative Mode Only) + // Host clears SW_CC flag + cirque_pinnacle_clear_flags(); + +#if CIRQUE_PINNACLE_POSITION_MODE RAP_Write(HOSTREG__FEEDCONFIG2, HOSTREG__FEEDCONFIG2_DEFVAL); +#else + // FeedConfig2 (Feature flags for Relative Mode Only) + uint8_t feedconfig2 = HOSTREG__FEEDCONFIG2__GLIDE_EXTEND_DISABLE | HOSTREG__FEEDCONFIG2__INTELLIMOUSE_MODE; +# if !defined(CIRQUE_PINNACLE_TAP_ENABLE) + feedconfig2 |= HOSTREG__FEEDCONFIG2__ALL_TAP_DISABLE; +# endif +# if !defined(CIRQUE_PINNACLE_SECONDARY_TAP_ENABLE) + feedconfig2 |= HOSTREG__FEEDCONFIG2__SECONDARY_TAP_DISABLE; +# elif !defined(CIRQUE_PINNACLE_TAP_ENABLE) +# error CIRQUE_PINNACLE_TAP_ENABLE must be defined for CIRQUE_PINNACLE_SECONDARY_TAP_ENABLE to work +# endif +# if !defined(CIRQUE_PINNACLE_SIDE_SCROLL_ENABLE) + feedconfig2 |= HOSTREG__FEEDCONFIG2__SCROLL_DISABLE; +# endif + RAP_Write(HOSTREG__FEEDCONFIG2, feedconfig2); +#endif // FeedConfig1 (Data Output Flags) RAP_Write(HOSTREG__FEEDCONFIG1, CIRQUE_PINNACLE_POSITION_MODE ? HOSTREG__FEEDCONFIG1__DATA_TYPE__REL0_ABS1 : HOSTREG__FEEDCONFIG1_DEFVAL); +#if CIRQUE_PINNACLE_POSITION_MODE // Host sets z-idle packet count to 5 (default is 0x1E/30) RAP_Write(HOSTREG__ZIDLE, 5); +#endif + + bool calibrate = cirque_pinnacle_set_adc_attenuation(CIRQUE_PINNACLE_ATTENUATION); - cirque_pinnacle_set_adc_attenuation(CIRQUE_PINNACLE_ATTENUATION); #ifdef CIRQUE_PINNACLE_CURVED_OVERLAY cirque_pinnacle_tune_edge_sensitivity(); + calibrate = true; #endif - // Force a calibration after setting ADC attenuation - cirque_pinnacle_calibrate(); + if (calibrate) { + // Force a calibration after setting ADC attenuation + cirque_pinnacle_calibrate(); + } cirque_pinnacle_enable_feed(true); } @@ -265,10 +314,18 @@ pinnacle_data_t cirque_pinnacle_read_data(void) { #else // Decode data for relative mode // Registers 0x16 and 0x17 are unused in this mode - result.buttons = data[0] & 0x07; // bit0 = primary button, bit1 = secondary button, bit2 = auxilary button, if Taps enabled then also software-recognized taps are reported - result.xDelta = data[1]; - result.yDelta = data[2]; - result.wheelCount = data[3]; + result.buttons = data[0] & 0x07; // Only three buttons are supported + if ((data[0] & 0x10) && data[1] != 0) { + result.xDelta = -((int16_t)256 - (int16_t)(data[1])); + } else { + result.xDelta = data[1]; + } + if ((data[0] & 0x20) && data[2] != 0) { + result.yDelta = ((int16_t)256 - (int16_t)(data[2])); + } else { + result.yDelta = -((int16_t)data[2]); + } + result.wheelCount = ((int8_t*)data)[3]; #endif result.valid = true; diff --git a/drivers/sensors/cirque_pinnacle.h b/drivers/sensors/cirque_pinnacle.h index 1c9bf06fd3..e9bb9621e4 100644 --- a/drivers/sensors/cirque_pinnacle.h +++ b/drivers/sensors/cirque_pinnacle.h @@ -21,24 +21,35 @@ # define CIRQUE_PINNACLE_DIAMETER_MM 40 #endif +#if CIRQUE_PINNACLE_POSITION_MODE // Coordinate scaling values -#ifndef CIRQUE_PINNACLE_X_LOWER -# define CIRQUE_PINNACLE_X_LOWER 127 // min "reachable" X value -#endif -#ifndef CIRQUE_PINNACLE_X_UPPER -# define CIRQUE_PINNACLE_X_UPPER 1919 // max "reachable" X value -#endif -#ifndef CIRQUE_PINNACLE_Y_LOWER -# define CIRQUE_PINNACLE_Y_LOWER 63 // min "reachable" Y value -#endif -#ifndef CIRQUE_PINNACLE_Y_UPPER -# define CIRQUE_PINNACLE_Y_UPPER 1471 // max "reachable" Y value -#endif -#ifndef CIRQUE_PINNACLE_X_RANGE -# define CIRQUE_PINNACLE_X_RANGE (CIRQUE_PINNACLE_X_UPPER - CIRQUE_PINNACLE_X_LOWER) -#endif -#ifndef CIRQUE_PINNACLE_Y_RANGE -# define CIRQUE_PINNACLE_Y_RANGE (CIRQUE_PINNACLE_Y_UPPER - CIRQUE_PINNACLE_Y_LOWER) +# ifndef CIRQUE_PINNACLE_X_LOWER +# define CIRQUE_PINNACLE_X_LOWER 127 // min "reachable" X value +# endif +# ifndef CIRQUE_PINNACLE_X_UPPER +# define CIRQUE_PINNACLE_X_UPPER 1919 // max "reachable" X value +# endif +# ifndef CIRQUE_PINNACLE_Y_LOWER +# define CIRQUE_PINNACLE_Y_LOWER 63 // min "reachable" Y value +# endif +# ifndef CIRQUE_PINNACLE_Y_UPPER +# define CIRQUE_PINNACLE_Y_UPPER 1471 // max "reachable" Y value +# endif +# ifndef CIRQUE_PINNACLE_X_RANGE +# define CIRQUE_PINNACLE_X_RANGE (CIRQUE_PINNACLE_X_UPPER - CIRQUE_PINNACLE_X_LOWER) +# endif +# ifndef CIRQUE_PINNACLE_Y_RANGE +# define CIRQUE_PINNACLE_Y_RANGE (CIRQUE_PINNACLE_Y_UPPER - CIRQUE_PINNACLE_Y_LOWER) +# endif +# if defined(POINTING_DEVICE_GESTURE_SCROLL_ENABLE) +# define CIRQUE_PINNACLE_CIRCULAR_SCROLL_ENABLE +# endif +#else +# define CIRQUE_PINNACLE_X_RANGE 256 +# define CIRQUE_PINNACLE_Y_RANGE 256 +# if defined(POINTING_DEVICE_GESTURE_SCROLL_ENABLE) +# define CIRQUE_PINNACLE_SIDE_SCROLL_ENABLE +# endif #endif #if !defined(POINTING_DEVICE_TASK_THROTTLE_MS) # define POINTING_DEVICE_TASK_THROTTLE_MS 10 // Cirque Pinnacle in normal operation produces data every 10ms. Advanced configuration for pen/stylus usage might require lower values. @@ -86,9 +97,9 @@ typedef struct { uint8_t buttonFlags; bool touchDown; #else - uint8_t xDelta; - uint8_t yDelta; - uint8_t wheelCount; + int16_t xDelta; + int16_t yDelta; + int8_t wheelCount; uint8_t buttons; #endif } pinnacle_data_t; diff --git a/drivers/sensors/cirque_pinnacle_gestures.c b/drivers/sensors/cirque_pinnacle_gestures.c index dc2f682a83..a73b745e59 100644 --- a/drivers/sensors/cirque_pinnacle_gestures.c +++ b/drivers/sensors/cirque_pinnacle_gestures.c @@ -24,11 +24,11 @@ # include "keyboard.h" #endif -#if defined(CIRQUE_PINNACLE_TAP_ENABLE) || defined(CIRQUE_PINNACLE_CIRCULAR_SCROLL_ENABLE) +#if (defined(CIRQUE_PINNACLE_TAP_ENABLE) || defined(CIRQUE_PINNACLE_CIRCULAR_SCROLL_ENABLE)) && CIRQUE_PINNACLE_POSITION_MODE static cirque_pinnacle_features_t features = {.tap_enable = true, .circular_scroll_enable = true}; #endif -#ifdef CIRQUE_PINNACLE_TAP_ENABLE +#if defined(CIRQUE_PINNACLE_TAP_ENABLE) && CIRQUE_PINNACLE_POSITION_MODE static trackpad_tap_context_t tap; static report_mouse_t trackpad_tap(report_mouse_t mouse_report, pinnacle_data_t touchData) { @@ -62,6 +62,9 @@ void cirque_pinnacle_enable_tap(bool enable) { #endif #ifdef CIRQUE_PINNACLE_CIRCULAR_SCROLL_ENABLE +# if !CIRQUE_PINNACLE_POSITION_MODE +# error "Circular scroll is not supported in relative mode" +# endif /* To set a trackpad exclusively as scroll wheel: outer_ring_pct = 100, trigger_px = 0, trigger_ang = 0 */ static circular_scroll_context_t scroll = {.config = {.outer_ring_pct = 33, .trigger_px = 16, @@ -213,6 +216,9 @@ bool cirque_pinnacle_gestures(report_mouse_t* mouse_report, pinnacle_data_t touc bool suppress_mouse_update = false; #ifdef CIRQUE_PINNACLE_CIRCULAR_SCROLL_ENABLE +# if !CIRQUE_PINNACLE_POSITION_MODE +# error "Circular scroll is not supported in relative mode" +# endif circular_scroll_t scroll_report; if (features.circular_scroll_enable) { scroll_report = circular_scroll(touchData); @@ -222,7 +228,7 @@ bool cirque_pinnacle_gestures(report_mouse_t* mouse_report, pinnacle_data_t touc } #endif -#ifdef CIRQUE_PINNACLE_TAP_ENABLE +#if defined(CIRQUE_PINNACLE_TAP_ENABLE) && CIRQUE_PINNACLE_POSITION_MODE if (features.tap_enable) { *mouse_report = trackpad_tap(*mouse_report, touchData); } diff --git a/drivers/sensors/cirque_pinnacle_gestures.h b/drivers/sensors/cirque_pinnacle_gestures.h index f39782b467..d2aa206b2b 100644 --- a/drivers/sensors/cirque_pinnacle_gestures.h +++ b/drivers/sensors/cirque_pinnacle_gestures.h @@ -24,7 +24,7 @@ typedef struct { bool circular_scroll_enable; } cirque_pinnacle_features_t; -#ifdef CIRQUE_PINNACLE_TAP_ENABLE +#if defined(CIRQUE_PINNACLE_TAP_ENABLE) && CIRQUE_PINNACLE_POSITION_MODE # ifndef CIRQUE_PINNACLE_TAPPING_TERM # include "action.h" # include "action_tapping.h" @@ -44,6 +44,9 @@ void cirque_pinnacle_enable_tap(bool enable); #endif #ifdef CIRQUE_PINNACLE_CIRCULAR_SCROLL_ENABLE +# if !CIRQUE_PINNACLE_POSITION_MODE +# error "Circular scroll is not supported in relative mode" +# endif typedef enum { SCROLL_UNINITIALIZED, SCROLL_DETECTING, diff --git a/drivers/sensors/cirque_pinnacle_regdefs.h b/drivers/sensors/cirque_pinnacle_regdefs.h index 993da1e757..fb9e09af6e 100644 --- a/drivers/sensors/cirque_pinnacle_regdefs.h +++ b/drivers/sensors/cirque_pinnacle_regdefs.h @@ -384,7 +384,7 @@ #define EXTREG__TRACK_ADCCONFIG 0x0187 // ADC-attenuation settings (held in BIT_7 and BIT_6) // 1X = most sensitive, 4X = least sensitive -# define EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_MASK 0x3F +# define EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_MASK 0xC0 # define EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_1X 0x00 # define EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_2X 0x40 # define EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_3X 0x80 diff --git a/quantum/pointing_device/pointing_device_drivers.c b/quantum/pointing_device/pointing_device_drivers.c index 3780f3d2da..b96f8ff4b3 100644 --- a/quantum/pointing_device/pointing_device_drivers.c +++ b/quantum/pointing_device/pointing_device_drivers.c @@ -116,38 +116,35 @@ void cirque_pinnacle_configure_cursor_glide(float trigger_px) { } # endif +# if CIRQUE_PINNACLE_POSITION_MODE report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) { pinnacle_data_t touchData = cirque_pinnacle_read_data(); mouse_xy_report_t report_x = 0, report_y = 0; static uint16_t x = 0, y = 0; -# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE +# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE cursor_glide_t glide_report = {0}; if (cursor_glide_enable) { glide_report = cursor_glide_check(&glide); } -# endif - -# if !CIRQUE_PINNACLE_POSITION_MODE -# error Cirque Pinnacle with relative mode not implemented yet. -# endif +# endif if (!touchData.valid) { -# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE +# 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 +# endif return mouse_report; } -# if CONSOLE_ENABLE +# 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 +# endif // Scale coordinates to arbitrary X, Y resolution cirque_pinnacle_scale_data(&touchData, cirque_pinnacle_get_scale(), cirque_pinnacle_get_scale()); @@ -160,7 +157,7 @@ report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) { x = touchData.xValue; y = touchData.yValue; -# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE +# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE if (cursor_glide_enable) { if (touchData.touchDown) { cursor_glide_update(&glide, report_x, report_y, touchData.zValue); @@ -172,12 +169,12 @@ report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) { } } } -# endif +# endif } -# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE +# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE mouse_report_update: -# endif +# endif mouse_report.x = report_x; mouse_report.y = report_y; @@ -199,6 +196,32 @@ const pointing_device_driver_t pointing_device_driver = { .get_cpi = cirque_pinnacle_get_cpi }; // clang-format on +# else +report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) { + pinnacle_data_t touchData = cirque_pinnacle_read_data(); + + // Scale coordinates to arbitrary X, Y resolution + cirque_pinnacle_scale_data(&touchData, cirque_pinnacle_get_scale(), cirque_pinnacle_get_scale()); + + if (touchData.valid) { + mouse_report.buttons = touchData.buttons; + mouse_report.x = CONSTRAIN_HID_XY(touchData.xDelta); + mouse_report.y = CONSTRAIN_HID_XY(touchData.yDelta); + mouse_report.v = touchData.wheelCount; + } + return mouse_report; +} + +// 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 +}; +// clang-format on +# endif + #elif defined(POINTING_DEVICE_DRIVER_paw3204) report_mouse_t paw3204_get_report(report_mouse_t mouse_report) {