Files
edgetx-gx12/radio/src/targets/horus/tp_gt911.cpp
T
2020-04-25 13:39:28 +02:00

427 lines
10 KiB
C++

/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "tp_gt911.h"
uint8_t touchGT911Flag = 0;
uint8_t touchPanelEvent = 0;
struct TouchData touchData;
struct TouchState touchState;
void GT911_INT_Change(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = TOUCH_INT_GPIO_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_Init(TOUCH_INT_GPIO, &GPIO_InitStructure);
}
uint8_t GT911_Send_Cfg(uint8_t mode)
{
uint8_t buf[2];
uint8_t i = 0;
buf[0] = 0;
buf[1] = mode; //
for (i = 0; i < sizeof(GT911_Cfg); i++)
buf[0] += GT911_Cfg[i];//check sum
buf[0] = (~buf[0]) + 1;
gt911WriteRegister(GT_CFGS_REG, (uint8_t *) GT911_Cfg, sizeof(GT911_Cfg));//
gt911WriteRegister(GT_CHECK_REG, buf, 2);//write checksum
return 0;
}
static void I2C_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//I2C_InitTypeDef I2C_InitStructure;
/* GPIO Peripheral clock enable */
RCC_AHB1PeriphClockCmd(I2C_RCC_AHB1Periph, ENABLE);
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
//PB6: I2C1_SCL PB7: I2C1_SDA
GPIO_InitStructure.GPIO_Pin = I2C_SCL_GPIO_PIN | I2C_SDA_GPIO_PIN;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(I2C_GPIO, &GPIO_InitStructure);
GPIO_SetBits(I2C_GPIO, I2C_SCL_GPIO_PIN | I2C_SDA_GPIO_PIN);
}
static void TOUCH_AF_ExtiStop(void)
{
SYSCFG_EXTILineConfig(TOUCH_INT_EXTI_PortSource, TOUCH_INT_EXTI_PinSource1);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_StructInit(&EXTI_InitStructure);
EXTI_InitStructure.EXTI_Line = TOUCH_INT_EXTI_LINE1;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = DISABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TOUCH_INT_EXTI_IRQn1;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 9;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* Not used as 4 bits are used for the pre-emption priority. */;
NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
NVIC_Init(&NVIC_InitStructure);
}
static void TOUCH_AF_ExtiConfig(void)
{
SYSCFG_EXTILineConfig(TOUCH_INT_EXTI_PortSource, TOUCH_INT_EXTI_PinSource1);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_StructInit(&EXTI_InitStructure);
EXTI_InitStructure.EXTI_Line = TOUCH_INT_EXTI_LINE1;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TOUCH_INT_EXTI_IRQn1;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 9;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* Not used as 4 bits are used for the pre-emption priority. */;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
static void TOUCH_AF_GPIOConfig(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = TOUCH_RST_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(TOUCH_RST_GPIO, &GPIO_InitStructure);
GPIO_ResetBits(TOUCH_RST_GPIO, TOUCH_RST_GPIO_PIN);
GPIO_InitStructure.GPIO_Pin = TOUCH_INT_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(TOUCH_INT_GPIO, &GPIO_InitStructure);
GPIO_ResetBits(TOUCH_INT_GPIO, TOUCH_INT_GPIO_PIN);
}
void SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_GPIOB, ENABLE);
//RCC_AHB1PeriphClockCmd(I2C_RCC_AHB1Periph, ENABLE);
GPIO_InitStructure.GPIO_Pin = I2C_SDA_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(I2C_GPIO, &GPIO_InitStructure);
}
void SDA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_GPIOB, ENABLE);
//RCC_AHB1PeriphClockCmd(I2C_RCC_AHB1Periph, ENABLE);
GPIO_InitStructure.GPIO_Pin = I2C_SDA_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(I2C_GPIO, &GPIO_InitStructure);
}
void I2C_Start(void)
{
SDA_OUT();
I2C_SDA_H();
I2C_SCL_H();
delay_us(2);
I2C_SDA_L();//START:when CLK is high,DATA change form high to low
delay_us(2);
I2C_SCL_L();//
delay_us(2);
}
void I2C_Stop(void)
{
SDA_OUT();
I2C_SCL_L();
I2C_SDA_L();//STOP:when CLK is high DATA change form low to high
delay_us(2);
I2C_SCL_H();
I2C_SDA_H();//
delay_us(2);
}
uint8_t I2C_Wait_Ack(void)
{
uint8_t ucErrTime = 0;
SDA_IN(); //
I2C_SDA_H();
delay_us(2);
//I2C_SCL_L();delay_us(6);
I2C_SCL_H();//delay_us(6);
while (READ_SDA) {
ucErrTime++;
if (ucErrTime > 166) {
I2C_Stop();
return 1;
}
delay_us(1);
}
I2C_SDA_L();
I2C_SCL_L();//
return 0;
}
void I2C_Ack(void)
{
I2C_SCL_L();
SDA_OUT();
I2C_SDA_L();
delay_us(2);
I2C_SCL_H();
delay_us(2);
I2C_SCL_L();
}
void I2C_NAck(void)
{
I2C_SCL_L();
SDA_OUT();
I2C_SDA_H();
delay_us(2);
I2C_SCL_H();
delay_us(2);
I2C_SCL_L();
}
void I2C_Send_Byte(uint8_t txd)
{
uint8_t t;
SDA_OUT();
I2C_SCL_L();//
for (t = 0; t < 8; t++) {
if ((txd & 0x80) >> 7)
I2C_SDA_H();
else
I2C_SDA_L();
txd <<= 1;
delay_us(1);
I2C_SCL_H();
delay_us(2);
I2C_SCL_L();
delay_us(1);
}
}
uint8_t I2C_Read_Byte(unsigned char ack)
{
unsigned char i, receive = 0;
SDA_IN();
for (i = 0; i < 8; i++) {
I2C_SCL_L();
delay_us(2);
I2C_SCL_H();
receive <<= 1;
if (READ_SDA)receive++;
delay_us(1);
}
if (!ack)
I2C_NAck();
else
I2C_Ack();
return receive;
}
uint8_t gt911WriteRegister(uint16_t reg, uint8_t * buf, uint8_t len)
{
{
uint8_t i;
uint8_t ret = 0;
I2C_Start();
I2C_Send_Byte(GT_CMD_WR); //send cmd
I2C_Wait_Ack();
I2C_Send_Byte(reg >> 8); //send hi
I2C_Wait_Ack();
I2C_Send_Byte(reg & 0XFF); //send low
I2C_Wait_Ack();
for (i = 0; i < len; i++) {
I2C_Send_Byte(buf[i]);
ret = I2C_Wait_Ack();
if (ret)break;
}
I2C_Stop();
return ret;
}
}
void gt911ReadRegister(u16 reg, uint8_t * buf, uint8_t len)
{
uint8_t i;
//I2C_GenerateSTART(I2C1, ENABLE);
I2C_Start();
I2C_Send_Byte(GT_CMD_WR); //send addr
I2C_Wait_Ack();
I2C_Send_Byte(reg >> 8); //send hi
I2C_Wait_Ack();
I2C_Send_Byte(reg & 0XFF); //send low
I2C_Wait_Ack();
I2C_Start();
I2C_Send_Byte(GT_CMD_RD); //send rd
I2C_Wait_Ack();
for (i = 0; i < len; i++) {
buf[i] = I2C_Read_Byte(i == (len - 1) ? 0 : 1); //send data
}
I2C_Stop();
}
void touchPanelDeInit(void)
{
TOUCH_AF_ExtiStop();
}
bool touchPanelInit(void)
{
uint8_t tmp[4] = {0};
TRACE("Touchpanel init start ...");
TOUCH_AF_GPIOConfig(); //SET RST=OUT INT=OUT INT=LOW
I2C_Config();
TPRST_LOW();
TPINT_HIGH();
delay_us(200);
TPRST_HIGH();
delay_ms(6);
TPINT_LOW();
delay_ms(55);
GT911_INT_Change(); //Set INT INPUT INT=LOW
delay_ms(50);
TRACE("Reading Touch registry");
gt911ReadRegister(GT_PID_REG, tmp, 4);
if (strcmp((char *) tmp, "911") == 0) //ID==9147
{
TRACE("GT911 chip detected");
tmp[0] = 0X02;
gt911WriteRegister(GT_CTRL_REG, tmp, 1);
gt911ReadRegister(GT_CFGS_REG, tmp, 1);
if (tmp[0] < 0X69)//ver
{
TRACE("Default Ver:%x\r\n",tmp[0]);
GT911_Send_Cfg(1);
}
delay_ms(10);
tmp[0] = 0X00;
gt911WriteRegister(GT_CTRL_REG, tmp, 1);//end reset
touchGT911Flag = true;
TOUCH_AF_ExtiConfig();
return true;
}
TRACE("GT911 chip NOT FOUND");
return false;
}
void touchPanelRead()
{
uint8_t state = 0;
gt911ReadRegister(GT911_READ_XY_REG, &state, 1);
touchPanelEvent = false;
if ((state & 0x80u) == 0x00) {
// not ready
return;
}
uint8_t pointsCount = (state & 0x0Fu);
if (pointsCount > 0 && pointsCount < GT911_MAX_TOUCH_POINTS) {
gt911ReadRegister(GT911_READ_XY_REG + 1, touchData.data, pointsCount * sizeof(TouchPoint));
if (touchData.pointsCount == 0) {
touchState.event = TE_DOWN;
touchState.startX = touchState.x = touchData.points[0].x;
touchState.startY = touchState.y = touchData.points[0].y;
}
else {
touchState.deltaX = touchData.points[0].x - touchState.x;
touchState.deltaY = touchData.points[0].y - touchState.y;
if (touchState.event == TE_SLIDE || abs(touchState.deltaX) >= SLIDE_RANGE || abs(touchState.deltaY) >= SLIDE_RANGE) {
touchState.event = TE_SLIDE;
touchState.x = touchData.points[0].x;
touchState.y = touchData.points[0].y;
}
}
touchData.pointsCount = pointsCount;
}
else {
if (touchData.pointsCount > 0) {
touchData.pointsCount = 0;
if (touchState.event == TE_SLIDE)
touchState.event = TE_SLIDE_END;
else
touchState.event = TE_UP;
}
}
uint8_t zero = 0;
gt911WriteRegister(GT911_READ_XY_REG, &zero, 1);
}
extern "C" void TOUCH_INT_EXTI_IRQHandler1(void)
{
if (EXTI_GetITStatus(TOUCH_INT_EXTI_LINE1) != RESET) {
TRACE("TI");
touchPanelEvent = 1;
EXTI_ClearITPendingBit(TOUCH_INT_EXTI_LINE1);
}
}