もともと初代 Raspberry Pi 用に買ったものだけれど、初代 Raspberry Pi をいよいよ捨てたので、ついでにいろいろ調べながら再度使ってみる。
- waveshare spotpear 3.2 v3
LCD-show-180817.tar.gz の中の ./LCD32-show がやっていることは以下の通り。
- https://github.com/tasanakorn/rpi-fbcp をいれて起動
- device tree のインストールなど
しかし fbcp のインストールは失敗してた。まぁとりあえず使える。
なお、どういったコントローラが使われているかスペックに書いてないが、以下の通り。
- タッチコントローラーは SPI ads7846
- 液晶は SPI ili9340 240x320
fbcp は何をしている?
frame buffer をコピーするアプリケーションなのは名前から明らかだけれど、何のために?と思った。結論をいうと GPU でレンダリングした結果を SPI 接続の液晶へ表示させるためのハックのようだ。GPU を使わないなら入れなくても動かすことはできる。
dtb dts
dtb ファイル (コンパイル済みのデバイスツリーブロブ) が含まれているけど、ソースファイルがない。以下のようにするとソースにディスアセンブルできる。
dtc -I dtb -O dts -o waveshare32b-overlay.dts waveshare32b-overlay.dtb
以下のような感じのデバイスツリーとなっていた。
/dts-v1/; / { compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; fragment@0 { target = <0xdeadbeef>; __overlay__ { status = "okay"; spidev@0 { status = "disabled"; }; spidev@1 { status = "disabled"; }; }; }; fragment@1 { target = <0xdeadbeef>; __overlay__ { waveshare32b_pins { brcm,pins = <0x11 0x1b 0x16>; brcm,function = <0x0 0x0 0x0>; linux,phandle = <0x1>; phandle = <0x1>; }; }; }; fragment@2 { target = <0xdeadbeef>; __overlay__ { #address-cells = <0x1>; #size-cells = <0x0>; waveshare32b@0 { compatible = "ilitek,ili9340"; reg = <0x0>; pinctrl-names = "default"; pinctrl-0 = <0x1>; spi-max-frequency = <0xf42400>; rotate = <0x5a>; fps = <0x19>; bgr; buswidth = <0x8>; reset-gpios = <0xdeadbeef 0x1b 0x0>; dc-gpios = <0xdeadbeef 0x16 0x0>; debug = <0x0>; linux,phandle = <0x2>; phandle = <0x2>; }; waveshare35a-ts@1 { compatible = "ti,ads7846"; reg = <0x1>; }; waveshare32b_ts@1 { compatible = "ti,ads7846"; reg = <0x1>; spi-max-frequency = <0x1e8480>; interrupts = <0x11 0x2>; interrupt-parent = <0xdeadbeef>; pendown-gpio = <0xdeadbeef 0x11 0x0>; ti,x-plate-ohms = [00 3c]; ti,pressure-max = [00 ff]; }; }; }; __overrides__ { speed = <0x2 0x7370692d 0x6d61782d 0x66726571 0x75656e63 0x793a3000>; rotate = [00 00 00 02 72 6f 74 61 74 65 3a 30 00]; fps = [00 00 00 02 66 70 73 3a 30 00]; debug = <0x2 0x64656275 0x673a3000>; }; __symbols__ { waveshare32b_pins = "/fragment@1/__overlay__/waveshare32b_pins"; waveshare32b = "/fragment@2/__overlay__/waveshare32b@0"; }; __fixups__ { spi0 = "/fragment@0:target:0", "/fragment@2:target:0"; gpio = "/fragment@1:target:0", "/fragment@2/__overlay__/waveshare32b@0:reset-gpios:0", "/fragment@2/__overlay__/waveshare32b@0:dc-gpios:0", "/fragment@2/__overlay__/waveshare32b_ts@1:interrupt-parent:0", "/fragment@2/__overlay__/waveshare32b_ts@1:pendown-gpio:0"; }; __local_fixups__ { fixup = "/fragment@2/__overlay__/waveshare32b@0:pinctrl-0:0", "/__overrides__:speed:0", "/__overrides__:rotate:0", "/__overrides__:fps:0", "/__overrides__:debug:0"; }; };
Device Tree って何か?
簡単にいうとそのハードウェアのドライバの用の設定ファイル。ほぼ同じ制御方法をするハードウェアであっても、細かい制御アドレスの違い・使用バス・接続されているGPIOピンの違いが存在する。これらをいちいちカーネルにハードコードしてコンパイルするのは面倒なので、設定ファイルとして分離してある。ARM Linux だと標準的に使われている。
DTS ファイルの書きかた https://elinux.org/Device_Tree_Usage
- compatible = "ilitek,ili9340" の部分でドライバを指定している "vendor,product" 形式。
正直読むのに苦労する。完全に理解してない。
タッチコントローラのキャリブレーション
$ DISPLAY=:0 xinput_calibrator ... Section "InputClass" Identifier "calibration" MatchProduct "ADS7846 Touchscreen" Option "Calibration" "195 3780 3881 252" Option "SwapAxes" "1" EndSection
$ sudo vi /usr/share/X11/xorg.conf.d/99-calibration.conf # copy calibration from above