[OrangePi] Fix lỗi màn MPI3501 TFT 3.5 inch lên màu không chuẩn

 Mình có con board Orange pi zero 2w, có thể coi là 1 phiên bản hiệu năng cao mà lại rẻ hơn Raspberry Pi Zero 2w. Đánh đổi của nó là ít tài liệu và thiếu support hơn. Mình nhận ra sâu sắc điều này hơn khi gặp vấn đề màn hình chạy trên board hiển thị màu không đúng 

1. VẤN ĐỀ 

Mình muốn có con màn để hiển thị, vừa rẻ vừa tiện cho việc cắm. Board có sẵn output ra mini HDMI. Nên sẽ có 1 số lựa chọn về màn như 

  1. Màn có HDMI MPI3508 : Đặt shopee nước ngoài tầm 300k, nhưng phải thêm dây và cổng chuyển nữa, nên sẽ lên tầm 400k.
  2. Màn SPI chính hãng Wavesharehttps://www.waveshare.com/wiki/3.5inch_RPi_LCD_(C). Ngon, bổ rồi nhưng tất nhiên chính hãng thì không rẻ ~500k 
  3. Màn SPI clone MPI 3501: http://www.lcdwiki.com/3.5inch_RPi_Display, giá con này chỉ 200k shopee, cắm SPI rất tiện
--> Chọn màn clone MPI 3501 là rõ rồi 
Màn MPI3501 là màn clone của màn Waveshare, 2 con dùng chung chip xử lý ILI9486 và chip cảm ứng ADS7846 . Tuy nhiên khi cùng 1 device tree setup, màn waveshare thì lên màu chuẩn,còn  màn MPI3501 lại bị lỗi màu trên board Orange Pi Zero 2W



Bên trái là MPI3501, bên phải là màn Waveshare. Orange Pi thì nó đáng ra phải là màu cam rồi :v 
-->Đồ rẻ thì phải làm nhiều thôi. Làm xong lại học được nhiều thứ 


2. BẮT ĐẦU KIỂM TRA

2.1 Cài overlay

Hệ điều hành mình dùng là Debian Bookworm Kernel 6.1. Thực tế về cách cài thì tương tự với nhau trên những image mà trang chủ Orange Pi support (http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-Zero-2W.html). Lúc mình cài được là đang chạy Armbian. 

Mình dựa theo hướng dẫn tại đây https://github.com/dev-null2019/orangepizero2w35tft. Với màn waveshare là khởi động lại là lên màu đúng cảm ứng ok luôn. Còn màn clone thì bị như trên.

Mình sợ rằng bản thân cái màn đang hiển thị bị sai nên cũng đã cấu hình trên Raspberry Pi 4 theo nhà sản xuất (https://github.com/goodtft/LCD-show), thì nó vẫn ra đúng màu như thường 

--> Có vẻ vấn đề là driver.

2.2 Kiểm tra driver 

2.2.1 Trên Raspberry Pi 4

Đầu tiên do trên Raspberry Pi 4 màn chạy ra màu chuẩn nên mình kiểm tra driver đang được dùng ở đây. Với các board nhúng này đã lên được màn thì đa phần sẽ có device frame buffer tương ứng cho driver. Check bằng câu lệnh 


Hiểu đơn giản màn bạn hiển thị chính là hiển thị cái frame buffer này. Nó đang ở dạng raw data . Dữ liệu ở đây hiện đang được tạo bởi DRM (Direct Rendering Manager ) driver cho ILI9486. 
Lấy tên driver bằng cách 
cat /sys/class/graphics/fb<>/name

Trước đó do cắm HDMI PI đã nhận fb0, cắm tiếp màn MPI3501, board khởi tạo fb1, với driver name fb_ili9486

2.2.2 Trên Orange Pi Zero 2W


Làm tương tự trên OPi ta thu được 
orangepi@orangepi:/boot$ cat /sys/class/graphics/fb0/name
ili9486drmfb

Vậy là giữa 2 con đang có sự khác nhau về driver.

--> Build thử Driver fb_ili9486 xem sao 

2.2.3 Build Driver fb_ili9486 

Mình tìm source code của con orange pi. Check name và kernel ta được 
orangepi@orangepi:/boot$ uname -a
Linux Gigi-Connect 6.1.31-sun50iw9 #1.0.2 SMP Thu Jul 11 17:24:28 CST 2024 aarch64 GNU/Linux
orangepi@orangepi:/boot$ lsb_release -a
No LSB modules are available.
Distributor ID:    Debian
Description:    Orange Pi 1.0.2 Bookworm
Release:    12
Codename:    bookworm

Thế là đi tìm source code, được nguồn https://github.com/orangepi-xunlong/linux-orangepi

Tạo môi trường build các thứ, ra được file .ko để insmod bên orange pi. 

Tuy nhiên không hiểu sao insmod luôn bị Invalid Symbol mà không biết xem ở đâu, cấu hình đúng kernel Check bằng modinfo rồi :v. 

--> Đổi sang xem liệu có thể thay đổi BGR không 

 2.3 Thay đổi BGR cho màn 

Mình đi đến cách tiếp cận này khi tự build và cài driver không khả quan. Và còn đọc được trên diễn đàn là fb_ili9486 không còn được support sau bản kernel 5.4

Vậy màn theo cảm quan là đang bị ngược màu, nhưng làm sao để check là nó thật sự bị ngược màu không. 

--> Viết 1 script python đơn giản rồi output ra màn 

python3 -c 'open("red.raw", "wb").write(b"\xF8\x00" * 153600)'
sudo dd if=red.raw of=/dev/fb0 bs=1

python3 -c 'open("green.raw", "wb").write(b"\x07\xE0" * 153600)'
sudo dd if=green.raw of=/dev/fb0 bs=1

python3 -c 'open("blue.raw", "wb").write(b"\x00\x1F" * 153600)'
sudo dd if=blue.raw of=/dev/fb0 bs=1

Việc test thế này giúp mình nhận ra nó thật sự bị ngược màu 

Red. —> blue
Green —> red
Blue. —> green

Tuy nhiên ngược thế này là do framebuffer đã bị ngược sẵn rồi hay ra tới màn nó mới bị ngược
--> Dịch chính framebuffer ra thôi 
sudo ffmpeg -f fbdev -framerate 1 -i /dev/fb0 -vframes 1 framebuffer.png
Mở file png thì thấy màu vẫn chuẩn :v 
--> Lỗi config trên màn 

2.3.1 Đọc kỹ hơn về Config:

 Có 2 cái mình đã đọc: 

1. https://github.com/goodtft/LCD-show/blob/master/LCD35-show : Cách cài đặt cho RPI 4 từ nhà sản xuất

2. https://github.com/dev-null2019/orangepizero2w35tft : Cách add overlay device tree

--> Cả 2 đều sẽ thêm device tree để cấu hình cho ili9486 và ads7846. 

--> 1 bên thêm thủ công, 1 bên thêm command có sẵn là orangepi-add-overlay


Mục đích : 

  • Tạo file calib cho x11 server (calib cảm ứng cũng như fb)
  • Compile dts file to dtbo rồi copy tới /boot/overlay-user
  • Thêm overlay-user=<tên file dtbo> vào /boot/orangepiEnv.txt

2.3.2 Đọc kỹ Device tree file 

Dễ thấy ngay trường bgr = <0x00>. Hiểu thì nó sẽ là Blue-green-red thứ tự như nào.


Như vớ được vàng, mình thay nó sang <0x01> như ở trên rồi reboot 
--> Không có gì thay đổi 
Mình bắt đầu nghi ngờ không biết trường này có được parse khi duyệt device tree không. Nên phải check.
 

Mình check bằng việc đọc device tree ra, và bgr có được apply và thay đổi ở đây 

Vậy chỉ còn 1 trường là khả nghi nhất, đó là trường init

init = <0x10000b0 0x00
	0x1000011
	0x20000ff
	0x100003a 0x55
	0x1000036 0x28
	0x10000c2 0x44
	0x10000c5 0x00 0x00 0x00 0x00
	0x10000e0 0x0f 0x1f 0x1c 0x0c 0x0f 0x08 0x48 0x98 0x37 0x0a 0x13 0x04 0x11 0x0d 0x00
	0x10000e1 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00
	0x10000e2 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00
	0x1000036 0x28
	0x1000011
	0x1000029>;

--> Sau khi đọc thêm datasheet của ILI9486 mình cuối cùng cũng biết cách để đổi BGR của màn (https://www.hpinfotech.ro/ILI9486.pdf)

3. GIẢI PHÁP

Trường init này chính là init command sẽ được gửi tới màn lúc khởi động, Được nói cụ thể ở mục 8 từ trang 147


Nó sẽ là Command + Parameter, và cần đặc biệt lưu ý đến Command 36h 


Parameter bit D3 sẽ define RGB-BGR cái nào sẽ được áp dụng

--> Việc này sẽ ghi đè lại trường bgr define bên device tree bên trên 

--> Sửa device tree thôi. Mình sửa trường init 2 cái command 0x100036 mình đều để parameter 0x48 (ban đầu 0x08 không được, nên mình đã thử thêm 1 số cái nữa, và cuối cùng 0x48 được :v )

Device tree sau cùng sẽ có dạng init kiểu 

init = <0x10000b0 0x00
	0x1000011
	0x20000ff
	0x100003a 0x55
	0x1000036 0x48
	0x10000c2 0x44
	0x10000c5 0x00 0x00 0x00 0x00
	0x10000e0 0x0f 0x1f 0x1c 0x0c 0x0f 0x08 0x48 0x98 0x37 0x0a 0x13 0x04 0x11 0x0d 0x00
	0x10000e1 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00
	0x10000e2 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00
	0x1000036 0x48
	0x1000011
	0x1000029>;

PS: Phải hạ cả max speed of spi (cái này thì không hiểu tại sao lắm)

Và kết quả khi khởi đôngj lại là màn đã lên đúng 


Cứ thế thôi :v 

P/s: Vô cùng cảm ơn robertoj từ forum Armbian 

https://forum.armbian.com/topic/52880-orangepi-zero-2w-wrong-color-display-on-mpi3501/

Đăng nhận xét

1 Nhận xét

  1. Bài viết hay, chi tiết. Ra thêm các chủ đề khác nhé ❤️

    Trả lờiXóa