2021-02-28 03:10 AM
Hi, I successfully used a HAL library to drive a TFT ili9341 LCD and tried drawing a line on the LCD by touching the LCD and the code was perfectly accurate then I rewrote the code with registers. the touch is not accurate now and when I touch the LCD the line shows up at a point far from the place which is touched I attached the code. what might be the problem? the pins are defined with maximum frequency.
#include "ILI9341_Touchscreen.h"
#include "stm32f10x.h"
#include "main.h"
//Internal Touchpad command, do not call directly
uint16_t TP_Read(void)
{
uint8_t i = 16;
uint16_t value = 0;
while(i > 0x00)
{
value <<= 1;
TP_CLK_PORT->BSRR=TP_CLK_PIN;
TP_CLK_PORT->BRR=TP_CLK_PIN;
if ((TP_MISO_PORT->IDR&TP_MISO_PIN)!=0)
{
value++;
}
i--;
};
return value;
}
//Internal Touchpad command, do not call directly
void TP_Write(uint8_t value)
{
uint8_t i = 0x08;
TP_CLK_PORT->BRR=TP_CLK_PIN;
while(i > 0)
{
if((value & 0x80) != 0x00)
{
TP_MOSI_PORT->BSRR=TP_MOSI_PIN;
}
else
{
TP_MOSI_PORT->BRR=TP_MOSI_PIN;
}
value <<= 1;
TP_CLK_PORT->BSRR=TP_CLK_PIN;
TP_CLK_PORT->BRR=TP_CLK_PIN;
i--;
};
}
//Read coordinates of touchscreen press. Position[0] = X, Position[1] = Y
uint8_t TP_Read_Coordinates(uint16_t Coordinates[2])
{
TP_CLK_PORT->BSRR=TP_CLK_PIN;
TP_MOSI_PORT->BSRR=TP_MOSI_PIN;
TP_CS_PORT->BSRR=TP_CS_PIN;
uint32_t avg_x, avg_y = 0;
uint16_t rawx, rawy = 0;
uint32_t calculating_x, calculating_y = 0;
uint32_t samples = NO_OF_POSITION_SAMPLES;
uint32_t counted_samples = 0;
TP_CS_PORT->BRR=TP_CS_PIN;
while((samples > 0)&&((TP_IRQ_PORT->IDR)& TP_IRQ_PIN) == 0)
{
TP_Write(CMD_RDY);
rawy = TP_Read();
avg_y += rawy;
calculating_y += rawy;
TP_Write(CMD_RDX);
rawx = TP_Read();
avg_x += rawx;
calculating_x += rawx;
samples--;
counted_samples++;
};
TP_CS_PORT->BSRR=TP_CS_PIN;
if((counted_samples == NO_OF_POSITION_SAMPLES)&&((TP_IRQ_PORT->IDR)&TP_IRQ_PIN) == 0)
{
calculating_x /= counted_samples;
calculating_y /= counted_samples;
rawx = calculating_x;
rawy = calculating_y;
rawx *= -1;
rawy *= -1;
//CONVERTING 16bit Value to Screen coordinates
// 65535/273 = 240!
// 65535/204 = 320!
Coordinates[0] = ((240 - (rawx/X_TRANSLATION)) - X_OFFSET)*X_MAGNITUDE;
Coordinates[1] = ((rawy/Y_TRANSLATION)- Y_OFFSET)*Y_MAGNITUDE;
return TOUCHPAD_DATA_OK;
}
else
{
Coordinates[0] = 0;
Coordinates[1] = 0;
return TOUCHPAD_DATA_NOISY;
}
}
//Check if Touchpad was pressed. Returns TOUCHPAD_PRESSED (1) or TOUCHPAD_NOT_PRESSED (0)
uint8_t TP_Touchpad_Pressed(void)
{
if((TP_IRQ_PORT->IDR&TP_IRQ_PIN) == 0)
{
return TOUCHPAD_PRESSED;
}
else
{
return TOUCHPAD_NOT_PRESSED;
}
}
Solved! Go to Solution.
2021-03-09 03:42 AM
I defined a dummy variable a and wrote a++ between
TP_CLK_PORT->BRR=TP_CLK_PIN;
and
if ((TP_MISO_PORT->IDR&TP_MISO_PIN)!=0)
It works fine now! my problem is solved. I think the reason it didn't work well was that I was violating the 200ns tCH spec based on the datasheet. the reason that the HAL code worked might be because the HAL code instructions take a longer time to operate.
2021-02-28 03:49 AM
Why this ugly code ??? Try show how HAL you mean
When you comunicate with chip that uses SPI , you need too use SPI , any gpio simulating is trouble
For example how is clock speed and duty when you start write ??
...
TP_CLK_PORT->BSRR=TP_CLK_PIN;
TP_CLK_PORT->BRR=TP_CLK_PIN;
2021-02-28 06:14 AM
I'm sorry I didn't mention that it is only part of the code that is related to touch I didn't bring the part about SPI because that part works fine. I used SPI to communicate with the ili9341 and I am able to draw pixels with the desired color. but for the touch IC, I am using GPIO like this example https://github.com/martnak/STM32-ILI9341
i used macros to rename the pins and the GPIO configuration is in another library which is called by a function in the main I can include it here if you like
#include "stm32f10x.h"
void GPIO_init(void){
RCC->APB2ENR |=(1<<4);
RCC->APB2ENR |=(1<<2);
GPIOC->CRL &=~0xF00FFFFF; //// Clearing C0 to C4
GPIOC->CRL |= 0x30033834; //// configuring C0 input floating , C1 , C3, C4 output pushpull C2 input with pull up/pull down
GPIOC->ODR |=(1<<2); /// making C2 pull up
GPIOC->CRH &=~0xF0000F; /// clearing C13 and C8
GPIOC->CRH |= 0x300003; // C13 and C8 output push pull
}
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f10x.h"
void Error_Handler(void);
/* Private defines -----------------------------------------------------------*/
#define DC_Pin (1<<13)
#define DC_GPIO_Port GPIOC
#define T_IRQ_Pin (1<<0)
#define T_IRQ_GPIO_Port GPIOC
#define T_CLK_Pin (1<<1)
#define T_CLK_GPIO_Port GPIOC
#define T_MISO_Pin (1<<2)
#define T_MISO_GPIO_Port GPIOC
#define T_MOSI_Pin (1<<3)
#define T_MOSI_GPIO_Port GPIOC
#define T_CS_Pin (1<<4)
#define T_CS_GPIO_Port GPIOC
#define CS_Pin (1<<7)
#define CS_GPIO_Port GPIOC
#define RST_Pin (1<<8)
#define RST_GPIO_Port GPIOC
#ifdef __cplusplus
}
#endif
#endif
2021-03-09 03:42 AM
I defined a dummy variable a and wrote a++ between
TP_CLK_PORT->BRR=TP_CLK_PIN;
and
if ((TP_MISO_PORT->IDR&TP_MISO_PIN)!=0)
It works fine now! my problem is solved. I think the reason it didn't work well was that I was violating the 200ns tCH spec based on the datasheet. the reason that the HAL code worked might be because the HAL code instructions take a longer time to operate.