Petalinux2018.3でキャラクタLCD制御(ST7032i) のバックアップ差分(No.2)

更新


  • 追加された行はこの色です。
  • 削除された行はこの色です。
[[電気回路/zynq/Petalinux2018.3環境を整える]]

* I2C 経由で繋いだキャラクタ型の液晶ディスプレイ(LCD)を制御する [#b227347f]

繋いだのはこれ [[digikey:NHD-C0216CIZ-FSW-FBW-3V3-ND]]

- 16 文字 x 2 行
- I2C 通信可能
16 文字 x 2 行 で白色バックライト付きの LCD

付属の PDF だけだといろいろ情報が足りなくて困るのだけれど、
どうやらこの LCD には ST7032i という有名なコントローラが載っているらしいので、
このキーワードで検索すればいろいろと情報が得られる。



* 環境 [#h9cf1202]

[[作業履歴>電気回路/zynq/Petalinux2018.3環境を整える#wa39ab55]] のように
Petalinux 2018.3 を基本として作業しています。

LCD は i2c-1 に繋がっているはずで、
Petalinux はちゃんとこれを認識して dtb に反映してくれています。
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 クロックになっている。

* まずはリセットピンを制御可能にする [#e9ee91d6]

** axi_gpio の追加 [#cf1a998e]

CPU から axi_gpio 経由で制御する。

vivado の Block Diagram に axi_gpio を置き、ダブルクリック。
GPIO Width に適当な値を入れる。
(ここでは LCD_RST ピン以外も制御したかったため5を入れた)

&ref(axi_gpio-width.png,,33%);

GPIO ポートの上で右クリック後 [Make External] する。

&ref(axi_gpio-make_external.png,,50%);

追加された GPIO_1 ポートをクリックして、プロパティエディタで適当な名前に変更。

&ref(axi_gpio-port-rename.png,,50%);

Diagram の右クリックから [Run Connection Automation] すると、

&ref(axi_gpio-connection.png,,33%);

Processor System Reset および AXI Interconnect が追加され、接続が完了する。

** design_1_wrapper の編集 [#td6a4ab7]

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),
        ...
 );

** ピン配置の指定 [#ie814751]

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]

- コメントは # の前に ; を付けておかないとエラーになるらしい

https://japan.xilinx.com/support/answers/51613.html

** vivado 上でビルド [#u89f9a56]

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] してからビルドしたところうまくいった。

&ref(design-reset-output.png,,50%);
** PL をプログラムする [#i092c854]

(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 の更新 [#tab2c783]

上のようにして追加した 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 との通信 [#cdba4dc7]

LCD のアドレスは 0x7c だそうで、

 $ mkdir lcd-control
 $ cd lcd-control
 $ git init
 $ jed lcd-control.c


Counter: 3274 (from 2010/06/03), today: 3, yesterday: 0