bdk: touch: refactor/improve

- Remove useless poll wait
- Use more defines
- Deduplicate code
- Add more checks
- Add switch sense mode
This commit is contained in:
CTCaer
2026-02-15 02:32:38 +02:00
parent 38e73d6492
commit 0a55598ab6
2 changed files with 55 additions and 66 deletions

View File

@@ -29,10 +29,6 @@
#include <utils/btn.h> #include <utils/btn.h>
#include "touch.h" #include "touch.h"
#include <gfx_utils.h>
#define DPRINTF(...) gfx_printf(__VA_ARGS__)
static touch_panel_info_t _panels[] = static touch_panel_info_t _panels[] =
{ {
{ 0, 1, 1, 1, "NISSHA NFT-K12D" },// 0. { 0, 1, 1, 1, "NISSHA NFT-K12D" },// 0.
@@ -67,15 +63,17 @@ static int touch_wait_event(u8 event, u8 status, u32 timeout, u8 *buf)
u32 timer = get_tmr_ms() + timeout; u32 timer = get_tmr_ms() + timeout;
while (true) while (true)
{ {
u8 tmp[8] = {0}; u8 tmp[STMFTS_EVENT_SIZE] = {0};
i2c_recv_buf_small(tmp, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_ONE_EVENT); int res = i2c_recv_buf_small(tmp, STMFTS_EVENT_SIZE, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_ONE_EVENT);
if (tmp[1] == event && tmp[2] == status) if (res && tmp[1] == event && tmp[2] == status)
{ {
if (buf) if (buf)
memcpy(buf, &tmp[3], 5); memcpy(buf, &tmp[3], 5);
return 0; return 0;
} }
usleep(1000);
if (get_tmr_ms() > timer) if (get_tmr_ms() > timer)
return 1; return 1;
} }
@@ -159,59 +157,42 @@ static void _touch_parse_event(touch_event *event)
event->type = STMFTS_EV_MULTI_TOUCH_MOTION; event->type = STMFTS_EV_MULTI_TOUCH_MOTION;
else else
event->type = STMFTS_EV_MULTI_TOUCH_LEAVE; event->type = STMFTS_EV_MULTI_TOUCH_LEAVE;
break;
} }
// gfx_con_setpos(0, 300);
// DPRINTF("x = %d \ny = %d \nz = %d \n", event->x, event->y, event->z);
// DPRINTF("0 = %02X\n1 = %02X\n2 = %02X\n3 = %02X\n", event->raw[0], event->raw[1], event->raw[2], event->raw[3]);
// DPRINTF("4 = %02X\n5 = %02X\n6 = %02X\n7 = %02X\n", event->raw[4], event->raw[5], event->raw[6], event->raw[7]);
} }
void touch_poll(touch_event *event) void touch_poll(touch_event *event)
{ {
i2c_recv_buf_small(event->raw, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_LATEST_EVENT); i2c_recv_buf_small(event->raw, STMFTS_EVENT_SIZE, I2C_3, STMFTS_I2C_ADDR, STMFTS_LATEST_EVENT);
_touch_parse_event(event); _touch_parse_event(event);
} }
touch_event touch_poll_wait()
{
touch_event event;
do
{
touch_poll(&event);
} while (event.type != STMFTS_EV_MULTI_TOUCH_LEAVE);
return event;
}
touch_info touch_get_info() touch_info touch_get_info()
{ {
touch_info info; touch_info info = {0};
u8 buf[8]; u8 buf[STMFTS_EVENT_SIZE] = {0};
memset(&buf, 0, 8);
i2c_recv_buf_small(buf, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_INFO);
info.chip_id = buf[0] << 8 | buf[1]; if (!i2c_recv_buf_small(buf, STMFTS_EVENT_SIZE, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_INFO))
info.fw_ver = buf[2] << 8 | buf[3]; return info;
info.config_id = buf[4];
info.config_ver = buf[5];
//DPRINTF("ID: %04X, FW Ver: %d.%02d\nCfg ID: %02X, Cfg Ver: %d\n", info.chip_id = buf[0] << 8 | buf[1]; // 0x3670.
// info.chip_id, info.fw_ver >> 8, info.fw_ver & 0xFF, info.config_id, info.config_ver); info.fw_ver = buf[2] << 8 | buf[3];
info.config_id = buf[4]; // FTB.
info.config_ver = buf[5]; // FTB.
return info; return info;
} }
touch_panel_info_t *touch_get_panel_vendor() touch_panel_info_t *touch_get_panel_vendor()
{ {
u8 buf[5] = {0};
u8 cmd = STMFTS_VENDOR_GPIO_STATE; u8 cmd = STMFTS_VENDOR_GPIO_STATE;
static touch_panel_info_t panel_info = { -2, 0, 0, 0, ""}; static touch_panel_info_t panel_info = { -2, 0, 0, 0, ""};
if (touch_command(STMFTS_VENDOR, &cmd, 1)) if (touch_command(STMFTS_VENDOR, &cmd, 1))
return NULL; return NULL;
u8 buf[5] = {0};
if (touch_wait_event(STMFTS_EV_VENDOR, STMFTS_VENDOR_GPIO_STATE, 2000, buf)) if (touch_wait_event(STMFTS_EV_VENDOR, STMFTS_VENDOR_GPIO_STATE, 2000, buf))
return NULL; return NULL;
@@ -232,26 +213,26 @@ touch_panel_info_t *touch_get_panel_vendor()
int touch_get_fw_info(touch_fw_info_t *fw) int touch_get_fw_info(touch_fw_info_t *fw)
{ {
u8 buf[8] = {0}; u8 buf[STMFTS_EVENT_SIZE] = {0};
memset(fw, 0, sizeof(touch_fw_info_t)); memset(fw, 0, sizeof(touch_fw_info_t));
// Get fw address info. // Get fw address info.
u8 cmd[3] = { STMFTS_RW_FRAMEBUFFER_REG, 0, 0x60 }; u8 cmd[3] = { STMFTS_RW_FRAMEBUFFER_REG, 0, 0x60 };
int res = touch_read_reg(cmd, 3, buf, 3); int res = touch_read_reg(cmd, sizeof(cmd), buf, 3);
if (!res) if (!res)
{ {
// Get fw info. // Get fw info.
cmd[1] = buf[2]; cmd[2] = buf[1]; cmd[1] = buf[2]; cmd[2] = buf[1];
res = touch_read_reg(cmd, 3, buf, 8); res = touch_read_reg(cmd, sizeof(cmd), buf, 8);
if (!res) if (!res)
{ {
fw->fw_id = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4]; fw->fw_id = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4];
fw->ftb_ver = (buf[6] << 8) | buf[5]; fw->ftb_ver = (buf[6] << 8) | buf[5];
} }
cmd[2]++; cmd[2]++;
res = touch_read_reg(cmd, 3, buf, 8); res = touch_read_reg(cmd, sizeof(cmd), buf, 8);
if (!res) if (!res)
fw->fw_rev = (buf[7] << 8) | buf[6]; fw->fw_rev = (buf[7] << 8) | buf[6];
} }
@@ -281,36 +262,21 @@ int touch_sys_reset()
int touch_panel_ito_test(u8 *err) int touch_panel_ito_test(u8 *err)
{ {
int res = 0;
// Reset touchscreen module. // Reset touchscreen module.
if (touch_sys_reset()) if (touch_sys_reset())
return res; return 1;
// Do ITO Production test. // Do ITO Production test.
u8 cmd[2] = { 1, 0 }; u8 cmd[2] = { 1, 0 };
if (touch_command(STMFTS_ITO_CHECK, cmd, 2)) if (touch_command(STMFTS_ITO_CHECK, cmd, 2))
return res; return 1;
u32 timer = get_tmr_ms() + 2000; u8 buf[5] = {0};
while (true) int res = touch_wait_event(STMFTS_EV_ERROR, 5, 2000, buf);
if (!res && err)
{ {
u8 tmp[8] = {0}; err[0] = buf[0];
i2c_recv_buf_small(tmp, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_ONE_EVENT); err[1] = buf[1];
if (tmp[1] == 0xF && tmp[2] == 0x5)
{
if (err)
{
err[0] = tmp[3];
err[1] = tmp[4];
}
res = 1;
break;
}
if (get_tmr_ms() > timer)
break;
} }
// Reset touchscreen module. // Reset touchscreen module.
@@ -334,7 +300,7 @@ int touch_get_fb_info(u8 *buf)
cmd[1] = (i >> 8) & 0xFF; cmd[1] = (i >> 8) & 0xFF;
cmd[2] = i & 0xFF; cmd[2] = i & 0xFF;
memset(tmp, 0xCC, 5); memset(tmp, 0xCC, 5);
res = touch_read_reg(cmd, 3, tmp, 5); res = touch_read_reg(cmd, sizeof(cmd), tmp, 5);
memcpy(&buf[i], tmp + 1, 4); memcpy(&buf[i], tmp + 1, 4);
} }
} }
@@ -342,6 +308,29 @@ int touch_get_fb_info(u8 *buf)
return res; return res;
} }
int touch_switch_sense_mode(u8 mode, bool gis_6_2)
{
// Set detection config.
u8 cmd[3] = { 1, 0x64, 0 };
switch (mode)
{
case STMFTS_STYLUS_MODE:
cmd[2] = !gis_6_2 ? 0xC8 : 0xAD;
break;
case STMFTS_FINGER_MODE:
cmd[2] = !gis_6_2 ? 0x8C : 0x79;
break;
}
touch_command(STMFTS_DETECTION_CONFIG, cmd, 3);
// Sense mode.
cmd[0] = mode;
return touch_command(STMFTS_SWITCH_SENSE_MODE, cmd, 1);
}
int touch_sense_enable() int touch_sense_enable()
{ {
// Switch sense mode and enable multi-touch sensing. // Switch sense mode and enable multi-touch sensing.
@@ -428,7 +417,7 @@ int touch_power_on()
if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN)) if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
{ {
u8 err[2]; u8 err[2];
if (touch_panel_ito_test(err)) if (!touch_panel_ito_test(err))
if (!err[0] && !err[1]) if (!err[0] && !err[1])
return touch_execute_autotune(); return touch_execute_autotune();
} }

View File

@@ -2,7 +2,7 @@
* Touch driver for Nintendo Switch's STM FingerTip S (4CD60D) touch controller * Touch driver for Nintendo Switch's STM FingerTip S (4CD60D) touch controller
* *
* Copyright (c) 2018 langerhans * Copyright (c) 2018 langerhans
* Copyright (c) 2018-2020 CTCaer * Copyright (c) 2018-2026 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -163,12 +163,12 @@ typedef struct _touch_fw_info_t {
} touch_fw_info_t; } touch_fw_info_t;
void touch_poll(touch_event *event); void touch_poll(touch_event *event);
touch_event touch_poll_wait();
touch_panel_info_t *touch_get_panel_vendor(); touch_panel_info_t *touch_get_panel_vendor();
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_panel_ito_test(u8 *err); int touch_panel_ito_test(u8 *err);
int touch_execute_autotune(); int touch_execute_autotune();
int touch_switch_sense_mode(u8 mode, bool gis_6_2);
int touch_sense_enable(); int touch_sense_enable();
int touch_power_on(); int touch_power_on();
void touch_power_off(); void touch_power_off();