This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TSC2013 question

Other Parts Discussed in Thread: TSC2013-Q1, TSC2013EVM

Can RESET PIN be connected to GND  straightly?

It disables hardware reset function, but i am not sure if It can influence the reset function by using POR method and software method?

The normal work of TSC2013 after a period of time, the value of register couldn't change when touch the panel, and the output signal of interrupt couldn't change also. What is the reason? Could anyone help to check driver code? Thanks.

/**
 *******************************************************************************
 * @file      tsc2013_driver.c
 * @version   V1.0.0    
 * @date      2013.05.20
 * @brief     tsc2013 driver for Tananis.	
 *            Resources: 
 *            None, call I2C_transfer function
 *
 *******************************************************************************
 * @author    - Adela 
 *            - Robert Zhang <armner@gmail.com>
 *            - 
 *
 */
 
#include "stm32f4xx.h"
#include "tsc2013_driver.h"
#include "interrupt.h"
#include "FreeRTOS.h"
#include "semphr.h"
#include "i2c_dma_driver.h"
#include "stdlib.h"
#include "string.h"

#include "i2c_tsc2013.h"

#define MAX_FINGER_NUM  2
volatile uint16_t g_touch_detected =0;

uint16_t tsc2013_touch_status;
tsc2013_data_block  data_block;

static xSemaphoreHandle tsc2013_sema=NULL;
int touchread_mode=0;


uint16_t finger_pos_x[MAX_FINGER_NUM];
uint16_t finger_pos_y[MAX_FINGER_NUM];

void swap(uint8_t *high_byte, uint8_t *low_byte)
{
	uint8_t temp;

	temp = *high_byte;
	*high_byte = *low_byte;
	*low_byte = temp;
}


static void delay_01us(uint16_t nCount)
{
	uint32_t index = 0; 
	for(index = (10 * nCount); index != 0; index--)
	{
	}
}

static void EXTILine2_Config(void)
{
	EXTI_InitTypeDef EXTI_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;	
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

	GPIO_Init(GPIOE,&GPIO_InitStructure);

	vSemaphoreCreateBinary(tsc2013_sema);
	if(tsc2013_sema ==NULL)
	{
		return;
	}  
	xSemaphoreTake(tsc2013_sema,portMAX_DELAY);


	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource2);
	
	EXTI_InitStructure.EXTI_Line = EXTI_Line2;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  	

	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);

	NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 9;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}
void Reset_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);

	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;

	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;	
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_SetBits(GPIOA, GPIO_Pin_1);	

	delay_01us(20);

	GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}

void tsc2013_read_touch_status(void)
{
	tsc2013_register reg;

	TSC2013_ReadDataBuffer(REG_STATUS_RD,(uint8_t*)&reg.value,2);

	swap(&reg.bytes.high_byte,&reg.bytes.low_byte); 

	tsc2013_touch_status =reg.value;
}

void tsc2013_read_touch_data(void)
{
	uint8_t i;

	TSC2013_ReadDataBuffer(REG_X1_RD,data_block.buffer,16);

	for(i=0;i<8;i++)
	{
		swap(&data_block.buffer[i * 2],&data_block.buffer[i * 2 + 1]);
	}

}

int tsc2013_write_ConfigValue()
{
	
	uint16_t configvalue=0;
	uint16_t RegValue=0;
	uint8_t IOE_BufferRX[4];  

	configvalue = CFR0_PSM_1 |               
				  CFR0_STS_0 | 
				  CFR0_RESOLUTION_12_BIT | 
				  CFR0_CONVERSION_CLOCK_4MHz |
				  CFR0_PANEL_VOLTAGE_STABILIZATION_TIME_3 |  //1ms
				  CFR0_PRECHARGE_TIME_4 |    //1.044ms
				  CFR0_SENSE_TIME_3 | 		//608us
				  CFR0_DTW_DISABLED |
				  CFR0_LSM_DISABLED;
	TSC2013_WriteDeviceRegister(REG_CFR0_WR, configvalue);

	configvalue =CFR1_BTD_0;
	
	TSC2013_WriteDeviceRegister(REG_CFR1_WR,configvalue);

	TSC2013_ReadDataBuffer(REG_CFR1_RD, &IOE_BufferRX,4);
	
    RegValue = (IOE_BufferRX[0]<<8)|(IOE_BufferRX[1]&0xff);
	
	if(RegValue!=configvalue)
	{
		return 0x01;
	}

	configvalue = CFR2_PINTS_2 |  
              CFR2_M_3 |     //M
              CFR2_W_2 |     //W
              CFR2_MAVE_X_ENABLED |
              CFR2_MAVE_Y_ENABLED |
              CFR2_MAVE_Z_ENABLED |
              CFR2_MAVE_AUX_DISABLED;
    TSC2013_WriteDeviceRegister(REG_CFR2_WR, configvalue);
  
	TSC2013_ReadDataBuffer(REG_CFR2_RD,  &IOE_BufferRX,4);

	RegValue = (IOE_BufferRX[0]<<8)|(IOE_BufferRX[1]&0xff);
   
	if(RegValue!=configvalue)
	{
		return 0x02;
	}

	return 0;	
}

void calculate_finger_pos(void)
{
	if(data_block.values.X1 >= data_block.values.X2)
	{
		finger_pos_x[0] = data_block.values.X2 + ((data_block.values.X1 - data_block.values.X2) >> 1);
	}
	else
	{
		finger_pos_x[0] = data_block.values.X1 + ((data_block.values.X2 - data_block.values.X1) >> 1);         
	}

	if(data_block.values.Y1 >= data_block.values.Y2)
	{
		finger_pos_y[0] = data_block.values.Y2 + ((data_block.values.Y1 - data_block.values.Y2) >> 1);
	}
	else
	{
		finger_pos_y[0] = data_block.values.Y1 + ((data_block.values.Y2 - data_block.values.Y1) >> 1);         
	}

	finger_pos_x[0] = 4096 - finger_pos_x[0];
	finger_pos_y[0] = 4096 - finger_pos_y[0];  
}


int  tsc2013_open( Driver *driver)
{

	I2C_transfer_block i2c_block[2];
	int reat=1;
	uint8_t IOE_BufferRX[4]; 

	I2Cx_init();
  	Reset_Init();
	reat = tsc2013_write_ConfigValue();
	TSC2013_WriteDeviceByte(0x84);
	
	TSC2013_ReadDataBuffer(REG_CFR1_RD, &IOE_BufferRX,2);

   	EXTILine2_Config();

	return 0;

}

int tsc2013_write(Driver *driver,void *buffer,int len,OFFSET offset1)
{

	return 0;
}

int tsc2013_read(Driver *driver,void *buffer,int len,OFFSET offset1)
{
    uint16_t *pBuffer;
	

	pBuffer = (uint16_t*)buffer;
	if(!touchread_mode)
	{
		xSemaphoreTake(tsc2013_sema,portMAX_DELAY);  //interrupt mode
		tsc2013_read_touch_data();
	}
	else
	{
		touchread_mode=1;
		tsc2013_read_touch_status();	
		if((tsc2013_touch_status & 0xf000) == 0xf000)
		{
			tsc2013_read_touch_data(); 			
		}
		else
		{
			touchread_mode=0;
			return -1;
		}

	}
	calculate_finger_pos();
	pBuffer[0] = finger_pos_x[0];
	pBuffer[1] = finger_pos_y[0];

	return 0;
}
int tsc2013_io_control(Driver *driver,int cmd ,int data)
{
	if(!cmd)
	{
		touchread_mode=0;
	}
	else
	{
		touchread_mode=1;
	}
	return 0;
}

int tsc2013_close(Driver *driver)
{
	return 0;
}


void EXTI2_IRQHandler(void)
{
	signed portBASE_TYPE xHigherPriorityTaskWoken;

	if(EXTI_GetITStatus(EXTI_Line2) != RESET)
	{		
		EXTI_ClearITPendingBit(EXTI_Line2);
		if(!touchread_mode)
		{
			xHigherPriorityTaskWoken =pdFALSE;
			
			xSemaphoreGiveFromISR(tsc2013_sema, &xHigherPriorityTaskWoken);
			if(xHigherPriorityTaskWoken == pdTRUE)
			{
				portEND_SWITCHING_ISR(1);
			}

		}
	}
	else
	{
		return;
	}
}

Driver tsc2013_driver =
{
    &tsc2013_open,
    &tsc2013_write,
    &tsc2013_read,
    &tsc2013_io_control,
    &tsc2013_close
};



tsc2013_driver.h

  • Could anyone help to check the drive code?Thanks.
  • Hi Walsh,

    Have you fixed the reset pin issue yet?  

    I just took a look at your code. However, I have not found any obvious issue.  Here is my suggestion about how to debug the issue you have met with.

    Step 1 : Comment all the firmware code that reads the data from the TSC2013-Q1. Probe the /PINTDAV pin with a scope or digital analyzer and rerun you firmware.  Then if you touch the touch panel,  you should see the /PINTDAV behave like the picture below.

    If you set PINTS[1:0] = 00 (CFR2_PINTS_0), below shows you what you should see.

    Step 2: If the /PINTDAV pin always behaves as expected, your hardware should be OK. If not, I think you probably have some hardware issues on the TSC2013-Q1.  

    Step 3:  Enable the code that was just commented and try to capture the i2c communications waveforms with a digital analyzer when this issue happens again.  

    Andy

  • Dear Andy:

    Thanks fot the reply. The problem had not been fixed yet.

    Under normal work, The waveform is ok as you show. But when the fault was occured, /PINTDAV pin

    was no output signal. So, i have not found the reason yet.
  • Hi Walsh,

    How many units have you tried? Did all of them have the same issue?  Could you post screenshots of the schematic and layout?

    Andy

  • Dear Andy:

    We utilized the TSC2013 hardware part of TSC2013EVM to test. We provided external power and MCU to connect TSC2013.

    The detailed fault presentation is as below,
    1. /PINTDAV is no pulse signal, always high-level.
    2. The status register(0X43) didn't change when touch the panel. The abnormal value was 4B or 47 but the correct value was F04B etc.

    Walsh