mirror of
https://github.com/openmv/openmv.git
synced 2025-09-26 23:09:13 +08:00
728 lines
18 KiB
C
728 lines
18 KiB
C
/* Copyright (C) 2023 Alif Semiconductor - All Rights Reserved.
|
|
* Use, distribution and modification of this code is permitted under the
|
|
* terms stated in the Alif Semiconductor Software License Agreement
|
|
*
|
|
* You should have received a copy of the Alif Semiconductor Software
|
|
* License Agreement with this file. If not, please write to:
|
|
* contact@alifsemi.com, or visit: https://alifsemi.com/license
|
|
*
|
|
*/
|
|
|
|
/**************************************************************************//**
|
|
* @file GT911_touch_driver.c
|
|
* @author Prasanna Ravi, Ahmad Rashed and Chandra Bhushan Singh
|
|
* @email prasanna.ravi@alifsemi.com , ahmad.rashed@alifsemi.com and
|
|
* chandrabhushan.singh@alifsemi.com
|
|
* @version V1.0.0
|
|
* @date 3 August 2023
|
|
* @brief GT911 touch screen driver.
|
|
* @bug None.
|
|
* @Note None.
|
|
******************************************************************************/
|
|
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
|
|
#include "RTE_Components.h"
|
|
#include "system_utils.h"
|
|
|
|
/* GPIO Driver */
|
|
#include "Driver_GPIO.h"
|
|
|
|
/* I2C Driver */
|
|
#include "Driver_I2C.h"
|
|
|
|
/* Pinmux Driver */
|
|
#include "pinconf.h"
|
|
|
|
/* Touchscreen Driver */
|
|
#include "Driver_Touch_Screen.h"
|
|
|
|
#if (!defined(RTE_Drivers_GT911))
|
|
#error "GT911 Touch not configured in RTE_Components.h!"
|
|
#endif
|
|
|
|
#if !( RTE_TOUCH_SCREEN)
|
|
#error "Touch Driver not enabled in the RTE_Device.h"
|
|
#endif
|
|
|
|
#if !(RTE_GT911)
|
|
#error "GT911 Touch is not enabled in the RTE_Device.h"
|
|
#endif
|
|
|
|
#if !(RTE_ACTIVE_TOUCH_POINTS)
|
|
#error "GT911 at least enable one active touch point"
|
|
#endif
|
|
|
|
/* Touch reset pin control GPIO port */
|
|
extern ARM_DRIVER_GPIO ARM_Driver_GPIO_(RTE_GT911_TOUCH_RESET_GPIO_PORT);
|
|
static ARM_DRIVER_GPIO *GPIO_Driver_RST = &ARM_Driver_GPIO_(RTE_GT911_TOUCH_RESET_GPIO_PORT);
|
|
|
|
/* Touch INT pin control GPIO port */
|
|
extern ARM_DRIVER_GPIO ARM_Driver_GPIO_(RTE_GT911_TOUCH_INT_GPIO_PORT);
|
|
static ARM_DRIVER_GPIO *GPIO_Driver_INT = &ARM_Driver_GPIO_(RTE_GT911_TOUCH_INT_GPIO_PORT);
|
|
|
|
/* I2C Driver instance for Touch screen communication */
|
|
#if(RTE_GT911_TOUCH_I2C_INSTANCE == 4)
|
|
#define GT911_TOUCH_I2C_INSTANCE I3C
|
|
#else
|
|
#define GT911_TOUCH_I2C_INSTANCE RTE_GT911_TOUCH_I2C_INSTANCE
|
|
#endif
|
|
|
|
extern ARM_DRIVER_I2C ARM_Driver_I2C_(GT911_TOUCH_I2C_INSTANCE);
|
|
static ARM_DRIVER_I2C *I2C_Driver = &ARM_Driver_I2C_(GT911_TOUCH_I2C_INSTANCE);
|
|
|
|
/* GT911 Driver specific macros */
|
|
|
|
/* Set the GT911_SLAVE_ADDR macro to either 0x5D or 0x14 to select the desired I2C slave address */
|
|
#define GT911_SLAVE_ADDR RTE_GT911_TOUCH_I2C_SLAVE_ADDRESS_SEL
|
|
|
|
#define GT911_COMMAND_REG 0x8040
|
|
#define GT911_PRODUCT_ID 0x8140
|
|
#define GT911_TOUCH_STATUS 0x814E
|
|
#define GT911_NUM_TOUCH_POINTS_MSK 0x7
|
|
#define GT911_FIRST_TOUCHPOINT_DATA 0x8150
|
|
|
|
#define GT911_REG_INDX_SIZE 2
|
|
#define TOUCH_I2C_TIMEOUT_US 100000
|
|
|
|
/* I2C transmission stop or restart selection macros */
|
|
#define RESTART (0X01)
|
|
#define STOP (0X00)
|
|
|
|
/* GT911 Driver status */
|
|
#define GT911_FLAG_DRV_INIT_DONE (1U << 0)
|
|
#define GT911_FLAG_POWER_ENABLED (1U << 1)
|
|
|
|
/* GT911 Touch event variables */
|
|
volatile uint8_t touch_event_gpio;
|
|
volatile uint8_t touch_event_i2c;
|
|
|
|
/* GT911 Touch driver Info variable */
|
|
static struct GT911_DRV_INFO
|
|
{
|
|
uint32_t touch_drv_status;
|
|
} gt911_drv_info;
|
|
|
|
#define ARM_TOUCH_SCREEN_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0) /*Driver version*/
|
|
|
|
/*Driver version*/
|
|
static const ARM_DRIVER_VERSION DriverVersion =
|
|
{
|
|
ARM_TOUCH_SCREEN_API_VERSION,
|
|
ARM_TOUCH_SCREEN_DRV_VERSION
|
|
};
|
|
|
|
/* Driver Capabilities */
|
|
static const ARM_TOUCH_SCREEN_CAPABILITIES DriverCapabilities =
|
|
{
|
|
0, /* Not supports reentrant_operation */
|
|
1, /* Multiple touch points supported*/
|
|
0 /* reserved (must be zero)*/
|
|
};
|
|
|
|
/**
|
|
\fn ARM_DRIVER_VERSION ARM_TOUCH_SCREEN_GetVersion (void)
|
|
\brief Get touch screen driver version.
|
|
\return \ref ARM_DRIVER_VERSION.
|
|
*/
|
|
static ARM_DRIVER_VERSION ARM_TOUCH_SCREEN_GetVersion (void)
|
|
{
|
|
return DriverVersion;
|
|
}
|
|
|
|
/**
|
|
\fn ARM_TOUCH_SCREEN_CAPABILITIES ARM_TOUCH_SCREEN_GetCapabilities (void)
|
|
\brief Get touch screen driver capabilities.
|
|
\return \ref ARM_MIPI_DPHY_CAPABILITIES.
|
|
*/
|
|
static ARM_TOUCH_SCREEN_CAPABILITIES ARM_TOUCH_SCREEN_GetCapabilities (void)
|
|
{
|
|
return DriverCapabilities;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t TOUCH_Write(uint8_t dev_addr, uint16_t reg_addr,
|
|
uint8_t *reg_data, uint8_t num_bytes)
|
|
\brief write register value to GT911 Touch screen registers.
|
|
\param[in] dev_addr : I2c slave address.
|
|
\param[in] reg_addr : Register address.
|
|
\param[in] reg_data : pointer to register data.
|
|
\param[in] num_bytes : Number of bytes to write.
|
|
\return \ref execution_status.
|
|
*/
|
|
static int32_t TOUCH_Write(uint8_t dev_addr, uint16_t reg_addr,
|
|
uint8_t *reg_data, uint8_t num_bytes)
|
|
{
|
|
uint8_t tx_data[12] = {0};
|
|
uint8_t i;
|
|
int32_t ret;
|
|
int32_t lp_count = 0;
|
|
|
|
tx_data[0] = (reg_addr >> 8) & 0xFF;
|
|
tx_data[1] = (reg_addr) & 0xFF;
|
|
|
|
if (num_bytes)
|
|
{
|
|
for(i = 0; i < num_bytes; i++)
|
|
tx_data[i + GT911_REG_INDX_SIZE] = reg_data[i];
|
|
}
|
|
|
|
touch_event_i2c = 0;
|
|
|
|
do
|
|
{
|
|
ret = I2C_Driver->MasterTransmit(dev_addr, tx_data,
|
|
num_bytes + GT911_REG_INDX_SIZE, STOP);
|
|
|
|
if(lp_count++ < TOUCH_I2C_TIMEOUT_US)
|
|
{
|
|
sys_busy_loop_us(1);
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
|
|
} while(ret == ARM_DRIVER_ERROR_BUSY);
|
|
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
lp_count = 0;
|
|
|
|
while (touch_event_i2c == 0)
|
|
{
|
|
if(lp_count++ < TOUCH_I2C_TIMEOUT_US)
|
|
{
|
|
sys_busy_loop_us(1);
|
|
}
|
|
else
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
}
|
|
|
|
if (!(touch_event_i2c & ARM_I2C_EVENT_TRANSFER_DONE))
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t TOUCH_Read(uint8_t dev_addr, uint16_t reg_addr,
|
|
uint8_t *reg_data, uint8_t num_bytes)
|
|
\brief read register value from GT911 Touch screen registers.
|
|
\param[in] dev_addr : I2c slave address.
|
|
\param[in] reg_addr : Register address.
|
|
\param[in] reg_data : pointer to register data.
|
|
\param[in] num_bytes : Number of bytes to read.
|
|
\return \ref execution_status.
|
|
*/
|
|
static int32_t TOUCH_Read(uint8_t dev_addr, uint16_t reg_addr,
|
|
uint8_t *reg_data, uint8_t num_bytes)
|
|
{
|
|
uint8_t rx_data[12] = {0};
|
|
int32_t ret;
|
|
int32_t lp_count = 0;
|
|
|
|
ret = TOUCH_Write(dev_addr, reg_addr, NULL, 0);
|
|
if (ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
touch_event_i2c = 0;
|
|
|
|
ret = I2C_Driver->MasterReceive(dev_addr, rx_data, num_bytes, STOP);
|
|
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
while (touch_event_i2c == 0)
|
|
{
|
|
if(lp_count++ < TOUCH_I2C_TIMEOUT_US)
|
|
{
|
|
sys_busy_loop_us(1);
|
|
}
|
|
else
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
}
|
|
|
|
if (!(touch_event_i2c & ARM_I2C_EVENT_TRANSFER_DONE))
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
memcpy(reg_data, rx_data, num_bytes);
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t TOUCH_IntEnable(bool enable)
|
|
\brief GT911 Touch screen INT line GPIO control.
|
|
\param[in] enable : true or false.
|
|
\return \ref execution_status.
|
|
*/
|
|
static int32_t TOUCH_IntEnable(bool enable)
|
|
{
|
|
uint32_t arg = ARM_GPIO_IRQ_POLARITY_LOW | ARM_GPIO_IRQ_EDGE_SENSITIVE_SINGLE | ARM_GPIO_IRQ_SENSITIVE_EDGE;
|
|
int32_t ret;
|
|
|
|
if(enable)
|
|
{
|
|
ret = GPIO_Driver_INT->Control(RTE_GT911_TOUCH_INT_PIN_NO, ARM_GPIO_ENABLE_INTERRUPT, &arg);
|
|
}
|
|
else
|
|
{
|
|
ret = GPIO_Driver_INT->Control(RTE_GT911_TOUCH_INT_PIN_NO, ARM_GPIO_DISABLE_INTERRUPT, NULL);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
\fn void TOUCH_I2C_CB(uint32_t event)
|
|
\brief GT911 Touch screen I2C callback event.
|
|
\param[in] event: \ref I3C Event.
|
|
\return \ref execution_status.
|
|
*/
|
|
static void TOUCH_I2C_CB(uint32_t event)
|
|
{
|
|
touch_event_i2c |= event;
|
|
}
|
|
|
|
/**
|
|
\fn void TOUCH_GPIO_CB(uint32_t event)
|
|
\brief GT911 Touch screen GPIO callback event.
|
|
\param[in] event: \ref GPIO Interrupt events.
|
|
\return \ref execution_status.
|
|
*/
|
|
static void TOUCH_GPIO_CB(uint32_t event)
|
|
{
|
|
ARG_UNUSED (event);
|
|
(void)TOUCH_IntEnable(false);
|
|
touch_event_gpio = 1;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t TOUCH_Reset(void)
|
|
\brief Hard Reset GT911 Touch Screen.
|
|
\param[in] none.
|
|
\return \ref execution_status.
|
|
*/
|
|
static int32_t TOUCH_Reset(void)
|
|
{
|
|
int32_t ret;
|
|
|
|
/* TOUCH INT pin */
|
|
ret = GPIO_Driver_INT->Control(RTE_GT911_TOUCH_INT_PIN_NO, ARM_GPIO_DISABLE_INTERRUPT, NULL);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
ret = GPIO_Driver_INT->SetValue(RTE_GT911_TOUCH_INT_PIN_NO, GPIO_PIN_OUTPUT_STATE_LOW);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
ret = GPIO_Driver_INT->SetDirection(RTE_GT911_TOUCH_INT_PIN_NO, GPIO_PIN_DIRECTION_OUTPUT);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
/* TOUCH RST pin */
|
|
ret = GPIO_Driver_RST->Control(RTE_GT911_TOUCH_RESET_PIN_NO, ARM_GPIO_DISABLE_INTERRUPT, NULL);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
ret = GPIO_Driver_RST->SetValue(RTE_GT911_TOUCH_RESET_PIN_NO, GPIO_PIN_OUTPUT_STATE_LOW);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
ret = GPIO_Driver_RST->SetDirection(RTE_GT911_TOUCH_RESET_PIN_NO, GPIO_PIN_DIRECTION_OUTPUT);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
sys_busy_loop_us(1000);
|
|
|
|
#if (GT911_SLAVE_ADDR == 0x14)
|
|
ret = GPIO_Driver_INT->SetValue(RTE_GT911_TOUCH_INT_PIN_NO, GPIO_PIN_OUTPUT_STATE_HIGH);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
sys_busy_loop_us(100);
|
|
#endif
|
|
|
|
ret = GPIO_Driver_RST->SetValue(RTE_GT911_TOUCH_RESET_PIN_NO, GPIO_PIN_OUTPUT_STATE_HIGH);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
sys_busy_loop_us(50000);
|
|
|
|
#if (GT911_SLAVE_ADDR == 0x14)
|
|
ret = GPIO_Driver_INT->SetValue(RTE_GT911_TOUCH_INT_PIN_NO, GPIO_PIN_OUTPUT_STATE_LOW);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
ret = GPIO_Driver_INT->SetDirection(RTE_GT911_TOUCH_INT_PIN_NO, GPIO_PIN_DIRECTION_INPUT);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
return ARM_DRIVER_OK ;
|
|
|
|
}
|
|
|
|
/**
|
|
\fn int32_t TOUCH_Init(void)
|
|
\brief Initialize GT911 Touch Screen.
|
|
This function will
|
|
- initialize i2c instance.
|
|
- initialize gpio interrupt and reset instance.
|
|
\param[in] none.
|
|
\return \ref execution_status.
|
|
*/
|
|
int32_t TOUCH_Init(void)
|
|
{
|
|
int32_t ret;
|
|
|
|
ret = I2C_Driver->Initialize(TOUCH_I2C_CB);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
ret = I2C_Driver->PowerControl(ARM_POWER_FULL);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
ret = I2C_Driver->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_STANDARD);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
ret = GPIO_Driver_INT->Initialize(RTE_GT911_TOUCH_INT_PIN_NO, &TOUCH_GPIO_CB);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
ret = GPIO_Driver_INT->PowerControl(RTE_GT911_TOUCH_INT_PIN_NO, ARM_POWER_FULL);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
ret = GPIO_Driver_RST->Initialize(RTE_GT911_TOUCH_RESET_PIN_NO, NULL);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
ret = GPIO_Driver_RST->PowerControl(RTE_GT911_TOUCH_RESET_PIN_NO, ARM_POWER_FULL);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t TOUCH_Setup(void)
|
|
\brief Setup GT911 Touch Screen.
|
|
This function will
|
|
- read GT911 product id, proceed only it is correct.
|
|
\param[in] none.
|
|
\return \ref execution_status.
|
|
*/
|
|
int32_t TOUCH_Setup(void)
|
|
{
|
|
uint8_t data = 0;
|
|
uint8_t product_id_1st_byte = 0;
|
|
int32_t ret;
|
|
|
|
ret = TOUCH_Reset();
|
|
{
|
|
if(ret != ARM_DRIVER_OK)
|
|
return ret;
|
|
}
|
|
|
|
ret = TOUCH_IntEnable(true);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
ret = TOUCH_Write(GT911_SLAVE_ADDR, GT911_COMMAND_REG, &data, 1);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
ret = TOUCH_Read(GT911_SLAVE_ADDR, GT911_PRODUCT_ID, &product_id_1st_byte, 1);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
/* "911" product id is in ascii character*/
|
|
if (product_id_1st_byte != '9')
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t TOUCH_Deinit(void)
|
|
\brief Un-initialize GT911 Touch Screen.
|
|
\param[in] none.
|
|
\return \ref execution_status.
|
|
*/
|
|
int32_t TOUCH_Deinit(void)
|
|
{
|
|
int32_t ret;
|
|
|
|
ret = I2C_Driver->PowerControl(ARM_POWER_OFF);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
ret = I2C_Driver->Uninitialize();
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t ARM_TOUCH_SCREEN_Initialize (void)
|
|
\brief Initialize touch screen Interface.
|
|
\param[in] none.
|
|
\return \ref execution_status.
|
|
*/
|
|
static int32_t ARM_TOUCH_SCREEN_Initialize (void)
|
|
{
|
|
int32_t ret;
|
|
|
|
if(gt911_drv_info.touch_drv_status & GT911_FLAG_DRV_INIT_DONE)
|
|
{
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
ret = TOUCH_Init();
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
gt911_drv_info.touch_drv_status = GT911_FLAG_DRV_INIT_DONE;
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t ARM_TOUCH_SCREEN_Uninitialize (void)
|
|
\brief uninitialize touch screen Interface.
|
|
\return \ref execution_status.
|
|
*/
|
|
static int32_t ARM_TOUCH_SCREEN_Uninitialize (void)
|
|
{
|
|
int32_t ret;
|
|
|
|
ret = TOUCH_Deinit();
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
gt911_drv_info.touch_drv_status = 0;
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t ARM_TOUCH_SCREEN_PowerControl (ARM_POWER_STATE state)
|
|
\brief Control touch screen Interface Power.
|
|
\param[in] state Power state.
|
|
\return \ref execution_status.
|
|
*/
|
|
static int32_t ARM_TOUCH_SCREEN_PowerControl (ARM_POWER_STATE state)
|
|
{
|
|
int32_t ret;
|
|
|
|
switch (state)
|
|
{
|
|
case ARM_POWER_OFF:
|
|
{
|
|
/*Disabling the IRQs*/
|
|
ret = TOUCH_IntEnable(false);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
gt911_drv_info.touch_drv_status &= ~GT911_FLAG_POWER_ENABLED;
|
|
|
|
break;
|
|
}
|
|
|
|
case ARM_POWER_FULL:
|
|
{
|
|
if (!(gt911_drv_info.touch_drv_status & GT911_FLAG_DRV_INIT_DONE))
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
if (gt911_drv_info.touch_drv_status & GT911_FLAG_POWER_ENABLED)
|
|
{
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
ret = TOUCH_Setup();
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
gt911_drv_info.touch_drv_status |= GT911_FLAG_POWER_ENABLED;
|
|
|
|
break;
|
|
}
|
|
|
|
case ARM_POWER_LOW:
|
|
default:
|
|
{
|
|
return ARM_DRIVER_ERROR_UNSUPPORTED;
|
|
}
|
|
}
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
/**
|
|
\fn int32_t ARM_TOUCH_SCREEN_GetState (ARM_TOUCH_STATE *state)
|
|
\brief Get touch screen touch state.
|
|
\param[in] state pointer to ARM_TOUCH_STATE.
|
|
\return \ref execution_status.
|
|
*/
|
|
static int32_t ARM_TOUCH_SCREEN_GetState (ARM_TOUCH_STATE *state)
|
|
{
|
|
uint8_t data;
|
|
uint16_t nextXY = GT911_FIRST_TOUCHPOINT_DATA;
|
|
uint8_t rx_buf[4] = {0};
|
|
int32_t ret;
|
|
|
|
if (!(gt911_drv_info.touch_drv_status & GT911_FLAG_POWER_ENABLED))
|
|
{
|
|
return ARM_DRIVER_ERROR;
|
|
}
|
|
|
|
state->numtouches = 0;
|
|
|
|
if(touch_event_gpio)
|
|
{
|
|
touch_event_gpio = 0;
|
|
|
|
ret = TOUCH_Read(GT911_SLAVE_ADDR, GT911_TOUCH_STATUS, &data, 1);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
/* Get buffer status from GT911_TOUCH_STATUS 7th bit*/
|
|
bool msb = data & 0x80;
|
|
|
|
/* Get number of touch points from GT911_TOUCH_STATUS 0-3 bit*/
|
|
state->numtouches = ((data & GT911_NUM_TOUCH_POINTS_MSK) > RTE_ACTIVE_TOUCH_POINTS ?
|
|
RTE_ACTIVE_TOUCH_POINTS : (data & GT911_NUM_TOUCH_POINTS_MSK));
|
|
|
|
if (msb)
|
|
{
|
|
if(state->numtouches)
|
|
{
|
|
for(uint8_t i = 0; i < state->numtouches; i++)
|
|
{
|
|
ret = TOUCH_Read(GT911_SLAVE_ADDR, nextXY, rx_buf, 4);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
state->coordinates[i].x = rx_buf[1];
|
|
state->coordinates[i].y = rx_buf[3];
|
|
state->coordinates[i].x <<= 8;
|
|
state->coordinates[i].y <<= 8;
|
|
state->coordinates[i].x |= rx_buf[0];
|
|
state->coordinates[i].y |= rx_buf[2];
|
|
nextXY += 8U;
|
|
}
|
|
}
|
|
|
|
/*Clear status register*/
|
|
data = 0;
|
|
ret = TOUCH_Write(GT911_SLAVE_ADDR, GT911_TOUCH_STATUS, &data, 1);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
/* re-enable gt911 interrupt */
|
|
ret = TOUCH_IntEnable(true);
|
|
if(ret != ARM_DRIVER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
return ARM_DRIVER_OK;
|
|
}
|
|
|
|
extern ARM_DRIVER_TOUCH_SCREEN GT911;
|
|
ARM_DRIVER_TOUCH_SCREEN GT911 =
|
|
{
|
|
ARM_TOUCH_SCREEN_GetVersion,
|
|
ARM_TOUCH_SCREEN_GetCapabilities,
|
|
ARM_TOUCH_SCREEN_Initialize,
|
|
ARM_TOUCH_SCREEN_Uninitialize,
|
|
ARM_TOUCH_SCREEN_PowerControl,
|
|
ARM_TOUCH_SCREEN_GetState
|
|
};
|