IMX8QXP spi slave从模式测试

        在汽车的应用中,是有可能使用 SPI 接口来连接外设的,甚至有可能是 MCU做主通过SPI接口来访问 i.MX8X,刚好我们项目中MCU做从效率低有丢包情况,所以测试一下i.MX8X从模式MCU主模式。

IMX8QXP SPI资源

         疑问:MCLK_IN0,MCLK_IN0,MCLK_OUT0为何与SPI2复用,但电路图设计分开??

16.12.3.1 LPSPI register descriptions

         4个spi,怎么单独设置每个spi的寄存器呢?

16.12.3.1.9 Configuration Register 1 (CFGR1)

IMX8QXP demo板spi0与spi3飞线连接

         由于驱动中PINCFG[25/24]默认设置spi从模式下SDI和SDO交换输入输出,所以需要反向连接如下所示:

dts文件和驱动

        参考手册《MX8X_4.14.98_ga_kernel_V3-20190903_chn.pdf6.10 SPI与SPI Slave驱动

        由于spi3的MISO不好飞线,所以spi3做主,spi0做从。内核版本基于NXP的linux-4.14.98

        修改设备树:fsl-imx8qxp-mek.dtsi

		pinctrl_lpspi0: lpspi0grp {
			fsl,pins = <
				SC_P_SPI0_SCK_ADMA_SPI0_SCK 0x0600004c
				SC_P_SPI0_SDO_ADMA_SPI0_SDO 0x0600004c
				SC_P_SPI0_SDI_ADMA_SPI0_SDI 0x0600004c
				SC_P_SPI0_CS0_ADMA_SPI0_CS0 0x0600004c

			>;
		};
 
		pinctrl_lpspi3_cs: lpspi0cs {
			fsl,pins = <
				SC_P_SPI3_CS0_LSIO_GPIO0_IO16 0x21
			>;
		};

		pinctrl_lpspi3: lpspi3grp {
			fsl,pins = <
				SC_P_SPI3_SCK_ADMA_SPI3_SCK 0x0600004c
				SC_P_SPI3_SDO_ADMA_SPI3_SDO 0x0600004c
				SC_P_SPI3_SDI_ADMA_SPI3_SDI 0x0600004c
			>;
		};


&lpspi0 { 
	#address-cells = <1>;
	#size-cells = <0>;
	fsl,spi-num-chipselects = <1>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_lpspi0>;
	spi-slave;
	status = "okay";
};

&lpspi3 {
	#address-cells = <1>;
	#size-cells = <0>;
	fsl,spi-num-chipselects = <1>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_lpspi3  &pinctrl_lpspi3_cs>;
	cs-gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
	status = "okay";
	spidev0: spi@0 {
		reg = <0>;
		compatible = "rohm,dh2228fv";
		spi-max-frequency = <30000000>;
	};
};

         fsl-imx8dx.dtsi

	lpspi3: lpspi@5a030000 { //寄存器值
		compatible = "fsl,imx7ulp-spi";
		reg = <0x0 0x5a030000 0x0 0x10000>;
		interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>; //中断号
		interrupt-parent = <&gic>;
		clocks = <&clk IMX8QXP_SPI3_CLK>,
					<&clk IMX8QXP_SPI3_IPG_CLK>;
		clock-names = "per", "ipg";
		assigned-clocks = <&clk IMX8QXP_SPI3_CLK>;
		assigned-clock-rates = <20000000>;
		power-domains = <&pd_dma2_chan7>; //johnli details as follows DMA channel
		dma-names = "tx","rx";
		dmas = <&edma2 7 0 0>, <&edma2 6 0 1>;
		status = "disabled";
	};
			
			pd_dma_lpspi3: PD_DMA_SPI_3 { //PD
				reg = <SC_R_SPI_3>;
				#power-domain-cells = <0>;
				power-domains = <&pd_dma>;
				wakeup-irq = <339>;
//johnli add
				pd_dma2_chan6: PD_LPSPI3_RX {
					reg = <SC_R_DMA_2_CH6>;
					power-domains =<&pd_dma_lpspi3>;
					#power-domain-cells = <0>;
					#address-cells = <1>;
					#size-cells = <0>;

					pd_dma2_chan7: PD_LPSPI3_TX {
						reg = <SC_R_DMA_2_CH7>;
						power-domains =<&pd_dma2_chan6>;
						#power-domain-cells = <0>;
						#address-cells = <1>;
						#size-cells = <0>;
					};
				};
//end
			};
	从:
	echo spidev > /sys/class/spi_slave/spi0/slave
	./spidev-test -D /dev/spidev0.0 -p slave-hello-to-master -v

	主:
	./spidev-test -D /dev/spidev1.0 -p slave-hello-to-master -v 

root@genvict_imx8qxp:~# ls /dev/spidev* -l
crw------- 1 root root 236, 0 Mar 17 11:59 /dev/spidev2.0
crw------- 1 root root 153, 0 Mar 17 09:38 /dev/spidev3.0
root@genvict_imx8qxp:~# ls /sys/class/spi_master/
spi2  spi3
root@genvict_imx8qxp:~# ls /sys/class/spi_master/ -l
total 0
lrwxrwxrwx 1 root root 0 Mar 17 09:38 spi2 -> ../../devices/platform/5a020000.lpspi/spi_master/spi2
lrwxrwxrwx 1 root root 0 Mar 17 09:38 spi3 -> ../../devices/platform/5a030000.lpspi/spi_master/spi3
root@genvict_imx8qxp:~# ls /sys/class/spi_slave/    
root@genvict_imx8qxp:~# ls /sys/class/spi*      
/sys/class/spi_master:
spi2  spi3

/sys/class/spi_slave:

/sys/class/spidev:
spidev3.0

/sys/class/spidev2.0:
spidev2.0

        怎么查看已经设置为slave模式了呢?spi_master下面还是有spi3,spi_slave下面没有设备节点。

        外部使用MCU做主模式验证【验证不通过】

NXP官方方案测试-失败的案例

        NXP官方手册《MX8X_4.14.98_ga_kernel_V3-20190903_chn.pdf》《6.10 SPI与SPI Slave驱动》,修改项目的DTS设备树,spi2做主,spi3做从:

pinctrl_lpspi3: lpspi3grp { 
	fsl,pins = < 
		SC_P_SPI3_SCK_ADMA_SPI3_SCK 0x0600004c 
		SC_P_SPI3_SDO_ADMA_SPI3_SDO 0x0600004c 
		SC_P_SPI3_SDI_ADMA_SPI3_SDI 0x0600004c 
		SC_P_SPI3_CS0_ADMA_SPI3_CS0 0x0600004c 
	>; 
};

&lpspi3 { 
	#address-cells = <1>;
	#size-cells = <0>; 
	fsl,spi-num-chipselects = <1>; 
	pinctrl-names = "default"; 
	pinctrl-0 = <&pinctrl_lpspi3>; 
	spi-slave; 
	status = "okay"; 
};
			pd_dma_lpspi3: PD_DMA_SPI_3 { //PD
				reg = <SC_R_SPI_3>;
				#power-domain-cells = <0>;
				power-domains = <&pd_dma>;
				wakeup-irq = <339>;

				pd_dma2_chan6: PD_LPSPI3_RX {
					reg = <SC_R_DMA_2_CH6>;
					power-domains =<&pd_dma_lpspi3>;
					#power-domain-cells = <0>;
					#address-cells = <1>;
					#size-cells = <0>;

					pd_dma2_chan7: PD_LPSPI3_TX {
						reg = <SC_R_DMA_2_CH7>;
						power-domains =<&pd_dma2_chan6>;
						#power-domain-cells = <0>;
						#address-cells = <1>;
						#size-cells = <0>;
					};
				};
			};

	lpspi3: lpspi@5a030000 {
		compatible = "fsl,imx7ulp-spi";
		reg = <0x0 0x5a030000 0x0 0x10000>;
		interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
		interrupt-parent = <&gic>;
		clocks = <&clk IMX8QXP_SPI3_CLK>,
					<&clk IMX8QXP_SPI3_IPG_CLK>;
		clock-names = "per", "ipg";
		assigned-clocks = <&clk IMX8QXP_SPI3_CLK>;
		assigned-clock-rates = <20000000>;
		power-domains = <&pd_dma2_chan7>; //johnli details as follows DMA channel
		dma-names = "tx","rx";
		dmas = <&edma2 7 0 0>, <&edma2 6 0 1>;
		status = "disabled";
	};
root@genvict_imx8qxp:~# ls /dev/spidev2.0  -l
crw------- 1 root root 236, 0 Mar 17 11:59 /dev/spidev2.0
root@genvict_imx8qxp:~# ls /sys/class/spi_master/
spi2
root@genvict_imx8qxp:~# ls /sys/class/spi_slave/ 
spi3
root@genvict_imx8qxp:~# ls /sys/class/spi_slave/spi3/
device  of_node  power  slave  statistics  subsystem  uevent
root@genvict_imx8qxp:~# echo spidev > /sys/class/spi_slave/spi3/slave
root@genvict_imx8qxp:~# ls /dev/spidev* -l
crw------- 1 root root 236, 0 Mar 17 11:59 /dev/spidev2.0
crw------- 1 root root 153, 0 Mar 17 12:02 /dev/spidev3.0

        编译内核工具spidev_test:tools/spi

[wangyb@wangyb-VirtualBox:spi]$ ls
Build  include  Makefile  spidev_fdx  spidev_fdx.c  spidev_fdx-in.o  spidev_fdx.o  spidev_test  spidev_test.c  spidev_test-in.o  spidev_test.o
root@genvict_imx8qxp:~# ./spidev_test --help
./spidev_test: unrecognized option '--help'
Usage: ./spidev_test [-DsbdlHOLC3vpNR24SI]
  -D --device   device to use (default /dev/spidev1.1)
  -s --speed    max speed (Hz)
  -d --delay    delay (usec)
  -b --bpw      bits per word
  -i --input    input data from a file (e.g. "test.bin")
  -o --output   output data to a file (e.g. "results.bin")
  -l --loop     loopback
  -H --cpha     clock phase
  -O --cpol     clock polarity
  -L --lsb      least significant bit first
  -C --cs-high  chip select active high
  -3 --3wire    SI/SO signals shared
  -v --verbose  Verbose (show tx buffer)
  -p            Send data (e.g. "1234\xde\xad")
  -N --no-cs    no chip select
  -R --ready    slave pulls low to pause
  -2 --dual     dual transfer
  -4 --quad     quad transfer
  -S --size     transfer size
  -I --iter     iterations

        NXP IMX8QXP demo板SPI0连接测试用例:

         项目中由于SPI2连接了安全芯片,IMX8与MCU验证:IMX8从机,MCU主机。

/home/root/spidev_test -D /dev/spidev3.0 -p slave-hello-to-master -v

spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)

        从机未开始运行测试程序时,主机时钟片选核发送数据正常,从机运行测试程序后,发送数据异常。

        参考手册,使用IMX8QXP B.V demo板,短接SPI0与SPI3,由于SPI3的MISO直接到连接器不能飞线,所以改为SPI3作为主机,SPI0作为从机。

        时钟和片选波形正常:

        全部参考手册默认dts配置,SPI3单独发送数据正常:

         从机运行spidev-test接收数据,发送数据就开始异常了:

root@OpenWrt:~# ./spidev-test -D /dev/spidev1.0 -p slave-hello-to-master -v
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
TX | 73 6C 61 76 65 2D 68 65 6C 6C 6F 2D 74 6F 2D 6D 61 73 74 65 72 __ __ __ __ __ __ __ __ __ __ __  | slave-hello-to-master
RX | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 __ __ __ __ __ __ __ __ __ __ __  | .....................
root@OpenWrt:~# ./spidev-test -D /dev/spidev0.0 -p slave-hello-to-master -v
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
TX | 73 6C 61 76 65 2D 68 65 6C 6C 6F 2D 74 6F 2D 6D 61 73 74 65 72 __ __ __ __ __ __ __ __ __ __ __  | slave-hello-to-master
RX | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 __ __ __ __ __ __ __ __ __ __ __  | .....................

         后面主机单独发送电平不能拉低:

         使用spi-slave-read接收数据异常:

root@OpenWrt:~# ./spi-slave-read-2 
recv :0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0  0 
recv :0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0  1 

        这是为什么呢? 改数据线为上下拉都无改善,难道是NXP的SPI从模式本身有问题,或者需要打驱动补丁? 

        咨询过NXP支持,看到示波器波形得出两端都在驱动,所以需要交叉数据线,然后通信就正常了:

         通过查看手册和驱动有说明:

        spi-fsl-lpspi.c :405

         还需修改驱动测试一下不交叉线的情况,验证不交叉飞线可行:

        #define CFGR1_PINCFG 0

        附上spi slave补丁:

From bfb5b9bbcf115410353b9b952516814c3ea610c1 Mon Sep 17 00:00:00 2001
From: Taichun Yuan <[email protected]>
Date: Mon, 18 Nov 2019 14:08:32 +0800
Subject: [PATCH 2/2] enable lpspi3 as spi_slave

Note:
    When working under slave mode, spidev should not be in
the DT since it will be dynamically controlled by the sysfs:
    /sys/class/spi_slave/spi<X>/slave
To enable spidev on slave:
    echo spidev > /sys/class/spi_slave/spi<X>/slave
There're also other modes supported if enabled in defconfig
    spi-slave-system-control
    spi-slave-time
Details can be found:
    /Documentation/spi/spi-summary
LWN for slave support:
    https://lwn.net/Articles/723440/
---
 arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek.dtsi | 7 +------
 arch/arm64/configs/defconfig                       | 4 ++++
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek.dtsi b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek.dtsi
index cda6e7902..b345c1c4a 100755
--- a/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-imx8qxp-mek.dtsi
@@ -1417,12 +1417,7 @@
         fsl,spi-num-chipselects = <1>;
         pinctrl-names = "default";
         pinctrl-0 = <&pinctrl_lpspi3>;
+        spi-slave;
         status = "okay";
-
-        spidev0: spi@0 {
-                reg = <0>;
-                compatible = "rohm,dh2228fv";
-                spi-max-frequency = <10000000>;
-        };
 };
 
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 9c3d9ea7c..9bf0676e2 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -826,3 +826,7 @@ CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
 CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
 CONFIG_CRYPTO_CHACHA20_NEON=m
 CONFIG_CRYPTO_AES_ARM64_BS=m
+CONFIG_SPI_SPIDEV=y
+CONFIG_SPI_SLAVE=y
+CONFIG_SPI_SLAVE_TIME=y
+CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y
-- 
2.17.0

猜你喜欢

转载自blog.csdn.net/TSZ0000/article/details/123393514
SPI
今日推荐