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.
This commit is contained in:
CTCaer 2020-03-21 22:03:51 +02:00
parent a8db070755
commit 91a241dafa
2 changed files with 107 additions and 33 deletions

View file

@ -26,6 +26,7 @@
#include "../power/max77620.h" #include "../power/max77620.h"
#include "../soc/gpio.h" #include "../soc/gpio.h"
#include "../soc/t210.h" #include "../soc/t210.h"
#include "../utils/btn.h"
#include "../utils/util.h" #include "../utils/util.h"
#include "touch.h" #include "touch.h"
@ -52,15 +53,18 @@ static int touch_read_reg(u8 *cmd, u32 csize, u8 *buf, u32 size)
return 0; 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) while (true)
{ {
u8 tmp = 0; u8 tmp[8] = {0};
i2c_recv_buf_small(&tmp, 1, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_ONE_EVENT); i2c_recv_buf_small(tmp, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_ONE_EVENT);
if (tmp == STMFTS_EV_CONTROLLER_READY || get_tmr_ms() > timeout) if (tmp[1] == event && tmp[2] == status)
break; 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; 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() 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. // Configure touchscreen GPIO.
PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1; PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1;
gpio_config(GPIO_PORT_J, GPIO_PIN_7, GPIO_MODE_GPIO); gpio_config(GPIO_PORT_J, GPIO_PIN_7, GPIO_MODE_GPIO);
@ -235,32 +326,14 @@ int touch_power_on()
clock_enable_i2c(I2C_3); clock_enable_i2c(I2C_3);
i2c_init(I2C_3); i2c_init(I2C_3);
// Enables LDO6 for touchscreen VDD/AVDD supply // Wait for the touchscreen module to get ready.
max77620_regulator_set_volt_and_flags(REGULATOR_LDO6, 2900000, MAX77620_POWER_MODE_NORMAL); touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20);
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));
touch_wait_controller_ready(); u32 btn = btn_wait_timeout(0, BTN_VOL_DOWN | BTN_VOL_UP);
if ((btn & BTN_VOL_DOWN) && (btn & BTN_VOL_UP))
// Initialize touchscreen module. return touch_execute_autotune();
u8 cmd[3] = { 0, 0x28, 0x80 }; // System reset cmd. else
if (touch_command(STMFTS_WRITE_REG, cmd, 3)) return touch_init();
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;
} }
void touch_power_off() void touch_power_off()

View file

@ -119,11 +119,12 @@ typedef struct _touch_fw_info_t {
u16 fw_rev; u16 fw_rev;
} touch_fw_info_t; } touch_fw_info_t;
int touch_power_on();
void touch_power_off();
void touch_poll(touch_event *event); void touch_poll(touch_event *event);
touch_event touch_poll_wait(); touch_event touch_poll_wait();
int touch_get_fw_info(touch_fw_info_t *fw); int touch_get_fw_info(touch_fw_info_t *fw);
touch_info touch_get_info(); touch_info touch_get_info();
int touch_execute_autotune();
int touch_power_on();
void touch_power_off();
#endif /* __TOUCH_H_ */ #endif /* __TOUCH_H_ */