Regarding ADS7846 touchscreen controller

Hi Team,

I’m working on verdin AM62 integrated on verdin development board. I’m connecting a 3.5” MSP3520 TFT display which supports touch facility via SPI3. ADS7846 is the touch controller. Luckily, the ads7846 driver is available in the torizon linux kernel. I used this in my overlay to enable my touchscreen.

Overlay for my tft display:-

🐧 root @GalaxyBook/home/Meenakshy/Projects/SPI_TFT_Display/tcbdir: cat device-trees/overlays/verdin-am62_msp3520_tft_display_spi3_overlay.dts 
/dts-v1/;
/plugin/;

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include "k3-pinctrl.h"

/ {
    compatible = "toradex,verdin-am62";
};

/* Disable HDMI connector */
&{/hdmi-connector} {
    status = "disabled";
};

/* Disable the HDMI bridge on I2C1 */
&{/bus@f0000/i2c@20010000/hdmi@48} {
    status = "disabled";
};

/* Disable connector that uses conflicting pins */
&{/connector} {
    status = "disabled";
};

/* Disable PWM modules */
&epwm0 {
    status = "disabled";
};

&epwm1 {
    status = "disabled";
};

/* Pin configuration for SPI0 (Verdin SPI_3) */
&main_pmx0 {
    spi3_pins_default: spi3-default-pins {
        pinctrl-single,pins = <
            AM62X_IOPAD(0x01bc, PIN_OUTPUT, 0) /* (A14) SPI0_CLK - SODIMM 19 */
            AM62X_IOPAD(0x01b4, PIN_OUTPUT, 0) /* (A13) SPI0_CS0 - SODIMM 15 */
            AM62X_IOPAD(0x01b8, PIN_OUTPUT, 0) /* (C13) SPI0_CS1 - SODIMM 16 */
            AM62X_IOPAD(0x01c4, PIN_OUTPUT, 0) /* (B14) SPI0_D1 - MOSI - SODIMM 161 */
            AM62X_IOPAD(0x01c0, PIN_INPUT, 0)  /* (B13) SPI0_D0 - MISO - SODIMM 66 */
        >;
    };
};

/* MCU GPIO pins configuration */
&mcu_pmx0 {
    /* SODIMM 206 - DC pin - gpio-532 (line 1) */
    pinctrl_sodimm_206_gpio: sodimm-206-gpio-pins {
        pinctrl-single,pins = <
            AM62X_MCU_IOPAD(0x0004, PIN_OUTPUT, 7) /* MCU_GPIO0_1 - SODIMM 206 */
        >;
    };
    
    /* SODIMM 208 - Reset pin - gpio-533 (line 2) */
    pinctrl_sodimm_208_gpio: sodimm-208-gpio-pins {
        pinctrl-single,pins = <
            AM62X_MCU_IOPAD(0x0008, PIN_OUTPUT, 7) /* MCU_GPIO0_2 - SODIMM 208 */
        >;
    };
    
    /* SODIMM 210 - Backlight pin - gpio-534 (line 3) */
    pinctrl_sodimm_210_gpio: sodimm-210-gpio-pins {
        pinctrl-single,pins = <
            AM62X_MCU_IOPAD(0x000c, PIN_OUTPUT, 7) /* MCU_GPIO0_3 - SODIMM 210 */
        >;
    };
    
    /* SODIMM 212 - Touch interrupt - gpio-535 (line 4) */
    pinctrl_sodimm_212_gpio: sodimm-212-gpio-pins {
        pinctrl-single,pins = <
            AM62X_MCU_IOPAD(0x0010, PIN_INPUT, 7) /* MCU_GPIO0_4 - SODIMM 212 */
        >;
    };
};

/* Enable MCU GPIO controller with all pin groups */
&mcu_gpio0 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_sodimm_206_gpio>,
                <&pinctrl_sodimm_208_gpio>,
                <&pinctrl_sodimm_210_gpio>,
                <&pinctrl_sodimm_212_gpio>;
};

/* Configure SPI0 for display and touchscreen */
&main_spi0 {
    pinctrl-names = "default";
    pinctrl-0 = <&spi3_pins_default>;
    status = "okay";
    ti,spi-num-cs = <2>;
    #address-cells = <1>;
    #size-cells = <0>;
    
    /* MSP3520 Display on CS0 */
    msp3520_display@0 {
        compatible = "rohm,dh2228fv";
        reg = <0>;
        spi-max-frequency = <32000000>;
        reset-gpios = <&mcu_gpio0 2 GPIO_ACTIVE_LOW>;   /* SODIMM 208 - Line 2 */
        dc-gpios = <&mcu_gpio0 1 GPIO_ACTIVE_HIGH>;     /* SODIMM 206 - Line 1 */
        led-gpios = <&mcu_gpio0 3 GPIO_ACTIVE_HIGH>;    /* SODIMM 210 - Line 3 */
    };
  
  
    /* ADS7846 Touchscreen on CS1 */
    msp3520_touch@1 {
        compatible = "ti,ads7846";
        reg = <1>;
        spi-max-frequency = <2000000>;
        vcc-supply = <&reg_3v3>;
        
        /* CRITICAL: ADD SPI MODE CONFIGURATION */
        /*spi-cpol;*/      /* Clock polarity low */
        /*spi-cpha;    */  /* Clock phase - sample on first edge */
        /* This combination gives SPI Mode 0 */

        interrupt-parent = <&mcu_gpio0>;
        interrupts = <4 IRQ_TYPE_EDGE_FALLING>;        /* SODIMM 212 - Line 4 */
        pendown-gpio = <&mcu_gpio0 4 GPIO_ACTIVE_LOW>; /* SODIMM 212 - Line 4 */
        
        ti,x-plate-ohms = /bits/ 16 <400>;
        ti,y-plate-ohms = /bits/ 16 <400>;
        ti,pressure-max = /bits/ 16 <150>;                                      
        
        ti,x-min = /bits/ 16 <0>;
        ti,x-max = /bits/ 16 <4095>; 
        ti,y-min = /bits/ 16 <0>;
        ti,y-max = /bits/ 16 <4095>;
        
        ti,settle-delay-usec = /bits/ 16 <150>;
        ti,penirq-recheck-delay-usecs = /bits/ 16 <100>;
        ti,vref-delay-usecs = /bits/ 16 <100>;
        ti,vref-mv = /bits/ 16 <3300>;
        
        ti,debounce-rep = /bits/ 16 <3>;
        ti,debounce-tol = /bits/ 16 <25>;
        ti,debounce-max = /bits/ 16 <3>;
        
        ti,keep-vref-on;
        wakeup-source;
    };
};
🐧 root @GalaxyBook/home/Meenakshy/Projects/SPI_TFT_Display/tcbdir: 

Now I could see interrupt count is increasing, when I touch the screen

torizon@verdin-am62-15415886:~$ cat /proc/interrupts | grep ads7846
312:          0          1      GPIO   4 Edge    -davinci_gpio  ads7846
torizon@verdin-am62-15415886:~$ cat /proc/interrupts | grep ads7846
312:        872          1      GPIO   4 Edge    -davinci_gpio  ads7846
torizon@verdin-am62-15415886:~$

Also, evtest is also working. But evtest is giving output for some touch. It’s output is not consistent

torizon@verdin-am62-15415886:~$ evtest /dev/input/event2
Input driver version is 1.0.1
Input device ID: bus 0x1c vendor 0x0 product 0x1ea6 version 0x0
Input device name: "ADS7846 Touchscreen"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 330 (BTN_TOUCH)
  Event type 3 (EV_ABS)
    Event code 0 (ABS_X)
      Value      8
      Min        0
      Max     4095
    Event code 1 (ABS_Y)
      Value      1
      Min        0
      Max     4095
    Event code 24 (ABS_PRESSURE)
      Value      0
      Min        0
      Max      150
Properties:
Testing ... (interrupt to exit)
Event: time 1764068211.307261, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
Event: time 1764068211.307261, type 3 (EV_ABS), code 0 (ABS_X), value 4
Event: time 1764068211.307261, type 3 (EV_ABS), code 1 (ABS_Y), value 6
Event: time 1764068211.307261, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 146
Event: time 1764068211.307261, -------------- SYN_REPORT ------------
Event: time 1764068212.945771, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0
Event: time 1764068212.945771, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 0
Event: time 1764068212.945771, -------------- SYN_REPORT ------------
Event: time 1764068216.638363, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
Event: time 1764068216.638363, type 3 (EV_ABS), code 1 (ABS_Y), value 1
Event: time 1764068216.638363, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 147
Event: time 1764068216.638363, -------------- SYN_REPORT ------------
Event: time 1764068217.235656, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0
Event: time 1764068217.235656, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 0
Event: time 1764068217.235656, -------------- SYN_REPORT ------------
Event: time 1764068248.968563, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
Event: time 1764068248.968563, type 3 (EV_ABS), code 0 (ABS_X), value 1
Event: time 1764068248.968563, type 3 (EV_ABS), code 1 (ABS_Y), value 2
Event: time 1764068248.968563, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 149
Event: time 1764068248.968563, -------------- SYN_REPORT ------------
Event: time 1764068249.605655, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0
Event: time 1764068249.605655, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 0
Event: time 1764068249.605655, -------------- SYN_REPORT ------------

Also, pendown value is 1 for some touch, otherwise 0.
cat /sys/bus/spi/devices/spi0.1/pen_down

How to resolve this issue? Why this is giving output for some touch?

Thanks & Regards,
Meenakshy

Hi, I’m the Toradex AI Assistant.

I might make mistakes or occasionally get you wrong. Our support team will step in if needed.


ADS7846 Touchscreen Inconsistent Response Issue

Based on your device tree overlay and the symptoms you’re describing, the inconsistent touch response is likely related to SPI configuration and calibration parameters. Let me help you troubleshoot this systematically.

Root Cause Analysis

The inconsistent touch response typically stems from:

  1. SPI timing and mode configuration issues
  2. Incorrect debounce and settling parameters
  3. Power supply stability problems
  4. Calibration range mismatches

Recommended Solutions

1. SPI Configuration Optimization

Your overlay shows commented SPI mode settings. For ADS7846, you should explicitly configure SPI Mode 0 (1):

/* ADS7846 Touchscreen on CS1 */
msp3520_touch@1 {
    compatible = "ti,ads7846";
    reg = <1>;
    spi-max-frequency = <1000000>;  /* Reduce from 2MHz to 1MHz */
    vcc-supply = <&reg_3v3>;
    
    /* Enable SPI Mode 0 explicitly */
    spi-cpol;      /* Clock polarity */
    spi-cpha;      /* Clock phase */

(1)

2. Timing Parameter Adjustments

Modify these critical timing parameters in your overlay:

    ti,settle-delay-usec = /bits/ 16 <500>;        /* Increase from 150 */
    ti,penirq-recheck-delay-usecs = /bits/ 16 <200>; /* Increase from 100 */
    ti,vref-delay-usecs = /bits/ 16 <200>;         /* Increase from 100 */
    
    ti,debounce-rep = /bits/ 16 <5>;               /* Increase from 3 */
    ti,debounce-tol = /bits/ 16 <50>;              /* Increase from 25 */
    ti,debounce-max = /bits/ 16 <5>;               /* Increase from 3 */

3. Power Supply Verification

Ensure stable 3.3V supply to the touchscreen controller. The vcc-supply = <&reg_3v3>; reference should point to a clean, stable regulator (1).

4. Interrupt Configuration Check

Your interrupt configuration looks correct, but verify the GPIO line state:

# Check GPIO line 4 state
gpioget gpiochip0 4

5. Pin Multiplexing Verification

According to the Toradex documentation, when creating custom pin groups, you should ensure no conflicts exist (2). Verify that SODIMM 212 (MCU_GPIO0_4) isn’t being used elsewhere:

&mcu_pmx0 {
    pinctrl_sodimm_212_gpio: sodimm-212-gpio-pins {
        pinctrl-single,pins = <
            AM62X_MCU_IOPAD(0x0010, PIN_INPUT, 7) /* MCU_GPIO0_4 - SODIMM 212 */
        >;
    };
};

(2)

6. Calibration Range Adjustment

Your current calibration uses the full ADC range (0-4095). Try narrowing this based on your actual touch area:

    ti,x-min = /bits/ 16 <200>;
    ti,x-max = /bits/ 16 <3800>; 
    ti,y-min = /bits/ 16 <200>;
    ti,y-max = /bits/ 16 <3800>;

Debugging Steps

  1. Monitor SPI communication:

    # Check SPI device registration
    ls -la /sys/bus/spi/devices/spi0.1/
    
  2. Verify driver loading:

    lsmod | grep ads7846
    dmesg | grep ads7846
    
  3. Test with reduced frequency:
    Lower the spi-max-frequency to 500kHz initially to rule out timing issues (1).

Expected Outcome

After implementing these changes and rebuilding your TorizonCore image with TorizonCore Builder, you should see:

  • Consistent touch events in evtest
  • Stable pen_down values
  • Improved touch accuracy and responsiveness

The device tree overlay approach you’re using follows the proper Toradex methodology for enabling custom peripherals (2), so the foundation is solid—it just needs fine-tuning of the timing and configuration parameters.

Best regards,
Toradex AI Assistant.


Did you like my answer? :+1: :-1:

If I answered your question, please tick the “Solution” checkbox.

For follow-up questions to me, please use @ToradexAI in your post.

@ToradexAI I tried with the recommended solution provided by Toradex AI assistant.
When I made spi_speed to 500KHz and made the changes that AI suggested, I didn’t get any output for evtest.
But when I use my old spi_speed as 2MHz, I could see output for some touch.
Even though, there is no output for all evtest.

Hi @Meenakshy!

It’s hard to investigate your issue since you’re working with a customized setup, and we don’t have the necessary hardware (ADS7846 and the display) to test it.

The answer given by the Toradex AI has some good starting points to narrow down the issue.

That said, we’re keen to help you move forward as efficiently as possible. In similar cases, we typically recommend working with one of our specialized partners who can provide more targeted support. For advanced device tree work or kernel modifications, our Software Services Partners can offer hands-on assistance tailored to your specific application.

Best regards.