BeagleBoneGreenのDeviceTree

GPSのPPS信号をBeagleBoneで取り込むにはDeviceTreeの作成が必要になります。
しかし、いろいろなサイトに載っている方法を試すとうまくいきません。
DeviceTreeCompilerを実行したときに、

```
$ dtc -O dtb -o DD-GPS-PPS-00A0.dtbo -b 0 -@ DD-GPS-PPS-00A0.dts
DD-GPS-PPS-00A0.dtbo: Warning (unit_address_vs_reg): Node /fragment@0 has a unit name, but no reg property
DD-GPS-PPS-00A0.dtbo: Warning (unit_address_vs_reg): Node /fragment@1 has a unit name, but no reg property
DD-GPS-PPS-00A0.dtbo: Warning (unit_address_vs_reg): Node /fragment@2 has a unit name, but no reg property
```
というような警告が出たり、
`/sys/devices/bone_capemgr.9/slots`なんてものは無いと怒られたりする。。。

調べたら、どうやらKernel4.xからはKernel OverlaysというのからU-Boot Overlaysに代わったらしいです。
>Kernel Overlays are going bye-bye, too many bugs, too many race conditions, no kernel maintainers interested. We've said our farewells and U-Boot Overlays is the way forward: https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#U-Boot_Overlays With multiple parties working on the U-Boot infrastructure.

#Kernel version
この記事でのカーネルバージョンは
`Linux beaglebone 4.14.71-ti-r80 #1 SMP PREEMPT Fri Oct 5 23:50:11 UTC 2018 armv7l GNU/Linux`
イメージは
`Debian 9.5 2018-10-07 4GB SD IoT` 
です。

#DeviceTreeSouceの作成

ファイルの作成

```
$ nano DD-GPS-PPS-00A0.dts
```
実際にはネットで調べながらコピペ&編集していたため、Windows上で作成してTeraTermでコピーしてました。
GPSのPPS信号はP9.28に接続しています。
UART1もついでに有効にしています。[BeagleBoneGreenのGPIO端子の設定](https://qiita.com/pata128/items/308e027dc8fb187fe479)で作成したサービスは使えなくなるので無効にしておきましょう。

##DeviceTreeSouceコード
```DD-GPS-PPS-00A0.dts
/dts-v1/;
/plugin/;

/ {
        compatible = "ti,beaglebone", "ti,beaglebone-black", "ti,beaglebone-green";

        /* identification */
        part-number = "DD-GPS-PPS";
        version = "00A0";

        /* state the resources this cape uses */
        exclusive-use =
                /* the pin header uses */
                "P9.24",         /* UART1 TXD */
                "P9.26",         /* UART1 RXD */
                "P9.28",         /* PPS/GPIO_113 */
                /* the hardware ip uses */
                "uart1";

        /*
         * Free up the pins used by the cape from the pinmux helpers.
         */
        fragment@0 {
            target = <&ocp>;
            __overlay__ {
               P9_24_pinmux { status = "disabled"; }; /* uart1_txd */
               P9_26_pinmux { status = "disabled"; }; /* uart1_rxd */
               P9_28_pinmux { status = "disabled"; }; 
            };
        };

        fragment@1 {
                target = <&am33xx_pinmux>;
                __overlay__ {
                        bb_uart1_pins: pinmux_bb_uart1_pins {
                                pinctrl-single,pins = <
                                      0x184 0x08 /* P9.24 uart1_txd.uart1_txd MODE0 OUTPUT (TX) */
                                      0x180 0x30 /* P9.26 uart1_rxd.uart1_rxd MODE0 INPUT (RX) */
                                >;
                        };

                        gps_pps_pins: pinmux_gps_pps_pins {
                                pinctrl-single,pins = <
                                      0x19C 0x27 /* P9.28 gpio3_17 PIN_INPUT | MUX_MODE7 */
                                >;
                        };

                };
        };

        fragment@2 {
                target = <&uart1>; /*really uart1*/

                __overlay__ {
                                status = "okay";
                                pinctrl-names = "default";
                                pinctrl-0 = <&bb_uart1_pins>;
                };
        };

        fragment@3 {
                target = <&ocp>;

                __overlay__ {
                        pps {
                                compatible = "pps-gpio";
                                status = "okay";
                                pinctrl-names = "default";
                                pinctrl-0 = <&gps_pps_pins>;
                                gpios = <&gpio3 17 0 >; /*really gpio3*/
                                assert-rising-edge;
                        };
                };
        };
};
```

##DeviceTreeSouce作成時の注意点
1.`fragment@0`で記述した部分では設定を変更するピンのpinmux helpersの機能を無効にしています。これをしないと以降のピン設定が反映されません。
2.`fragment@1`の部分`pinctrl-single,pins`に並んでいる二つの数字ですが、例えばP9.24の`0x184 0x08`について
-`0x184`はP9.29(UART1 TX)端子の機能を設定するためのレジスタ(*CONTROL_MODULE REGISTERS*の*conf_uart1_txd*レジスタ)のアドレスオフセット値を示しています。*CONTROL_MODULE REGISTERS*での*conf_uart1_txd*レジスタのアドレスオフセット値は 0x984 ですが、*conf_\<module>_\<pin>*レジスタの開始アドレスが 0x800 からですので設定値は 0xA84-0x800=0x184 となっています。
-`0x08`は*conf_uart1_txd*レジスタの設定値です。入出力方向、モード(機能)、内蔵プルアップ&プルダウンの設定を行います。

レシスタ詳細はAM3358のテクニカルリファレンスマニュアル
>http://www.tij.co.jp/jp/lit/ug/spruh73p/spruh73p.pdf
P1455 9.3.1 CONTROL_MODULE Registers
P1512 9.3.1.50 conf_<module>_<pin> Register (offset = 800h–A34h)

各端子のMODE設定値と機能の対応はAM3358のデータシート
>http://www.ti.com/lit/ds/sprs717k/sprs717k.pdf
P19 Table 4-2. Pin Attributes (ZCE and ZCZ Packages)

に記載されています。
アドレスオフセット値は以下でも確認できます。
>https://github.com/jadonk/bonescript/blob/64732854d4c296de8792d5d4c49639ae5f5ecede/src/bone.js

3.`fragment@2`の`target = <&uart1>`と`fragment@3`の`gpios = <&gpio3 17 0 >`は以前は"one based count"(1から数え始める)であったため、それぞれUART1は`&uart2`、GPIO3は`&gpio4`と各ペリフェラルの番号に+1する必要がありました。現在では"zero based count"(0から数え始める)になっていますのでペリフェラルの番号そのまま指定できます。

#DeviceTreeSouceのコンパイル
1.`bb.org-overlays`をクローンします。

```
$ git clone https://github.com/beagleboard/bb.org-overlays
```
2.先程作成した`DD-GPS-PPS-00A0.dts`を`bb.org-overlays/src/arm`ディレクトリにコピーします。

```
$ cp DD-GPS-PPS-00A0.dts bb.org-overlays/src/arm
```
3.install.shの実行。コンパイルからできあがった\*.dtboファイルの/lib/firmware/へのコピーもしてくれます。`bb.org-overlays/src/arm`には他のデバイスツリーファイルがありますので、これも全て\*.dtboにして/lib/firmware/へコピーしてくれます。uEnv.txtでファイルの指定しなければ他のデバイスツリーファイルが存在することは問題ないです。

```
$ cd ./bb.org-overlays
./install.sh
```

4.`/boot/uEnv.txt`の編集
DD-GPS-PPS-00A0.dtboをロードするように編集します。

```
sudo nano /boot/uEnv.txt
```


```
###Custom Cape
#dtb_overlay=/lib/firmware/<file8>.dtbo
###
```
の部分を

```
###Custom Cape
#dtb_overlay=/lib/firmware/<file8>.dtbo
dtb_overlay=/lib/firmware/DD-GPS-PPS-00A0.dtbo
###
```
と追記します。保存して再起動します。

#動作確認
再起動後に動作確認します。

```
$ dmesg | grep pps
[    0.618029] pps_core: LinuxPPS API ver. 1 registered
[    0.618037] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[   84.629947] pps pps0: new PPS source ocp:pps.-1
[   84.630076] pps pps0: Registered IRQ 123 as PPS source
```
`pps pps0`の行が表示されていれば成功です。また`ls /dev`で`pps0`が存在することでも確認できます。
PPS信号を正しく受信できているかは`ppstest `を使います。

```
$ sudo ppstest /dev/pps0
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1552488214.005742405, sequence: 1 - clear  0.000000000, sequence: 0
source 0 - assert 1552488215.005727821, sequence: 2 - clear  0.000000000, sequence: 0
```
UARTは`cat /dev/ttyS1`でNMEAが受信できていることを確認できます。gpsdが起動している場合は`cgps` `gpsmon`で確認します。

#参考
https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#U-Boot_Overlays
https://github.com/beagleboard/bb.org-overlays
https://github.com/beagleboard/bb.org-overlays/issues/91
https://elinux.org/Device_Tree_Reference
https://cdn-learn.adafruit.com/downloads/pdf/introduction-to-the-beaglebone-black-device-tree.pdf
http://www.tij.co.jp/product/jp/AM3358
https://dev.ti.com/pinmux