【調試筆記】韋東山:在100ASK_IMX6ULL板子上支持其他型號的屏幕

在100ASK_IMX6ULL板子上支持其他型號的屏幕

1.在100ASK_IMX6ULL底板上如何接其他廠家的屏幕

很多學員有過STM32的學習經驗,他們手上的開發板很多,LCD也很多。
一個LCD還挺貴的,不能浪費。
各家的LCD引腳順序都不一樣,所以別家的LCD不能直接接到100ASK_IMX6ULL開發板,需要轉接板。
大部分單片機學員都是使用正點原子、野火的板子,有他們的屏。
針對這兩家的屏,我們做了轉接板,如下:
在這裏插入圖片描述

我們提供的內核、設備樹,並不能直接支持其他廠家的LCD,可以聯繫我們,我們來調試。
下面的文檔是示例,教你們怎麼自己移植。

2.移植思路

LCD除了顯示之外,它的表面通常還貼有一個觸摸屏。
所以我們移植的是2個設備的驅動:LCD、觸摸屏。

LCD驅動在內核中已經有了,並且很完善,我們只需要修改設備樹就可以:修改時序等LCD參數,修改背光引腳等板子參數。

觸摸屏的驅動在內核中一般也有了,各廠家用的觸摸屏IC可能不同。需要配置內核把它加進去,同時修改設備樹:指定觸摸IC的信息(比如I2C地址),指定中斷引腳。

如果能拿到這塊LCD在別的板子上的內核源碼,就可以參考它的LCD參數、觸摸IC信息。
再結合你用的開發板,把涉及的GPIO找出來寫入設備樹。
簡單吧?
開工!

3.移植LCD驅動

注意:100ASK_IMX6ULL不能直接連接其他廠家的屏,需要轉接板。
IMX6ULL跟LCD的連接框圖如下:
在這裏插入圖片描述
IMX6ULL內部有LCD控制器,肯定是廠家對這個LCD控制器最熟悉了,所以他們爲了賣芯片,一般都會在內核中做好LCD控制器的驅動程序。
而IMX6ULL可以接各種LCD,這些LCD參數各有不同。LCD控制器的驅動程序會去設備樹中獲得這些參數,並根據這些參數來設置LCD控制器。
所以,我們要做的事情從理論上講很簡單:根據LCD參數修改設備樹。
但是,誰說廠家的驅動就沒有BUG,就完美無缺了?
我們要做的事有3項:確定LCD參數,修改設備樹,完善驅動

3.1 確定LCD參數

如果還保留有LCD的芯片手冊,這是最好的。可惜我碰到的大多學員早已經忘記這些資料在哪了。
野火的屏在板子背後直接寫明分辨率是多少,這比較簡單直接。
正點原子的屏在背後畫有一個表格,如下:
在這裏插入圖片描述
上圖例子中,M2、M1接地,M0接電源,所以M2M1M0爲001;對比表格可知它的分辨率爲800x480。
如果是從零開發,我們還需要找到芯片手冊確定LCD的詳細時序。

我們沒有LCD的手冊,即使有也懶得看。
直接看廠家的源碼不就行了?直接點,直接看它的設備樹不就行了?
找到LCD廠家的IMX6ULL內核源碼,執行以下命令:

$ cd  arch/arm/boot/dts/
$ ls  *imx6ull*.dts

結果如下:
在這裏插入圖片描述

可以找到2個設備樹文件,我們只關心裏面的LCD信息,打開任意一個看看:
在這裏插入圖片描述

3.2 修改設備樹

100ASK_IMX6ULL用的內核版本是4.9.88,版本高一點,但是IMX6ULL設備樹的寫法完全一樣。
設備樹文件是arch/arm/boot/dts/100ask_imx6ull-14x14.dts,替換下圖紅框部分:
在這裏插入圖片描述

修改好設備樹後,就可以編譯了。
爲方便你們操作,下面貼出編譯命令,假設你已經位於我們提供的內核源碼目錄中:

$ export  ARCH=arm
$ export  CROSS_COMPILE=arm-linux-gnueabihf-
$ export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin
$ make  dtbs

新編譯好的設備樹文件爲:arch/arm/boot/dts/100ask_imx6ull-14x14.dtb。
怎麼更新設備樹?請看我們的開發板使用手冊
更新設備樹後,重啓板子觀察效果。

3.3 完善驅動

使用新的設備樹啓動板子後,你會發現一個神奇的現象:LCD有時候有顯示,有時候沒有,不斷地冷啓動偶爾會有顯示。
如果你經驗豐富,可以判斷這是復位問題。
爲驗證是否復位問題,我們可以執行命令手工發出復位信號,先確定LCD復位引腳是哪個GPIO:
在這裏插入圖片描述

從上圖可以確定LCD的復位引腳用到GPIO3_IO04,那我們可以使用GPIO子系統來驗證。
執行某些命令讓GPIO輸出低電平,再輸出高電平,這樣就可以復位LCD了。

3.3.1 使用GPIO子系統復位LCD

GPIO3_IO04在GPIO子系統中編號爲:(3-1)*32+4=68,它是第68號GPIO。
板子進入Linux後,執行以下命令:

$ fb-test                                          // LCD上應該顯示紅綠藍色塊
$ echo  68 > /sys/class/gpio/export                  // 導出68號GPIO
$ echo out > /sys/class/gpio/gpio68/direction          // 設置爲輸出引腳
$ echo 0 > /sys/class/gpio/gpio68/value              // 讓它輸出0
$ echo 1 > /sys/class/gpio/gpio68/value              // 讓它輸出1
$ echo  68 > /sys/class/gpio/unexport               // unexport

你會發現一旦執行上述命令,LCD立刻就有顯示了。
所以,LCD驅動不完善,應該加上覆位信號。

3.3.2 修改設備樹:指定復位引腳

設備樹文件爲:arch/arm/boot/dts/100ask_imx6ull-14x14.dts
如下圖修改:
在這裏插入圖片描述
爲了方便大家複製代碼,我把添加的代碼寫出來:

reset-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; /* 100ask */

3.3.3 修改驅動:復位LCD

LCD驅動程序是哪個?
在Linux內核源碼目錄下執行命令:

$ ls drivers/video/fbdev/*.o

drivers/video/fbdev/built-in.o drivers/video/fbdev/mx3fb.o
drivers/video/fbdev/mxsfb.o

發現有2個.o文件:mx3fb.o、mxsfb.o。我們是imx6ull,應該是後者。
我們在mxsfb.c中mxsfb_probe函數的後面添加復位代碼,如下圖修改:
在這裏插入圖片描述

爲了方便大家複製代碼,我把添加的代碼寫出來(在mxsfb.c中mxsfb_probe函數的後面添加復位代碼,):

   /* 100ask */
    printk("100ask, %s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    rst_gpio = of_get_named_gpio(pdev->dev.of_node, "reset-gpios", 0);
    if (gpio_is_valid(rst_gpio)) {
            ret = gpio_request(rst_gpio, "lcdif_rst");
            if (ret < 0) {
                    dev_err(&pdev->dev,
                            "Failed to request GPIO:%d, ERRNO:%d\n",
                            (s32)rst_gpio, ret);
            } else {
                    gpio_direction_output(rst_gpio, 0);
                    msleep(2);
                    gpio_direction_output(rst_gpio, 1);
                    dev_info(&pdev->dev,  "Success seset LCDIF\n");
            }
    }

修改完後,重新編譯得到zImage和100ask_imx6ull-14x14.dtb,更新開發板,重啓,完美!

4.移植觸摸屏驅動

4.1 確定觸摸屏型號

還是那句話,如果有觸摸屏數據手冊,看手冊就好了。
如果沒有手冊,怎麼辦?
觸摸屏的主控芯片一般都是I2C接口的,那麼我們可以把屏接到板子上,用i2cdetect檢測出I2C設備的地址,根據地址就可以知道它的型號。
注意:100ASK_IMX6ULL不能直接連接其他廠家的屏,需要轉接板。
接上屏幕後,啓動開發板進入Linux,執行如下命令:

[root@imx6ull:~]# i2cdetect -y 1

命令解析:“-y”表示 Disable interactive mode,簡單地說就是“別讓我確認了,趕緊執行”;“1”表示I2C總線1(從0開始)。
結果如下:
在這裏插入圖片描述

上圖中,
“–”表示沒有這個地址對應的I2C設備;
“UU”表示這個地址的I2C設備已經有驅動在使用佔用它了,那這個I2C設備肯定是存在的;
其他數值表示該地址對應的I2C設備是存在的,並且還沒有驅動程序跟它匹配。
根據上圖,我們可以知道0x38就是觸摸屏設備,爲什麼!爲什麼不是0x60?你可以把屏幕取下,再重新執行命令,就可以看到“38”消失了。
根據0x38,我們得找到對應的芯片型號,怎麼找?去內核設備樹目錄裏找。

$ cd arch/arm/boot/dts/
$ grep "@38" * -nR

可以得到很多結果,比如:
在這裏插入圖片描述

地址爲0x38的I2C芯片有不少,比如HDMI PHY,還有ft5306、ft5x06。你在百度搜一下“ft5306”,它確實就是觸摸屏芯片。所以這款觸摸屏的主控芯片就是ft5x06。x表示某些數字,可能有多個型號,我們暫時沒不用去細分。

4.2 在設備樹中指定觸摸IC信息

IMX6ULL跟觸摸IC的連接圖如下:
在這裏插入圖片描述

所以,我們要確定的信息是:
a. 它接在哪個I2C控制器上?
b. 它的I2C地址是?
c. 復位引腳使用哪個GPIO?低電平有效還是高電平有效?
d. 中斷引腳使用哪個GPIO?低電平有效還是高電平有效?

不知道怎麼寫?沒關係,參考!
a. 對於ft5x06,設備樹節點中有哪些內容?
b. 那些內容怎麼適配100ASM_IMX6ULL板子?即怎麼改成100ASK_IMX6ULL所用的GPIO引腳
前面說過,根據I2C設備的地址0x38,執行如下命令:

$ cd arch/arm/boot/dts/
$ grep "@38" * -nR

我們可以得到很多結果,打開跟imx6ull最相近的imx6ul-tx6ul.dtsi,可以看到如下代碼:
在這裏插入圖片描述

我們把這個結點的內容先複製下來,粘貼到哪裏去?
100ASK_IMX6ULL也配有觸摸屏,我們用的型號是gt9xx,把這個結點放到gt9xx結點相同位置去就可以了,如下圖所示:
在這裏插入圖片描述
100ASK_IMX6ULL接標配的LCD時,觸摸IC是gt9xx,用的引腳假設是 AAA;
那麼同一個底板接上另一塊LCD時,雖然觸摸IC型號不同,但是它仍然用的是同一個引腳AAA。
所以,新加的節點,其內容可以參考gt9xx節點的內容。
下圖就是改好的樣子:
在這裏插入圖片描述

重新編譯設備樹,更新到板子上,發現觸摸屏還是不能用。
這還得往內核里加驅動。

4.3 重新配置內核添加驅動

這設備節點對應哪個驅動啊?它有這個屬性:

compatible = "edt,edt-ft5x06"

在內核drivers/input/touchscreen目錄下搜搜"edt,edt-ft5x06":

$ cd drivers/input/touchscreen/
$ grep "edt,edt-ft5x06" * -nr

什麼都沒搜到,再搜“edt-ft5x06”:

$ grep "edt-ft5x06" * -nr

edt-ft5x06.c:1071: { .name = “edt-ft5x06”, .driver_data =
(long)&edt_ft5x06_data }, Kconfig:667: module will be called
edt-ft5x06. Makefile:31:obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06) +=
edt-ft5x06.o

顯然,驅動程序是edt-ft5x06.c,內核配置項是CONFIG_TOUCHSCREEN_EDT_FT5X06
我們需要配置內核,把CONFIG_TOUCHSCREEN_EDT_FT5X06配置爲y。
在內核目錄下執行“make menuconfig”,然後搜“CONFIG_TOUCHSCREEN_EDT_FT5X06”:
在這裏插入圖片描述

在菜單裏找到它,把它配置爲y,如下圖:
在這裏插入圖片描述

重新編譯內核zImage,更新到板子上,啓動。
發現觸摸屏有反應,但是點不準,還得調試。

4.4 調試:找出問題

Tslib是觸摸屏的庫,自帶有很多工具:
a. ts_print_raw :打印觸摸屏原始數據
b. ts_print :打印經過較準的數據
c. ts_test_mt:測試電容屏,點擊觸摸屏,同時就會在LCD上顯示觸點位置。

我們先把系統自帶的QT系統去掉,在開發板執行:

#mv /etc/init.d/S07hmi  /root/
#reboot

然後設置環境變量,執行ts_test_mt:

export TSLIB_TSDEVICE=/dev/input/event1
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_PLUGINDIR=/usr/lib/ts
ts_test_mt

可以在LCD屏幕上看到提示,你點擊某個位置,正常的話在該位置就會顯示一個標號。
我們發現有意思的現象:從左往右點,標號從上邊移動到下邊;從上往下點,標號從左邊移動到右邊。
猜測:XY座標對調了。

再試一下,執行 ts_print_raw,然後從左往右點,現象如下:
在這裏插入圖片描述
從左往右點,x座標應該發生變化,y座標保持不變;但是從上圖看來,這是相反的。
所以,確實是xy座標對調了。

4.5 解決方法

可以從應用層面(修改/etc/ts.conf)解決,也可以從驅動層面(修改設備樹)解決。二選一就好了,不要同時做。

4.5.1 修改/etc/ts.conf

如下圖加上xyswap就可以了:
在這裏插入圖片描述

4.5.2 修改設備樹

有時候我們並不願意、不能修改應用層的東西,那可以修改設備樹:
在這裏插入圖片描述

4.6 其他情況

100ASK_IMX6ULL標配的屏,帶的觸摸IC是gt9xx;但是我們發現別家的LCD即使同樣使用gt9xx,但是它的xy值是反轉的。
什麼意思呢?
你從左往右點,正常來說x值是從小變大,但是有些屏是從大變小。
你從上往下點,正常來說y值是從小變大,但是有些屏是從大變小。
這時候,你同樣可以修改設備樹,或是修改/etc/ts.conf。

怎麼修改設備樹?
參考內核文檔:Documentation/devicetree/bindings/input/touchscreen,該目錄下有很多I2C觸摸芯片的設備樹說明,比如有goodix.txt,對應gt9xx芯片;有edt-ft5x06.txt。
要讓x反轉,或是y反轉,在設備節點中加入這樣的屬性值就可以:

touchscreen-inverted-x = <1>;
touchscreen-inverted-y = <1>;

有時爲了測試方便,就是想臨時改一下/etc/ts.conf,怎麼做?
這個文件本身是有些註釋的,可以參考:
在這裏插入圖片描述
“x0=1024”的意思就是:x座標,0表示1024;
“y0=600”的意思是:y座標,0表示600。

4.7 gt9xx芯片固件更新

gt9xx芯片功能強大,可以寫入配置信息讓它支持不同分辨率的觸摸屏。
但是出廠的觸摸屏IC一般都已經寫好配置信息了,我們不應該讓驅動程序去修改這些配置信息。
可以在設備樹中加上這一句,禁止驅動去修改配置信息:

goodix,driver-send-cfg = <0>;

這是我們調試過程中碰到的一個坑。

如有問題歡迎加我同事微信13163769879 反饋。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章