diff options
Diffstat (limited to 'drivers/sensors/cirque_pinnacle.c')
-rw-r--r-- | drivers/sensors/cirque_pinnacle.c | 83 |
1 files changed, 70 insertions, 13 deletions
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 <stdlib.h> + #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; |