Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CloudShell2 LCD + Fan on ODROID-XU4 — Armbian / kernel 6.x

Get the ODROID CloudShell2 LCD and case fan working on an ODROID-XU4 running a modern Armbian "current" (kernel 6.6.x) image — where, out of the box, the LCD stays dark and the case fan is uncontrolled.

One script applies every fix:

git clone https://github.com/<you>/cloudshell2-xu4-kernel6.git
cd cloudshell2-xu4-kernel6
sudo ./install.sh
sudo reboot

Tested on Armbian 26.5.1 (resolute), kernel 6.6.141-current-odroidxu4, ODROID-XU4 + CloudShell2. Should apply to any Armbian odroidxu4 current (6.x) image that ships the hktft-cs-ogst overlay.


Is this for me?

Use this if, on an XU4 + CloudShell2 with a kernel-6 Armbian image:

  • the LCD only shows the backlight (or nothing) — no console/image, and/or
  • the case fan never turns on/off under control (always on, or you can't drive it).

The Hardkernel cloudshell-lcd / cloudshell2-fan packages target their own kernel-5 images and do not make the LCD work on Armbian 6.x as-is.


What actually breaks (and the fixes)

# Problem Root cause Fix applied
1 CloudShell2 overlays never load Armbian's /boot/boot.ini runs setenv cs2enable "false" after importing armbianEnv.txt, so setting it in armbianEnv.txt has no effect set cs2enable "true" inside boot.ini
2 LCD backlight off → screen dark Armbian's hktft-cs-ogst overlay declares the backlight led-gpios active-LOW, but the CloudShell2 backlight is active-HIGH flip led-gpios flag 10 in the overlay
5 Case fan not controllable The CloudShell2 case fan is an I2C device (0x60, reg 0x05: 0x00=on, 0x05=off) — not the SoC pwm-fan install a small systemd service that drives it by temperature
3 (optional) fb_hktft32 ... SPI transfer failed: -5 on a marginal link s3c64xx SPI DMA timing force PIO with TXBUFLEN=32off by default
4 (optional) blank/unstable panel at 40 MHz on a marginal link SPI signal integrity over the cabling lower clock with SPI_HZ=10000000off by default

The required fixes are #1, #2 and #5. A controlled test (fresh image, stock 40 MHz + DMA, only the backlight-polarity fix) showed the LCD works — so install.sh leaves the SPI clock and DMA at stock by default. #3 and #4 are opt-in fallbacks (SPI_HZ / TXBUFLEN) only for marginal cabling. Every edited file is backed up as *.bak.<timestamp>.

⚠️ Hardware note: the LCD uses SPI and the fan uses I2C through the same XU4 ↔ CloudShell2 board connector. If the fan (I2C) works but the LCD is still blank after these fixes, the SPI lines on that connector are likely not making contact — reseat the board / check the connector. (In our case a marginal connection caused a blank LCD until it was reseated; the fixes above were still required.)


What install.sh changes

  • apt install i2c-tools device-tree-compiler
  • /boot/boot.inisetenv cs2enable "true"
  • /boot/dtb/hktft-cs-ogst.dtbo (decompiled, patched, recompiled):
    • led-gpiosactive-high (the only required LCD overlay change)
    • (only if SPI_HZ is set) lower spi-max-frequency
    • (only if TXBUFLEN is set) add txbuflen
  • /usr/local/sbin/cloudshell2-fan-i2c (the fan controller)
  • /etc/cloudshell2-fan.conf (fan settings — kept if it already exists)
  • /etc/systemd/system/cloudshell2-fan.service (enabled at boot)

Fallback tuning (only if the LCD stays blank/unstable on a known-good connection):

SPI_HZ=10000000 TXBUFLEN=32 sudo ./install.sh

After reboot — verify

LCD — the Linux text console should appear on the CloudShell2 screen:

ls /dev/fb0                       # fb0 should be the fbtft panel
cat /sys/class/graphics/fb0/name  # -> fb_hktft32
# quick colour test (R/G/B vertical bars):
python3 - <<'PY'
import struct
w,h=[int(x) for x in open('/sys/class/graphics/fb0/virtual_size').read().split(',')]
s=int(open('/sys/class/graphics/fb0/stride').read())
bars=[0xF800,0x07E0,0x001F]
row=b''.join(struct.pack('<H',bars[min(2,(x*3)//w)]) for x in range(w)).ljust(s,b'\0')
open('/dev/fb0','wb').write(row*h)
PY

Fan:

systemctl status cloudshell2-fan
journalctl -u cloudshell2-fan -f      # watch "temp NNC -> ON/OFF"

Fan configuration — /etc/cloudshell2-fan.conf

ON_TEMP=60      # turn fan ON  at/above this SoC temperature (°C)
OFF_TEMP=50     # turn fan OFF below this temperature (°C)  -> hysteresis
INTERVAL=5      # seconds between checks
BUS=1           # i2c bus with the 0x60 controller (empty = auto-detect)
ALWAYS_ON=0     # 1 = ignore temperature, keep fan always on (Hardkernel default)

Apply changes with sudo systemctl restart cloudshell2-fan. Manual control: sudo i2cset -y 1 0x60 0x05 0x00 (ON) / ... 0x05 (OFF).

The fan coasts for a few seconds after an "off" — a 2–3 s off command can look like "still running". Hold it off ~8 s to confirm it stops.


Optional: show system info on the LCD

By default the kernel console is rendered to the LCD. If you want a CloudShell-style status screen (CPU/temp/disks), install Hardkernel's cloudshell-lcd display daemon (it writes to tty1, which fbcon renders to the panel):

sudo apt install cloudshell-lcd        # from the hardkernel PPA, if available for your release

Caveats

  • Re-run after kernel/package updates. A kernel or linux-dtb/bootini package upgrade can replace boot.ini or the overlay and revert the patches. Just run sudo ./install.sh again.
  • These fixes assume the standard Armbian odroidxu4 overlay set (hktft-cs-ogst.dtbo, cs2enable in boot.ini). Other boards/images differ.
  • The fan controller is on i2c-1 on the tested image; the script auto-detects the bus if you set BUS= (empty) in the config.

Uninstall

sudo ./uninstall.sh      # removes the fan service, restores boot.ini & overlay backups
sudo reboot

Background

These fixes came out of a long debugging session. Key findings:

  • cs2enable belongs in boot.ini on Armbian XU4 (the armbianEnv.txt value is overridden), and the stock CloudShell overlay has a backlight-polarity bug.
  • The LCD is driven by the staging fbtft fb_hktft32 driver (ILI9340, SPI1), not DRM. Stock 40 MHz + DMA works on a healthy link (verified by a controlled test); a lower clock / PIO (SPI_HZ, TXBUFLEN) only matter for marginal cabling.
  • The CloudShell2 case fan is I2C 0x60 (on/off), unrelated to the SoC pwm-fan that the kernel thermal subsystem drives.

Contributions / corrections welcome.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages