正点原子IM6基于SDK2.2 > I2C触摸板驱动
#include <string.h>
#include <stdio.h>
#include "fsl_iomuxc.h"
#include "fsl_i2c.h"
#include "fsl_gpio.h"
#include "td_touch.h"
#include "td_ledkeybeep.h"
#include "td_lcd_ui_manager.h"
#include "td_usart1_down_controller.h"
#define ResetTouchRESET() GPIO_WritePinOutput(GPIO5, 9, 0)
#define SetTouchRESET() GPIO_WritePinOutput(GPIO5, 9, 1)
#define ResetTouchINT() GPIO_WritePinOutput(GPIO1, 9, 0)
#define SetTouchINT() GPIO_WritePinOutput(GPIO1, 9, 1)
#define GT1151QSlaveAddr 0x14
typedef union{
struct {
unsigned char Commend;
unsigned char Data;
unsigned char CheckSum;
};
unsigned char Buffer[3];
} GTRealCommand,*pGTRealCommand;
typedef union{
struct {
unsigned char Version;
unsigned char Datas[235];
unsigned short Chksum;
unsigned char Fresh;
}__attribute__((__packed__));
unsigned char Buffer[239];
} GTConfigData,*pGTConfigData;
typedef union{
struct {
unsigned char Datas[126];
unsigned short Chksum;
};
unsigned char Buffer[128];
} GTConfigDataEx,*pGTConfigDataEx;
typedef union{
struct {
unsigned char ProductID[4];
unsigned char PatchCID;
unsigned char PatchMain;
unsigned char PatchSub;
unsigned char MASKMain;
unsigned char MASKSub;
unsigned char MASKInternal;
unsigned char Bonding;
unsigned char CheckSum;
};
unsigned char Buffer[12];
} GTPointVersion,*pGTPointVersion;
typedef union{
struct {
unsigned char Config;
};
unsigned char Buffer[1];
} GTTouchNumConfig,*pGTTouchNumConfig;
typedef union{
struct {
unsigned char Value;
};
unsigned char Buffer[1];
} GTTouchKeyValue,*pGTTouchKeyValue;
typedef union{
struct {
unsigned char Statue;
unsigned short PointX;
unsigned short PointY;
unsigned char SizeW;
unsigned char SizeH;
}__attribute__((__packed__));
unsigned char Buffer[7];
} GTPointData,*pGTPointData;
typedef union{
struct {
unsigned char ProductID[4];
unsigned char VersionMain;
unsigned char VersionSub;
unsigned char VersionInternal;
unsigned char MASKMain;
unsigned char MASKSub;
unsigned char MASKInternal;
unsigned char Bonding;
unsigned char CheckSum;
};
unsigned char Buffer[12];
} GTGestureVer,*pGTGestureVer;
static GTPointData gPointDatas[10];
volatile static unsigned int GTPointColour;
volatile static unsigned char GTPointCount;
volatile static unsigned char CanOutScreen;
volatile static unsigned char CanOutPC;
volatile static unsigned char GTPointDataOk;
static void TD_Touch_Reset(void);
static void TD_Touch_WriteConfig(void);
static void TD_Touch_RequestClear(void);
static unsigned char TD_Touch_ReadRequest(void);
static unsigned char TD_Touch_ReadPointsStatue(void);
static void GT_INT_IRQHandler(uint32_t giccIar, void *param);
void TD_Touch_Init(void)
{
IOMUXC_SetPinMux(IOMUXC_UART5_TX_DATA_I2C2_SCL,1U);
IOMUXC_SetPinMux(IOMUXC_UART5_RX_DATA_I2C2_SDA,1U);
IOMUXC_SetPinConfig(IOMUXC_UART5_TX_DATA_I2C2_SCL, 0x70B0);
IOMUXC_SetPinConfig(IOMUXC_UART5_RX_DATA_I2C2_SDA,
IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
IOMUXC_SW_PAD_CTL_PAD_DSE(6U) |
IOMUXC_SW_PAD_CTL_PAD_SPEED(2U) |
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK |
IOMUXC_SW_PAD_CTL_PAD_PUS(1U));
IOMUXC_SetPinMux(IOMUXC_GPIO1_IO09_GPIO1_IO09,0);
IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO09_GPIO1_IO09,
IOMUXC_SW_PAD_CTL_PAD_DSE(6U) |
IOMUXC_SW_PAD_CTL_PAD_SPEED(2U) |
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK);
IOMUXC_SetPinMux(IOMUXC_SNVS_SNVS_TAMPER9_GPIO5_IO09,0);
IOMUXC_SetPinConfig(IOMUXC_SNVS_SNVS_TAMPER9_GPIO5_IO09,
IOMUXC_SW_PAD_CTL_PAD_DSE(6U) |
IOMUXC_SW_PAD_CTL_PAD_SPEED(2U) |
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK);
gpio_pin_config_t gp;
gp.interruptMode = kGPIO_IntRisingEdge;
gp.direction = kGPIO_DigitalOutput;
gp.outputLogic = 1;
GPIO_PinInit(GPIO1, 9, &gp);
gp.direction = kGPIO_DigitalOutput;
gp.outputLogic = 0;
GPIO_PinInit(GPIO5, 9, &gp);
TD_Touch_Reset();
gp.direction = kGPIO_DigitalInput;
gp.outputLogic = 1;
GPIO_PinInit(GPIO1, 9, &gp);
SystemInstallIrqHandler(GPIO1_Combined_0_15_IRQn, GT_INT_IRQHandler, NULL);
EnableIRQ(GPIO1_Combined_0_15_IRQn);
GPIO_EnableInterrupts(GPIO1, 1U << 9);
i2c_master_config_t mc;
mc.baudRate_Bps = 300000;
mc.enableMaster = true;
I2C_MasterInit(I2C2, &mc, CLOCK_GetFreq(kCLOCK_IpgClk) / (CLOCK_GetDiv(kCLOCK_PerclkDiv) + 1U));
GTPointDataOk = false;
GTPointCount = 0;
CanOutScreen = false;
CanOutPC = false;
GTPointColour = 0x1f0000ff;
switch(TD_Touch_ReadRequest())
{
case 0x01:
TD_Touch_WriteConfig();
break;
case 0x03:
TD_Touch_Init();
break;
case 0xff:
default:
break;
}
TD_Touch_RequestClear();
}
/**********************************************************************************
触摸屏GT_INT中断,每次扫描完之后会发送高电平有效的脉冲,
**********************************************************************************/
void GT_INT_IRQHandler(uint32_t giccIar, void *param)
{
GPIO_ClearPinsInterruptFlags(GPIO1, 1U << 9);
GTPointDataOk = true;
}
/**********************************************************************************
触摸屏执行复位时序
**********************************************************************************/
void TD_Touch_Reset(void)
{
//10ms以上
for(int i = 0;i < 20000;i++) gPointDatas[0].Statue++;
SetTouchRESET();//复位低电平有效
//200us以上
for(int i = 0;i < 500;i++) gPointDatas[0].Statue++;
ResetTouchINT();//拉低INT表示让芯片恢复到nomorl模式
//200us以上
for(int i = 0;i < 500;i++) gPointDatas[0].Statue++;
SetTouchINT();
//200us以上
for(int i = 0;i < 500;i++) gPointDatas[0].Statue++;
ResetTouchINT();
//200us以上
for(int i = 0;i < 500;i++) gPointDatas[0].Statue++;
SetTouchINT();
//上电复位时许完成,需要等60ms以上才能开始读写数据
for(int i = 0;i < 40000;i++) gPointDatas[0].Statue++;
}
/**********************************************************************************
触摸屏写入配置
**********************************************************************************/
void TD_Touch_WriteConfig(void)
{
static GTConfigData tConfig;
i2c_master_transfer_t mxf;
tConfig.Version |= 0x80;//固化配置
tConfig.Version++;//版本增加,否则写入无效
tConfig.Chksum--;//计算校验和
mxf.slaveAddress = GT1151QSlaveAddr;
mxf.direction = kI2C_Write;
mxf.subaddress = 0x8050;
mxf.subaddressSize = 2;
mxf.data = tConfig.Buffer;
mxf.dataSize = sizeof(GTConfigData);
mxf.flags = kI2C_TransferDefaultFlag;
I2C_MasterTransferBlocking(I2C2, &mxf);
}
/**********************************************************************************
触摸屏读取芯片的请求,地址0X8044
**********************************************************************************/
unsigned char TD_Touch_ReadRequest(void)
{
static unsigned char buf[2];
i2c_master_transfer_t mxf;
mxf.slaveAddress = GT1151QSlaveAddr;
mxf.direction = kI2C_Read;
mxf.subaddress = 0x8044;//读取的地址
mxf.subaddressSize = 2;
mxf.data = buf;
mxf.dataSize = 1;
mxf.flags = kI2C_TransferDefaultFlag;
I2C_MasterTransferBlocking(I2C2, &mxf);
return buf[0];
}
/**********************************************************************************
触摸屏写入Request为0
**********************************************************************************/
void TD_Touch_RequestClear(void)
{
unsigned char buf[2];
i2c_master_transfer_t mxf;
buf[0] = 0x00;//写入的数据为0
mxf.slaveAddress = GT1151QSlaveAddr;
mxf.direction = kI2C_Write;
mxf.subaddress = 0x8044;
mxf.subaddressSize = 2;
mxf.data = buf;
mxf.dataSize = 1;
mxf.flags = kI2C_TransferDefaultFlag;
I2C_MasterTransferBlocking(I2C2, &mxf);
}
/**********************************************************************************
触摸屏读取触点个数及相关信息寄存器
**********************************************************************************/
unsigned char TD_Touch_ReadPointsStatue(void)
{
static unsigned char buf[2];
i2c_master_transfer_t mxf;
mxf.slaveAddress = GT1151QSlaveAddr;
mxf.direction = kI2C_Read;
mxf.subaddress = 0x814E;
mxf.subaddressSize = 2;
mxf.data = buf;
mxf.dataSize = 1;
mxf.flags = kI2C_TransferDefaultFlag;
I2C_MasterTransferBlocking(I2C2, &mxf);
return buf[0];
}
/**********************************************************************************
触摸屏读取指定的触点的信息,0-9总共10个
**********************************************************************************/
void TD_Touch_ReadPointData(int pid, pGTPointData point)
{
i2c_master_transfer_t mxf;
mxf.slaveAddress = GT1151QSlaveAddr;
mxf.direction = kI2C_Read;
mxf.subaddress = 0x814f + (pid << 3);
mxf.subaddressSize = 2;
mxf.data = point->Buffer;
mxf.dataSize = sizeof(GTPointData);
mxf.flags = kI2C_TransferDefaultFlag;
I2C_MasterTransferBlocking(I2C2, &mxf);
}
/**********************************************************************************
触摸屏读取完触点数据后必须要清除寄存器
**********************************************************************************/
void TD_Touch_PointsStatueClear(void)
{
unsigned char buf[2];
i2c_master_transfer_t mxf;
buf[0] = 0x00;//写入的数据
mxf.slaveAddress = GT1151QSlaveAddr;
mxf.direction = kI2C_Write;
mxf.subaddress = 0x814e;
mxf.subaddressSize = 2;
mxf.data = buf;
mxf.dataSize = 1;
mxf.flags = kI2C_TransferDefaultFlag;
I2C_MasterTransferBlocking(I2C2, &mxf);
}
/**********************************************************************************
触摸屏设置是否将触点输出到显示屏,0表示不输出,1表示输出
**********************************************************************************/
void TD_Touch_SetOutToScreen(unsigned char newstatue)
{
CanOutScreen = newstatue;
}
/**********************************************************************************
触摸屏设置是否将触点输出到pc上位机,0表示不输出,1表示输出
**********************************************************************************/
void TD_Touch_SetOutToPC(unsigned char newstatue)
{
CanOutPC = newstatue;
}
/**********************************************************************************
触摸屏设置新的触摸颜色
**********************************************************************************/
void TD_Touch_ConfigColor(unsigned int newcolor)
{
GTPointColour = newcolor;
}
/**********************************************************************************
触摸屏服务
**********************************************************************************/
void TD_Touch_Server(void)
{
if(GTPointDataOk){
GTPointDataOk = false;
unsigned char statue = TD_Touch_ReadPointsStatue();
GTPointCount = statue & 0x0f;//获取触点的个数
for(int i = 0;i < 10 && i < GTPointCount;i++){
TD_Touch_ReadPointData(i, &gPointDatas[i]);
if(CanOutScreen) TD_LcdUIManager_DrawPoint(gPointDatas[i].Buffer[1] | gPointDatas[i].Buffer[2] << 8, gPointDatas[i].Buffer[3] | gPointDatas[i].Buffer[4] << 8,gPointDatas[i].Buffer[5],GTPointColour);//表示将触点渲染到显示屏上
if(CanOutPC) TD_Usart1DownController_Send(gPointDatas[i].Buffer, 7);
}
TD_Touch_PointsStatueClear();//读取完之后清空寄存器
}
}
/**********************************************************************************
单独线程方式运行
**********************************************************************************/
void TD_Touch_Run(void)
{
TD_Touch_Init();
while(1) TD_Touch_Server();
}