GPIOがうまくいったら次はSPIということで、ROCK64でどうやるかを調べてみたところ
https://forum.pine64.org/showthread.php?tid=6282&pid=40056#pid40056
のスレッドで書いてあることが大いに参考になったので、こちらの内容を基に動作を確認してみた。
* ayufanのkernel4.4系のOS(bionic-lxde-rock64-0.9.14-1159-armhf.img.xz)で動作確認したが
armbianの最新のKernel5.*系ではSPIのデバイスドライバがうまく認識しなかったので、注意。
まずはSPIのデバイス(/dev/devspi*)の認識が必要なので、デバイスツリーを更新するためのDTSファイル(spi1.dts)を作成。
その後dtcコマンドでdtsファイルをdtcファイルに変換し、カーネルにファイルを読み込ませてデバイスツリーを更新するという
流れになる。
うまく行けば/dev以下に「spidev32766.1」ファイルが生成。
$ vi spi1.dts
/dts-v1/;
/plugin/;
/ {
compatible = "pine64,rock64";
fragment@0 {
target-path = "/spi@ff190000";
__overlay__ {
spidev@1 {
compatible="rockchip,spidev";
reg=<1>;
spi-max-frequency=<10000000>;
};
};
};
};
$ dtc spi1.dts -o spi1.dtbo
$ mkdir /sys/kernel/config/device-tree/overlays/spi1
$ cat spi1.dtbo > /sys/kernel/config/device-tree/overlays/spi1/dtbo
$ ls /dev/spidev*
/dev/spidev32766.1
ついでに/sys/firmware/device/tree/baseの構成も確認してみると、オーバーレイで追加したデバイス情報が表示されていたのでツリーの更新も期待通りになっている。
$ dtc -I fs /sys/firmware/devicetree/base | less
...
spi@ff190000 {
reg = <0x0 0xff190000 0x0 0x1000>;
dmas = <0xc 0x8 0xc 0x9>;
interrupts = <0x0 0x31 0x4>;
pinctrl-0 = <0x4d 0x4e 0x4f 0x50>;
compatible = "rockchip,rk3328-spi", "rockchip,rk3066-spi";
clock-names = "spiclk", "apb_pclk";
clocks = <0x2 0x20 0x2 0xd1>;
status = "okay";
#address-cells = <0x1>;
phandle = <0xb0>;
#size-cells = <0x0>;
dma-names = "tx", "rx";
pinctrl-names = "default";
spidev@1 {
reg = <0x1>;
compatible = "rockchip,spidev";
spi-max-frequency = <0x989680>;
};
flash@0 {
reg = <0x0>;
compatible = "gigadevice,gd25q128", "jedec,spi-nor";
m25p,fast-read;
spi-max-frequency = <0x2faf080>;
#address-cells = <0x1>;
#size-cells = <0x1>;
partitions {
compatible = "fixed-partitions";
#address-cells = <0x1>;
#size-cells = <0x1>;
loader@8000 {
reg = <0x8000 0x3f0000>;
label = "loader";
};
};
...
ROCK64のPi2-BusからSPIを出力するとなると,ピン設定は以下になる。N_CSはGPIOを使うので、ここでは26ピンを使用。
PIN19: MOSI
PIN21: MISO
PIN23: CLK
PIN26: N_CS (GPIOで制御)
GPIOとSPIを制御するのにPython3を使いたいので、以下で必要なパッケージ(spidev, Rcok64-R64.GPIO,etc)をインストール。
$ apt update $ apt install python3-pip python3-setuptools python3-dev $ pip3 install spidev $ git clone https://github.com/Leapo/Rock64-R64.GPIO.git $ ln -s Rock64-R64.GPIO/R64 .
後はテスト用のプログラムを用意して実行。
$ vi spi_test.py #!/usr/bin/python3 import spidev import time import sys import R64.GPIO as GPIO PIN_CS = 26 # PIN26をCSに指定 GPIO.setmode(GPIO.BOARD) GPIO.setup(PIN_CS, GPIO.OUT, initial=GPIO.HIGH) spi = spidev.SpiDev() spi.open(32766,1) # /dev/spidev32766.1 spi.max_speed_hz = 2000000 # CLK 2MHz spi.mode = 0b00 # CPOL=0, CPHA=0 GPIO.output(PIN_CS, GPIO.LOW) # Low enable spi.xfer([0xaa, 0xbb, 0xcc, 0xdd]) # transfer data to MOSI GPIO.output(PIN_CS, GPIO.HIGH) # Hi disable GPIO.cleanup(PIN_CS) $ sudo python3 ./spi_test.py
ロジック・アナライザでピンの出力結果を確認したところ、バイト列「0xaa 0xbb 0xcc 0xdd」がCLK 2MHzでちゃんと再生されている。ただ、CSのHI/LOWの切り替えに時間がかかっている(約0.8ms)ので、上の方法だと高速にデバイス間を切り替えて通信するのは不向きかも。


ひとまずROCK64でもSPIを使うための手順が把握できたというところなので、次はSPIのデバイスでも何か動かしてみようかと思案中。
