Petalinux2018.3でキャラクタLCD制御(ST7032i) のバックアップソース(No.6)

更新

[[電気回路/zynq/Petalinux2018.3環境を整える]]

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

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

16 文字 x 2 行 で白色バックライト付きの LCD

付属の PDF だけだといろいろ情報が足りなくて困るのだけれど、
どうやらこの LCD には [[Strawberry Linux の ST7032i>https://strawberry-linux.com/pub/ST7032i.pdf]] 
という有名なコントローラが載っているらしいので、このキーワードで検索すればいろいろと情報が得られる。

ST7032i のマニュアル:~
https://strawberry-linux.com/pub/ST7032i.pdf
* 環境 [#h9cf1202]

[[作業履歴>電気回路/zynq/Petalinux2018.3環境を整える#wa39ab55]] のように
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 クロックにはなっているが、status = "disabled" なのでこれを書き換える。

 LANG:console
 $ cat << EOT > i2c1-enabled.dtso
  /dts-v1/;
  /plugin/;
  / {
    fragment@0 {
      target-path = "/amba";
      __overlay__ {
        #address-cells = <1>;
        #size-cells = <1>;
        i2c1: i2c@e0005000 {
          status = "okay";
        };
      };
    };
  };
  EOT
 $ sudo dto i2c1-enabled i2c1-enabled.dtso
 $ cat /proc/device-tree/amba/i2c@e0005000/status
  okay

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

[[電気回路/zynq/Petalinux2018.3でaxi_gpio]] により、
/sys/class/gpio/gpio905/value 経由でリセットピンの上げ下げができるようになった。

リセットは Active Low なので、使用時には上げておく必要がある。

* LCD との通信 [#cdba4dc7]

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

- int i2c = open("/dev/i2c-1", O_RDWR);
- ioctl(i2c, I2C_SLAVE, 0x7c);
- write(i2c, &bytes, length_of_bytes);
- read(i2c, &buffer, length_to_receive);

の組み合わせでやりとりすればいいのかと思ったのだけれど、

https://www.kernel.org/doc/Documentation/i2c/dev-interface

を見ると、

> Note that only a subset of the I2C and SMBus protocols can be achieved by
the means of read() and write() calls. In particular, so-called combined
transactions (mixing read and write messages in the same transaction)
aren't supported. For this reason, this interface is almost never used by
user-space programs.

などと書かれてた orz

LCD の制御だけが目的の場合にはデータの読み出しを必要としないので、
まあそこそこ行ける・・・かな?

試してみる。

zynq のコンソールから、

 LANG:console
 $ mkdir ~/lcd-control
 $ cd ~/lcd-control
 $ git init
 $ jed lcd-control.c

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