cancel
Showing results for 
Search instead for 
Did you mean: 

Touch controller on 2478 Adafruit display and ADC reading

clar123
Associate

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);
}
 

 

 

0 REPLIES 0