Added PiTFT V2 and stripping out old stuff

This commit is contained in:
Melissa LeBlanc-Williams 2025-07-09 14:52:51 -07:00
parent 923d409ffd
commit 160bf98cff
13 changed files with 1335 additions and 84 deletions

1007
adafruit-pitft-old.py Normal file

File diff suppressed because it is too large Load diff

View file

@ -19,12 +19,44 @@ except ImportError:
shell = Shell() shell = Shell()
shell.group = 'PITFT' shell.group = 'PITFT'
__version__ = "3.9.0" __version__ = "4.0.0"
""" """
This is the main configuration. Displays should be placed in the order This is the main configuration. Displays should be placed in the order
they are to appear in the menu. they are to appear in the menu.
Config Parameters:
REQUIRED fields:
type: Unique identifier for the display type.
menulabel: The label to display in the menu.
product: The product name for the display.
kernel_upgrade: Whether the kernel needs to be upgraded for this display.
overlay: The overlay string to apply for the display.
width: Width of the display in pixels.
height: Height of the display in pixels.
OPTIONAL fields:
touchscreen: Dictionary containing touchscreen settings for displays with touchscreens.
identifier: Name of the touchscreen calibration.
product: Product name for the touchscreen.
transforms: X11 transforms for different rotations.
overlay_params: Overlay parameters for different rotations.
calibrations: Calibration data for the touchscreen. Can be overall or per rotation.
overlay_drm_option: Optional parameter to add for DRM support.
overlay_src: Source path for the overlay file (if applicable).
overlay_dest: Destination path for the compiled overlay file (if applicable).
mipi_data (Optional): Dictionary containing MIPI display data.
command_bin: Name of the command binary for MIPI.
gpio: GPIO settings for the display.
viewport: Viewport settings for different rotations.
use_kms: Whether to use KMS for the display.
""" """
# Touchscreen Products
TS_STMPE = "stmpe"
TS_TSC2007 = "tsc2007"
TS_FOCALTOUCH = "EP0110M09"
config = [ config = [
{ {
"type": "28r", "type": "28r",
@ -33,7 +65,8 @@ config = [
"kernel_upgrade": False, "kernel_upgrade": False,
"touchscreen": { "touchscreen": {
"identifier": "STMPE Touchscreen Calibration", "identifier": "STMPE Touchscreen Calibration",
"product": "stmpe", "product": TS_STMPE,
# X11 Transforms
"transforms": { "transforms": {
"0": "0.988809 -0.023645 0.060523 -0.028817 1.003935 0.034176 0 0 1", "0": "0.988809 -0.023645 0.060523 -0.028817 1.003935 0.034176 0 0 1",
"90": "0.014773 -1.132874 1.033662 1.118701 0.009656 -0.065273 0 0 1", "90": "0.014773 -1.132874 1.033662 1.118701 0.009656 -0.065273 0 0 1",
@ -46,16 +79,15 @@ config = [
"180": "touch-invx,touch-invy", "180": "touch-invx,touch-invy",
"270": "touch-swapxy,touch-invy", "270": "touch-swapxy,touch-invy",
}, },
"calibrations": {
"0": "4232 11 -879396 1 5786 -752768 65536",
"90": "33 -5782 21364572 4221 35 -1006432 65536",
"180": "-4273 61 16441290 4 -5772 21627524 65536",
"270": "-9 5786 -784608 -4302 19 16620508 65536",
},
}, },
"overlay": "dtoverlay=pitft28-resistive,rotate={pitftrot},speed=64000000,fps=30", "overlay": "dtoverlay=pitft28-resistive,rotate={pitftrot},speed=64000000,fps=30",
"overlay_drm_option": "drm", "overlay_drm_option": "drm",
"force_x11": True,
"calibrations": {
"0": "4232 11 -879396 1 5786 -752768 65536",
"90": "33 -5782 21364572 4221 35 -1006432 65536",
"180": "-4273 61 16441290 4 -5772 21627524 65536",
"270": "-9 5786 -784608 -4302 19 16620508 65536",
},
"width": 320, "width": 320,
"height": 240, "height": 240,
}, },
@ -76,7 +108,8 @@ config = [
"kernel_upgrade": False, "kernel_upgrade": False,
"touchscreen": { "touchscreen": {
"identifier": "FocalTech Touchscreen Calibration", "identifier": "FocalTech Touchscreen Calibration",
"product": "EP0110M09", "product": TS_FOCALTOUCH,
# X11 Transforms
"transforms": { "transforms": {
"0": "-1 0 1 0 -1 1 0 0 1", "0": "-1 0 1 0 -1 1 0 0 1",
"90": "0 1 0 -1 0 1 0 0 1", "90": "0 1 0 -1 0 1 0 0 1",
@ -89,11 +122,10 @@ config = [
"180": None, "180": None,
"270": "touch-swapxy,touch-invx", "270": "touch-swapxy,touch-invx",
}, },
"calibrations": "320 65536 0 -65536 0 15728640 65536",
}, },
"overlay": "dtoverlay=pitft28-capacitive,rotate={pitftrot},speed=64000000,fps=30", "overlay": "dtoverlay=pitft28-capacitive,rotate={pitftrot},speed=64000000,fps=30",
"overlay_drm_option": "drm", "overlay_drm_option": "drm",
"force_x11": True,
"calibrations": "320 65536 0 -65536 0 15728640 65536",
"width": 320, "width": 320,
"height": 240, "height": 240,
}, },
@ -104,7 +136,8 @@ config = [
"kernel_upgrade": False, "kernel_upgrade": False,
"touchscreen": { "touchscreen": {
"identifier": "STMPE Touchscreen Calibration", "identifier": "STMPE Touchscreen Calibration",
"product": "stmpe", "product": TS_STMPE,
# X11 Transforms
"transforms": { "transforms": {
"0": "-1.098388 0.003455 1.052099 0.005512 -1.093095 1.026309 0 0 1", "0": "-1.098388 0.003455 1.052099 0.005512 -1.093095 1.026309 0 0 1",
"90": "-0.000087 1.094214 -0.028826 -1.091711 -0.004364 1.057821 0 0 1", "90": "-0.000087 1.094214 -0.028826 -1.091711 -0.004364 1.057821 0 0 1",
@ -117,16 +150,15 @@ config = [
"180": "touch-invx,touch-invy", "180": "touch-invx,touch-invy",
"270": "touch-swapxy,touch-invy", "270": "touch-swapxy,touch-invy",
}, },
"calibrations": {
"0": "5724 -6 -1330074 26 8427 -1034528 65536",
"90": "5 8425 -978304 -5747 61 22119468 65536",
"180": "-5682 -1 22069150 13 -8452 32437698 65536",
"270": "3 -8466 32440206 5703 -1 -1308696 65536",
},
}, },
"overlay": "dtoverlay=pitft35-resistive,rotate={pitftrot},speed=20000000,fps=20", "overlay": "dtoverlay=pitft35-resistive,rotate={pitftrot},speed=20000000,fps=20",
"overlay_drm_option": "drm", "overlay_drm_option": "drm",
"force_x11": True,
"calibrations": {
"0": "5724 -6 -1330074 26 8427 -1034528 65536",
"90": "5 8425 -978304 -5747 61 22119468 65536",
"180": "-5682 -1 22069150 13 -8452 32437698 65536",
"270": "3 -8466 32440206 5703 -1 -1308696 65536",
},
"width": 480, "width": 480,
"height": 320, "height": 320,
"x11_scale": 1.5, "x11_scale": 1.5,
@ -247,6 +279,35 @@ config = [
"270": "3", "270": "3",
}, },
}, },
{
"type": "24v2",
"menulabel": "PiTFT 2.4\" V2 resistive (240x320)",
"product": "2.4\" V2 resistive",
"kernel_upgrade": False,
"overlay_src": "overlays/pitft24v2-tsc2007-overlay.dts",
"overlay_dest": "{boot_dir}/overlays/pitft24v2.dtbo",
"touchscreen": {
"identifier": "TSC2007 Touchscreen Calibration",
"product": TS_TSC2007,
"transforms": {
# TODO: Test because 0 and 180 may be reversed
"0": "-1 0 1 0 -1 1",
"90": "0 1 0 -1 0 1",
"180": "1 0 0 0 1 0",
"270": "0 -1 1 1 0 0",
},
"calibrations": {
"0": "4232 11 -879396 1 5786 -752768 65536",
"90": "33 -5782 21364572 4221 35 -1006432 65536",
"180": "-4273 61 16441290 4 -5772 21627524 65536",
"270": "-9 5786 -784608 -4302 19 16620508 65536",
},
},
"overlay": "dtoverlay=pitft24v2,rotate={pitftrot},fps=60",
"overlay_drm_option": "drm",
"width": 320,
"height": 240,
},
] ]
# default rotations # default rotations
@ -277,12 +338,12 @@ def warn_exit(message):
shell.warn(message) shell.warn(message)
shell.exit(1) shell.exit(1)
def uninstall_cb(ctx, param, value): def uninstall_cb(ctx, _param, value):
if not value or ctx.resilient_parsing: if not value or ctx.resilient_parsing:
return return
uninstall() uninstall()
def print_version(ctx, param, value): def print_version(ctx, _param, value):
if not value or ctx.resilient_parsing: if not value or ctx.resilient_parsing:
return return
print("Adafruit PiTFT Helper v{}".format(__version__)) print("Adafruit PiTFT Helper v{}".format(__version__))
@ -311,6 +372,7 @@ def sysupdate():
############################ Sub-Scripts ############################ ############################ Sub-Scripts ############################
def is_wayland(): def is_wayland():
"Check if the current session is Wayland"
username = os.environ["SUDO_USER"] username = os.environ["SUDO_USER"]
output = shell.run_command("loginctl show-session $(loginctl | grep $(whoami) | awk '{print $1}') -p Type | grep wayland", suppress_message=True, return_output=True, run_as_user=username).strip() output = shell.run_command("loginctl show-session $(loginctl | grep $(whoami) | awk '{print $1}') -p Type | grep wayland", suppress_message=True, return_output=True, run_as_user=username).strip()
return len(output) > 0 return len(output) > 0
@ -423,34 +485,29 @@ def update_configtxt(rotation_override=None, tinydrm_install=False):
if "gpio" in mipi_data: if "gpio" in mipi_data:
overlay += f"\ndtparam={mipi_data['gpio']}" overlay += f"\ndtparam={mipi_data['gpio']}"
if tinydrm_install and "overlay_drm_option" in pitft_config: if tinydrm_install: # Wayland ignores X11 Transformations, so use overlay params instead
overlay += "," + pitft_config["overlay_drm_option"] overlay += ",drm"
if tinydrm_install: # Wayland ignores X11 Transformations, so use params instead
if "overlay_params" in pitft_config and pitftrot in pitft_config["overlay_params"] and pitft_config["overlay_params"][pitftrot] is not None: if "overlay_params" in pitft_config and pitftrot in pitft_config["overlay_params"] and pitft_config["overlay_params"][pitftrot] is not None:
overlay += "," + pitft_config["overlay_params"][pitftrot] overlay += "," + pitft_config["overlay_params"][pitftrot]
shell.write_text_file(f"{boot_dir}/config.txt", """ config_text_base = shell.load_template("templates/config_text_base.txt", date=shell.date(), overlay=overlay)
# --- added by adafruit-pitft-helper {date} --- shell.write_text_file(f"{boot_dir}/config.txt", config_text_base)
[all]
hdmi_force_hotplug=1 # required for cases when HDMI is not plugged in!
dtparam=spi=on
dtparam=i2c1=on
dtparam=i2c_arm=on
{overlay}
# --- end adafruit-pitft-helper {date} ---
""".format(date=shell.date(), overlay=overlay))
return True return True
def update_udev(): def update_udev():
shell.write_text_file("/etc/udev/rules.d/95-touchmouse.rules", """ product = None
SUBSYSTEM=="input", ATTRS{name}=="touchmouse", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen" if "touchscreen" in pitft_config and "product" in pitft_config["touchscreen"]:
""", append=False) product = pitft_config["touchscreen"]["product"]
shell.write_text_file("/etc/udev/rules.d/95-ftcaptouch.rules", """ shell.write_templated_file("/etc/udev/rules.d/", "templates/95-touchmouse.rules")
SUBSYSTEM=="input", ATTRS{name}=="EP0110M09", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen" if product == TS_FOCALTOUCH:
SUBSYSTEM=="input", ATTRS{name}=="generic ft5x06*", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen" shell.write_templated_file("/etc/udev/rules.d/", "templates/95-ftcaptouch.rules")
""", append=False) elif product == TS_STMPE:
shell.write_text_file("/etc/udev/rules.d/95-stmpe.rules", """ shell.write_templated_file("/etc/udev/rules.d/", "templates/95-stmpe.rules")
SUBSYSTEM=="input", ATTRS{name}=="*stmpe*", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen" elif product == TS_TSC2007:
""", append=False) calibration_matrix = "0 1 0 -1 0 1" # Default calibration matrix
if "transforms" in pitft_config["touchscreen"] and pitftrot in pitft_config["touchscreen"]["transforms"]:
calibration_matrix = pitft_config["touchscreen"]["transforms"][pitftrot]
shell.write_templated_file("/etc/udev/rules.d/", "templates/99-tsc2007-touchscreen.rules", calibration_matrix=calibration_matrix)
shell.write_templated_file("/etc/udev/rules.d/", "templates/99-tsc2007-touchscreen-drm.rules")
return True return True
def compile_display_fw(): def compile_display_fw():
@ -473,33 +530,32 @@ def compile_display_fw():
return True return True
def update_pointercal(): def update_pointercal():
if "calibrations" in pitft_config: if "touchscreen" in pitft_config and "calibrations" in pitft_config["touchscreen"]:
if isinstance(pitft_config["calibrations"], dict): if isinstance(pitft_config["touchscreen"]["calibrations"], dict):
shell.write_text_file("/etc/pointercal", pitft_config["calibrations"][pitftrot]) shell.write_text_file("/etc/pointercal", pitft_config["touchscreen"]["calibrations"][pitftrot])
else: else:
shell.write_text_file("/etc/pointercal", pitft_config["calibrations"]) shell.write_text_file("/etc/pointercal", pitft_config["touchscreen"]["calibrations"])
return True return True
def install_console(): def install_console():
print("Set up main console turn on") print("Installing console fbcon map helper...")
if not shell.pattern_search(f"{boot_dir}/cmdline.txt", 'fbcon=map:10 fbcon=font:VGA8x8'): shell.copy("con2fbmap-helper.sh", "/usr/local/bin/")
print(f"Updating {boot_dir}/cmdline.txt") shell.chmod("/usr/local/bin/con2fbmap-helper.sh", "+x")
shell.pattern_replace(f"{boot_dir}/cmdline.txt", "rootwait", "rootwait fbcon=map:10 fbcon=font:VGA8x8")
else: print("Installing console fbcon map service...")
print(f"{boot_dir}/cmdline.txt already updated") shell.copy("con2fbmap.service", "/etc/systemd/system/")
shell.run_command("systemctl daemon-reload")
shell.run_command("systemctl restart con2fbmap.service")
print("Turning off console blanking") print("Turning off console blanking")
# removing old versions
# pre-stretch this is what you'd do:
if shell.exists("/etc/kbd/config"):
shell.pattern_replace("/etc/kbd/config", "BLANK_TIME=.*", "BLANK_TIME=0")
# as of stretch....
# removing any old version
shell.pattern_replace("/etc/rc.local", '# disable console blanking.*') shell.pattern_replace("/etc/rc.local", '# disable console blanking.*')
shell.pattern_replace("/etc/rc.local", 'sudo sh -c "TERM=linux setterm -blank.*') shell.pattern_replace("/etc/rc.local", 'sudo sh -c "TERM=linux setterm -blank.*')
# adding new version
shell.pattern_replace("/etc/rc.local", '^exit 0', "# disable console blanking on PiTFT\\nsudo sh -c \"TERM=linux setterm -blank 0 >/dev/tty0\"\\nexit 0") shell.pattern_replace("/etc/rc.local", '^exit 0', "# disable console blanking on PiTFT\\nsudo sh -c \"TERM=linux setterm -blank 0 >/dev/tty0\"\\nexit 0")
# Set the console font to Terminus 6x12
shell.reconfig("/etc/default/console-setup", "^.*FONTFACE.*$", "FONTFACE=\"Terminus\"") shell.reconfig("/etc/default/console-setup", "^.*FONTFACE.*$", "FONTFACE=\"Terminus\"")
shell.reconfig("/etc/default/console-setup", "^.*FONTSIZE.*$", "FONTSIZE=\"6x12\"") shell.reconfig("/etc/default/console-setup", "^.*FONTSIZE.*$", "FONTSIZE=\"6x12\"")
@ -514,9 +570,15 @@ def install_console():
def uninstall_console(): def uninstall_console():
print(f"Removing console fbcon map from {boot_dir}/cmdline.txt") print(f"Removing console fbcon map from {boot_dir}/cmdline.txt")
shell.pattern_replace(f"{boot_dir}/cmdline.txt", 'rootwait fbcon=map:10 fbcon=font:VGA8x8', 'rootwait') shell.pattern_replace(f"{boot_dir}/cmdline.txt", 'rootwait fbcon=map:10 fbcon=font:VGA8x8', 'rootwait')
print("Screen blanking time reset to 10 minutes")
if shell.exists("/etc/kbd/config"): print("Removing console fbcon map service...")
shell.pattern_replace(f"{boot_dir}/cmdline.txt", 'BLANK_TIME=0', 'BLANK_TIME=10') shell.run_command("systemctl stop con2fbmap.service")
shell.run_command("systemctl disable con2fbmap.service")
shell.remove("/etc/systemd/system/con2fbmap.service")
print("Removing console fbcon map helper...")
shell.remove("/usr/local/bin/con2fbmap-helper.sh")
shell.pattern_replace("/etc/rc.local", '^# disable console blanking.*') shell.pattern_replace("/etc/rc.local", '^# disable console blanking.*')
shell.pattern_replace("/etc/rc.local", '^sudo sh -c "TERM=linux.*') shell.pattern_replace("/etc/rc.local", '^sudo sh -c "TERM=linux.*')
return True return True
@ -568,7 +630,7 @@ def install_fbcp():
shell.bail("Unable to install fbcp unit file") shell.bail("Unable to install fbcp unit file")
shell.run_command("sudo systemctl enable fbcp.service") shell.run_command("sudo systemctl enable fbcp.service")
# if there's X11 installed... # if desktop environment is installed...
if shell.exists("/etc/lightdm"): if shell.exists("/etc/lightdm"):
print("Setting raspi-config to boot to desktop w/o login...") print("Setting raspi-config to boot to desktop w/o login...")
shell.run_command("raspi-config nonint do_boot_behaviour B4") shell.run_command("raspi-config nonint do_boot_behaviour B4")
@ -636,19 +698,7 @@ scale = {scale}
def install_fbcp_unit(): def install_fbcp_unit():
shell.write_text_file("/etc/systemd/system/fbcp.service", shell.write_templated_file("/etc/systemd/system/", "templates/fbcp.service")
"""[Unit]
Description=Framebuffer copy utility for PiTFT
After=network.target
[Service]
Type=simple
ExecStartPre=/bin/sleep 10
ExecStart=/usr/local/bin/fbcp
[Install]
WantedBy=multi-user.target
""", append=False)
return True return True
def uninstall_fbcp(): def uninstall_fbcp():
@ -684,7 +734,8 @@ def update_xorg(tinydrm_install=False):
if not tinydrm_install and "old_transforms" in pitft_config["touchscreen"]: if not tinydrm_install and "old_transforms" in pitft_config["touchscreen"]:
transform_setting = pitft_config["touchscreen"]["old_transforms"][pitftrot] transform_setting = pitft_config["touchscreen"]["old_transforms"][pitftrot]
transform = f"Option \"TransformationMatrix\" \"{transform_setting}\"" transform = f"Option \"TransformationMatrix\" \"{transform_setting}\""
shell.write_text_file("/usr/share/X11/xorg.conf.d/20-calibration.conf", """ if shell.exists("/usr/share/X11/xorg.conf.d"):
shell.write_text_file("/usr/share/X11/xorg.conf.d/20-calibration.conf", """
Section "InputClass" Section "InputClass"
Identifier "{identifier}" Identifier "{identifier}"
MatchProduct "{product}" MatchProduct "{product}"
@ -804,10 +855,6 @@ Run time of up to 5 minutes. Reboot required!
print("Display Type: {}".format(pitft_config["menulabel"])) print("Display Type: {}".format(pitft_config["menulabel"]))
if is_kernel_upgrade_required(): if is_kernel_upgrade_required():
print("WARNING! WILL UPGRADE YOUR KERNEL TO LATEST") print("WARNING! WILL UPGRADE YOUR KERNEL TO LATEST")
if "force_x11" in pitft_config and pitft_config["force_x11"] and wayland:
if not interactive or shell.prompt("This display works better with X11, but Wayland is currently running. Use X11 instead? (Recommended)", default="y"):
shell.set_window_manager("x11")
wayland = False
if display in [str(x) for x in range(1, len(config) + 1)]: if display in [str(x) for x in range(1, len(config) + 1)]:
select_display(config[int(display) - 1]) select_display(config[int(display) - 1])

25
con2fbmap-helper.sh Normal file
View file

@ -0,0 +1,25 @@
#!/bin/bash
# Wait for TFT framebuffer to be ready
echo "Waiting for SPI TFT framebuffer..."
# Wait up to 30 seconds for /dev/fb0 or /dev/fb1 to appear
for i in {1..300}; do
for fbdev in 0 1; do
if [ -e /dev/fb$fbdev ]; then
echo "Found /dev/fb$fbdev, checking if it's ili9341..."
# Check if it's actually the ili9341 device
if dmesg | grep -q "ili9341.*fb$fbdev"; then
echo "ili9341 framebuffer ready, mapping console..."
con2fbmap 1 $fbdev
echo "Console mapped to framebuffer $fbdev"
exit 0
fi
fi
done
sleep 0.1
done
echo "Timeout waiting for SPI TFT framebuffer"
exit 1

14
con2fbmap.service Normal file
View file

@ -0,0 +1,14 @@
[Unit]
Description=Map console to framebuffer for SPI TFT
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/con2fbmap-helper.sh
RemainAfterExit=yes
StandardOutput=journal
StandardError=journal
TimeoutStartSec=60
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,114 @@
/*
* Device Tree overlay for Adafruit PiTFT 2.4" resistive touch screen with tsc2007
*
*/
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&spi0>;
__overlay__ {
status = "okay";
};
};
fragment@2 {
target = <&spidev0>;
__overlay__ {
status = "disabled";
};
};
fragment@3 {
target = <&spidev1>;
__overlay__ {
status = "disabled";
};
};
fragment@4 {
target = <&gpio>;
__overlay__ {
adafruit_2_4_tft_pins: adafruit_2_4_tft_pins {
brcm,pins = <25 24 18>;
brcm,function = <1 0 1>; /* out in out*/
brcm,pull = <0 2 2>; /* none up up */
};
};
};
fragment@5 {
target = <&spi0>;
__overlay__ {
/* needed to avoid dtc warning */
#address-cells = <1>;
#size-cells = <0>;
cs-gpios = <&gpio 8 1>;
adafruit_2_4_tft: adafruit_2_4_tft@0{
compatible = "adafruit,yx240qv29";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&adafruit_2_4_tft_pins>;
spi-max-frequency = <32000000>;
rotation = <90>;
reset-gpios = <&gpio 23 0>;
dc-gpios = <&gpio 25 0>;
};
};
};
fragment@7 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
tsc2007: tsc2007@48 {
compatible = "ti,tsc2007";
reg = <0x48>;
ti,fuzzx = <4>;
ti,fuzzy = <4>;
ti,max-rt = <3700>;
ti,fuzzz = <4>;
ti,x-plate-ohms = <180>;
panel = <&adafruit_2_4_tft>;
pinctrl-0 = <&adafruit_2_4_tft_pins>;
interrupt-parent = <&gpio>;
interrupts = <24 2>;
gpios = <&gpio 24 1>;
};
};
};
fragment@8 {
target-path = "/soc";
__overlay__ {
backlight: backlight {
compatible = "gpio-backlight";
pinctrl-0 = <&adafruit_2_4_tft_pins>;
gpios = <&gpio 18 2>;
default-on;
};
};
};
__overrides__ {
speed = <&adafruit_2_4_tft>,"spi-max-frequency:0";
rotate = <&adafruit_2_4_tft>,"rotation:0";
fps = <&adafruit_2_4_tft>,"fps:0";
debug = <&adafruit_2_4_tft>,"debug:0";
// xohms = <&tsc2007>,"touchscreen-x-plate-ohms;0";
// swapxy = <&tsc2007>,"touchscreen-swapped-x-y?";
};
};

View file

@ -0,0 +1,3 @@
# udev rule for Focaltouch Capactive Touchscreen
SUBSYSTEM=="input", ATTRS{name}=="EP0110M09", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"
SUBSYSTEM=="input", ATTRS{name}=="generic ft5x06*", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"

2
templates/95-stmpe.rules Normal file
View file

@ -0,0 +1,2 @@
udev rule for STMPE Resistive Touchscreen Controller
SUBSYSTEM=="input", ATTRS{name}=="*stmpe*", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"

View file

@ -0,0 +1 @@
SUBSYSTEM=="input", ATTRS{name}=="touchmouse", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"

View file

@ -0,0 +1,14 @@
# udev rules for SPI TFT DRM devices to create reliable symlinks
# Supports ili9341, st7789, and other SPI TFT displays
# Rule for ili9341 DRM device (and other SPI TFT displays)
SUBSYSTEM=="drm", KERNEL=="card*", KERNELS=="spi0.0", DRIVERS=="ili9341", SYMLINK+="dri/spitft"
# Generic rule for any SPI TFT display on spi0.0
SUBSYSTEM=="drm", KERNEL=="card*", KERNELS=="spi0.0", SUBSYSTEMS=="spi", SYMLINK+="dri/spitft"
# Rule for st7789 displays (add when needed)
SUBSYSTEM=="drm", KERNEL=="card*", KERNELS=="spi0.0", DRIVERS=="st7789", SYMLINK+="dri/spitft"
# Alternative rule using device path pattern
SUBSYSTEM=="drm", KERNEL=="card*", DEVPATH=="*/spi0/spi0.0/drm/card*", SYMLINK+="dri/spitft"

View file

@ -0,0 +1,5 @@
# udev rule for TSC2007 touchscreen to create /dev/input/touchscreen symlink and apply transformation
SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="TSC2007 Touchscreen", SYMLINK+="input/touchscreen", ENV{LIBINPUT_CALIBRATION_MATRIX}="{calibration_matrix}"
# Backup rule using touchscreen capability and TSC2007 name pattern
SUBSYSTEM=="input", KERNEL=="event*", ENV{ID_INPUT_TOUCHSCREEN}=="1", ATTRS{name}=="*TSC2007*", SYMLINK+="input/touchscreen", ENV{LIBINPUT_CALIBRATION_MATRIX}="{calibration_matrix}"

View file

@ -0,0 +1,8 @@
# --- added by adafruit-pitft-helper {date} ---
[all]
hdmi_force_hotplug=1 # required for cases when HDMI is not plugged in!
dtparam=spi=on
dtparam=i2c1=on
dtparam=i2c_arm=on
{overlay}
# --- end adafruit-pitft-helper {date} ---

11
templates/fbcp.service Normal file
View file

@ -0,0 +1,11 @@
[Unit]
Description=Framebuffer copy utility for PiTFT
After=network.target
[Service]
Type=simple
ExecStartPre=/bin/sleep 10
ExecStart=/usr/local/bin/fbcp
[Install]
WantedBy=multi-user.target