cbad06d616
- 将 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 总线空闲
266 lines
7.9 KiB
C++
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);
|
|
}
|
|
}
|
|
}
|