cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to get the Touch function running properly XPT2046

ZExpo.1
Senior

Hello All,

               I have set XPT2046 and set sample touch as specified by the documentation and I have getting coordinates accordingly but the problem is when I try to press the button I register the X, and Y coordinates but there is a delayed response, or the key is registered but touch gfx doesn't process forward.

Touch Strokes are working fine when touch is pressed according to Debugger.

CHECK THE VIDEO LINK BELOW FOR CLARIFICATION

VIDEO

@jiangfan 

@Osman SOYKURT 

 

 

10 REPLIES 10

Hello @ZExpo.1 ,
Is it possible to share your touch controller code? 

Mohammad MORADI
ST Software Developer | TouchGFX

Sure

#include <STM32TouchController.hpp>

#include <stdio.h>
#include <stdlib.h>
#include "main.h"
#include <stdbool.h>
// Warning! Use SPI bus with < 2.5 Mbit speed, better ~650 Kbit to be save.
#define XPT2046_SPI_PORT hspi1
extern SPI_HandleTypeDef XPT2046_SPI_PORT;
extern TIM_HandleTypeDef htim4;

uint32_t raw_x,raw_y;

#define XPT2046_IRQ_Pin       	T_PEN_Pin
#define XPT2046_IRQ_GPIO_Port 	T_PEN_GPIO_Port
#define XPT2046_CS_Pin        	T_CS_Pin
#define XPT2046_CS_GPIO_Port  	T_CS_GPIO_Port

#define XPT2046_IRQ_Pin       	T_PEN_Pin
#define XPT2046_IRQ_GPIO_Port 	T_PEN_GPIO_Port
#define XPT2046_CS_Pin        	T_CS_Pin
#define XPT2046_CS_GPIO_Port  	T_CS_GPIO_Port

#define TOUCH_ORIENTATION_PORTRAIT 			(0U)
#define TOUCH_ORIENTATION_LANDSCAPE 		(1U)
#define TOUCH_ORIENTATION_PORTRAIT_MIRROR 	(2U)
#define TOUCH_ORIENTATION_LANDSCAPE_MIRROR 	(3U)

#define ORIENTATION	(TOUCH_ORIENTATION_LANDSCAPE)

// change depending on screen orientation
#if (ORIENTATION == 0)
#define XPT2046_SCALE_X 240
#define XPT2046_SCALE_Y 320
#elif (ORIENTATION == 1)
#define XPT2046_SCALE_X 480
#define XPT2046_SCALE_Y 272
#elif (ORIENTATION == 2)
#define XPT2046_SCALE_X 1280
#define XPT2046_SCALE_Y 800
#elif (ORIENTATION == 3)
#define XPT2046_SCALE_X 480
#define XPT2046_SCALE_Y 272
#endif

#define XPT2046_MIN_RAW_X 5800
#define XPT2046_MAX_RAW_X 28000//latest
#define XPT2046_MIN_RAW_Y 7500
#define XPT2046_MAX_RAW_Y 26000

// call before initializing any SPI devices
extern bool XPT2046_TouchPressed(void);
extern bool XPT2046_TouchGetCoordinates(uint16_t* x, uint16_t* y);


#if (ORIENTATION == 0)
#define READ_X 0xD0
#define READ_Y 0x90
#elif (ORIENTATION == 1)
#define READ_Y 0xD0
#define READ_X 0x90
#elif (ORIENTATION == 2)
#define READ_X 0xD0
#define READ_Y 0x90
#elif (ORIENTATION == 3)
#define READ_Y 0xD0
#define READ_X 0x90
#endif

#ifdef SOFTWARE_SPI

#define SPI_CLK_L()		HAL_GPIO_WritePin(XPT2046_CLK_GPIO_Port, XPT2046_CLK_Pin, GPIO_PIN_RESET)
#define SPI_CLK_H()		HAL_GPIO_WritePin(XPT2046_CLK_GPIO_Port, XPT2046_CLK_Pin, GPIO_PIN_SET)
#define SPI_MOSI_L()	HAL_GPIO_WritePin(XPT2046_MOSI_GPIO_Port, XPT2046_MOSI_Pin, GPIO_PIN_RESET)
#define SPI_MOSI_H()	HAL_GPIO_WritePin(XPT2046_MOSI_GPIO_Port, XPT2046_MOSI_Pin, GPIO_PIN_SET)
#define SPI_MISO()		HAL_GPIO_ReadPin(XPT2046_MISO_GPIO_Port, XPT2046_MISO_Pin)

static void spi_write_byte(uint8_t data)
{
	for(size_t i = 0; i < 8; i++)
	{
		if (data & 0x80)
		{
			SPI_MOSI_H();
		}
		else
		{
			SPI_MOSI_L();
		}
		data = data << 1;
		SPI_CLK_L();
		SPI_CLK_H();
	}
}

static uint8_t spi_read_byte(void)
{
	uint8_t i, ret , value;
	ret = 0;
	i = 8;

	do {
		i--;
		SPI_CLK_L();
		value = SPI_MISO();
		if (value)
		{
			//set the bit to 0 no matter what
			ret |= (1 << i);
		}

		SPI_CLK_H();
	} while (i > 0);

	return ret;
}

#endif /* SOFTWARE_SPI */

static void XPT2046_TouchSelect()
{
    HAL_GPIO_WritePin(XPT2046_CS_GPIO_Port, XPT2046_CS_Pin, GPIO_PIN_RESET);
}

static void XPT2046_TouchUnselect()
{
    HAL_GPIO_WritePin(XPT2046_CS_GPIO_Port, XPT2046_CS_Pin, GPIO_PIN_SET);
}

bool XPT2046_TouchPressed(void)
{
    return HAL_GPIO_ReadPin(XPT2046_IRQ_GPIO_Port, XPT2046_IRQ_Pin) == GPIO_PIN_RESET;
}

bool XPT2046_TouchGetCoordinates(uint16_t* x, uint16_t* y)
{
#ifndef SOFTWARE_SPI

	static const uint8_t cmd_read_x[] = { READ_X };
    static const uint8_t cmd_read_y[] = { READ_Y };
    static const uint8_t zeroes_tx[] = { 0x00, 0x00 };

#endif /* SOFTWARE_SPI */

    XPT2046_TouchSelect();

    uint32_t avg_x = 0;
    uint32_t avg_y = 0;
    uint8_t nsamples = 0;

    for(uint8_t i = 0; i < 128; i++)
    {
        if(!XPT2046_TouchPressed())
            break;

        nsamples++;

        uint8_t y_raw[2];
        uint8_t x_raw[2];

#ifdef SOFTWARE_SPI

       spi_write_byte(READ_Y);

	   y_raw[0] = spi_read_byte();
	   y_raw[1] = spi_read_byte();

	   spi_write_byte(READ_X);

	   x_raw[0] = spi_read_byte();
	   x_raw[1] = spi_read_byte();

#else

        HAL_SPI_Transmit(&XPT2046_SPI_PORT, (uint8_t*)cmd_read_y, sizeof(cmd_read_y), HAL_MAX_DELAY);
        HAL_SPI_TransmitReceive(&XPT2046_SPI_PORT, (uint8_t*)zeroes_tx, y_raw, sizeof(y_raw), HAL_MAX_DELAY);

        HAL_SPI_Transmit(&XPT2046_SPI_PORT, (uint8_t*)cmd_read_x, sizeof(cmd_read_x), HAL_MAX_DELAY);
        HAL_SPI_TransmitReceive(&XPT2046_SPI_PORT, (uint8_t*)zeroes_tx, x_raw, sizeof(x_raw), HAL_MAX_DELAY);

#endif /* SOFTWARE_SPI */

        avg_x += (((uint16_t)x_raw[0]) << 8) | ((uint16_t)x_raw[1]);
        avg_y += (((uint16_t)y_raw[0]) << 8) | ((uint16_t)y_raw[1]);
    }

    XPT2046_TouchUnselect();

    if(nsamples < 128)
        return false;

     raw_x = (avg_x / 128);
     if(raw_x < XPT2046_MIN_RAW_X) raw_x = XPT2046_MIN_RAW_X;
     if(raw_x > XPT2046_MAX_RAW_X) raw_x = XPT2046_MAX_RAW_X;

     raw_y = (avg_y / 128);
     if(raw_y < XPT2046_MIN_RAW_Y) raw_y = XPT2046_MIN_RAW_Y;
     if(raw_y > XPT2046_MAX_RAW_Y) raw_y = XPT2046_MAX_RAW_Y;

    // Uncomment this line to calibrate touchscreen:
   //  printf("raw_x = %6d, raw_y = %6d\r\n", (int) raw_x, (int) raw_y);
   //  printf("\x1b[1F");

#if (ORIENTATION == 0)
	*x = (raw_x - XPT2046_MIN_RAW_X) * XPT2046_SCALE_X / (XPT2046_MAX_RAW_X - XPT2046_MIN_RAW_X);
	*y = (raw_y - XPT2046_MIN_RAW_Y) * XPT2046_SCALE_Y / (XPT2046_MAX_RAW_Y - XPT2046_MIN_RAW_Y);
#elif (ORIENTATION == 1)
	*x = (raw_x - XPT2046_MIN_RAW_X) * XPT2046_SCALE_X / (XPT2046_MAX_RAW_X - XPT2046_MIN_RAW_X);
	*y = (raw_y - XPT2046_MIN_RAW_Y) * XPT2046_SCALE_Y / (XPT2046_MAX_RAW_Y - XPT2046_MIN_RAW_Y);
#elif (ORIENTATION == 2)
    *x = (raw_x - XPT2046_MIN_RAW_X) * XPT2046_SCALE_X / (XPT2046_MAX_RAW_X - XPT2046_MIN_RAW_X);
    *y = XPT2046_SCALE_Y - (raw_y - XPT2046_MIN_RAW_Y) * XPT2046_SCALE_Y / (XPT2046_MAX_RAW_Y - XPT2046_MIN_RAW_Y);
#elif (ORIENTATION == 3)
    *x = XPT2046_SCALE_X - (raw_x - XPT2046_MIN_RAW_X) * XPT2046_SCALE_X / (XPT2046_MAX_RAW_X - XPT2046_MIN_RAW_X);
    *y = (raw_y - XPT2046_MIN_RAW_Y) * XPT2046_SCALE_Y / (XPT2046_MAX_RAW_Y - XPT2046_MIN_RAW_Y);
#endif

    return true;
}

void STM32TouchController::init()
{
    /**
     * Initialize touch controller and driver
     *
     */
	/*  TIM4->CCR2 = 30;
			   HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2);
			   HAL_Delay(11);
			   HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_2);*/
}
uint16_t a=  0 , b =  0 ;
bool STM32TouchController::sampleTouch(int32_t& x, int32_t& y)
{
	if (XPT2046_TouchPressed())
	  {

	   if (XPT2046_TouchGetCoordinates( & a, & b))
	   {
		   x=a;
		   y=b;
	   }
	   return true;
	  }
   return false;
}

Any update?

jiangfan
ST Employee

Sorry, no experience with XPT2046.

XPT2046 Library is working fine I am getting the required coordinates in the variables, But as you can see in the video the button is pressed but nothing happens, and after pressing for quite a while it triggers.

Waiting for reply.

ZExpo.1
Senior

@Mohammad MORADI ESFAHANIASL 
Please provide your feedback.

Hey @ZExpo.1 ,

Sorry for the delay. The first thing I noticed with your code is in the sampleTouch function. the "return true" should happen when you have detected a touch and the point is detected successfully, so, it should be placed in the inner if-statement. 

If that fix doesn't work, please provide your application (or a simple example with the mentioned problem) to see if there is something that makes sense.

Have a good day. 

Mohammad MORADI
ST Software Developer | TouchGFX