Files
lishanpi/bsp/device/touch/touch.cpp
T
hm cbad06d616 refactor(touch): 集成硬件 I2C 驱动并添加 EXTI 中断支持
- 将 touch 底层从软件 I2C 位冲切换为硬件 I2C0 (PB6/PB7)
- 修复 i2c_driver I2C0 引脚映射 (PB8/PB9 -> PB6/PB7)
- 重写 master_write_read() 实现正确的重复起始条件
- 添加 i2c_driver.h C API 声明供 C 代码调用
- 添加 GT1151 EXTI 中断 (PD11, EXTI11 下降沿触发)
- 删除 touch.h 中废弃的软件 I2C 函数声明
- test_touch() 改为中断驱动,无触摸时 I2C 总线空闲
2026-04-26 20:36:54 +08:00

266 lines
7.9 KiB
C++

#include "touch.h"
#include "i2c_driver.h"
#include "stdio.h"
#include "string.h"
_m_tp_dev tp_dev;
volatile uint8_t g_touch_irq_flag = 0;
#define TOUCH_I2C_PORT 0
#define TOUCH_DEV_ADDR 0x28
uint8_t GT1151_WR_Reg(uint16_t reg, uint8_t *buf, uint8_t len)
{
uint8_t tmp[2 + 256];
tmp[0] = (uint8_t)(reg >> 8);
tmp[1] = (uint8_t)(reg & 0xFF);
for (uint8_t i = 0; i < len; i++)
{
tmp[2 + i] = buf[i];
}
int ret = i2c_master_write(TOUCH_I2C_PORT, TOUCH_DEV_ADDR, tmp, 2 + len);
return (ret == 0) ? 0 : 1;
}
void GT1151_RD_Reg(uint16_t reg, uint8_t *buf, uint8_t len)
{
uint8_t reg_bytes[2];
reg_bytes[0] = (uint8_t)(reg >> 8);
reg_bytes[1] = (uint8_t)(reg & 0xFF);
i2c_master_write_read(TOUCH_I2C_PORT, TOUCH_DEV_ADDR, reg_bytes, 2, buf, len);
}
const uint8_t GT1151_CFG_TBL[] =
{
0x63, 0xE0, 0x01, 0x20, 0x03, 0x05, 0x3D, 0x04, 0x00, 0x08,
0x09, 0x0F, 0x55, 0x37, 0x33, 0x11, 0x00, 0x03, 0x08, 0x56,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00,
0x3C, 0x08, 0x0A, 0x28, 0x1E, 0x50, 0x00, 0x00, 0x82, 0xB4,
0xD2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x85, 0x25, 0x10, 0x41, 0x43, 0x31,
0x0D, 0x00, 0xAD, 0x22, 0x24, 0x7D, 0x1D, 0x1D, 0x32, 0xDF,
0x4F, 0x44, 0x0F, 0x80, 0x2C, 0x50, 0x50, 0x00, 0x00, 0x00,
0x00, 0xD3, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x28, 0x1E, 0xFF,
0xF0, 0x37, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x50, 0xB4, 0xC0, 0x94, 0x53, 0x2D,
0x0A, 0x02, 0xBE, 0x60, 0xA2, 0x71, 0x8F, 0x82, 0x80, 0x92,
0x74, 0xA3, 0x6B, 0x01, 0x0F, 0x14, 0x03, 0x1E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0E, 0x0F, 0x10, 0x12,
0x13, 0x14, 0x15, 0x1F, 0x1D, 0x1B, 0x1A, 0x19, 0x18, 0x17,
0x16, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x08, 0x0C,
0x12, 0x13, 0x14, 0x15, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0xC4, 0x09, 0x23, 0x23, 0x50, 0x5D, 0x54, 0x4B, 0x3C, 0x0F,
0x32, 0xFF, 0xE4, 0x04, 0x40, 0x00, 0x8A, 0x05, 0x40, 0x00,
0xAA, 0x00, 0x22, 0x22, 0x00, 0x00, 0x73, 0x22, 0x01};
uint16_t CRC16(uint8_t *srcdata, uint16_t length)
{
uint16_t crc = 0xffff;
uint16_t i, j;
uint8_t value;
for (i = 0; i < length; i++)
{
for (j = 0; j < 8; j++)
{
value = ((srcdata[i] << j) & 0x80) ^ ((crc & 0x8000) >> 8);
crc <<= 1;
if (value != 0)
{
crc ^= 0x8005;
}
}
}
return crc;
}
void check_sum(void)
{
uint16_t checksum = 0;
uint8_t checksumH, checksumL;
uint8_t i = 0;
for (i = 0; i < (sizeof(GT1151_CFG_TBL) - 3); i += 2)
checksum += ((GT1151_CFG_TBL[i] << 8) | GT1151_CFG_TBL[i + 1]);
checksum = (~checksum) + 1;
checksumH = checksum >> 8;
checksumL = checksum;
printf("chksum:0x%X,\r\n", checksum);
printf("chksumH:0x%X,\r\n", checksumH);
printf("chksumL:0x%X,\r\n", checksumL);
}
uint8_t GT1151_Send_Cfg(uint8_t mode)
{
uint16_t checksum = 0;
uint8_t i = 0;
for (i = 0; i < (sizeof(GT1151_CFG_TBL) - 3); i += 2)
checksum += ((GT1151_CFG_TBL[i] << 8) | GT1151_CFG_TBL[i + 1]);
checksum = (~checksum) + 1;
printf("chksum:0x%x,\r\n", checksum);
GT1151_WR_Reg(GT_CFGS_REG, (uint8_t *)GT1151_CFG_TBL, sizeof(GT1151_CFG_TBL));
return 0;
}
static void GT1151_EXTI_Init(void)
{
rcu_periph_clock_enable(RCU_SYSCFG);
syscfg_exti_line_config(EXTI_SOURCE_GPIOD, EXTI_SOURCE_PIN11);
exti_init(TOUCH_EXTI_LINE, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
exti_interrupt_enable(TOUCH_EXTI_LINE);
nvic_irq_enable(TOUCH_EXTI_IRQn, 2, 0);
}
uint8_t GT1151_Init(void)
{
uint8_t temp[6] = {0};
uint8_t retry = 3;
// RST_PIN (PD12) 与 LCD 共享,LCD_Init 已完成硬件复位
// 通过 INT 引脚对 GT1151 做 I2C 复位握手
rcu_periph_clock_enable(INT_RCU);
gpio_mode_set(INT_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, INT_PIN);
gpio_output_options_set(INT_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, INT_PIN);
gpio_bit_reset(INT_PORT, INT_PIN);
delay_1ms(20);
// 初始化硬件 I2C0 (PB6=SCL, PB7=SDA)
i2c_init(TOUCH_I2C_PORT, 100000);
// 释放 INT(设为浮空输入),等待 GT1151 就绪
gpio_mode_set(INT_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, INT_PIN);
delay_1ms(150);
// 读取产品 ID,带重试
do
{
GT1151_RD_Reg(GT_PID_REG, temp, 4);
if (temp[0] != 0 && temp[0] != 0xFF)
break;
delay_1ms(50);
} while (--retry > 0);
printf("CTP ID: GT%s\r\n", temp);
if (strcmp((char *)temp, "1158") == 0 || strcmp((char *)temp, "1151") == 0)
{
GT1151_RD_Reg(GT_CFGS_REG, temp, 1);
printf("GT Config Version: 0x%02X\r\n", temp[0]);
GT1151_Send_Cfg(0);
delay_1ms(50);
GT1151_EXTI_Init();
printf("GT EXTI initialized\r\n");
return 0;
}
printf("GT Init: unknown ID, will still attempt to use touch\r\n");
return 1;
}
const uint16_t GT1151_TPX_TBL[5] = {GT_TP1_REG, GT_TP2_REG, GT_TP3_REG, GT_TP4_REG, GT_TP5_REG};
uint8_t GT1151_Scan(uint8_t mode)
{
uint8_t buf[4];
uint8_t i = 0;
uint8_t res = 0;
uint8_t temp;
uint8_t tempsta;
static uint8_t t = 0;
t++;
if ((t % 10) == 0 || t < 10)
{
GT1151_RD_Reg(GT_GSTID_REG, &mode, 1);
if (mode & 0X80 && ((mode & 0XF) < 6))
{
temp = 0;
GT1151_WR_Reg(GT_GSTID_REG, &temp, 1);
}
if ((mode & 0XF) && ((mode & 0XF) < 6))
{
temp = 0XFF << (mode & 0XF);
tempsta = tp_dev.sta;
tp_dev.sta = (~temp) | TP_PRES_DOWN | TP_CATH_PRES;
tp_dev.x[4] = tp_dev.x[0];
tp_dev.y[4] = tp_dev.y[0];
for (i = 0; i < 5; i++)
{
if (tp_dev.sta & (1 << i))
{
GT1151_RD_Reg(GT1151_TPX_TBL[i], buf, 4);
if (tp_dev.touchtype & 0X01)
{
tp_dev.x[i] = ((uint16_t)buf[1] << 8) + buf[0];
tp_dev.y[i] = ((uint16_t)buf[3] << 8) + buf[2];
}
else
{
tp_dev.x[i] = ((uint16_t)buf[1] << 8) + buf[0];
tp_dev.y[i] = ((uint16_t)buf[3] << 8) + buf[2];
}
if (tp_dev.x[i] > 0 && tp_dev.x[i] < 480 && tp_dev.y[i] > 0 && tp_dev.y[i] < 800)
printf("x[%d]:%d,y[%d]:%d\r\n", i, tp_dev.x[i], i, tp_dev.y[i]);
}
}
res = 1;
if (tp_dev.x[0] > 1024 || tp_dev.y[0] > 1024)
{
if ((mode & 0XF) > 1)
{
tp_dev.x[0] = tp_dev.x[1];
tp_dev.y[0] = tp_dev.y[1];
t = 0;
}
else
{
tp_dev.x[0] = tp_dev.x[4];
tp_dev.y[0] = tp_dev.y[4];
mode = 0X80;
tp_dev.sta = tempsta;
}
}
else
t = 0;
}
}
if ((mode & 0X8F) == 0X80)
{
if (tp_dev.sta & TP_PRES_DOWN)
{
tp_dev.sta &= ~(1 << 7);
}
else
{
tp_dev.x[0] = 0xffff;
tp_dev.y[0] = 0xffff;
tp_dev.sta &= 0XE0;
}
}
if (t > 240)
t = 10;
return res;
}
extern "C"
{
void EXTI10_15_IRQHandler(void)
{
if (exti_flag_get(TOUCH_EXTI_LINE) == SET)
{
g_touch_irq_flag = 1;
exti_flag_clear(TOUCH_EXTI_LINE);
}
}
}