From b81811a3a2017515c64b6156ca0ff5051e0ca765 Mon Sep 17 00:00:00 2001 From: Ira Cooper Date: Thu, 2 Jan 2025 15:47:59 -0500 Subject: [PATCH] azoteq: Fix the odd azoteq behavior. Not sure why old units did not show this random pressing of mouse 2 bug. This port of: https://github.com/qmk/qmk_firmware/pull/24611 Fixes it. Added axis code to make scroll more sane. --- drivers/sensors/azoteq_iqs5xx.c | 11 ++- drivers/sensors/azoteq_iqs5xx.h | 3 +- keyboards/svalboard/azoteq/azoteq.c | 19 +++++ keyboards/svalboard/azoteq/config.h | 2 + .../pointing_device/pointing_device_drivers.c | 69 ++++++++++++------- 5 files changed, 72 insertions(+), 32 deletions(-) create mode 100644 keyboards/svalboard/azoteq/azoteq.c diff --git a/drivers/sensors/azoteq_iqs5xx.c b/drivers/sensors/azoteq_iqs5xx.c index 367873eb062..5d9b863a896 100644 --- a/drivers/sensors/azoteq_iqs5xx.c +++ b/drivers/sensors/azoteq_iqs5xx.c @@ -17,6 +17,7 @@ #define AZOTEQ_IQS5XX_REG_PREVIOUS_CYCLE_TIME 0x000C #define AZOTEQ_IQS5XX_REG_SYSTEM_CONTROL_1 0x0432 #define AZOTEQ_IQS5XX_REG_REPORT_RATE_ACTIVE 0x057A +#define AZOTEQ_IQS5XX_REG_IDLE_MODE_TIMEOUT 0x0586 #define AZOTEQ_IQS5XX_REG_SYSTEM_CONFIG_0 0x058E #define AZOTEQ_IQS5XX_REG_SYSTEM_CONFIG_1 0x058F #define AZOTEQ_IQS5XX_REG_X_RESOLUTION 0x066E @@ -77,6 +78,10 @@ #ifndef AZOTEQ_IQS5XX_ZOOM_CONSECUTIVE_DISTANCE # define AZOTEQ_IQS5XX_ZOOM_CONSECUTIVE_DISTANCE 0x19 #endif +#ifndef AZOTEQ_IQS5XX_EVENT_MODE +// Event mode can't be used until the pointing code has changed (stuck buttons) +# define AZOTEQ_IQS5XX_EVENT_MODE false +#endif #if defined(AZOTEQ_IQS5XX_TPS43) # define AZOTEQ_IQS5XX_WIDTH_MM 43 @@ -105,12 +110,6 @@ static struct { uint16_t resolution_y; } azoteq_iqs5xx_device_resolution_t; -i2c_status_t azoteq_iqs5xx_wake(void) { - uint8_t data = 0; - i2c_status_t status = i2c_read_register16(AZOTEQ_IQS5XX_ADDRESS, AZOTEQ_IQS5XX_REG_PREVIOUS_CYCLE_TIME, (uint8_t *)&data, sizeof(data), 1); - wait_us(150); - return status; -} i2c_status_t azoteq_iqs5xx_end_session(void) { const uint8_t END_BYTE = 1; // any data return i2c_write_register16(AZOTEQ_IQS5XX_ADDRESS, AZOTEQ_IQS5XX_REG_END_COMMS, &END_BYTE, 1, AZOTEQ_IQS5XX_TIMEOUT_MS); diff --git a/drivers/sensors/azoteq_iqs5xx.h b/drivers/sensors/azoteq_iqs5xx.h index 704ec2bab3b..359ea11a39f 100644 --- a/drivers/sensors/azoteq_iqs5xx.h +++ b/drivers/sensors/azoteq_iqs5xx.h @@ -173,7 +173,8 @@ typedef struct { # define AZOTEQ_IQS5XX_REPORT_RATE 10 #endif #if !defined(POINTING_DEVICE_TASK_THROTTLE_MS) && !defined(POINTING_DEVICE_MOTION_PIN) -# define POINTING_DEVICE_TASK_THROTTLE_MS AZOTEQ_IQS5XX_REPORT_RATE +// Polling the Azoteq isn't recommended, ensuring we only poll after the report is ready stops any unexpected NACKs +# define POINTING_DEVICE_TASK_THROTTLE_MS AZOTEQ_IQS5XX_REPORT_RATE + 1 #endif void azoteq_iqs5xx_init(void); diff --git a/keyboards/svalboard/azoteq/azoteq.c b/keyboards/svalboard/azoteq/azoteq.c new file mode 100644 index 00000000000..83814214af1 --- /dev/null +++ b/keyboards/svalboard/azoteq/azoteq.c @@ -0,0 +1,19 @@ +#include "quantum.h" +#include "pointing_device.h" +#include "pointing_device_internal.h" +#include "axis_scale.h" + +extern const pointing_device_driver_t real_device_driver; + +static axis_scale_t h = { 1, 7, 0 }; +static axis_scale_t v = { 1, 7, 0 }; + +report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) { + + mouse_report = real_device_driver.get_report(mouse_report); + + mouse_report.h = add_to_axis(&h, mouse_report.h); + mouse_report.v = add_to_axis(&v, mouse_report.v); + + return mouse_report; +} diff --git a/keyboards/svalboard/azoteq/config.h b/keyboards/svalboard/azoteq/config.h index b36247d602d..18cdf82aa97 100644 --- a/keyboards/svalboard/azoteq/config.h +++ b/keyboards/svalboard/azoteq/config.h @@ -8,6 +8,8 @@ #define AZOTEQ_IQS5XX_TIMEOUT_MS 10 #define AZOTEQ_IQS5XX_PRESS_AND_HOLD_ENABLE true +//#define POINTING_DEVICE_MOTION_PIN GP18 + #define SPLIT_POINTING_ENABLE #define POINTING_DEVICE_COMBINED #define POINTING_DEVICE_AUTO_MOUSE_MH_ENABLE diff --git a/quantum/pointing_device/pointing_device_drivers.c b/quantum/pointing_device/pointing_device_drivers.c index 1748f03a0c1..4b08e9b6e02 100644 --- a/quantum/pointing_device/pointing_device_drivers.c +++ b/quantum/pointing_device/pointing_device_drivers.c @@ -117,18 +117,44 @@ const pointing_device_driver_t real_device_driver = { #elif defined(POINTING_DEVICE_DRIVER_azoteq_iqs5xx) +#ifndef AZOTEQ_IQS5XX_ADDRESS +# define AZOTEQ_IQS5XX_ADDRESS (0x74 << 1) +#endif +#ifndef AZOTEQ_IQS5XX_EVENT_MODE +// Event mode can't be used until the pointing code has changed (stuck buttons) +# define AZOTEQ_IQS5XX_EVENT_MODE false +#endif + +#define AZOTEQ_IQS5XX_REG_PRODUCT_NUMBER 0x0000 +#define AZOTEQ_IQS5XX_REG_PREVIOUS_CYCLE_TIME 0x000C +#define AZOTEQ_IQS5XX_REG_SYSTEM_CONTROL_1 0x0432 +#define AZOTEQ_IQS5XX_REG_REPORT_RATE_ACTIVE 0x057A +#define AZOTEQ_IQS5XX_REG_IDLE_MODE_TIMEOUT 0x0586 +#define AZOTEQ_IQS5XX_REG_SYSTEM_CONFIG_0 0x058E +#define AZOTEQ_IQS5XX_REG_SYSTEM_CONFIG_1 0x058F +#define AZOTEQ_IQS5XX_REG_X_RESOLUTION 0x066E +#define AZOTEQ_IQS5XX_REG_XY_CONFIG_0 0x0669 +#define AZOTEQ_IQS5XX_REG_Y_RESOLUTION 0x0670 +#define AZOTEQ_IQS5XX_REG_SINGLE_FINGER_GESTURES 0x06B7 +#define AZOTEQ_IQS5XX_REG_END_COMMS 0xEEEE + static i2c_status_t azoteq_iqs5xx_init_status = 1; void azoteq_iqs5xx_init(void) { i2c_init(); - azoteq_iqs5xx_wake(); + i2c_ping_address(AZOTEQ_IQS5XX_ADDRESS, 1); // wake azoteq_iqs5xx_reset_suspend(true, false, true); wait_ms(100); - azoteq_iqs5xx_wake(); + i2c_ping_address(AZOTEQ_IQS5XX_ADDRESS, 1); // wake if (azoteq_iqs5xx_get_product() != AZOTEQ_IQS5XX_UNKNOWN) { azoteq_iqs5xx_setup_resolution(); azoteq_iqs5xx_init_status = azoteq_iqs5xx_set_report_rate(AZOTEQ_IQS5XX_REPORT_RATE, AZOTEQ_IQS5XX_ACTIVE, false); - azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_event_mode(false, false); + azoteq_iqs5xx_init_status = azoteq_iqs5xx_set_report_rate(AZOTEQ_IQS5XX_REPORT_RATE, AZOTEQ_IQS5XX_IDLE, false); + azoteq_iqs5xx_init_status = azoteq_iqs5xx_set_report_rate(AZOTEQ_IQS5XX_REPORT_RATE, AZOTEQ_IQS5XX_IDLE_TOUCH, false); + + uint8_t no_timeout = 255; + azoteq_iqs5xx_init_status |= i2c_write_register16(AZOTEQ_IQS5XX_ADDRESS, AZOTEQ_IQS5XX_REG_IDLE_MODE_TIMEOUT, &no_timeout, 1, AZOTEQ_IQS5XX_TIMEOUT_MS); // Don't enter LP1, LP2 states + azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_event_mode(AZOTEQ_IQS5XX_EVENT_MODE, false); azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_reati(true, false); # if defined(AZOTEQ_IQS5XX_ROTATION_90) azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_xy_config(false, true, true, true, false); @@ -146,20 +172,18 @@ void azoteq_iqs5xx_init(void) { report_mouse_t azoteq_iqs5xx_get_report(report_mouse_t mouse_report) { report_mouse_t temp_report = {0}; - static uint8_t previous_button_state = 0; - static uint8_t read_error_count = 0; if (azoteq_iqs5xx_init_status == I2C_STATUS_SUCCESS) { - azoteq_iqs5xx_base_data_t base_data = {0}; -# if !defined(POINTING_DEVICE_MOTION_PIN) - azoteq_iqs5xx_wake(); -# endif - i2c_status_t status = azoteq_iqs5xx_get_base_data(&base_data); - bool ignore_movement = false; + azoteq_iqs5xx_base_data_t base_data = {0}; + i2c_status_t status = azoteq_iqs5xx_get_base_data(&base_data); + bool ignore_movement = false; if (status == I2C_STATUS_SUCCESS) { - // pd_dprintf("IQS5XX - previous cycle time: %d \n", base_data.previous_cycle_time); - read_error_count = 0; +#ifdef POINTING_DEVICE_DEBUG + if (base_data.previous_cycle_time > AZOTEQ_IQS5XX_REPORT_RATE) { + pd_dprintf("IQS5XX - previous cycle time missed, took: %dms\n", base_data.previous_cycle_time); + } +#endif if (base_data.gesture_events_0.single_tap || base_data.gesture_events_0.press_and_hold) { pd_dprintf("IQS5XX - Single tap/hold.\n"); temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON1); @@ -200,24 +224,15 @@ report_mouse_t azoteq_iqs5xx_get_report(report_mouse_t mouse_report) { temp_report.y = CONSTRAIN_HID_XY(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.y.h, base_data.y.l)); } - previous_button_state = temp_report.buttons; - } else { - if (read_error_count > 10) { - read_error_count = 0; - previous_button_state = 0; - } else { - read_error_count++; - } - temp_report.buttons = previous_button_state; - pd_dprintf("IQS5XX - get report failed: %d \n", status); + pd_dprintf("IQS5XX - get report failed, i2c status: %d \n", status); } } else { - pd_dprintf("IQS5XX - Init failed: %d \n", azoteq_iqs5xx_init_status); + pd_dprintf("IQS5XX - Init failed, i2c status: %d \n", azoteq_iqs5xx_init_status); } return temp_report; -} +}; // clang-format off const pointing_device_driver_t real_device_driver = { @@ -521,6 +536,10 @@ const pointing_device_driver_t real_device_driver = { }; // clang-format on +#endif +#ifndef AZOTEQ_IQS5XX_EVENT_MODE +// Event mode can't be used until the pointing code has changed (stuck buttons) +# define AZOTEQ_IQS5XX_EVENT_MODE false #endif __attribute__((weak)) void pointing_device_driver_init(void) {