From 91a241dafa8a55a2fe2f07e75a798441d75fcbd6 Mon Sep 17 00:00:00 2001 From: CTCaer Date: Sat, 21 Mar 2020 22:03:51 +0200 Subject: [PATCH] touch: Add Tuning Calibration This, for now, can be done at Nyx boot by holding VOL- and VOL+. Make sure that you don't touch the touchscreen. --- nyx/nyx_gui/input/touch.c | 135 +++++++++++++++++++++++++++++--------- nyx/nyx_gui/input/touch.h | 5 +- 2 files changed, 107 insertions(+), 33 deletions(-) diff --git a/nyx/nyx_gui/input/touch.c b/nyx/nyx_gui/input/touch.c index c03a625..1b7a0c1 100644 --- a/nyx/nyx_gui/input/touch.c +++ b/nyx/nyx_gui/input/touch.c @@ -26,6 +26,7 @@ #include "../power/max77620.h" #include "../soc/gpio.h" #include "../soc/t210.h" +#include "../utils/btn.h" #include "../utils/util.h" #include "touch.h" @@ -52,15 +53,18 @@ static int touch_read_reg(u8 *cmd, u32 csize, u8 *buf, u32 size) return 0; } -static void touch_wait_controller_ready() +static int touch_wait_event(u8 event, u8 status, u32 timeout) { - u32 timeout = get_tmr_ms() + 100; + u32 timer = get_tmr_ms() + timeout; while (true) { - u8 tmp = 0; - i2c_recv_buf_small(&tmp, 1, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_ONE_EVENT); - if (tmp == STMFTS_EV_CONTROLLER_READY || get_tmr_ms() > timeout) - break; + u8 tmp[8] = {0}; + i2c_recv_buf_small(tmp, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_ONE_EVENT); + if (tmp[1] == event && tmp[2] == status) + return 0; + + if (get_tmr_ms() > timer) + return 1; } } @@ -212,8 +216,95 @@ int touch_get_fw_info(touch_fw_info_t *fw) return res; } +int touch_sys_reset() +{ + u8 cmd[3] = { 0, 0x28, 0x80 }; // System reset cmd. + for (u8 retries = 0; retries < 3; retries++) + { + if (touch_command(STMFTS_WRITE_REG, cmd, 3)) + { + msleep(10); + continue; + } + msleep(10); + if (touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20)) + continue; + else + return 0; + } + + return 1; +} + +int touch_execute_autotune() +{ + // Reset touchscreen module. + if (touch_sys_reset()) + return 0; + + // Trim low power oscillator. + touch_command(STMFTS_LP_TIMER_CALIB, NULL, 0); + msleep(200); + + // Apply Mutual Sense Compensation tuning. + if (touch_command(STMFTS_MS_CX_TUNING, NULL, 0)) + return 0; + if (touch_wait_event(STMFTS_EV_STATUS, 1, 2000)) + return 0; + + // Apply Self Sense Compensation tuning. + if (touch_command(STMFTS_SS_CX_TUNING, NULL, 0)) + return 0; + if (touch_wait_event(STMFTS_EV_STATUS, 2, 2000)) + return 0; + + // Save Compensation data to EEPROM. + if (touch_command(STMFTS_SAVE_CX_TUNING, NULL, 0)) + return 0; + if (touch_wait_event(STMFTS_EV_STATUS, 4, 2000)) + return 0; + + // Enable auto tuning calibration and multi-touch sensing. + u8 cmd = 1; + if (touch_command(STMFTS_AUTO_CALIBRATION, &cmd, 1)) + return 0; + + if (touch_command(STMFTS_MS_MT_SENSE_ON, NULL, 0)) + return 0; + + if (touch_command(STMFTS_CLEAR_EVENT_STACK, NULL, 0)) + return 0; + + return 1; +} + +static int touch_init() +{ + // Initialize touchscreen module. + if (touch_sys_reset()) + return 0; + + // Enable auto tuning calibration and multi-touch sensing. + u8 cmd = 1; + if (touch_command(STMFTS_AUTO_CALIBRATION, &cmd, 1)) + return 0; + + if (touch_command(STMFTS_MS_MT_SENSE_ON, NULL, 0)) + return 0; + + if (touch_command(STMFTS_CLEAR_EVENT_STACK, NULL, 0)) + return 0; + + return 1; +} + int touch_power_on() { + // Enables LDO6 for touchscreen VDD/AVDD supply + max77620_regulator_set_volt_and_flags(REGULATOR_LDO6, 2900000, MAX77620_POWER_MODE_NORMAL); + i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2, + MAX77620_LDO_CFG2_ADE_ENABLE | (3 << 3) | (MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT)); + // Configure touchscreen GPIO. PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1; gpio_config(GPIO_PORT_J, GPIO_PIN_7, GPIO_MODE_GPIO); @@ -235,32 +326,14 @@ int touch_power_on() clock_enable_i2c(I2C_3); i2c_init(I2C_3); - // Enables LDO6 for touchscreen VDD/AVDD supply - max77620_regulator_set_volt_and_flags(REGULATOR_LDO6, 2900000, MAX77620_POWER_MODE_NORMAL); - i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2, - MAX77620_LDO_CFG2_ADE_ENABLE | (3 << 3) | (MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT)); + // Wait for the touchscreen module to get ready. + touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20); - touch_wait_controller_ready(); - - // Initialize touchscreen module. - u8 cmd[3] = { 0, 0x28, 0x80 }; // System reset cmd. - if (touch_command(STMFTS_WRITE_REG, cmd, 3)) - return 0; - msleep(10); - - touch_wait_controller_ready(); - - cmd[0] = 1; - if (touch_command(STMFTS_AUTO_CALIBRATION, cmd, 1)) - return 0; - - if (touch_command(STMFTS_MS_MT_SENSE_ON, NULL, 0)) - return 0; - - if (touch_command(STMFTS_CLEAR_EVENT_STACK, NULL, 0)) - return 0; - - return 1; + u32 btn = btn_wait_timeout(0, BTN_VOL_DOWN | BTN_VOL_UP); + if ((btn & BTN_VOL_DOWN) && (btn & BTN_VOL_UP)) + return touch_execute_autotune(); + else + return touch_init(); } void touch_power_off() diff --git a/nyx/nyx_gui/input/touch.h b/nyx/nyx_gui/input/touch.h index 30111ff..e85c658 100644 --- a/nyx/nyx_gui/input/touch.h +++ b/nyx/nyx_gui/input/touch.h @@ -119,11 +119,12 @@ typedef struct _touch_fw_info_t { u16 fw_rev; } touch_fw_info_t; -int touch_power_on(); -void touch_power_off(); void touch_poll(touch_event *event); touch_event touch_poll_wait(); int touch_get_fw_info(touch_fw_info_t *fw); touch_info touch_get_info(); +int touch_execute_autotune(); +int touch_power_on(); +void touch_power_off(); #endif /* __TOUCH_H_ */ \ No newline at end of file