2026-05-16 1:02 PM
Hello all, i have a part of code for the touch screen for the 2478 display.
I have found an example made with Arduino and i have adapted It for stm32, i would like to know if my code Is fine or It has some issues to fix and what u would suggest me to do.
This part Is only for the touch controller of the display but i got several questions, like how many readings i should make from the ADC? rn i do and average basically.
#include "main.h"
#include <stdint.h>
/* ================= CONFIGURAZIONE ================= */
#define LCD_W 320
#define LCD_H 240
// PIN TOUCH (MODIFICA!)
#define X1_PORT GPIOA
#define X1_PIN GPIO_PIN_0
#define X2_PORT GPIOA
#define X2_PIN GPIO_PIN_1
#define Y1_PORT GPIOA
#define Y1_PIN GPIO_PIN_2
#define Y2_PORT GPIOA
#define Y2_PIN GPIO_PIN_3
// CANALI ADC (MODIFICA!)
#define ADC_CH_Y1 ADC_CHANNEL_2
#define ADC_CH_X1 ADC_CHANNEL_0
#define ADC_SAMPLES 8
#define SETTLE_LOOP 3000
/* ================= CALIBRAZIONE ================= */
uint16_t X_MIN = 200, X_MAX = 3800;
uint16_t Y_MIN = 250, Y_MAX = 3750;
/* ================= STRUTTURA ================= */
typedef struct {
uint16_t x_raw;
uint16_t y_raw;
uint16_t x;
uint16_t y;
uint8_t pressed;
} touch_point_t;
touch_point_t tp;
/* ================= GPIO ================= */
static void gpio_out(GPIO_TypeDef* port, uint16_t pin)
{
GPIO_InitTypeDef g = {0};
g.Pin = pin;
g.Mode = GPIO_MODE_OUTPUT_PP;
g.Pull = GPIO_NOPULL;
g.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(port, &g);
}
static void gpio_in_hiz(GPIO_TypeDef* port, uint16_t pin)
{
GPIO_InitTypeDef g = {0};
g.Pin = pin;
g.Mode = GPIO_MODE_INPUT;
g.Pull = GPIO_NOPULL; // Hi-Z
HAL_GPIO_Init(port, &g);
}
static void gpio_analog(GPIO_TypeDef* port, uint16_t pin)
{
GPIO_InitTypeDef g = {0};
g.Pin = pin;
g.Mode = GPIO_MODE_ANALOG;
g.Pull = GPIO_NOPULL;
HAL_GPIO_Init(port, &g);
}
/* ================= ADC ================= */
static void adc_sel(ADC_HandleTypeDef* hadc, uint32_t channel)
{
ADC_ChannelConfTypeDef s = {0};
s.Channel = channel;
s.Rank = ADC_REGULAR_RANK_1;
s.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
HAL_ADC_ConfigChannel(hadc, &s);
}
static uint16_t adc_once(ADC_HandleTypeDef* hadc)
{
HAL_ADC_Start(hadc);
HAL_ADC_PollForConversion(hadc, HAL_MAX_DELAY);
return (uint16_t)HAL_ADC_GetValue(hadc);
}
static uint16_t adc_avg(ADC_HandleTypeDef* hadc, uint8_t n)
{
uint32_t sum = 0;
for (uint8_t i = 0; i < n; i++) {
sum += adc_once(hadc);
}
return (uint16_t)(sum / n);
}
/* ================= UTILS ================= */
static uint16_t clamp_u16(int32_t v, uint16_t lo, uint16_t hi)
{
if (v < lo) return lo;
if (v > hi) return hi;
return (uint16_t)v;
}
static uint16_t map_u16(uint16_t v, uint16_t in_min, uint16_t in_max, uint16_t out_max)
{
if (in_max <= in_min) return 0;
int32_t r = (int32_t)(v - in_min) * out_max / (in_max - in_min);
if (r < 0) r = 0;
if (r > out_max) r = out_max;
return (uint16_t)r;
}
/* ================= LETTURA X ================= */
static uint16_t read_x_raw(ADC_HandleTypeDef* hadc)
{
gpio_analog(Y1_PORT, Y1_PIN);
adc_sel(hadc, ADC_CH_Y1);
gpio_in_hiz(Y2_PORT, Y2_PIN);
gpio_out(X1_PORT, X1_PIN);
HAL_GPIO_WritePin(X1_PORT, X1_PIN, GPIO_PIN_SET);
gpio_out(X2_PORT, X2_PIN);
HAL_GPIO_WritePin(X2_PORT, X2_PIN, GPIO_PIN_RESET);
for (volatile int i = 0; i < SETTLE_LOOP; i++);
return adc_avg(hadc, ADC_SAMPLES);
}
/* ================= LETTURA Y ================= */
static uint16_t read_y_raw(ADC_HandleTypeDef* hadc)
{
gpio_analog(X1_PORT, X1_PIN);
adc_sel(hadc, ADC_CH_X1);
gpio_in_hiz(X2_PORT, X2_PIN);
gpio_out(Y1_PORT, Y1_PIN);
HAL_GPIO_WritePin(Y1_PORT, Y1_PIN, GPIO_PIN_SET);
gpio_out(Y2_PORT, Y2_PIN);
HAL_GPIO_WritePin(Y2_PORT, Y2_PIN, GPIO_PIN_RESET);
for (volatile int i = 0; i < SETTLE_LOOP; i++);
return adc_avg(hadc, ADC_SAMPLES);
}
/* ================= FUNZIONE PRINCIPALE ================= */
void touch_read(ADC_HandleTypeDef* hadc)
{
uint16_t xr = read_x_raw(hadc);
uint16_t yr = read_y_raw(hadc);
tp.x_raw = xr;
tp.y_raw = yr;
// Detect touch
if (xr < (X_MIN - 50) || xr > (X_MAX + 50) ||
yr < (Y_MIN - 50) || yr > (Y_MAX + 50))
{
tp.pressed = 0;
tp.x = 0;
tp.y = 0;
return;
}
tp.pressed = 1;
xr = clamp_u16(xr, X_MIN, X_MAX);
yr = clamp_u16(yr, Y_MIN, Y_MAX);
tp.x = map_u16(xr, X_MIN, X_MAX, LCD_W - 1);
tp.y = map_u16(yr, Y_MIN, Y_MAX, LCD_H - 1);
}