This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] PROCESSOR-SDK-AM335X:如何使用 SDK9配置 SPI 主/从模式

Guru**** 1815690 points
Other Parts Discussed in Thread: AM3351
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1397539/processor-sdk-am335x-how-to-configure-spi-master-slave-mode-with-sdk9

器件型号:PROCESSOR-SDK-AM335X
主题中讨论的其他器件:AM3351

工具与软件:

AM335x SDK v9的文档说明了 SPI 从模式受支持且不受支持。  在启用 DMA 的情况下是否支持 SPI 从模式?

不支持的功能
下面列出了 Linux 驱动程序不支持的功能。 请注意、这并不是详尽列表、而是仅考虑 SoC 中 SPI 外设能够实现但 Linux 驱动程序当前不支持的特性。

  • 仅在启用 DMA 时支持 SPI 从模式。

  • 不支持 SPI 从模式。

在 am33xx-L4.dtsi 中、我们发现 SPI0和 SPI1节点、

		target-module@30000 {			/* 0x48030000, ap 77 08.0 */
			compatible = "ti,sysc-omap2", "ti,sysc";
			reg = <0x30000 0x4>,
			      <0x30110 0x4>,
			      <0x30114 0x4>;
			reg-names = "rev", "sysc", "syss";
			ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
					 SYSC_OMAP2_SOFTRESET |
					 SYSC_OMAP2_AUTOIDLE)>;
			ti,sysc-sidle = <SYSC_IDLE_FORCE>,
					<SYSC_IDLE_NO>,
					<SYSC_IDLE_SMART>;
			ti,syss-mask = <1>;
			/* Domains (P, C): per_pwrdm, l4ls_clkdm */
			clocks = <&l4ls_clkctrl AM3_L4LS_SPI0_CLKCTRL 0>;
			clock-names = "fck";
			#address-cells = <1>;
			#size-cells = <1>;
			ranges = <0x0 0x30000 0x1000>;

			spi0: spi@0 {
				compatible = "ti,omap4-mcspi";
				#address-cells = <1>;
				#size-cells = <0>;
				reg = <0x0 0x400>;
				interrupts = <65>;
				ti,spi-num-cs = <2>;
				dmas = <&edma 16 0
					&edma 17 0
					&edma 18 0
					&edma 19 0>;
				dma-names = "tx0", "rx0", "tx1", "rx1";
				status = "disabled";
			};
		};
		
		target-module@a0000 {			/* 0x481a0000, ap 79 24.0 */
			compatible = "ti,sysc-omap2", "ti,sysc";
			reg = <0xa0000 0x4>,
			      <0xa0110 0x4>,
			      <0xa0114 0x4>;
			reg-names = "rev", "sysc", "syss";
			ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
					 SYSC_OMAP2_SOFTRESET |
					 SYSC_OMAP2_AUTOIDLE)>;
			ti,sysc-sidle = <SYSC_IDLE_FORCE>,
					<SYSC_IDLE_NO>,
					<SYSC_IDLE_SMART>;
			ti,syss-mask = <1>;
			/* Domains (P, C): per_pwrdm, l4ls_clkdm */
			clocks = <&l4ls_clkctrl AM3_L4LS_SPI1_CLKCTRL 0>;
			clock-names = "fck";
			#address-cells = <1>;
			#size-cells = <1>;
			ranges = <0x0 0xa0000 0x1000>;

			spi1: spi@0 {
				compatible = "ti,omap4-mcspi";
				#address-cells = <1>;
				#size-cells = <0>;
				reg = <0x0 0x400>;
				interrupts = <125>;
				ti,spi-num-cs = <2>;
				dmas = <&edma 42 0
					&edma 43 0
					&edma 44 0
					&edma 45 0>;
				dma-names = "tx0", "rx0", "tx1", "rx1";
				status = "disabled";
			};
		};

假设支持从模式、您是否能够在  启用 DMA 的情况下为 SPI1上的主器件和 SPI0上的从器件提供示例器件树节点?  大多数与 SPI 相关的线程早于 SDK9。

这是迄今为止 DTS 中 SPI0和 SPI1的情况。

&spi0 {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&spi0_pins>;
	ti,pindir-d0-out-d1-in = <1>;

	spislave@0 { /* Define a SPI device at chip select 0 in slave mode */
			compatible = "spislave"; /* Use the generic SPI slave-mode driver */
			spi-max-frequency = <32000000>; /* Set max SPI clock speed to 16MHz */
  		    spi-cpha;
			reg = <0>; /* Chip select 0 */
			spi-slave; /* Enable slave mode */
	};
};

&spi1 {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&spi1_pins>;

	spimaster@0 { /* Define a SPI device at chip select 0 */
			compatible = "spidev"; /* Use the generic SPI user-mode driver */
			spi-max-frequency = <16000000>; /* Set max SPI clock speed to 16MHz */
            spi-cpha;
			reg = <0>; /* Chip select 0 */
	};

与 SPI 相关的内核配置包括:
CONFIG_SPI_OMAP24xx=m
CONFIG_SPI_SPIDEV=m
CONFIG_SPI_SLAVE=y

重新启动后、我添加了没有错误的驱动程序、可以看到它们已加载、但/dev/中 没有 SPI 设备。
# modprobe spi_omap2_mcspi
# modprobe spidev
# lsmod
Module                  Size  Used by
spidev                 20480  0
spi_omap2_mcspi        24576  0
omap_sham              28672  0
omap_aes_driver        24576  0
omap_crypto            16384  1 omap_aes_driver
crypto_engine          20480  2 omap_aes_driver,omap_sham
omap_wdt               16384  0
rtc_omap               20480  1
wkup_m3_ipc            16384  0
wkup_m3_rproc          16384  1
设备树中的节点是否正确?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我们的专家目前不在办公室、请预计会延迟回复。

    此致、
    Krunal

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Krunal:
    感谢您的通知。 在我处理这一问题的过程中、我将继续更新该主题。

      当我们开始将工作代码从 SDK7移植到 SDK8时、这里有一个相关的线程。 我们停止等待 SDK9。 关于该线程、我们在不支持 b/c SPI 从模式时使用了定制驱动程序、因此 DTS SPI 节点中的"compatible ="slave、bf548"。 由于 SDK9 OMAP2 SPI 驱动器中现在支持的从模式、我们的首选策略是使用它。 我们来这里…

    我通过如下方式更改 DTS 节点、取得了进一步的进展(我相信):

    &spi0 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&spi0_pins>;
    	ti,pindir-d0-out-d1-in = <1>;
    
    	slave@0 { /* Define a SPI device at chip select 0 */
        compatible = "rohm,dh2228fv";
    		spi-max-frequency = <32000000>; /* Set max SPI clock speed to 32MHz */
    		spi-cpha;
    		reg = <0>; /* Chip select 0 */
    		spi-slave; /* Enable slave mode */
    	};
    };
    
    &spi1 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&spi1_pins>;
    
           master@0 {
                    compatible = "rohm,dh2228fv";
                    spi-max-frequency = <16000000>;
                    reg = <0>;
    								spi-cpha;
            };
    };

     现在、我在驱动程序加载时看到一条内核消息、spidev 模块会自动加载、并且/dev/中 有两个 SPI 设备。  

    [   12.951263] spi spi0.0: setup: speed 24000000, sample trailing edge, clk normal
    [   13.049742] spi spi1.0: setup: speed 16000000, sample trailing edge, clk normal
    [...]
    
    # lsmod | grep spi
    Module                  Size  Used by
    spidev                 20480  0
    spi_omap2_mcspi        24576  0
    
    # ls /dev/spi*
    /dev/spidev0.0  /dev/spidev1.0

    当我尝试针对 SDK9驱动程序的现有应用程序时、我将在此处进行更新...

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    使用 SDK9工具/SPI 中的 spidev_test、我将获得以下结果。

    # ./spidev_test -D /dev/spidev0.0 -v
    spi mode: 0x0
    bits per word: 8
    max speed: 500000 Hz (500 kHz)
    TX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 0D  |......@.........................|
    RX | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................................|
    
    # ./spidev_test -D /dev/spidev1.0 -v
    spi mode: 0x0
    bits per word: 8
    max speed: 500000 Hz (500 kHz)
    TX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 0D  |......@.........................|
    RX | 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01  |................................|
    

    如果我正确地解释了 SPI 模式、它们应该有所不同、因为 SPI0是在 DTS 中配置为 SPI-SLAVE 的。 此外、dts 节点中的最大速度不是最大速度。 因此、我还不相信 SPI 可以正常工作、尤其是我们的现有应用程序在通过 SPI 写入时遇到问题。 由于我无法将 MOSO 连接到 MISO 进行环回测试、是否有其他方法可以测试连接示波器的 SPI 短路情况?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这是分配给我的、我目前不在办公室、但这里仅提供一些快速指示、希望能帮助您顺利开展工作:

    1) 1)尝试添加 SPI-slave 控制器节点(. spi0 这里)、而不是实际的从器件定义。

    2)最大速度/实际速度可能会受到馈送 SPI 外设模块的时钟源以及它只能在内部使用整数分频器来实现请求的速度的限制。 因此、在某些情况下、实际速度将与配置的速度不同(较慢)。 您尝试配置的速度是多少?您测量的是什么?

    此致、Andreas

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Andreas:
    明白了;谢谢你让我知道你在做这个。

    我更正了上面的错误链接时、我们去年使用 SDK8与您一起开始使用这条路、但我们中止了等待 SDK9。 并介绍了我们如何使用 SPI0 (从器件)和 SPI1 (主器件)。  am3351-linux-support-for-spi-as-a-slave-device

    将 SPI-SLAVE 移到控制器节点会在 DTS 编译时产生错误:
      DTC     arch/arm/boot/dts/am335x-ct-apache.dtb
    arch/arm/boot/dts/am33xx-l4.dtsi:1728.16-1741.6: Warning (spi_bus_bridge): /ocp/interconnect@48000000/segment@100000/target-module@a0000/spi@0: incorrect #address-cells for SPI bus
      also defined at arch/arm/boot/dts/am335x-ct-gen2-common.dtsi:347.7-360.3
    arch/arm/boot/dts/am335x-ct-apache.dtb: Warning (spi_bus_reg): Failed prerequisite 'spi_bus_bridge'

    此外、我从 spidev_test 中报告的对"SPI 模式"的原始解释 不正确。 我认为它指的是模式1-4、而不是主/从模式
    模式0 (CPOL=0、CPHA=0)
    模式1 (CPOL=0、CPHA=1)
    模式2 (CPOL=1、CPHA=0)
    模式3 (CPOL=1、CPHA=1)
    但在控制器或子节点中设置 spi-cpha 不会影响 SPI 模式;始终为0x0。 我还在控制器和器件级别尝试了 spi-cpha=<1>、对模式没有任何影响。

    对于我们的传统应用、它"看起来"能够通过 SPI1 (主器件)发送数据、至少 WRITE (FD)会返回预期的写入字节数、并且不返回-1或设置 errno。 这会间歇性地成功。 在发送所有内容之后、它期望在 SPI1 (从器件)上接收来自另一个器件的请求、但未能接收到请求。 我认为 SPI0还未在从模式下正确配置。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    回复:设置 SPI 模式
    设置(spi-cpha/或 spi-cpol)必须位于器件定义中。 在控制器节点中使用 spi-cpha 和/或 spi-cpol 不起作用。 内核日志显示了加载驱动程序时引导期间的模式。 作为测试在 DTS 中设置 SPI0.slave (spi-cpha)、SPI1.master (spi-cpha 和 spi-cpol)、我们看到下面的效果。

    [ 12.609943] spi spi0.0:设置:速度24000000采样前沿时钟正常
    [ 12.749822] SPI spi1.0:设置:速度16000000采样后缘时钟反转

    至于 spidev_test 报告的内容...在查看源代码时、我们看到 spidev_test 在启动时设置了 SPI 模式。 如果不指定'--cpha'和/或'--cpol'、它会将模式(正确)设置为模式0。 我添加了一个仅查询选项、在启动后产生以下结果。 它准确地显示了我们对 DTS 中节点的期望。
    # spidev_test -D /dev/spidev0.0 -q
    /dev/spidev0.0的当前状态:SPI 模式0x1 (后沿采样、正常时钟)、每个字8位、设置为32000000Hz 最大值
    # spidev_test -D /dev/spidev1.0 -q
    /dev/spidev1.0的当前状态:SPI 模式0x1 (后沿采样、正常时钟)、每字8位、设置为最大16000000Hz

    以下是 SPI0和 SPI1的当前 dts 节点:

    &spi0 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&spi0_pins>;
    	ti,pindir-d0-out-d1-in = <1>;
    	spi-slave; /* Enable slave mode */
    	
    	slave@0 { 	/* Define a SPI device at chip select 0 */
    		compatible = "rohm,dh2228fv";
    		spi-max-frequency = <32000000>; /* Set max SPI clock speed to 32MHz */
    	/*	reg = <0>; /* Chip select 0 */
    		spi-cpha; 	/* SPI Mode 1 (CPOL=0, CPHA=1) */
    	};
    };
    
    &spi1 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&spi1_pins>;
    
    	master@0 {
    		compatible = "rohm,dh2228fv";
    		spi-max-frequency = <16000000>;
    		reg = <0>;
    		spi-cpha; 	/* SPI Mode 1 (CPOL=0, CPHA=1) */
    	};
    };

    我认为模式和速度配置正确。 我将单独回复 SPI0从器件状态。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    关于:SPI0从器件状态

    我向 spi-omap2-mcspi.c:omap2_mcspi_setup_transfer ()添加了一些调试逻辑、用以打印每个器件的主/从状态。
    if (spi_controller_is_slave(spi->controller)) {
    	dev_info(&spi->dev, "is a SLAVE\n");
    } else {
    	dev_info(&spi->dev, "is a MASTER\n");
    }
      
    我们看到、 在从器件 DTS 配置中、SPI0仍是具有 SPI-slave 的主器件。
    [ 706.295806] SPI spi0.0:设置:速度24000000、样本后沿、时钟正常
    [706.304657] SPI spi0.0:是主设备(SPI->CONTROLLER->SLAVE=0、SPI->MASTER->SLAVE=0)
    [ 706.336865] SPI spi1.0:设置:速度16000000、样本后沿、时钟正常
    [706.344277] SPI spi1.0:是主设备(SPI->CONTROLLER->SLAVE=0、SPI->MASTER->SLAVE=0)
    ....由于 spi_controller_is_slave()检查 CONFIG_SPI_SLAVE、我已经验证这是在内核.config 文件中设置的:
    $ grep CONFIG_SPI_SLAVE .config
    CONFIG_SPI_SLAVE=y
    CONFIG_SPI_SLAVE_TIME=y
    CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y
     
    如果 SPI-slave 需要位于控制器节点中、那么控制器还需要其他什么才能使 #address-cells 满意?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、Glen、

    尝试添加 SPI-slave 控制器节点(. spi0 此处)、而不是实际的从设备定义。

    您是否尝试过以上建议? 您发布的最新 DTS 仍在错误位置。

    另外、我将在接下来的两天离开办公室、因此回复将会延迟。

    此致、Andreas

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Andreas:

    是的、我尝试将 SPI-slave 移到控制器节点、但 DTS 编译失败:

    DTC arch/arm/boot/dts/am335x-ct-apache.dtb
    arch/arm/boot/dts/ am33xx-L4.dtsi :1728.16-1741.6:警告(SPI_BUS_BRIDGE):/ocp/interconnect@48000000/segment@100000/target-module@a0000/spi@0: SPI 总线的#address-cells 不正确
    也在 arch/arm/boot/dts/am335x-ct-gen2-common.dtsi:347.7-360.3中定义
    arch/arm/boot/dts/am335x-ct-apache.dtb:警告(spi_BUS_reg):失败的先决条件"spi_BUS_bridge"

    其中 SPI0是什么

    &spi0 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&spi0_pins>;
    	ti,pindir-d0-out-d1-in = <1>;
    	spi-slave; /* Enable slave mode */
    	
    	slave@0 { 	/* Define a SPI device at chip select 0 */
    		compatible = "rohm,dh2228fv";
    		spi-max-frequency = <32000000>; /* Set max SPI clock speed to 32MHz */
    		reg = <0>; /* Chip select 0 */
    		spi-cpha; 	/* SPI Mode 1 (CPOL=0, CPHA=1) */
    	};
    };

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    Andreas 将在接下来的几天内不在办公室、请预计回复会延迟。

    此致、
    Krunal

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我添加了"#address-cells =<0>;"并删除了控制器节点上的"reg =<0>"、这时 DTS 编译成功。  我现在看到 SPI0配置为从模式:

    # journalctl |grep spi
    Aug 12 17:00:14 1530163d kernel: spi spi0.0: setup: speed 48000000, sample trailing edge, clk normal
    Aug 12 17:00:14 1530163d kernel: spi spi0.0: is a SLAVE (spi->controller->slave=1, spi->master->slave=1)
    Aug 12 17:00:14 1530163d kernel: spi spi1.0: setup: speed 16000000, sample trailing edge, clk normal
    Aug 12 17:00:14 1530163d kernel: spi spi1.0: is a MASTER (spi->controller->slave=0, spi->master->slave=0)

    如果您同意 "#address-cells =<0>;"是必需的、请查看并注释。  

    当前 spi0 dts 从节点为:

    &spi0 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&spi0_pins>;
    	ti,pindir-d0-out-d1-in = <1>;
    	#address-cells = <0>;
    	spi-slave;
    
    	slave@0 { 	/* Define a SPI device at chip select 0 */
    		compatible = "rohm,dh2228fv";
    		spi-max-frequency = <16000000>; /* Set max SPI clock speed to 16MHz */
    		spi-cpha; 	/* SPI Mode 1 (CPOL=0, CPHA=1) */
    	};
    };

    此时、我希望(最乐观的)现有应用程序可以运行、但它不能运行。 主应用做的第一件事是通过 SPI1将"引导加载程序"发送到 DSP。 DSP 通过 SPI0发回一条消息、指出引导加载程序正在启动。 主应用程序从不会在 SPI1上看到消息。 我确实具有在旧 SDK 和 Linux 内核4.14下运行的 开发板的优势、因此我想我会在/sys/devices/platform/ocp 中比较这两款器件、但它们大不相同;我想这是因为 am33xx-L4.dtsi 器件树的发展。

    我在找到了 SPI 器件

    # spi0
    ocp/48000000.interconnect/48000000.interconnect:segment@0/48030000.target-module/48030000.spi# ls
    dma:rx0                            dma:tx1                            modalias                           spi_slave                          uevent
    dma:rx1                            driver                             of_node                            subsystem
    dma:tx0                            driver_override                    power                              supplier:platform:44e10800.pinmux
    
    # where spidev0.0 is found at
    ocp/48000000.interconnect/48000000.interconnect:segment@0/48030000.target-module/48030000.spi/spi_slave/spi0/spi0.0/spidev/spidev0.0
    
    # and spi1
    ocp/48000000.interconnect/48000000.interconnect:segment@100000/481a0000.target-module/481a0000.spi# ls
    dma:rx0                            dma:tx1                            modalias                           spi_master                         uevent
    dma:rx1                            driver                             of_node                            subsystem
    dma:tx0                            driver_override                    power                              supplier:platform:44e10800.pinmux
    
    # where spidev1.0 is found at
    ocp/48000000.interconnect/48000000.interconnect:segment@100000/481a0000.target-module/481a0000.spi/spi_master/spi1/spi1.0/spidev/spidev1.0

    这是否确认 DTS 现在正确? 为了使用 spidev0.0和 spidev1.0、我需要向应用程序添加什么新的/不同的内容(DMA 调用等)吗?

    我可以使用 SDK 中的 spidev_test 和 spidev_FDX 测试应用程序来读取/写入 SPI1 (配置为主器件)。 如果我尝试读取或写入/dev/spidev0.0 (配置为从器件)、该应用会挂起、并以100%的速度锁定 CPU。 A `kill -9`不会终止进程、并且当它尝试对进程进行 SIGTERM 时、重新引导将挂起。 必须重启电路板才能重启。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我在板上放置了一个 o 型示波器并确信 SPI1作为主器件可正常工作。 尝试从 spi0 (从器件)读取时、应用程序像 spidev_test 一样挂起。 我不认为 spi0在设备树中配置正确。

    请提供建议。 谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的
    为了完整起见、我将从 dts 文件中为 spi0和 SPI1添加 pinmux:

    	// spi0 is in Slave mode
        spi0_pins: pinmux_spi0_pins {
            pinctrl-single,pins = <
    			AM33XX_IOPAD(0x950, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* (A18) spi0_sclk.spi0_sclk */
    			AM33XX_IOPAD(0x954, PIN_OUTPUT | MUX_MODE0) /* (B18) spi0_d0.spi0_d0 MISO*/
    			AM33XX_IOPAD(0x958, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* (B17) spi0_d1.spi0_d1 MOSI*/
    			AM33XX_IOPAD(0x95c, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* (A17) spi0_cs0.spi0_cs0 */
           >;
        };
    
    	// spi1 is in Master mode
        spi1_pins: pinmux_spi1_pins {
            pinctrl-single,pins = <
    			AM33XX_IOPAD(0x964, PIN_OUTPUT | MUX_MODE4) /* (E18) eCAP0_in_PWM0_out.spi1_sclk */
    			AM33XX_IOPAD(0x968, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE4) /* (F19) uart0_ctsn.spi1_d0 MISO */
    			AM33XX_IOPAD(0x96c, PIN_OUTPUT | MUX_MODE4) /* (F18) uart0_rtsn.spi1_d1 MOSI */
    			AM33XX_IOPAD(0x978, PIN_OUTPUT | MUX_MODE4) /* (E17) uart1_ctsn.spi1_cs0 */
            >;
        };

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 

    作为附加测试、我将 spi0重新配置为器件树中的主器件、并使用 spidev_test 成功测试写入/读取。 SPI0以类似于作为主器件的 SPI1的方式进行响应。 读取字节均为0x00、因为另一端没有东西发回数据。 但它不像在从模式下那样挂起。 我可以看到 spi0 MOSI 上的数据

    # spidev_test -D /dev/spidev0.0 -s 1000000 -H -v
    Current state of /dev/spidev0.0: spi mode 0x1 (sample trailing edge, clk normal), 8 bits per word, set to 48000000 Hz max
    spi mode: 0x1
    bits per word: 8
    max speed: 1000000 Hz (1000 kHz)
    TX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 0D  |......@.........................|
    RX | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................................|
    #

    在从模式下、您最后看到的是"max speed:1000000Hz (1000kHz)"、然后 Sitara 跃升到 CPU 利用率的30%。 如果是 I Ctrl-C、利用率将跳到100%、并且无法终止进程或执行重新引导。 必须对电路板进行下电上电。  

    您能否使用 speedev_test 复制` pi-slave `s并进行测试?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 

    向 spi-omap2-mcspi.c 驱动程序添加了一些 dev_dbg ()语句、并比较了以下两个命令中的日志:

    #spidev_test -D /dev/spidev1.0 -v -H
    #spidev_test -D /dev/spidev0.0 -v -H

    走线与预期完全相同(如预期)、直至线条:
    [  88.001793] SPI_SLAVE spi0:spi-omap2-mcspi.c:omap2_mcspi_set_fifo ()

    其中驱动程序为 Slave spi0设置 FIFO 缓冲区、然后设置 Rx DMA 并调用调度程序 scheduler.c:wait_for_completion_interrupted()、但绝不返回。 我在调用调度程序之前添加了 dump_stack()。

     

    [   87.238463] spi_slave spi0: spi-omap2-mcspi.c:omap2_mcspi_setup()
    [   87.244723] spi_slave spi0: spi-omap2-mcspi.c:mcspi_write_reg()
    [   87.255467] spi_slave spi0: spi-omap2_mcspi: writing to register
    [   87.261549] spi_slave spi0: spi-omap2-mcspi.c:mcspi_write_reg()
    [   87.274058] spi_slave spi0: spi-omap2_mcspi: writing to register
    [   87.282857] spi_slave spi0: spi-omap2-mcspi.c:omap2_mcspi_setup_transfer()
    [   87.292606] spi_slave spi0: spi-omap2-mcspi.c:mcspi_write_cs_reg()
    [   87.301577] spi_slave spi0: spi-omap2_mcspi: writing to cs register
    [   87.310492] spi_slave spi0: spi-omap2-mcspi.c:mcspi_write_cs_reg()
    [   87.319587] spi_slave spi0: spi-omap2_mcspi: writing to cs register
    [   87.328547] spi_slave spi0: spi-omap2-mcspi.c:mcspi_read_cs_reg()
    [   87.334704] spi_slave spi0: spi-omap2_mcspi: reading from cs register
    [   87.345316] spidev spi0.0: setup: speed 48000000, sample trailing edge, clk normal
    [   87.352989] spi_slave spi0: spi-omap2-mcspi.c:omap2_mcspi_set_cs()
    [   87.365248] spi_slave spi0: spi-omap2-mcspi.c:mcspi_write_cs_reg()
    [   87.371500] spi_slave spi0: spi-omap2_mcspi: writing to cs register
    [   87.382397] spi_slave spi0: spi-omap2-mcspi.c:mcspi_read_cs_reg()
    [   87.391165] spi_slave spi0: spi-omap2_mcspi: reading from cs register
    [   87.400291] spidev spi0.0: setup mode 1, 8 bits/w, 48000000 Hz max --> 0
    [   87.409904] spidev spi0.0: spi mode 1
    [...]
    [   88.001793] spi_slave spi0: spi-omap2-mcspi.c:omap2_mcspi_set_fifo()
    [   88.014662] spi_slave spi0: spi-omap2-mcspi.c:mcspi_write_reg()
    [   88.023383] spi_slave spi0: spi-omap2_mcspi: writing to register
    [   88.032074] spi_slave spi0: spi-omap2-mcspi.c:mcspi_write_cs_reg()
    [   88.041474] spi_slave spi0: spi-omap2_mcspi: writing to cs register
    [   88.050806] spi_slave spi0: spi-omap2-mcspi.c:mcspi_read_cs_reg()
    [   88.059695] spi_slave spi0: spi-omap2_mcspi: reading from cs register
    [   88.068802] spi_slave spi0: spi-omap2_mcspi: set_fifo() success
    [   88.074781] spi_slave spi0: spi-omap2-mcspi.c:omap2_mcspi_set_enable()
    [   88.085197] spi_slave spi0: spi-omap2-mcspi.c:mcspi_write_cs_reg()
    [   88.091444] spi_slave spi0: spi-omap2_mcspi: writing to cs register
    [   88.103755] spi_slave spi0: spi-omap2-mcspi.c:mcspi_read_cs_reg()
    [   88.112488] spi_slave spi0: spi-omap2_mcspi: reading from cs register
    [   88.121527] spi_slave spi0: spi-omap2-mcspi.c:omap2_mcspi_txrx_dma()
    [   88.131001] spi_slave spi0: spi-omap2-mcspi.c:mcspi_write_reg()
    [   88.139602] spi_slave spi0: spi-omap2_mcspi: writing to register
    [   88.148249] spi_slave spi0: spi-omap2-mcspi.c:omap2_mcspi_tx_dma()
    [   88.154514] spi_slave spi0: spi-omap2-mcspi.c:omap2_mcspi_set_dma_req()
    [   88.165233] spi_slave spi0: spi-omap2-mcspi.c:mcspi_write_cs_reg()
    [   88.171480] spi_slave spi0: spi-omap2_mcspi: writing to cs register
    [   88.183352] spi_slave spi0: spi-omap2-mcspi.c:mcspi_read_cs_reg()
    [   88.192252] spi_slave spi0: spi-omap2_mcspi: reading from cs register
    [   88.201306] spi_slave spi0: spi-omap2-mcspi.c:omap2_mcspi_rx_dma()
    [   88.210279] spi_slave spi0: spi-omap2-mcspi.c:omap2_mcspi_set_dma_req()
    [   88.219583] spi_slave spi0: spi-omap2-mcspi.c:mcspi_write_cs_reg()
    [   88.228390] spi_slave spi0: spi-omap2_mcspi: writing to cs register
    [   88.234721] spi_slave spi0: spi-omap2-mcspi.c:mcspi_read_cs_reg()
    [   88.245181] spi_slave spi0: spi-omap2_mcspi: reading from cs register
    [   88.251690] spi_slave spi0: spi-omap2-mcspi.c:mcspi_wait_for_completion()
    [   88.263703] spi_slave spi0: spi-omap2_mcspi.c: wait_for_completion(on SLAVE)
    [   88.273335] spi_slave spi0: ---- Call Stack ----
    [   88.280520] CPU: 0 PID: 672 Comm: spidev_test Not tainted 6.1.46-00001-g50c291694ae5-dirty #25
    [   88.289212] Hardware name: TI AM335X_CT_GEN2 (Flattened Device Tree)
    [   88.295614]  unwind_backtrace from show_stack+0x10/0x14
    [   88.300908]  show_stack from dump_stack_lvl+0x24/0x2c
    [   88.306007]  dump_stack_lvl from mcspi_wait_for_completion+0x74/0xfc
    [   88.312427]  mcspi_wait_for_completion from omap2_mcspi_transfer_one+0x61c/0xe0c
    [   88.319888]  omap2_mcspi_transfer_one from spi_transfer_one_message+0x298/0x75c
    [   88.327265]  spi_transfer_one_message from __spi_pump_transfer_message+0x2e8/0x4e8
    [   88.334888]  __spi_pump_transfer_message from __spi_sync+0x2b8/0x3a0
    [   88.341289]  __spi_sync from spi_sync+0x24/0x3c
    [   88.345855]  spi_sync from spidev_sync+0x4c/0x80
    [   88.350516]  spidev_sync from spidev_ioctl+0x798/0x900
    [   88.355698]  spidev_ioctl from sys_ioctl+0x2a4/0xbdc
    [   88.360719]  sys_ioctl from ret_fast_syscall+0x0/0x54
    [   88.365814] Exception stack(0xe0239fa8 to 0xe0239ff0)
    [   88.370901] 9fa0:                   000230c0 00000001 00000003 40206b00 be929ad0 be929ac8
    [   88.379125] 9fc0: 000230c0 00000001 00000020 00000036 0002308c 00000005 be929b30 00000000
    [   88.387344] 9fe0: 00000036 be929ab0 b6e783a9 b6df1ae6
    [   88.399215] spi_slave spi0: ---- Call Stack ----
    [   88.403895] spi_slave spi0: mcspi_wait_for_completion() calling completion.c:wait_for_completion_interruptible()

     您是否能够使用 spidev_test 复制此示例?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、Glen、

    我现在已经回来了、但仍有很多积压的任务需要处理。 将在下周的第一件事情中优先考虑这一点。 一般而言、我记得 SPI 从站支持在某种程度上是一个灰色区域(还请注意您在 OP 中指出的 SDK 文档中存在令人困惑的陈述)、并且我仅在较新的 AM6x 器件上支持该功能、而在 AM335x 上不支持。 这将需要进行一些工作来获取此设置、对其进行实验、以及研究是否可以使用此设置。

    此致、Andreas

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Andreas:

    我们在从模式下使用 spi0已超过5年、至少可以追溯到 AM335x ~SDK5、kernel 4.14。 好的、我知道 在 AM335x 和我们当前的电路板设计上、在从模式下使用 SPI 是可行的。 我们 都是根据 SPI-omap2-mcspi 和 spidev 编写我们自己的驱动程序。 在等待 E2E 支持时、我一直在尝试让它们在 SDK9、内核6.1下工作。 到目前为止、我还没有成功。 如果我用我们的基线 SDK5、内核4.14 SD 卡替换基于 SDK9的 SD 卡、则 spi0从器件工作正常。 spidev_test 也可以很好地处理从模式 SPI 器件。

    为了消除任何疑问、SPI 从模式器件上的写入/读取将阻止( 按照 spidev_test 中的方法使用 ioctl (FD、SPI_IOC_MESSAGE (1)和& tr))、我修改了 spidev_test 并添加了一个超时为1的 select ()。 选择也会挂起、并且从不返回。

    对于器件树、我已经解编译了 DTB、下面是 SPI 的相关部分。 回想一下、为了让节点在向控制器添加`π 从器 件`s后进行编译、我需要在控制器中添加"#address-cells =<0>;"并从器件节点中删除"reg =<0>"。 显示的 DTC 来源是正确的。 从脚本/DTC/CHECK.c:

    if (get_property(node, "spi-slave"))
    	spi_addr_cells = 0;
    if (node_addr_cells(node) != spi_addr_cells)
    	FAIL(c, dti, node, "incorrect #address-cells for SPI bus");
    if (node_size_cells(node) != 0)
    	FAIL(c, dti, node, "incorrect #size-cells for SPI bus");

    我从 dtb 中解压缩的器件树:

    aliases {
    [...]
        spi0 = "/ocp/interconnect@48000000/segment@0/target-module@30000/spi@0";
    	spi1 = "/ocp/interconnect@48000000/segment@100000/target-module@a0000/spi@0";
    };
    [...]
    
    pinmux_spi0_pins {
    	pinctrl-single,pins = <0x150 0x28 0x00 0x154 0x08 0x00 0x158 0x28 0x00 0x15c 0x28 0x00>;
    	phandle = <0x37>;
    };
    
    pinmux_spi1_pins {
    	pinctrl-single,pins = <0x164 0x0c 0x00 0x168 0x2c 0x00 0x16c 0x0c 0x00 0x178 0x0c 0x00>;
    	phandle = <0x3c>;
    };
    [...]
    
    target-module@30000 {
    	compatible = "ti,sysc-omap2\0ti,sysc";
    	reg = <0x30000 0x04 0x30110 0x04 0x30114 0x04>;
    	reg-names = "rev\0sysc\0syss";
    	ti,sysc-mask = <0x303>;
    	ti,sysc-sidle = <0x00 0x01 0x02>;
    	ti,syss-mask = <0x01>;
    	clocks = <0x34 0x14 0x00>;
    	clock-names = "fck";
    	#address-cells = <0x01>;
    	#size-cells = <0x01>;
    	ranges = <0x00 0x30000 0x1000>;
    
    	spi@0 {
    		compatible = "ti,omap4-mcspi";
    		#address-cells = <0x00>;
    		#size-cells = <0x00>;
    		reg = <0x00 0x400>;
    		interrupts = <0x41>;
    		ti,spi-num-cs = <0x02>;
    		dmas = <0x24 0x10 0x00 0x24 0x11 0x00 0x24 0x12 0x00 0x24 0x13 0x00>;
    		dma-names = "tx0\0rx0\0tx1\0rx1";
    		status = "okay";
    		pinctrl-names = "default";
    		pinctrl-0 = <0x37>;
    		spi-max-frequency = <0xf42400>;
    		ti,pindir-d0-out-d1-in = <0x01>;
    		spi-slave;
    
    		slave@0 {
    			compatible = "rohm,dh2228fv";
    			spi-max-frequency = <0xf42400>;
    			spi-cpha;
    		};
    	};
    };
    
    target-module@a0000 {
    	compatible = "ti,sysc-omap2\0ti,sysc";
    	reg = <0xa0000 0x04 0xa0110 0x04 0xa0114 0x04>;
    	reg-names = "rev\0sysc\0syss";
    	ti,sysc-mask = <0x303>;
    	ti,sysc-sidle = <0x00 0x01 0x02>;
    	ti,syss-mask = <0x01>;
    	clocks = <0x34 0x18 0x00>;
    	clock-names = "fck";
    	#address-cells = <0x01>;
    	#size-cells = <0x01>;
    	ranges = <0x00 0xa0000 0x1000>;
    
    	spi@0 {
    		compatible = "ti,omap4-mcspi";
    		#address-cells = <0x01>;
    		#size-cells = <0x00>;
    		reg = <0x00 0x400>;
    		interrupts = <0x7d>;
    		ti,spi-num-cs = <0x02>;
    		dmas = <0x24 0x2a 0x00 0x24 0x2b 0x00 0x24 0x2c 0x00 0x24 0x2d 0x00>;
    		dma-names = "tx0\0rx0\0tx1\0rx1";
    		status = "okay";
    		pinctrl-names = "default";
    		pinctrl-0 = <0x3c>;
    
    		master@0 {
    			compatible = "rohm,dh2228fv";
    			spi-max-frequency = <0xf42400>;
    			reg = <0x00>;
    			spi-cpha;
    		};
    	};
    };

    我期待着我们的参与。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 

    同时、我从 ti.git.com 主站提取了最新的内核(6.11.0-RC4)。 不幸的是、它表现出相同的症状。 我无法在 SPI 从设备/dev/spidev0.0.上执行 select()或 read() 它从 WAIT_FOR_completion_interruptable (x)开始等待(挂起/从不返回)。 这可以通过 spidev_test 应用程序再现。

    请参与。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、Glen、

    在这里、我在处理多个其他优先事项时遇到了一些挑战、但我花了一些时间来审视今天和明天的工作。 首先、将详细查看您尝试的所有内容、看看我是否可以重新创建和/或创建一个有效的示例。

    此致、Andreas

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、Glen、

    我仍然需要弄清楚主设备/从设备的设置、以便重新创建您看到的内容、但我花了一些时间来编写代码。

    这是一个很长的时间,但你可以恢复下面的提交,如图所示,看看这是否有区别:

    a0797059@dasso:~/git/linux (ti-linux-6.1.y)
    $ git revert ea7d9188568669e6a1eb2e413b6c46bc208f0eb8
    Auto-merging drivers/spi/spi-omap2-mcspi.c
    [ti-linux-6.1.y 6182d5bdb0466] Revert "spi: spi-omap2-mcspi: Use EOW interrupt for completion when DMA enabled"
     1 file changed, 108 insertions(+), 50 deletions(-)

    在 SDK v9.2类型的内核树中、它应恢复而不会发生任何冲突。

    此外、您是否每次都修改过  drivers/spi/spi-omap2-mcspi.c 中的以下定义

    /* use PIO for small transfers, avoiding DMA setup/teardown overhead and
     * cache operations; better heuristics consider wordsize and bitrate.
     */
    #define DMA_MIN_BYTES                   160

    通常需要将这个值减小到一个非常小的值(甚至1个)才能使 DMA 参与传输、而具有默认传输大小的 spidev-test 工具不会触发该传输。 尝试强制将此值设置为"1"、然后查看其是否产生影响。

    此致、Andreas

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Andreas:

    我无法使`git 恢复`正常工作、因此我下载了补丁文件。 即使这样、我也会遇到一些我手动合并到 SPI-omap2-mcspi.c 中的故障 总之、从属问题仍然存在。  对从器件使用 spidev_test 时、它会将 CPU 跳到~30%并挂起。 如果是 I ctrl-C、CPU 将跳至100%。 此过程无法进行 SIGTERM、因此必须对电路板进行下电上电才能重新启动。

    Mem: 154396K used, 349108K free, 12244K shrd, 2252K buff, 92464K cached
    CPU:   4% usr  95% sys   0% nic   0% idle   0% io   0% irq   0% sirq
    Load average: 1.14 1.01 0.64 2/116 3483
      PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND
     2166   618 root     R     1564   0%  87% ./spidev_test -D /dev/spidev0.0
    

    我确实注意到了一些关于 DMA 请求的"奇怪"的内核消息。 以下是放置在 dmaengine.c:dma_request_chan()中的 dev_dbg ()。 从控制器(spi0)的 DMA 请求看似奇怪、而来自主控制器(SPI1)的 DMA 请求是我应该看到的。

    journalctl |grep spi
    Apr 28 17:42:28 1530163d kernel: DMA RX requested (spi@0, rx0).
    Apr 28 17:42:29 1530163d kernel: DMA RX requested (spi@0, rx0).
    Apr 28 17:42:29 1530163d kernel: DMA RX requested (spi@0, rx0).
    Apr 28 17:42:29 1530163d kernel: DMA RX requested (spi@0, tx0).
    Apr 28 17:42:29 1530163d kernel: DMA RX requested (spi@0, rx1).
    Apr 28 17:42:29 1530163d kernel: DMA RX requested (spi@0, tx1).
    Apr 28 17:42:29 1530163d kernel: omap2_mcspi 48030000.spi: registered slave spi0
    Apr 28 17:42:29 1530163d kernel: spi spi0.0: setup: speed 48000000, sample trailing edge, clk normal
    Apr 28 17:42:29 1530163d kernel: omap2_mcspi 48030000.spi: registered child spi0.0
    Apr 28 17:42:30 1530163d kernel: DMA RX requested (spi@0, rx0).
    Apr 28 17:42:30 1530163d kernel: DMA RX requested (spi@0, tx0).
    Apr 28 17:42:30 1530163d kernel: DMA RX requested (spi@0, rx1).
    Apr 28 17:42:30 1530163d kernel: DMA RX requested (spi@0, tx1).
    Apr 28 17:42:30 1530163d kernel: omap2_mcspi 481a0000.spi: registered master spi1
    Apr 28 17:42:30 1530163d kernel: spi spi1.0: setup: speed 16000000, sample trailing edge, clk normal
    Apr 28 17:42:30 1530163d kernel: omap2_mcspi 481a0000.spi: registered child spi1.0
    Jan 01 00:00:02 1530163d kernel: spidev: module is already loaded
    Jan 01 00:00:02 1530163d kernel: spidev: module is already loaded
    Jan 01 00:00:03 1530163d kernel: spidev: module is already loaded
    Jan 01 00:00:03 1530163d kernel: spidev: module is already loaded
    

    对于 dma_min_Bytes 的值、我没有更改它。  如果控制器被配置为从器件、它在 OMAP2_mcspi_can_dma ()中被忽略(并且强制执行 DMA)。 我认为此设置仅影响主配置的控制器的 DMA/PIO 传输阈值。  虽然我只是把它更改为"1"没有任何效果。

    static bool omap2_mcspi_can_dma(struct spi_master *master,
    				struct spi_device *spi,
    				struct spi_transfer *xfer)
    {
    	struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master);
    	struct omap2_mcspi_dma *mcspi_dma =
    		&mcspi->dma_channels[spi->chip_select];
    
    	if (!mcspi_dma->dma_rx || !mcspi_dma->dma_tx)
    		return false;
    
    	if (spi_controller_is_slave(master))
    		return true;
    
    	master->dma_rx = mcspi_dma->dma_rx;
    	master->dma_tx = mcspi_dma->dma_tx;
    
    	return (xfer->len >= DMA_MIN_BYTES);
    }

    最后、纠正我之前的一条评论。 在 Slave spi0上使用 select()时返回正常。 当 READ ()或 ioctl (FD、SPI_IOC_MESSAGE (1)、& tr)驱动程序挂起时。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、Glen、

    感谢您的详细实验和描述,这是非常有用的,因为我尝试重新创建你看到的东西...

    在 dma_min_Bytes 的值上、我没有更改它。  如果控制器被配置为从器件、它在 OMAP2_mcspi_can_dma ()中被忽略(并且强制执行 DMA)。 我认为此设置仅影响主配置的控制器的 DMA/PIO 传输阈值。  虽然我只是把它更改为"1"、但没有任何效果。

    虽然我还没有谈到这个具体的代码段、但你说的是合理的、因为我知道要使我们的 DMA 从模式在 Linux 中工作、使用 DMA 是一个先决条件。 这一切相加、得出结果很好。

    此后、我完成了 Kernel 和 DTS 更改以进行一些测试、还找到了我计划使用的外部 SPI 主机适配器(此处为 https://www.totalphase.com/products/aardvark-i2cspi/)、因为我更喜欢  在测试期间与外部已知良好且独立的实体进行交流。 由于 SPI 从器件不会使用 我期望的 CS 信号、我只需为它提供足够的时钟脉冲即可继续并最终完成传输。 我将在明天用我收集到的物品测试所有这些。

    在一个相关/不相关的说明中、您过去是如何解决 FPGA-SPI-master 与 AM335x-SPI-SLAVE 同步问题的? 您是否在定制驱动程序中使用了一些 GPIO 信号来判断"帧起始"类型的情况? 还是基于时间间隙? 问题是、如果时钟脉冲丢失或出现干扰、现在您的从设备将无法再了解主设备正在进行何种通信。

    此致、Andreas

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我准备在早上与我的团队开会、首先是为了确保能够准确回答您最后的相关问题。

    感谢您对此的关注。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Andreas:
    虽然不是最佳的执行方式、但是同步是通过软件执行的。 尽管我们有以下优势:

    1.信噪比非常大。
    在两侧都采用接地层、布线较短且直接。 (即电路板上的另一个器件)
    3、信号完整性极佳。
    4.运行速度为15Mbps…μ s 速度不是很快。

    但如果字节组帧错位、我们就会遇到突发错误、因为这不是丢字节问题… 每个字节都是错误的、直到有一段时间间隔或重启。

    我们与您分享您的担忧、一旦我们有了可正常运行的驱动程序、我们计划实施 CS 驱动型同步。

    我刚刚订购了 AM335x EVM、并已具有 TotalPhase 的 Cheetah SPI 主机适配器。 这也有助于重现您的工作台、并将我们的定制板从方程中移除。

    如果您有任何进展、或者可以在从通道上重现 spidev_test 的失败(挂起)、请告诉我。 我不确定当没有主器件驱动时钟(不是 Cheetah、我的当前测试床)时、从通道上的 DMA RX 的预期行为。 我希望它能在 SPI 器件上执行读取操作、DMA Rx 启动并返回零或垃圾数据、但不会将系统挂起。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、Glen、

    我能够进行设置、而且使用外部 SPI 主器件的 AM335x SPI 从器件传输可立即生效。 让我总结一下所有内容、以便您可以将其作为已知的良好数据点。

    在 HW POV 中、我使用了基于 AM335x 的 BeagleBone 板(SPI 从器件)和外部 SPI 主机适配器(https://www.totalphase.com/products/aardvark-i2cspi/)。 设置如下所示:

    在 SW POV 中、我使用 TI Linux 内核标签 09.02.00.010作为基础。 然后,在此之上,我应用了下面的 diff ,这基本上是你之前发布的内容。 这里同样是实际差值以供参考。

    a0797059@dasso:~/git/linux (ti-linux-6.1.y)
    $ git  diff
    diff --git a/arch/arm/boot/dts/am335x-bone.dts b/arch/arm/boot/dts/am335x-bone.dts
    index b5d85ef51a021..76862fcfd08df 100644
    --- a/arch/arm/boot/dts/am335x-bone.dts
    +++ b/arch/arm/boot/dts/am335x-bone.dts
    @@ -21,3 +21,29 @@ &ldo3_reg {
     &mmc1 {
            vmmc-supply = <&ldo3_reg>;
     };
    +
    +&am33xx_pinmux {
    +    spi0_pins: pinmux_spi0_pins {
    +        pinctrl-single,pins = <
    +                       AM33XX_IOPAD(0x950, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* (A18) spi0_sclk.spi0_sclk */
    +                       AM33XX_IOPAD(0x954, PIN_OUTPUT | MUX_MODE0) /* (B18) spi0_d0.spi0_d0 MISO*/
    +                       AM33XX_IOPAD(0x958, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* (B17) spi0_d1.spi0_d1 MOSI*/
    +                       AM33XX_IOPAD(0x95c, PIN_INPUT | SLEWCTRL_FAST | MUX_MODE0) /* (A17) spi0_cs0.spi0_cs0 */
    +       >;
    +    };
    +};
    +
    +&spi0 {
    +       status = "okay";
    +       pinctrl-names = "default";
    +       pinctrl-0 = <&spi0_pins>;
    +       ti,pindir-d0-out-d1-in = <1>;
    +       spi-slave;
    +       #address-cells = <0>;
    +
    +       slave@0 {       /* Define a SPI device at chip select 0 */
    +               compatible = "rohm,dh2228fv";
    +               spi-max-frequency = <16000000>; /* Set max SPI clock speed to 16MHz */
    +               spi-cpha;       /* SPI Mode 1 (CPOL=0, CPHA=1) */
    +       };
    +};
    

     CONFIG_SPI_SLAVE=y`mSDK 文档设置 Kernel defconfig 后、我还`了"make ... menuconfig "选项、默认情况下处于关闭状态。

    然后、我将内核、内核 模块和 DTB 文件插入(在顶部)使用 AM335x SDK v9.1安装程序中的 tisdk-base-image 编程的 SD 卡、并引导系统。 我还从相同的内核树中构建和安装`spidev`工具。

    然后、我能够多次运行该命令、每次都在 PC 上运行主机工具。

    以下是来自 AM335x 平台的日志...

    root@am335x-evm:~# ./spidev_test -D /dev/spidev0.0 -v -H
    spi mode: 0x1
    bits per word: 8
    max speed: 500000 Hz (500 kHz)
    TX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 0D  |......@.........................|
    RX | 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  |.................... !"#$%&'()01|
    root@am335x-evm:~# ./spidev_test -D /dev/spidev0.0 -v -H
    spi mode: 0x1
    bits per word: 8
    max speed: 500000 Hz (500 kHz)
    TX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 0D  |......@.........................|
    RX | 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  |.................... !"#$%&'()01|
    root@am335x-evm:~# ./spidev_test -D /dev/spidev0.0 -v -H
    spi mode: 0x1
    bits per word: 8
    max speed: 500000 Hz (500 kHz)
    TX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 0D  |......@.........................|
    RX | 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  |.................... !"#$%&'()01|
    root@am335x-evm:~#
    

    这是主机工具的屏幕截图。 请注意我如何发送在 AM335x 上正确接收的32个字节(00 ... 31)序列。 反过来、`spidev`工具发送的默认数据将在主机 SPI 主设备上正确接收(请参阅屏幕底部的"Transaction Log")。

    没有任何问题。 我在`s过程中"了解到"的唯一内容是` SPI 时钟相位/极性的"dpidev"命令行参数必须与器件树中设置的参数以及主机端配置的参数匹配。 为了教育目的、我将了解目标平台上存在这些看似2个冗余选项(DTS 与命令行参数)的原因。

    此致、Andreas

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、Glen、

    但是如果字节组帧未对齐、我们将遇到突发错误、因为这不是丢字节问题… 每个字节都错误、直至有一段时间间隔或重新启动。

    正确。

    请告诉我您是否取得了任何进展或者是否可以在从属通道上重现 spidev_test 的故障(挂起)。 [报价]

    请参阅上面的 POST、我在测试 SPI 从运行时没有看到任何问题。

    我不确定当没有主设备驱动时钟时从通道上 DMA RX 的预期行为(我当前未使用 Cheetah 进行测试)。 我希望它能在 SPI 器件上执行读取操作、DMA Rx 启动并返回零或垃圾数据、但不会将系统挂起。  [报价]

    SPI 从器件只有在由外部主器件计时的情况下才有效。 如果没有时钟、则会一直等待传入数据。 除非使用基于 SW 的超时机制。 为什么您希望在不提供时钟的情况下返回0?

    此致、Andreas

    [/quote]
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Andreas:
    在 SPI 从驱动器方面前景很好。 谢谢你。

    现在我必须弄清我们的板为什么使用自定义从站驱动程序时工作正常、而使用 OMAP2-MCSPI SPI-SLAVE 时工作不正常。  对于 spi0 (从器件)和 SPI1 (主器件)、引导期间的内核日志看起来正常。  

    我理解您对为什么 spidev_test 在没有主器件来控制时钟时始终等待传入数据的其他评论。 在我们的电路板上、spi0 CS 始终保持低电平(此时)、clk0由另一个处理器驱动。 当另一个处理器发送时、我可以在 spi0 MOSI 上看到数据。 我目前不理解为什么在从/dev/spidev0.0.读取数据时 AM3351上的应用程序没有通过 DMA 机制看到这一点 从端应用程序 以比主端发送的速度更快的速率对/dev/spidev0.0执行轮询/选择()。 因此、如果要读取有数据、则在主器件可以发送/覆盖它之前、从器件应将其移至循环缓冲区。 从器件绝不会通过此器件向主器件传输任何内容。 从器件是否需要看到 CS 从高电平到低电平的转换、或者是否将其保持为低电平?

    我将根据需要提供更新。

    此致、Glen

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我将提供适用的更新。

    谢谢 Glen。

    从器件是否需要看到 CS 从高电平到低电平的转换、或者是否将其保持在低电平?

    虽然 HW McSPI 外设支持主机-从器件 CS 信令("3线制模式与4线制模式")、但确实需要确保某些场景正常工作(CPOL=CPHA=0、模式0)、以便正确输出第一位、Linux 驱动程序似乎不会使用/配置此信号(请记住、在编译期间我们必须删除 reg =<0>节点、因为这是强制执行的)。 如果您想查看(我现在无法访问我的硬件)、查看 McSPI HW 寄存器(例如通过`devmem2`)可以快速确认从机所处的模式。

    请注意、我现在不在办公室、11月9日返回、因此需要在那之后根据需要取回物品。 您至少应该能够像我一样确认/重新创建工作中的从属通信。

    此致、Andreas