Petalinux2018.3でキャラクタLCD制御(ST7032i) の履歴(No.2)
更新- 履歴一覧
- 差分 を表示
- 現在との差分 を表示
- ソース を表示
- 電気回路/zynq/Petalinux2018.3でキャラクタLCD制御(ST7032i) へ行く。
電気回路/zynq/Petalinux2018.3環境を整える
I2C 経由で繋いだキャラクタ型の液晶ディスプレイ(LCD)を制御する†
繋いだのはこれ digikey:NHD-C0216CIZ-FSW-FBW-3V3-ND
16 文字 x 2 行 で白色バックライト付きの LCD
付属の PDF だけだといろいろ情報が足りなくて困るのだけれど、 どうやらこの LCD には ST7032i という有名なコントローラが載っているらしいので、 このキーワードで検索すればいろいろと情報が得られる。
環境†
作業履歴 のように Petalinux 2018.3 を基本として作業しています。
LCD は i2c-1 に繋がっているはず。
Petalinux は i2c-1 を認識して dtb に反映してくれています。
Zynq 機器で動作する Ubuntu 18.04LTC のコンソールで、
LANG:console $ less /boot/system.dts ... i2c1: i2c@e0005000 { compatible = "cdns,i2c-r1p10"; status = "disabled"; clocks = <&clkc 39>; interrupt-parent = <&intc>; interrupts = <0 48 4>; reg = <0xe0005000 0x1000>; #address-cells = <1>; #size-cells = <0>; }; ... $ sudo grep i2c /var/log/syslog Jan 28 15:58:20 zturn2018_3 kernel: i2c /dev entries driver Jan 28 15:58:20 zturn2018_3 kernel: cdns-i2c e0004000.i2c: 400 kHz mmio e0004000 irq 24 Jan 28 15:58:20 zturn2018_3 kernel: cdns-i2c e0005000.i2c: 400 kHz mmio e0005000 irq 25 $ ls -l /dev | grep i2c crw------- 1 root root 89, 0 1月 28 15:58 i2c-0 crw------- 1 root root 89, 1 1月 28 15:58 i2c-1
ちゃんと 400kHz クロックになっている。
まずはリセットピンを制御可能にする†
axi_gpio の追加†
CPU から axi_gpio 経由で制御する。
vivado の Block Diagram に axi_gpio を置き、ダブルクリック。 GPIO Width に適当な値を入れる。 (ここでは LCD_RST ピン以外も制御したかったため5を入れた)
GPIO ポートの上で右クリック後 [Make External] する。
追加された GPIO_1 ポートをクリックして、プロパティエディタで適当な名前に変更。
Diagram の右クリックから [Run Connection Automation] すると、
Processor System Reset および AXI Interconnect が追加され、接続が完了する。
design_1_wrapper の編集†
design_1 は Dialog から生成されるのだけれど、 design_1_wrapper は手動で変更しなければならないらしい?
LANG:verilog module design_1_wrapper( ... //user define io, DATAPINS, ... ); inout [4:0] DATAPINS; .... // user wire define code wire [4:0] DATAPINS_i, DATAPINS_o, DATAPINS_t; ... //user logic example IOBUF DATAPINS_0_iobuf(.I(DATAPINS_o[0]),.IO(DATAPINS[0]),.O(DATAPINS_i[0]),.T(DATAPINS_t[0])); IOBUF DATAPINS_1_iobuf(.I(DATAPINS_o[1]),.IO(DATAPINS[1]),.O(DATAPINS_i[1]),.T(DATAPINS_t[1])); IOBUF DATAPINS_2_iobuf(.I(DATAPINS_o[2]),.IO(DATAPINS[2]),.O(DATAPINS_i[2]),.T(DATAPINS_t[2])); IOBUF DATAPINS_3_iobuf(.I(DATAPINS_o[3]),.IO(DATAPINS[3]),.O(DATAPINS_i[3]),.T(DATAPINS_t[3])); IOBUF DATAPINS_4_iobuf(.I(DATAPINS_o[4]),.IO(DATAPINS[4]),.O(DATAPINS_i[4]),.T(DATAPINS_t[4])); design_1 design_1_i( ... .DATAPINS_tri_i(DATAPINS_i), .DATAPINS_tri_o(DATAPINS_o), .DATAPINS_tri_t(DATAPINS_i), ... );
ピン配置の指定†
xdc ファイルの中で PACKAGE_PIN を指定する。
LANG:xdc set_property PACKAGE_PIN A20 [get_ports {DATAPINS[4]}] ;# IO_B35_LN[2] set_property IOSTANDARD LVCMOS33 [get_ports {DATAPINS[4]}] ;# IO_B35_LN[2]
- コメントは # の前に ; を付けておかないとエラーになるらしい
vivado 上でビルド†
vivado 上で Generate Block Design 後、Generate Bitstream する。
あれ?
[Synth 8-439] module 'design_1_processing_system7_0_0' not found ["(snip).srcs/sources_1/bd/design_1/synth/design_1.v":239]
のエラーが出た。
[Design Sources]-[design_1_wrapper]-[design_1_i] の上で右クリックから、 [Reset Output Products] してからビルドしたところうまくいった。
PL をプログラムする†
(project).runs\impl_1\design_1_wrapper.bit を ~/lcd-control/design_1_wrapper.bit にコピーする
LANG:console $ sudo fpga-bit-to-bin.py --flip design_1_wrapper.bit /lib/firmware/bit.bin/gpio1.bit.bin $ sudo mkdir -p /sys/kernel/config/device-tree/overlays/fpga-region $ cat << EOT | dtc -I dts -O dtb | sudo tee /sys/kernel/config/device-tree/overlays/fpga-region/dtbo > // Device Tree File for FPGA Region: fpga_reg.dts > /dts-v1/; > /plugin/; > / { > fragment@0 { > target-path = "/fpga-full"; > #address-cells = <1>; > #size-cells = <1>; > __overlay__ { > #address-cells = <1>; > #size-cells = <1>; > firmware-name = "bit.bin/gpio1.bit.bin"; > }; > }; > }; > EOT
devicetree.dtb の更新†
上のようにして追加した axi_gpio は petalinux の作る system.dtb に現れるんだろうか?
試してみたいところだが、system.dtb のみをビルドする方法が分からない
普通にやるなら hdf を petalinux へ持って行って、 もう一度 petalinux-configure してから petalinux-build だけど、 これをやると小一時間かかるのでいくらなんでも・・・
そこで zynq 上で 電気回路/zynq/Petalinux2018.3でPLとDevice Treeを動的に変更する#fc20918e で作成した /boot/system.dts を見ながら対応する overlay を作成する。
LANG:console $ less /boot/system.dts ... amba: amba { ... gpio0: gpio@e000a000 { compatible = "xlnx,zynq-gpio-1.0"; #gpio-cells = <2>; clocks = <&clkc 42>; gpio-controller; interrupt-controller; #interrupt-cells = <2>; interrupt-parent = <&intc>; interrupts = <0 20 4>; reg = <0xe000a000 0x1000>; }; ... $ cat << EOT > gpio1.dtso > // Device Tree File for gpio1 > /dts-v1/; > /plugin/; > / { > fragment@0 { > target-path = "/amba"; > __overlay__ { > #address-cells = <1>; > #size-cells = <1>; > gpio1: gpio@41200000 { > compatible = "xlnx,zynq-gpio-1.0"; > #gpio-cells = <2>; > clocks = <1 42>; > gpio-controller; > interrupt-controller; > #interrupt-cells = <2>; > interrupt-parent = <4>; > interrupts = <0 20 4>; > reg = <0x41200000 0x1000>; > }; > }; > }; > }; > EOT $ dtc -o dtb gpio1.dtso -o gpio1.dtbo gpio1.dtbo: Warning (unit_address_vs_reg): Node /fragment@0 has a unit name, but no reg property gpio1.dtbo: Warning (clocks_property): Could not get phandle node for /fragment@0/__overlay__/gpio@41200000:clocks(cell 0) gpio1.dtbo: Warning (interrupts_property): Bad interrupt-parent phandle for /fragment@0/__overlay__/gpio@41200000 $ ls /sys/kernel/config/device-tree/overlays/ $ sudo mkdir -p /sys/kernel/config/device-tree/overlays/gpio1 $ ls /sys/kernel/config/device-tree/overlays/gpio1 dtbo path status $ sudo dtc -o dtb gpio1.dtso -o /sys/kernel/config/device-tree/overlays/gpio1/dtbo $ ls -l /proc/device-tree/amba/gpi* /proc/device-tree/amba/gpio@41200000: total 0 -r--r--r-- 1 root root 4 3月 22 16:21 '#gpio-cells' -r--r--r-- 1 root root 4 3月 22 16:21 '#interrupt-cells' -r--r--r-- 1 root root 8 3月 22 16:21 clocks -r--r--r-- 1 root root 19 3月 22 16:20 compatible -r--r--r-- 1 root root 0 3月 22 16:21 gpio-controller -r--r--r-- 1 root root 0 3月 22 16:21 interrupt-controller -r--r--r-- 1 root root 4 3月 22 16:21 interrupt-parent -r--r--r-- 1 root root 12 3月 22 16:21 interrupts -r--r--r-- 1 root root 5 3月 22 16:21 name -r--r--r-- 1 root root 8 3月 22 16:21 reg /proc/device-tree/amba/gpio@e000a000: total 0 -r--r--r-- 1 root root 4 3月 22 16:21 '#gpio-cells' -r--r--r-- 1 root root 4 3月 22 16:21 '#interrupt-cells' -r--r--r-- 1 root root 8 3月 22 16:21 clocks -r--r--r-- 1 root root 19 3月 22 16:21 compatible -r--r--r-- 1 root root 4 3月 22 16:18 emio-gpio-width -r--r--r-- 1 root root 0 3月 22 16:21 gpio-controller -r--r--r-- 1 root root 4 3月 22 16:21 gpio-mask-high -r--r--r-- 1 root root 4 3月 22 16:21 gpio-mask-low -r--r--r-- 1 root root 0 3月 22 16:21 interrupt-controller -r--r--r-- 1 root root 4 3月 22 16:21 interrupt-parent -r--r--r-- 1 root root 12 3月 22 16:21 interrupts -r--r--r-- 1 root root 5 3月 22 16:21 name -r--r--r-- 1 root root 4 3月 22 16:21 phandle -r--r--r-- 1 root root 8 3月 22 16:21 reg $ # 登録できたのは良いけれど、gpio@e000a000 に比べると項目が少ない? $ cat /proc/device-tree/amba/gpio@41200000/compatible xlnx,zynq-gpio-1.0 $ od -tx1z /proc/device-tree/amba/gpio@e000a000/emio-gpio-width 0000000 00 00 00 40 >...@< 0000004 $ od -tx1z /proc/device-tree/amba/gpio@e000a000/gpio-mask-high 0000000 00 00 00 00 >....< 0000004 $ od -tx1z /proc/device-tree/amba/gpio@e000a000/gpio-mask-low 0000000 00 00 56 00 >..V.< 0000004 $ od -tx1z /proc/device-tree/amba/gpio@e000a000/phandle 0000000 00 00 00 06 >....< 0000004
LCD との通信†
LCD のアドレスは 0x7c だそうで、
$ mkdir lcd-control $ cd lcd-control $ git init $ jed lcd-control.c