Light Up RDK X5 SPI LCD (ST7796S + GT911)
This skill automates the full driver install for a 3.5" ST7796S SPI LCD (480×320) and GT911 capacitive touch on an RDK X5 board. It reuses the pre-compiled artifacts from the Cathay-Launch-UI repo — no kernel cross-compilation needed.
Prerequisites
Before running, confirm with the user:
- Hardware wired correctly — Critical pins:
- LCD CS → RDK X5 pin 26 (CS1), NOT pin 24 (CS0)
- Both LCD + GT911 use 3.3V (NOT 5V)
- LCD DC → pin 15 (BCM 22), RST → pin 13 (BCM 27), Backlight → pin 12 (BCM 18)
- GT911 SDA/SCL → pin 3/5 (I2C5), INT → pin 4 (BCM 4), RST → pin 1 (BCM 1)
- Full pinout: seeCathay-Launch-UI/SPI-LCD-SETUP.md - Board reachable over SSH — Get from user (defaults assumed: IP
192.168.128.10, usersunrise, passwordsunrise) - Kernel version is 6.1.83 — The pre-built
.komodules only work on this exact kernel. If different, the.dtbooverlays and firmware still work, but modules must be rebuilt (seeSPI-LCD-SETUP.mdstep 2). - RDK X5 Desktop image (not Server) — The board must have a display manager + desktop environment pre-installed so a desktop actually appears on the LCD after boot. The official RDK X5 Desktop image ships with LightDM + Sway/XFCE; the headless Server image does not. Step 9b checks this and aborts early if missing.
sshpassinstalled locally —sudo apt install sshpassif missing
Ask the user for IP/user/password if they differ from defaults. Verify SSH reachability before proceeding.
Steps
1. Get the repo
If ~/Cathay-Launch-UI doesn't already exist, clone it:
test -d ~/Cathay-Launch-UI || git clone https://github.com/shockley6668/Cathay-Launch-UI.git ~/Cathay-Launch-UI
2. Verify board reachable + kernel version
sshpass -p '<PASSWORD>' ssh -o StrictHostKeyChecking=no <USER>@<IP> "uname -r"
Expected output: 6.1.83. If different, STOP and tell the user — they must either downgrade kernel or rebuild the .ko files using SPI-LCD-SETUP.md Phase 2.
3. Push device tree overlays
cd ~/Cathay-Launch-UI
sshpass -p '<PASSWORD>' scp overlay-st7796s.dtbo overlay-gt911.dtbo <USER>@<IP>:/tmp/
sshpass -p '<PASSWORD>' ssh <USER>@<IP> \
"sudo cp /tmp/overlay-st7796s.dtbo /tmp/overlay-gt911.dtbo /boot/overlays/ && \
grep -q overlay-st7796s /boot/config.txt || printf 'dtoverlay=overlay-st7796s\ndtoverlay=overlay-gt911\n' | sudo tee -a /boot/config.txt"
4. Push ST7796S firmware
sshpass -p '<PASSWORD>' scp st7796s.bin <USER>@<IP>:/tmp/
sshpass -p '<PASSWORD>' ssh <USER>@<IP> "sudo cp /tmp/st7796s.bin /lib/firmware/panel-mipi-dbi-spi.bin"
5. Push kernel modules
sshpass -p '<PASSWORD>' scp kernel-modules/panel-mipi-dbi.ko kernel-modules/drm_mipi_dbi.ko <USER>@<IP>:/tmp/
sshpass -p '<PASSWORD>' ssh <USER>@<IP> \
"sudo mkdir -p /lib/modules/6.1.83/extra && \
sudo cp /tmp/panel-mipi-dbi.ko /tmp/drm_mipi_dbi.ko /lib/modules/6.1.83/extra/ && \
sudo depmod -a"
6. Write X11 display config
sshpass -p '<PASSWORD>' ssh <USER>@<IP> "sudo tee /etc/X11/xorg.conf.d/99-spi-lcd.conf > /dev/null << 'EOF'
Section \"Device\"
Identifier \"SPI LCD\"
Driver \"modesetting\"
Option \"kmsdev\" \"/dev/dri/card0\"
EndSection
EOF"
7. Write X11 touch calibration
This rotates the GT911 portrait coords to match the landscape display:
sshpass -p '<PASSWORD>' ssh <USER>@<IP> "sudo tee /etc/X11/xorg.conf.d/90-touchscreen.conf > /dev/null << 'EOF'
Section \"InputClass\"
Identifier \"Goodix TouchScreen Calibration\"
MatchProduct \"Goodix Capacitive TouchScreen\"
MatchDriver \"libinput\"
Option \"CalibrationMatrix\" \"0 -1 1 1 0 0 0 0 1\"
EndSection
EOF"
8. Install backlight GPIO systemd service
sshpass -p '<PASSWORD>' ssh <USER>@<IP> "sudo tee /etc/systemd/system/st7796s-backlight.service > /dev/null << 'EOF'
[Unit]
Description=ST7796S LCD Backlight
After=multi-user.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/sh -c 'echo 421 > /sys/class/gpio/export 2>/dev/null; echo out > /sys/class/gpio/gpio421/direction; echo 1 > /sys/class/gpio/gpio421/value'
ExecStop=/bin/sh -c 'echo 0 > /sys/class/gpio/gpio421/value'
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable st7796s-backlight.service"
9. Disable any old userspace x11-to-spi service (if present)
sshpass -p '<PASSWORD>' ssh <USER>@<IP> "sudo systemctl disable x11-to-spi 2>/dev/null; sudo systemctl stop x11-to-spi 2>/dev/null; true"
9b. Ensure graphical session is enabled
The RDK X5 official image ships with LightDM + a desktop environment (XFCE/Sway). This step makes sure systemd actually boots into graphical mode (not multi-user) so the desktop appears on the SPI LCD after reboot.
sshpass -p '<PASSWORD>' ssh <USER>@<IP> "
# Confirm a display manager is installed (LightDM is the RDK X5 default)
if ! systemctl list-unit-files | grep -qE 'lightdm|gdm|sddm'; then
echo 'ERROR: No display manager found. This skill requires an RDK X5 image with a desktop environment.'
echo 'Reflash with the official RDK X5 Desktop image, then re-run this skill.'
exit 1
fi
# Force graphical boot target (in case board was set to multi-user)
sudo systemctl set-default graphical.target
# Enable + start the display manager (LightDM by default on RDK X5)
DM=\$(systemctl list-unit-files | grep -oE '^(lightdm|gdm|sddm)\.service' | head -1)
sudo systemctl enable \$DM
"
If this step fails with "No display manager found", STOP and tell the user — they have a server-only image and need to reflash with the desktop image (or sudo apt install lightdm xfce4 themselves) before re-running.
10. Reboot
sshpass -p '<PASSWORD>' ssh <USER>@<IP> "sudo reboot" || true
Wait ~30 seconds for the board to come back up, then poll:
for i in {1..30}; do
sshpass -p '<PASSWORD>' ssh -o ConnectTimeout=3 -o StrictHostKeyChecking=no <USER>@<IP> "true" 2>/dev/null && break
sleep 2
done
11. Verify
Run these checks via SSH and report results to the user:
sshpass -p '<PASSWORD>' ssh <USER>@<IP> "
echo '=== Framebuffer ==='
ls /dev/fb* 2>/dev/null
cat /sys/class/graphics/fb0/name 2>/dev/null
cat /sys/class/graphics/fb0/modes 2>/dev/null
echo '=== DRM devices ==='
ls /dev/dri/
echo '=== Kernel modules ==='
lsmod | grep -E 'panel_mipi_dbi|drm_mipi_dbi'
echo '=== GT911 touch ==='
dmesg | grep -i goodix | tail -5
cat /proc/bus/input/devices | grep -A2 Goodix
echo '=== Backlight ==='
cat /sys/class/gpio/gpio421/value 2>/dev/null
echo '=== Boot target ==='
systemctl get-default
echo '=== Display manager ==='
systemctl is-active lightdm gdm sddm 2>/dev/null | grep -v inactive
echo '=== X server running ==='
DISPLAY=:0 xdpyinfo 2>/dev/null | grep -E 'dimensions|name of display' || echo 'X NOT running'
echo '=== Touch calibration ==='
DISPLAY=:0 xinput list-props 7 2>/dev/null | grep 'Calibration Matrix' || echo 'X not running yet'
"
Expected:
- /dev/fb0 exists, name = panel-mipi-dbid, modes contain U:480x320p-0
- /dev/dri/card0 exists (panel-mipi-dbi) and card1 (vs_drm for HDMI)
- Both panel_mipi_dbi and drm_mipi_dbi loaded
- goodix in dmesg, Goodix input device present
- Backlight GPIO value = 1
- Boot target = graphical.target
- Display manager (lightdm/gdm/sddm) = active
- xdpyinfo responds (X is actually running and serving the SPI LCD)
- Calibration matrix shows 0 -1 1 1 0 0 0 0 1
12. Smoke test + desktop screenshot
If verification passes, grab a screenshot from the running desktop to prove the SPI LCD is actually showing it:
sshpass -p '<PASSWORD>' ssh <USER>@<IP> "
# Install scrot if needed (it's tiny)
command -v scrot >/dev/null || sudo apt install -y scrot
DISPLAY=:0 scrot /tmp/spi-lcd-desktop.png 2>/dev/null && echo 'screenshot ok' || echo 'screenshot failed'
"
sshpass -p '<PASSWORD>' scp <USER>@<IP>:/tmp/spi-lcd-desktop.png /tmp/spi-lcd-desktop.png
Then use the Read tool on /tmp/spi-lcd-desktop.png to view it and confirm the desktop is rendering. Show this image to the user as proof.
Optional framebuffer smoke test (writes random noise then black to the screen — user sees a brief flash):
sshpass -p '<PASSWORD>' ssh <USER>@<IP> "sudo dd if=/dev/urandom of=/dev/fb0 bs=1024 count=300 2>/dev/null; sleep 1; sudo dd if=/dev/zero of=/dev/fb0 bs=1024 count=300 2>/dev/null"
User should see noise flash on the LCD, then black, then the desktop returns.
Troubleshooting
If verification fails, point the user to the troubleshooting section in ~/Cathay-Launch-UI/SPI-LCD-SETUP.md:
- Screen blank → Check wiring (CS=pin 26, both 3.3V), backlight GPIO 421, firmware at
/lib/firmware/panel-mipi-dbi-spi.bin, module loaded - Touch wrong orientation → Verify
/etc/X11/xorg.conf.d/90-touchscreen.confexists and X has picked it up - Touch calibration lost on reboot → Make sure config file (not
xinput set-prop) is being used - Display glitches → Lower
spi-max-frequencyin overlay from 40MHz to 32MHz, rebuild.dtbo - I2C bus number wrong → Run
i2cdetect -ltheni2cdetect -y 5to confirm GT911 at 0x5D
Notes
- The whole thing is idempotent — re-running is safe (the
grep -qguard avoids duplicatedtoverlay=lines in/boot/config.txt). - Modules auto-load at boot via device tree
compatiblestrings — no need tomodprobemanually after reboot. - The full English/Chinese setup guides are at
~/Cathay-Launch-UI/SPI-LCD-SETUP.mdandSPI-LCD-SETUP.zh.md. - For non-6.1.83 kernels, only the
.kofiles need rebuilding — the.dtbooverlays and.binfirmware are kernel-version-independent.