support new NV14 touch controller (#2027)

* support new NV14 touch controller

* implement review changes
reduced CST836U read delay to 5 us
This commit is contained in:
Malte Langermann
2022-06-25 16:09:04 +02:00
committed by Raphael Coeffic
parent 10c851469a
commit 42e54f5100
4 changed files with 200 additions and 50 deletions
@@ -187,17 +187,22 @@ int stm32_i2c_write(uint8_t bus, uint16_t addr, uint16_t reg, uint16_t reg_size,
return 0;
}
int stm32_i2c_is_dev_ready(uint8_t bus, uint16_t addr, uint32_t timeout)
int stm32_i2c_is_dev_ready(uint8_t bus, uint16_t addr, uint32_t retries, uint32_t timeout)
{
I2C_HandleTypeDef* h = get_i2c_handle(bus);
if (!h) return -1;
if (!h) return -1;
HAL_StatusTypeDef err = HAL_I2C_IsDeviceReady(h, addr << 1, (uint32_t)-1, timeout);
HAL_StatusTypeDef err = HAL_I2C_IsDeviceReady(h, addr << 1, retries, timeout);
if (err != HAL_OK) return -1;
return 0;
}
int stm32_i2c_is_dev_ready(uint8_t bus, uint16_t addr, uint32_t timeout)
{
return stm32_i2c_is_dev_ready(bus, addr, 1, timeout);
}
static int i2c_enable_gpio_clock(GPIO_TypeDef *GPIOx)
{
if (GPIOx == GPIOA)
@@ -51,4 +51,6 @@ int stm32_i2c_read(uint8_t bus, uint16_t addr, uint16_t reg, uint16_t reg_size,
int stm32_i2c_write(uint8_t bus, uint16_t addr, uint16_t reg, uint16_t reg_size,
uint8_t* data, uint16_t len, uint32_t timeout);
int stm32_i2c_is_dev_ready(uint8_t bus, uint16_t addr, uint32_t retries, uint32_t timeout);
int stm32_i2c_is_dev_ready(uint8_t bus, uint16_t addr, uint32_t timeout);
+155 -40
View File
@@ -41,15 +41,28 @@ volatile static bool touchEventOccured;
#define TOUCH_SDA_GPIO_PIN I2C_B1_SDA_GPIO_PIN // PB.09
#define TOUCH_FT6236_I2C_ADDRESS (0x70>>1)
#define TOUCH_CST836U_I2C_ADDRESS (0x15)
uint8_t ft6x06[FT6x06_MAX_INSTANCE] = {0};
static ft6x06_handle_TypeDef ft6x06_handle = {FT6206_I2C_NOT_INITIALIZED, 0, 0};
enum TouchControllers {TC_NONE, TC_FT6236, TC_CST836U};
TouchControllers touchController = TC_NONE;
static tc_handle_TypeDef tc_handle = {0, 0};
tmr10ms_t downTime = 0;
tmr10ms_t tapTime = 0;
short tapCount = 0;
#define TAP_TIME 25
struct TouchControllerDescriptor
{
void (*read)(uint16_t * X, uint16_t * Y, uint32_t * event);
uint8_t (*detectTouch)();
void (*printDebugInfo)();
uint32_t contactEvent;
};
static const TouchControllerDescriptor *tc = nullptr;
static TouchState internalTouchState = {};
void I2C_FreeBus()
@@ -179,12 +192,22 @@ void I2C_Init()
bool touch_i2c_read(uint8_t addr, uint8_t reg, uint8_t * data, uint8_t len)
{
if (stm32_i2c_read(TOUCH_I2C_BUS, addr, reg, 1, data, len, I2C_TIMEOUT_MAX) < 0)
return false;
if(touchController == TC_CST836U)
{
if(stm32_i2c_master_tx(TOUCH_I2C_BUS, addr, &reg, 1, 3) < 0)
return false;
delay_us(5);
if(stm32_i2c_master_rx(TOUCH_I2C_BUS, addr, data, len, I2C_TIMEOUT_MAX) < 0)
return false;
} else {
if (stm32_i2c_read(TOUCH_I2C_BUS, addr, reg, 1, data, len, I2C_TIMEOUT_MAX) < 0)
return false;
}
return true;
}
#if 0
static bool touch_i2c_write(uint8_t addr, uint8_t reg, uint8_t * data, uint8_t len)
{
if (stm32_i2c_write(TOUCH_I2C_BUS, addr, reg, 1, data, len, I2C_TIMEOUT_MAX) < 0)
@@ -193,7 +216,6 @@ static bool touch_i2c_write(uint8_t addr, uint8_t reg, uint8_t * data, uint8_t l
return true;
}
static void TS_IO_Write(uint8_t addr, uint8_t reg, uint8_t data)
{
uint8_t tryCount = 3;
@@ -202,6 +224,7 @@ static void TS_IO_Write(uint8_t addr, uint8_t reg, uint8_t data)
I2C_Init();
}
}
#endif
static uint8_t TS_IO_Read(uint8_t addr, uint8_t reg)
{
@@ -224,21 +247,16 @@ static uint16_t TS_IO_ReadMultiple(uint8_t addr, uint8_t reg, uint8_t * buffer,
return 1;
}
static uint8_t TS_IO_Read(uint8_t reg)
{
return TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, reg);
}
static void touch_ft6236_debug_info(void)
{
#if defined(DEBUG)
TRACE("ft6x36: thrhld = %d", TS_IO_Read(TOUCH_FT6236_REG_TH_GROUP) * 4);
TRACE("ft6x36: rep rate=", TS_IO_Read(TOUCH_FT6236_REG_PERIODACTIVE) * 10);
TRACE("ft6x36: fw lib 0x%02X %02X", TS_IO_Read(TOUCH_FT6236_REG_LIB_VER_H), TS_IO_Read(TOUCH_FT6236_REG_LIB_VER_L));
TRACE("ft6x36: fw v 0x%02X", TS_IO_Read(TOUCH_FT6236_REG_FIRMID));
TRACE("ft6x36: CHIP ID 0x%02X", TS_IO_Read(TOUCH_FT6236_REG_CIPHER));
TRACE("ft6x36: CTPM ID 0x%02X", TS_IO_Read(TOUCH_FT6236_REG_FOCALTECH_ID));
TRACE("ft6x36: rel code 0x%02X", TS_IO_Read(TOUCH_FT6236_REG_RELEASE_CODE_ID));
TRACE("ft6x36: thrhld = %d", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_TH_GROUP) * 4);
TRACE("ft6x36: rep rate=", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_PERIODACTIVE) * 10);
TRACE("ft6x36: fw lib 0x%02X %02X", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_LIB_VER_H), TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_LIB_VER_L));
TRACE("ft6x36: fw v 0x%02X", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_FIRMID));
TRACE("ft6x36: CHIP ID 0x%02X", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_CIPHER));
TRACE("ft6x36: CTPM ID 0x%02X", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_FOCALTECH_ID));
TRACE("ft6x36: rel code 0x%02X", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_RELEASE_CODE_ID));
#endif
}
@@ -249,22 +267,22 @@ static void touch_ft6236_debug_info(void)
* @param DeviceAddr: Device address on communication Bus.
* @retval : Number of active touches detected (can be 0, 1 or 2).
*/
static uint8_t ft6x06_TS_DetectTouch(uint16_t DeviceAddr)
static uint8_t ft6x06_TS_DetectTouch()
{
volatile uint8_t nbTouch = 0;
/* Read register FT6206_TD_STAT_REG to check number of touches detection */
nbTouch = TS_IO_Read(DeviceAddr, FT6206_TD_STAT_REG);
nbTouch = TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, FT6206_TD_STAT_REG);
nbTouch &= FT6206_TD_STAT_MASK;
if (nbTouch > FT6206_MAX_DETECTABLE_TOUCH) {
/* If invalid number of touch detected, set it to zero */
nbTouch = 0;
}
/* Update ft6x06 driver internal global : current number of active touches */
ft6x06_handle.currActiveTouchNb = nbTouch;
tc_handle.currActiveTouchNb = nbTouch;
/* Reset current active touch index on which to work on */
ft6x06_handle.currActiveTouchIdx = 0;
tc_handle.currActiveTouchIdx = 0;
return (nbTouch);
}
@@ -325,19 +343,19 @@ static void ft6x06_TS_GetTouchInfo(uint16_t DeviceAddr,
/**
* @brief Get the touch screen X and Y positions values
* Manage multi touch thanks to touch Index global
* variable 'ft6x06_handle.currActiveTouchIdx'.
* variable 'tc_handle.currActiveTouchIdx'.
* @param DeviceAddr: Device address on communication Bus.
* @param X: Pointer to X position value
* @param Y: Pointer to Y position value
* @retval None.
*/
static void ft6x06_TS_GetXY(uint16_t DeviceAddr, uint16_t * X, uint16_t * Y, uint32_t * event)
static void ft6x06_TS_GetXY(uint16_t * X, uint16_t * Y, uint32_t * event)
{
uint8_t regAddress = 0;
uint8_t dataxy[4];
if (ft6x06_handle.currActiveTouchIdx < ft6x06_handle.currActiveTouchNb) {
switch (ft6x06_handle.currActiveTouchIdx) {
if (tc_handle.currActiveTouchIdx < tc_handle.currActiveTouchNb) {
switch (tc_handle.currActiveTouchIdx) {
case 0 :
regAddress = FT6206_P1_XH_REG;
break;
@@ -350,7 +368,7 @@ static void ft6x06_TS_GetXY(uint16_t DeviceAddr, uint16_t * X, uint16_t * Y, uin
}
/* Read X and Y positions */
TS_IO_ReadMultiple(DeviceAddr, regAddress, dataxy, sizeof(dataxy));
TS_IO_ReadMultiple(TOUCH_FT6236_I2C_ADDRESS, regAddress, dataxy, sizeof(dataxy));
/* Send back ready X position to caller */
*X = ((dataxy[0] & FT6206_MSB_MASK) << 8) | (dataxy[1] & FT6206_LSB_MASK);
/* Send back ready Y position to caller */
@@ -362,29 +380,127 @@ static void ft6x06_TS_GetXY(uint16_t DeviceAddr, uint16_t * X, uint16_t * Y, uin
uint32_t area;
ft6x06_TS_GetTouchInfo(DeviceAddr, ft6x06_handle.currActiveTouchIdx, &weight, &area, event);
*/
ft6x06_handle.currActiveTouchIdx++;
tc_handle.currActiveTouchIdx++;
}
}
static void touch_cst836u_debug_info(void)
{
#if defined(DEBUG)
TRACE("cst836u: fw ver 0x%02X %02X", TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_FW_VERSION_H_REG), TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_FW_VERSION_L_REG));
TRACE("cst836u: module version 0x%02X", TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_MODULE_VERSION_REG));
TRACE("cst836u: project name 0x%02X", TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_PROJECT_NAME_REG));
TRACE("cst836u: chip type 0x%02X 0x%02X", TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_CHIP_TYPE_H_REG), TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_CHIP_TYPE_L_REG));
#endif
}
/**
* @brief Get the touch screen X and Y positions values
* Manage multi touch thanks to touch Index global
* variable 'tc_handle.currActiveTouchIdx'.
* @param DeviceAddr: Device address on communication Bus.
* @param X: Pointer to X position value
* @param Y: Pointer to Y position value
* @retval None.
*/
static void cst836u_TS_GetXY(uint16_t * X, uint16_t * Y, uint32_t * event)
{
uint8_t regAddress = 0;
uint8_t dataxy[4];
if (tc_handle.currActiveTouchIdx < tc_handle.currActiveTouchNb) {
switch (tc_handle.currActiveTouchIdx) {
case 0 :
regAddress = CST836U_TOUCH1_XH_REG;
break;
case 1 :
regAddress = CST836U_TOUCH2_XH_REG;
break;
default :
break;
}
/* Read X and Y positions */
TS_IO_ReadMultiple(TOUCH_CST836U_I2C_ADDRESS, regAddress, dataxy, sizeof(dataxy));
/* Send back ready X position to caller */
*X = ((dataxy[0] & CST836U_MSB_MASK) << 8) | dataxy[1];
/* Send back ready Y position to caller */
*Y = ((dataxy[2] & CST836U_MSB_MASK) << 8) | dataxy[3];
*event = (dataxy[0] & CST836U_TOUCH_EVT_FLAG_MASK) >> CST836U_TOUCH_EVT_FLAG_SHIFT;
/*
uint32_t weight;
uint32_t area;
*/
tc_handle.currActiveTouchIdx++;
}
}
/**
* @brief Return if there is touches detected or not.
* Try to detect new touches and forget the old ones (reset internal global
* variables).
* @param DeviceAddr: Device address on communication Bus.
* @retval : Number of active touches detected (can be 0, 1 or 2).
*/
static uint8_t cst836u_TS_DetectTouch()
{
volatile uint8_t nbTouch = 0;
/* Read register CST836U_TOUCH_NUM_REG to check number of touches detection */
nbTouch = TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_TOUCH_NUM_REG);
if (nbTouch > CST836U_MAX_DETECTABLE_TOUCH) {
/* If invalid number of touch detected, set it to zero */
nbTouch = 0;
}
tc_handle.currActiveTouchNb = nbTouch;
tc_handle.currActiveTouchIdx = 0;
return (nbTouch);
}
void TouchReset()
{
LL_GPIO_ResetOutputPin(TOUCH_RST_GPIO, TOUCH_RST_GPIO_PIN);
delay_ms(20);
delay_ms(10);
LL_GPIO_SetOutputPin(TOUCH_RST_GPIO, TOUCH_RST_GPIO_PIN);
delay_ms(300);
}
static const TouchControllerDescriptor FT6236 =
{
.read = ft6x06_TS_GetXY,
.detectTouch = ft6x06_TS_DetectTouch,
.printDebugInfo = touch_ft6236_debug_info,
.contactEvent = FT6206_TOUCH_EVT_FLAG_CONTACT
};
static const TouchControllerDescriptor CST836U =
{
.read = cst836u_TS_GetXY,
.detectTouch = cst836u_TS_DetectTouch,
.printDebugInfo = touch_cst836u_debug_info,
.contactEvent = CST836U_TOUCH_EVT_FLAG_CONTACT
};
void detectTouchController()
{
if( stm32_i2c_is_dev_ready(TOUCH_I2C_BUS, TOUCH_CST836U_I2C_ADDRESS, 3, 5) == 0)
{
touchController = TC_CST836U;
tc = &CST836U;
} else {
touchController = TC_FT6236;
tc = &FT6236;
}
}
void TouchInit(void)
{
I2C_Init();
TouchReset();
touch_ft6236_debug_info();
/* INT generation for new touch available */
/* Note TS_INT is active low */
uint8_t regValue = 0;
regValue = (FT6206_G_MODE_INTERRUPT_TRIGGER & (FT6206_G_MODE_INTERRUPT_MASK >> FT6206_G_MODE_INTERRUPT_SHIFT)) << FT6206_G_MODE_INTERRUPT_SHIFT;
/* Set interrupt TOUCH_FT6236_I2C_ADDRESS mode in FT6206_GMODE_REG */
TS_IO_Write(TOUCH_FT6236_I2C_ADDRESS, FT6206_GMODE_REG, regValue);
detectTouchController();
tc->printDebugInfo();
}
void handleTouch()
@@ -392,9 +508,8 @@ void handleTouch()
unsigned short touchX;
unsigned short touchY;
uint32_t tEvent = 0;
ft6x06_TS_GetXY(TOUCH_FT6236_I2C_ADDRESS, &touchX, &touchY, &tEvent);
// uint32_t gesture;
// ft6x06_TS_GetGestureID(TOUCH_FT6236_I2C_ADDRESS, &gesture);
tc->read(&touchX, &touchY, &tEvent);
#if defined( LCD_DIRECTION ) && (LCD_DIRECTION == LCD_VERTICAL)
touchX = LCD_WIDTH - touchX;
touchY = LCD_HEIGHT - touchY;
@@ -403,7 +518,7 @@ void handleTouch()
touchY = touchX;
touchX = tmp;
#endif
if (tEvent == FT6206_TOUCH_EVT_FLAG_CONTACT) {
if (tEvent == tc->contactEvent) {
int dx = touchX - internalTouchState.x;
int dy = touchY - internalTouchState.y;
@@ -462,7 +577,7 @@ TouchState touchPanelRead()
tmr10ms_t now = get_tmr10ms();
internalTouchState.tapCount = 0;
if (ft6x06_TS_DetectTouch(TOUCH_FT6236_I2C_ADDRESS)) {
if (tc->detectTouch()) {
handleTouch();
if (internalTouchState.event == TE_DOWN && downTime == 0) {
downTime = now;
+35 -7
View File
@@ -98,15 +98,13 @@ extern "C" {
*/
typedef struct
{
uint8_t i2cInitialized;
/* field holding the current number of simultaneous active touches */
uint8_t currActiveTouchNb;
/* field holding the touch index currently managed */
uint8_t currActiveTouchIdx;
} ft6x06_handle_TypeDef;
} tc_handle_TypeDef;
@@ -154,10 +152,6 @@ typedef struct
#define FT6206_STATUS_OK 0
#define FT6206_STATUS_NOT_OK 1
/* Possible values of global variable 'TS_I2C_Initialized' */
#define FT6206_I2C_NOT_INITIALIZED 0
#define FT6206_I2C_INITIALIZED 1
/* Max detectable simultaneous touches */
#define FT6206_MAX_DETECTABLE_TOUCH 2
@@ -322,6 +316,40 @@ typedef struct
#define FT6206_STATE_REG 0xBC
#define CST836U_WORK_MODE_REG 0x00
#define CST836U_PROXIMITY_ID_REG 0x01
#define CST836U_TOUCH_NUM_REG 0x02
#define CST836U_TOUCH1_XH_REG 0x03
#define CST836U_TOUCH1_XL_REG 0x04
#define CST836U_TOUCH1_YH_REG 0x05
#define CST836U_TOUCH1_YL_REG 0x06
#define CST836U_TOUCH2_XH_REG 0x09
#define CST836U_TOUCH2_XL_REG 0x0A
#define CST836U_TOUCH2_YH_REG 0x0B
#define CST836U_TOUCH2_YL_REG 0x0C
#define CST836U_FW_VERSION_L_REG 0xA6
#define CST836U_FW_VERSION_H_REG 0xA7
#define CST836U_MODULE_VERSION_REG 0xA8
#define CST836U_PROJECT_NAME_REG 0xA9
#define CST836U_CHIP_TYPE_L_REG 0xAA
#define CST836U_CHIP_TYPE_H_REG 0xAB
#define CST836U_CHECKSUM_L_REG 0xAC
#define CST836U_CHECKSUM_H_REG 0xAD
#define CST836U_PROX_STATE_REG 0xB0
#define CST836U_GES_STATE_REG 0xD0
#define CST836U_GES_ID_REG_REG 0xD3
#define CST836U_MAX_DETECTABLE_TOUCH 2
#define CST836U_MSB_MASK 0x0F
#define CST836U_TOUCH_EVT_FLAG_SHIFT 6
#define CST836U_TOUCH_EVT_FLAG_MASK (3 << CST836U_TOUCH_EVT_FLAG_SHIFT)
#define CST836U_TOUCH_EVT_FLAG_CONTACT 0x02
#define LCD_VERTICAL ( 0x00 )
#define LCD_HORIZONTAL ( 0x01 )
#define LCD_DIRECTION ( LCD_VERTICAL )