Implement relative mode for Cirque trackpad (#17760)

This commit is contained in:
Drzony 2022-07-30 06:20:34 +02:00 committed by GitHub
parent b085d5221b
commit 0b726a437b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 202 additions and 77 deletions

View File

@ -89,15 +89,14 @@ 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. 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 | | 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_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_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_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.
@ -107,6 +106,11 @@ Default attenuation is set to 4X, although if you are using a thicker overlay (s
* `ADC_ATTENUATE_2X` * `ADC_ATTENUATE_2X`
* `ADC_ATTENUATE_1X`: Most sensitive * `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 | | I2C Setting | Description | Default |
| ------------------------- | ------------------------------------------------------------------------------- | ------- | | ------------------------- | ------------------------------------------------------------------------------- | ------- |
| `CIRQUE_PINNACLE_ADDR` | (Required) Sets the I2C Address for the Cirque Trackpad | `0x2A` | | `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. 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 | | 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_X_LOWER` | (Optional) The minimum reachable X value on the sensor. | `127` |
| `CIRQUE_PINNACLE_TAP_ENABLE` | (Optional) Enable tap to click. This currently only works on the master side. | _not defined_ | | `CIRQUE_PINNACLE_X_UPPER` | (Optional) The maximum reachable X value on the sensor. | `1919` |
| `CIRQUE_PINNACLE_TAPPING_TERM` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` | | `CIRQUE_PINNACLE_Y_LOWER` | (Optional) The minimum reachable Y value on the sensor. | `63` |
| `CIRQUE_PINNACLE_TOUCH_DEBOUNCE` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` | | `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 ### 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. The CPI range is 400-1600, with supported values of (400, 500, 600, 800, 1000, 1200 and 1600). Defaults to 1000 CPI.
### Pimoroni Trackball ### Pimoroni Trackball
To use the Pimoroni Trackball module, add this to your `rules.mk`: 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 ## Common Configuration
| Setting | Description | Default | | Setting | Description | Default |
| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------- | | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `MOUSE_EXTENDED_REPORT` | (Optional) Enables support for extended mouse reports. (-32767 to 32767, instead of just -127 to 127). | _not defined_ | | `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_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_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_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_X` | (Optional) Inverts the X axis report. | _not defined_ |
| `POINTING_DEVICE_INVERT_Y` | (Optional) Inverts the Y 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_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_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_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. !> 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.

View File

@ -9,6 +9,8 @@
#include "wait.h" #include "wait.h"
#include "timer.h" #include "timer.h"
#include <stdlib.h>
#ifndef CIRQUE_PINNACLE_ATTENUATION #ifndef CIRQUE_PINNACLE_ATTENUATION
# ifdef CIRQUE_PINNACLE_CURVED_OVERLAY # ifdef CIRQUE_PINNACLE_CURVED_OVERLAY
# define CIRQUE_PINNACLE_ATTENUATION EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_2X # define CIRQUE_PINNACLE_ATTENUATION EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_2X
@ -31,6 +33,7 @@ void print_byte(uint8_t byte) {
} }
#endif #endif
#if CIRQUE_PINNACLE_POSITION_MODE
/* Logical Scaling Functions */ /* Logical Scaling Functions */
// Clips raw coordinates to "reachable" window of sensor // Clips raw coordinates to "reachable" window of sensor
// NOTE: values outside this window can only appear as a result of noise // 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; coordinates->yValue = CIRQUE_PINNACLE_Y_UPPER;
} }
} }
#endif
uint16_t cirque_pinnacle_get_scale(void) { uint16_t cirque_pinnacle_get_scale(void) {
return scale_data; return scale_data;
@ -56,6 +60,7 @@ void cirque_pinnacle_set_scale(uint16_t scale) {
// Scales data to desired X & Y resolution // Scales data to desired X & Y resolution
void cirque_pinnacle_scale_data(pinnacle_data_t* coordinates, uint16_t xResolution, uint16_t yResolution) { 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 xTemp = 0;
uint32_t yTemp = 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 // scale coordinates to (xResolution, yResolution) range
coordinates->xValue = (uint16_t)(xTemp * xResolution / CIRQUE_PINNACLE_X_RANGE); coordinates->xValue = (uint16_t)(xTemp * xResolution / CIRQUE_PINNACLE_X_RANGE);
coordinates->yValue = (uint16_t)(yTemp * yResolution / CIRQUE_PINNACLE_Y_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) // 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(); 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; uint8_t adcconfig = 0x00;
ERA_ReadBytes(EXTREG__TRACK_ADCCONFIG, &adcconfig, 1); 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; adcconfig |= adcGain;
ERA_WriteByte(EXTREG__TRACK_ADCCONFIG, adcconfig); ERA_WriteByte(EXTREG__TRACK_ADCCONFIG, adcconfig);
ERA_ReadBytes(EXTREG__TRACK_ADCCONFIG, &adcconfig, 1); ERA_ReadBytes(EXTREG__TRACK_ADCCONFIG, &adcconfig, 1);
return true;
} }
// Changes thresholds to improve detection of fingers // Changes thresholds to improve detection of fingers
@ -207,30 +234,52 @@ void cirque_pinnacle_init(void) {
touchpad_init = true; 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 // send a RESET command now, in case QMK had a soft-reset without a power cycle
RAP_Write(HOSTREG__SYSCONFIG1, HOSTREG__SYSCONFIG1__RESET); RAP_Write(HOSTREG__SYSCONFIG1, HOSTREG__SYSCONFIG1__RESET);
wait_ms(30); // Pinnacle needs 10-15ms to boot, so wait long enough before configuring wait_ms(30); // Pinnacle needs 10-15ms to boot, so wait long enough before configuring
RAP_Write(HOSTREG__SYSCONFIG1, HOSTREG__SYSCONFIG1_DEFVAL); RAP_Write(HOSTREG__SYSCONFIG1, HOSTREG__SYSCONFIG1_DEFVAL);
wait_us(50); 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); 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) // FeedConfig1 (Data Output Flags)
RAP_Write(HOSTREG__FEEDCONFIG1, CIRQUE_PINNACLE_POSITION_MODE ? HOSTREG__FEEDCONFIG1__DATA_TYPE__REL0_ABS1 : HOSTREG__FEEDCONFIG1_DEFVAL); 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) // Host sets z-idle packet count to 5 (default is 0x1E/30)
RAP_Write(HOSTREG__ZIDLE, 5); 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 #ifdef CIRQUE_PINNACLE_CURVED_OVERLAY
cirque_pinnacle_tune_edge_sensitivity(); cirque_pinnacle_tune_edge_sensitivity();
calibrate = true;
#endif #endif
// Force a calibration after setting ADC attenuation if (calibrate) {
cirque_pinnacle_calibrate(); // Force a calibration after setting ADC attenuation
cirque_pinnacle_calibrate();
}
cirque_pinnacle_enable_feed(true); cirque_pinnacle_enable_feed(true);
} }
@ -265,10 +314,18 @@ pinnacle_data_t cirque_pinnacle_read_data(void) {
#else #else
// Decode data for relative mode // Decode data for relative mode
// Registers 0x16 and 0x17 are unused in this 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.buttons = data[0] & 0x07; // Only three buttons are supported
result.xDelta = data[1]; if ((data[0] & 0x10) && data[1] != 0) {
result.yDelta = data[2]; result.xDelta = -((int16_t)256 - (int16_t)(data[1]));
result.wheelCount = data[3]; } 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 #endif
result.valid = true; result.valid = true;

View File

@ -21,24 +21,35 @@
# define CIRQUE_PINNACLE_DIAMETER_MM 40 # define CIRQUE_PINNACLE_DIAMETER_MM 40
#endif #endif
#if CIRQUE_PINNACLE_POSITION_MODE
// Coordinate scaling values // Coordinate scaling values
#ifndef CIRQUE_PINNACLE_X_LOWER # ifndef CIRQUE_PINNACLE_X_LOWER
# define CIRQUE_PINNACLE_X_LOWER 127 // min "reachable" X value # define CIRQUE_PINNACLE_X_LOWER 127 // min "reachable" X value
#endif # endif
#ifndef CIRQUE_PINNACLE_X_UPPER # ifndef CIRQUE_PINNACLE_X_UPPER
# define CIRQUE_PINNACLE_X_UPPER 1919 // max "reachable" X value # define CIRQUE_PINNACLE_X_UPPER 1919 // max "reachable" X value
#endif # endif
#ifndef CIRQUE_PINNACLE_Y_LOWER # ifndef CIRQUE_PINNACLE_Y_LOWER
# define CIRQUE_PINNACLE_Y_LOWER 63 // min "reachable" Y value # define CIRQUE_PINNACLE_Y_LOWER 63 // min "reachable" Y value
#endif # endif
#ifndef CIRQUE_PINNACLE_Y_UPPER # ifndef CIRQUE_PINNACLE_Y_UPPER
# define CIRQUE_PINNACLE_Y_UPPER 1471 // max "reachable" Y value # define CIRQUE_PINNACLE_Y_UPPER 1471 // max "reachable" Y value
#endif # endif
#ifndef CIRQUE_PINNACLE_X_RANGE # ifndef CIRQUE_PINNACLE_X_RANGE
# define CIRQUE_PINNACLE_X_RANGE (CIRQUE_PINNACLE_X_UPPER - CIRQUE_PINNACLE_X_LOWER) # define CIRQUE_PINNACLE_X_RANGE (CIRQUE_PINNACLE_X_UPPER - CIRQUE_PINNACLE_X_LOWER)
#endif # endif
#ifndef CIRQUE_PINNACLE_Y_RANGE # ifndef CIRQUE_PINNACLE_Y_RANGE
# define CIRQUE_PINNACLE_Y_RANGE (CIRQUE_PINNACLE_Y_UPPER - CIRQUE_PINNACLE_Y_LOWER) # 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 #endif
#if !defined(POINTING_DEVICE_TASK_THROTTLE_MS) #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. # 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; uint8_t buttonFlags;
bool touchDown; bool touchDown;
#else #else
uint8_t xDelta; int16_t xDelta;
uint8_t yDelta; int16_t yDelta;
uint8_t wheelCount; int8_t wheelCount;
uint8_t buttons; uint8_t buttons;
#endif #endif
} pinnacle_data_t; } pinnacle_data_t;

View File

@ -24,11 +24,11 @@
# include "keyboard.h" # include "keyboard.h"
#endif #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}; static cirque_pinnacle_features_t features = {.tap_enable = true, .circular_scroll_enable = true};
#endif #endif
#ifdef CIRQUE_PINNACLE_TAP_ENABLE #if defined(CIRQUE_PINNACLE_TAP_ENABLE) && CIRQUE_PINNACLE_POSITION_MODE
static trackpad_tap_context_t tap; static trackpad_tap_context_t tap;
static report_mouse_t trackpad_tap(report_mouse_t mouse_report, pinnacle_data_t touchData) { 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 #endif
#ifdef CIRQUE_PINNACLE_CIRCULAR_SCROLL_ENABLE #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 */ /* 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, static circular_scroll_context_t scroll = {.config = {.outer_ring_pct = 33,
.trigger_px = 16, .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; bool suppress_mouse_update = false;
#ifdef CIRQUE_PINNACLE_CIRCULAR_SCROLL_ENABLE #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; circular_scroll_t scroll_report;
if (features.circular_scroll_enable) { if (features.circular_scroll_enable) {
scroll_report = circular_scroll(touchData); scroll_report = circular_scroll(touchData);
@ -222,7 +228,7 @@ bool cirque_pinnacle_gestures(report_mouse_t* mouse_report, pinnacle_data_t touc
} }
#endif #endif
#ifdef CIRQUE_PINNACLE_TAP_ENABLE #if defined(CIRQUE_PINNACLE_TAP_ENABLE) && CIRQUE_PINNACLE_POSITION_MODE
if (features.tap_enable) { if (features.tap_enable) {
*mouse_report = trackpad_tap(*mouse_report, touchData); *mouse_report = trackpad_tap(*mouse_report, touchData);
} }

View File

@ -24,7 +24,7 @@ typedef struct {
bool circular_scroll_enable; bool circular_scroll_enable;
} cirque_pinnacle_features_t; } cirque_pinnacle_features_t;
#ifdef CIRQUE_PINNACLE_TAP_ENABLE #if defined(CIRQUE_PINNACLE_TAP_ENABLE) && CIRQUE_PINNACLE_POSITION_MODE
# ifndef CIRQUE_PINNACLE_TAPPING_TERM # ifndef CIRQUE_PINNACLE_TAPPING_TERM
# include "action.h" # include "action.h"
# include "action_tapping.h" # include "action_tapping.h"
@ -44,6 +44,9 @@ void cirque_pinnacle_enable_tap(bool enable);
#endif #endif
#ifdef CIRQUE_PINNACLE_CIRCULAR_SCROLL_ENABLE #ifdef CIRQUE_PINNACLE_CIRCULAR_SCROLL_ENABLE
# if !CIRQUE_PINNACLE_POSITION_MODE
# error "Circular scroll is not supported in relative mode"
# endif
typedef enum { typedef enum {
SCROLL_UNINITIALIZED, SCROLL_UNINITIALIZED,
SCROLL_DETECTING, SCROLL_DETECTING,

View File

@ -384,7 +384,7 @@
#define EXTREG__TRACK_ADCCONFIG 0x0187 #define EXTREG__TRACK_ADCCONFIG 0x0187
// ADC-attenuation settings (held in BIT_7 and BIT_6) // ADC-attenuation settings (held in BIT_7 and BIT_6)
// 1X = most sensitive, 4X = least sensitive // 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_1X 0x00
# define EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_2X 0x40 # define EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_2X 0x40
# define EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_3X 0x80 # define EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_3X 0x80

View File

@ -116,38 +116,35 @@ void cirque_pinnacle_configure_cursor_glide(float trigger_px) {
} }
# endif # endif
# if CIRQUE_PINNACLE_POSITION_MODE
report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) { report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) {
pinnacle_data_t touchData = cirque_pinnacle_read_data(); pinnacle_data_t touchData = cirque_pinnacle_read_data();
mouse_xy_report_t report_x = 0, report_y = 0; mouse_xy_report_t report_x = 0, report_y = 0;
static uint16_t x = 0, 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}; cursor_glide_t glide_report = {0};
if (cursor_glide_enable) { if (cursor_glide_enable) {
glide_report = cursor_glide_check(&glide); glide_report = cursor_glide_check(&glide);
} }
# endif # endif
# if !CIRQUE_PINNACLE_POSITION_MODE
# error Cirque Pinnacle with relative mode not implemented yet.
# endif
if (!touchData.valid) { if (!touchData.valid) {
# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE # ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
if (cursor_glide_enable && glide_report.valid) { if (cursor_glide_enable && glide_report.valid) {
report_x = glide_report.dx; report_x = glide_report.dx;
report_y = glide_report.dy; report_y = glide_report.dy;
goto mouse_report_update; goto mouse_report_update;
} }
# endif # endif
return mouse_report; return mouse_report;
} }
# if CONSOLE_ENABLE # if CONSOLE_ENABLE
if (debug_mouse && touchData.touchDown) { if (debug_mouse && touchData.touchDown) {
dprintf("cirque_pinnacle touchData x=%4d y=%4d z=%2d\n", touchData.xValue, touchData.yValue, touchData.zValue); 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 // Scale coordinates to arbitrary X, Y resolution
cirque_pinnacle_scale_data(&touchData, cirque_pinnacle_get_scale(), cirque_pinnacle_get_scale()); 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; x = touchData.xValue;
y = touchData.yValue; y = touchData.yValue;
# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE # ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
if (cursor_glide_enable) { if (cursor_glide_enable) {
if (touchData.touchDown) { if (touchData.touchDown) {
cursor_glide_update(&glide, report_x, report_y, touchData.zValue); 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: mouse_report_update:
# endif # endif
mouse_report.x = report_x; mouse_report.x = report_x;
mouse_report.y = report_y; mouse_report.y = report_y;
@ -199,6 +196,32 @@ const pointing_device_driver_t pointing_device_driver = {
.get_cpi = cirque_pinnacle_get_cpi .get_cpi = cirque_pinnacle_get_cpi
}; };
// clang-format on // 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) #elif defined(POINTING_DEVICE_DRIVER_paw3204)
report_mouse_t paw3204_get_report(report_mouse_t mouse_report) { report_mouse_t paw3204_get_report(report_mouse_t mouse_report) {