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.

TSC2046 strange behavior

Other Parts Discussed in Thread: TSC2046

I'm using tsc2046 to get touch input from 4-wire resistive touch panel.

Situation is

If i get Y axis result only, receive data is always 4095(with no touch to the panel)

However, The output of tsc2046 become very weird, if i get X axis just followed by Y axis( 1000 -> 3960, with no touch )

But if i get touch result following orders(Y->Z1->Z2->X), the result is ok(4095 -> 0~10 -> 4095 -> 4095 )

I have modified spi speed to drop the sampling speed(down to 328.125khz) but the situation is always same.

I also tried to new touch panel but the result is also same.

I use only differential mode with no power down and also no power to reference.

If the convert order is Y->Z1->Z2->X then the result seems correct but except that like Y->X->Z1->Z2 or Y->X alway seems weird.

Here are my source code and configuration

SPI Clock : 656.250Khz

Vcc / IOVDD / Vbat = 3.3V

U8 _getTouchSample( U16 size )
{

#define ADS_START                      (1 << 7)
#define ADS_A2A1A0_d_y                 (1 << 4)  // Differential
#define ADS_A2A1A0_d_z1                (3 << 4)  // Differential
#define ADS_A2A1A0_d_z2                (4 << 4)  // Differential
#define ADS_A2A1A0_d_x                 (5 << 4)  // Differential
#define ADS_A2A1A0_vaux                (6 << 4)  // Non-differential
#define ADS_12_BIT                     (0 << 3)
#define ADS_SER                        (1 << 2)  // Non-differential
#define ADS_DFR                        (0 << 2)  // Differential
#define ADS_PD10_ADC_ON                (1 << 0)  // ADC on
#define ADS_PD10_REF_ON                (2 << 0)  // vREF on + penirq
#define ADS_PD10_ALL_ON                (3 << 0)  // ADC + vREF on

#define READ_12BIT_DFR(D, ADC, VREF)  (ADS_START                    | \
                                       D                            | \
                                       ADS_12_BIT                   | \
                                       ADS_DFR                      | \
                                       (ADC  ? ADS_PD10_ADC_ON : 0) | \
                                       (VREF ? ADS_PD10_REF_ON : 0))


#define READ_12BIT_SER(x)              (ADS_START  | /* Single-ended samples need to power   */ \
                                        x          | /* up reference voltage first; therefor */ \
                                        ADS_12_BIT | /* we leave both VREF and ADC powered.  */ \
                                        ADS_SER)

#define REF_ON                         (READ_12BIT_DFR(ADS_A2A1A0_d_x,  1, 1))
#define READ_Y(VREF)                   (READ_12BIT_DFR(ADS_A2A1A0_d_y,  1, VREF))
#define READ_Z1(VREF)                  (READ_12BIT_DFR(ADS_A2A1A0_d_z1, 1, VREF))
#define READ_Z2(VREF)                  (READ_12BIT_DFR(ADS_A2A1A0_d_z2, 1, VREF))
#define READ_X(VREF)                   (READ_12BIT_DFR(ADS_A2A1A0_d_x,  1, VREF))
#define PWRDOWN                        (READ_12BIT_DFR(ADS_A2A1A0_d_y,  0, 0))


/* Utility Function to support Touch */
void _SSP_Send( U8 *buff, U16 cnt )
{
  volatile U8 dummy;
  while( !SPI1_TXE  ); // TXE  == 1
  SPI1->DR = *(buff++);
  while( !SPI1_RXNE ); // RXNE == 1
  dummy = SPI1->DR;
}

void _SSP_Recv( U8 *buff, U16 cnt )
{
	do {	
		while( !SPI1_TXE );
		SPI1->DR = 0x00;
		while( !SPI1_RXNE );
		*(buff++) = SPI1->DR;
	} while( -- cnt );
}

static U16 _SSP_SendCmd(U8 Cmd) {
  U8 v[2];

  v[0] = Cmd;

  TS_CS_SET();
  _SSP_Send(v, 1);
  _SSP_Recv(v, 2);
  TS_CS_CLR();

  return ((v[0] << 8) | v[1]);
}

U8 _getTouchSample( U16 size )
{
	static int i;
	g_sampY[i]  = _SSP_SendCmd(READ_Y(0)) >> 3;
//	g_sampZ1[i] = _SSP_SendCmd(READ_Z1(0)) >> 3;
//	if( NO_FZ2_MEASURE == 0 ) {
//		g_sampZ2[i] = _SSP_SendCmd(READ_Z2(0)) >> 3;
//	}
	g_sampX[i]  = _SSP_SendCmd(READ_X(0))  >> 3;
//	if( TSC_PWRDOWN == 1 ) {
//		_SSP_SendCmd(PWRDOWN);
//	}
	i++;
	if( i>=MEDIAN_FILTER_SIZE ) {
		i = 0;
		return 1;
	}
	return 0;
}