Browse Source

Azoteq - improve I2C behaviour while polling. (#24611)

Co-authored-by: Stefan Kerkmann <karlk90@pm.me>
Dasky 1 year ago
parent
commit
62e98327d2
2 changed files with 26 additions and 32 deletions
  1. 24 31
      drivers/sensors/azoteq_iqs5xx.c
  2. 2 1
      drivers/sensors/azoteq_iqs5xx.h

+ 24 - 31
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
@@ -112,12 +117,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);
@@ -324,14 +323,19 @@ 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);
@@ -348,21 +352,19 @@ 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;
+    report_mouse_t temp_report = {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);
@@ -403,20 +405,11 @@ 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;

+ 2 - 1
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
 
 const pointing_device_driver_t azoteq_iqs5xx_pointing_device_driver;