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




