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端子の設定で作成したサービスは使えなくなるので無効にしておきましょう。
##DeviceTreeSouceコード
/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__ 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