Linux 的 fb-tft 對 ILI9341 有完整的支援,但是解析度只有 320x240。KlipperScreen 要求的最低解析度是 480x320,若解析度低於這要求,雖然還是可以執行,但字跡會變模糊不清。
在淘寶可以找到較多人使用,480x320 的 SPI 界面 LCD,其控制晶片為 ILI9488/9486,另外則是 ST7796。因為搜尋 SPI LCD 的方案,大多會找到 ILI9488 相關的,因此先買 ILI9488 / ILI9486 來測試。很辛苦的改驅動,編譯 kernel module,最後是成功了。但是系統一更新,又變得改的程式都不能用了。
經過交叉測試,發現 Fly PI 的 LCD,使用 ST7796 控制器,用 fb_ili9341 的 driver,竟然能夠點亮,雖然顯示不正常,但可以看到在 320x240 的範圍內,正常顯示。
這表示 ST7796 可以使用 RGB565 的格式,經測試,只要把 fb_ili9341 的驅動程式的解析度改成 480x320 即可使用,幾乎完全不用改到程式的其他部分。
淘寶買 ili9488 的 LCD,用 fb_ili9341 的驅動程式來改,只會一片白屏。使用 fb_ili9486.c 來改,若 PIXEL_FORMAT 是 0x55,顯示一片白屏。將 PIXEL_FORMAT 是 0x66,會輸出雜亂的顯示。再加上轉換的 function,則可以成功驅動。
這類控制晶片透過 SPI 界面串列的傳送視訊資料,為了減少資料量,一個畫素 (pixel) 通常用 RGB565 或 RGB666 的格式。RGB565 為 R: 5bits, G: 6bits, B:5bits,共 16bits,傳送時,一個畫素佔 2bytes。RGB666 為 R: 6bits, G: 6bits, B:6bits,共 18bits ,傳送時,一個畫素佔 3bytes。相同的頻寬,後者可傳送的資料量只剩 2/3。
ILI9488 / ILI 9486,確定只能使用 RGB666 的格式。因此,較佳的選擇是買 ST7796 控制的 LCD。但 ILI9488 的 LCD,有較小的 3.5" 螢幕的選擇,價格更低。
參考連結
能夠找到的資訊,有的有點過時,或者,更新後,OS 版本太新,舊的方式不能用。因此雜亂地收集了一堆可能用得到的參考,等確定作法,再將沒用的刪除。
- https://www.kernel.org/doc/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
- https://github.com/KungfuPancake/v0_ips_touch_display/tree/main
- https://github.com/notro/panel-mipi-dbi/wiki
- https://forum.armbian.com/topic/48441-st7796-display-w-opiz3/
- https://forums.raspberrypi.com/viewtopic.php?t=380704
- https://forum.armbian.com/topic/47971-driving-the-ili9488-lcd-40-inch-cheap-chinese-clone/
- https://github.com/notro/panel-mipi-dbi/issues/2
- https://forums.raspberrypi.com/viewtopic.php?t=369139
- https://github.com/raspberrypi/linux/blob/rpi-5.15.y/arch/arm/boot/dts/overlays/mipi-dbi-spi-overlay.dts
- https://github.com/Vasily-Kapustin/ti9488/blob/master/ili9488.c
升級至最近的 kernel 6.12.30 之後,可以使用 tiny drm 的 panel-mipi-dbi-spi 模組,不用自行編譯 kernel module 了,方便很多。
SDO 和 T_DO 併聯問題
LCD 的 SDO 和觸控的 T_DO 都是接到 host 的 MISO。這兩支腳都是輸出,若將這兩支腳短路,可能會使得觸控不能運作。
將這兩支腳短路,在 ILI9341 的板子上沒問題,在 ILI9486 或 ILI9488 上,卻使得觸控不能運作。經過不斷的測試,花了好久的時間,才確認問題。
要同時驅動 LCD 和觸控,照著 ILI9341 測試成功的作法,將 SCK, SDO, SDI 三支腳都短路,然後 ILI9486 和 ILI9488 的觸控一直都沒反應。
先前因為 ads7846 驅動的設定改變,花了不少時間才解決。因而一開始也懷疑是 DTS 設定問題,或是某些 MCU 的接腳不能用。把手邊各種不同的 LCD 都拿來測試,包括 Fly Pi 的螢幕。改變各種設定,還是不能動作。
只能懷疑是 IC 壞掉,或是電阻膜被我弄壞。拿一塊新的 ILI9488,還沒把接腳短路,單獨測觸控功能,正常。但將接腳一短路,就掛了。
準備去買幾顆 IC 來換,發現 ILI9341 板子上的觸控 IC 是 XPT2046,ILI9488 板子上的觸控 IC 是 HR2046,是相容的 IC,才懷疑可能是 IC 的輸出短路造成問題。將 SDO 的短路線剪掉,測試觸控功能,OK。
LCD 沒用到 SDO,那就不要將這支腳短路吧,這樣 LCD 和觸控都正常了。
不能用的 pin
在 Orange PI Zero3,6.6.75-current-sunxi64,PC9 接腳不能用。
overlay 的改變
開始測試時,kernel 版本是 6.6.75,測試成功後。升級後,kernel 版本變 6.12.30,又變成不能驅動 LCD 了,會出現 "cannot register SPI host" 的錯誤。
[ 1.551842] ili9341@0 enforce active low on GPIO handle
[ 1.551871] sun6i-spi 5011000.spi: cannot register SPI host
------------
經過好久,終於撈到解答。
/dts-v1/;
/plugin/;
/ {
compatible = "xunlong,orangepi-zero3", "allwinner,sun50i-h616";
fragment@0 {
target = <&spi1>;
__overlay__ {
status = "okay";
pinctrl-names = "default"; // new for linux 6.12
pinctrl-0 = <&spi1_pins>; // new for linux 6.12
cs-gpios = <&pio 2 7 0>; /* PC7 */
st7796s: st7796s@0 {
compatible = "sitronix,st7796s";
reg = <0>; /* Chip Select 0 */
#spi-cs-high;
spi-max-frequency = <40000000>;
rotate = <180>;
bgr = <0>;
fps = <30>;
width = <480>;
height = <320>;
buswidth = <8>;
reset-gpios = <&pio 2 6 1>; /*RESET=PC6*/
dc-gpios = <&pio 2 5 0>; /*DC_RS=PC5*/
led-gpios = <&pio 2 8 0>; /*LED=PC8*/
debug = <4>;
};
};
};
};
要加上 pinctrl-names = "default"; 和 pinctrl-0 = <&spi1_pins>; 。
沒有留言:
張貼留言