【问题标题】:SPI interface with FPGA running LINUX与运行 LINUX 的 FPGA 的 SPI 接口
【发布时间】:2018-09-15 14:27:25
【问题描述】:

我有一个通过 microSD 卡运行 Ubuntu 16.04 的 DE1-SoC FPGA。我对设备树有些陌生,但通过使用 dtc 将 .dtb 文件反编译为 .dts 文件,我设法弄清楚了如何启用板上的各种外围设备。我这样做并在 nano 中编辑了 .dts 文件以将 SPI 端口从“禁用”更改为“好的”。然后,我从修改后的 .dts 文件中重新编译了 .dtb 文件(我还删除了 .dts 文件并重新反编译了第二个 .dts 文件以查看更改是否生效,并且确实生效了)。

此时,我重新启动系统,然后转到 cd/dev/,但没有列出 spidev 或 spi* 或 spidev*。当我转到 cd/proc/device-tree 时,我列出了以下内容:

ubuntu@DE1_SoC:/proc/device-tree$ dir
3-3-v-regulator      chosen          leds               name
#address-cells       compatible      __local_fixups__   #size-cells
aliases              cpus            memory             soc
bridge@0xff200000    intc@fffed000   model              __symbols__

当我导航到 /soc/ 文件夹时,我有以下内容,这与我拥有的 .dts 文件一致:

ubuntu@DE1_SoC:/proc/device-tree/soc$ dir
#address-cells        gpio@ff70a000       #size-cells
amba                  i2c@ffc04000        snoop-control-unit@fffec000
base-fpga-region      i2c@ffc05000        spi@ff705000
can@ffc00000          i2c@ffc06000        spi@fff00000
can@ffc01000          i2c@ffc07000        spi@fff01000
clkmgr@ffd04000       interrupt-parent    sram@ffff0000
compatible            l2-cache@fffef000   sysmgr@ffd08000
device_type           l2edac@xffd08140    timer0@ffc08000
dwmmc0@ff704000       l3regs@0xff800000   timer1@ffc09000
ethernet@ff700000     name                timer2@ffd00000
ethernet@ff702000     nand@ff900000       timer3@ffd01000
fpga2sdram-bridge     ocramedac@ffd08144  timer@fffec600
fpga-bridge@ff400000  ranges              usb@ffb00000
fpga-bridge@ff500000  rstmgr@ffd05000     usb@ffb40000
fpga-bridge@ff600000  sdramedac           usbphy@0
fpga-mgr@ff706000     sdr@ffc25000        watchdog@ffd02000
gpio@ff708000         serial0@ffc02000    watchdog@ffd03000
gpio@ff709000         serial1@ffc03000

所以,我不确定我做错了什么,我的串行外围接口无法正常工作。最终目标:FPGA 上的 SPI 连接到板载 ADC (AD7928),我想使用 C 编写的程序通过 Linux 访问它。i2C 工作正常,但由于某种原因 SPI 没有响应。

我想我可能错过了一步,但在这一点上我有点迷茫,所以任何帮助都会很棒。

编辑:忘记为 SPI 添加 .dts 条目:

spi@fff00000 {
    compatible = "snps,dw-apb-ssi";
    #address-cells = <0x1>;
    #size-cells = <0x0>;
    reg = <0xfff00000 0x1000>;
    interrupts = <0x0 0x9a 0x4>;
    num-cs = <0x4>;
    tx-dma-channel = <0x2c 0x10>;
    rx-dma-channel = <0x2c 0x11>;
    clocks = <0x11>;
    status = "okay";
    linux,phandle = <0x59>;
    phandle = <0x59>;
};

spi@fff01000 {
    compatible = "snps,dw-apb-ssi";
    #address-cells = <0x1>;
    #size-cells = <0x0>;
    reg = <0xfff01000 0x1000>;
    interrupts = <0x0 0x9b 0x4>;
    num-cs = <0x4>;
    tx-dma-channel = <0x2c 0x14>;
    rx-dma-channel = <0x2c 0x15>;
    clocks = <0x11>;
    status = "okay";
    linux,phandle = <0x5a>;
    phandle = <0x5a>;
};

并且地址与SPIM的板子datasheet一致。

通过添加更多编辑 .dts 来获得一点余地:

spi@fff00000 {
    compatible = "snps,dw-apb-ssi";
    #address-cells = <0x1>;
    #size-cells = <0x0>;
    reg = <0xfff00000 0x1000>;
    interrupts = <0x0 0x9a 0x4>;
    num-cs = <0x4>;
    tx-dma-channel = <0x2c 0x10>;
    rx-dma-channel = <0x2c 0x11>;
    clocks = <0x11>;
    status = "okay";
    linux,phandle = <0x59>;
    phandle = <0x59>;

    spidev@0 {
        compatible = "spidev";
        reg = <0x0>;
        spi-max-frequency = <0xb71b00>;
        enable-dma = <0x0>;
    }

现在 spidev32766.0 出现在我的 /dev/ 文件夹中。

【问题讨论】:

  • 您需要研究您正在使用的内核版本的 Documentation/spi/spi-summary 文件。 SPI 是总线,而不是“端口”。您所做的 DT 更改仅适用于 SPI 主控制器。这只是 SPI 总线的一端。你没有为另一端做任何事情,即 SPI 从设备。
  • 感谢您的回复。我在 .dts 文件中添加了一个条目(参见上面的编辑)并获得了一个新的 blob,然后 spidev32766.0 出现在 /dev/ 中,所以我认为 Linux 正在识别其中一个大师,对吧?
  • SPI 主控制器根本不会在 /dev 目录中有设备节点。有没有注意到/dev目录下有些设备如eth0不在?建议你多学习,例如文档/devicetree/bindings/spi/spi-bus.txt。 SPI 从设备需要为其定义片选(例如 GPIO 引脚)。
  • 我想我明白你在说什么。当我查看datasheet 时,SPI 有四个条目(2xSPIS 和 2xSPIM);但是,当我查看tut 时,它表明这些 SPI 确实出现在 dev 中,因此可以在用户空间中对其进行操作。我还在学习,但在运行 Linux 的 FPGA 上,您尝试访问 FPGA 外设可能会有所不同?
  • “我想我明白了……” -- 如果你真的明白了,那么当你使用“SPI”这个词时,你会更有眼光。如果你不知道你指的是主人还是奴隶,那么你会感到困惑。 “它表明这些 SPI 确实出现在 dev 中” -- 仅因为有四 (4) 个 SPI slave 设备实例(使用 kludge 协议驱动程序 spidev) 为该 SPI master 控制器定义。不,FPGA 不会违反 Linux 内核的约定。看来您需要进一步研究Documentation/spi/spi-summary

标签: linux fpga spi device-tree


【解决方案1】:

spidev32766.0 是你添加设备树后得到的设备节点 nodespidev@0 用于第一个 SPI 总线(控制器)spi@fff00000 上的 SPI 设备,芯片选择为 0。

按照惯例,频率属性spi-max-frequency = &lt;0xb71b00&gt; 应以十进制格式 12000000,而不是十六进制格式,并且在新版本的 spidev.c 中,驱动程序会抱怨 compatible = "spidev" 属性,因为该属性应该描述真实的硬件而不是某些软件抽象。

这个32766总线(控制器)号由内核动态分配,完全合法。 在较旧的内核中,在设备树文件之前,总线号必须在板文件平台数据中定义,例如:.bus_num = 0,

如前所述,/dev 文件系统下没有 SPI 总线(控制器)设备节点 spiX,只有客户端(芯片)设备节点 spidevX.Y

spidev.c是一种为通用SPI客户端(芯片)设备注册的特殊驱动程序,其主要目标是通过在/dev接口下创建字符设备节点,将内核低级SPI API导出到用户空间。

但如果您的目标是 ADC 的 SPI 驱动程序,那么最好为该芯片使用现有的 Linux SPI 驱动程序,例如对于 AD7791,或自己编写。 Linux 支持工业 I/O 子系统 (iio) 设备,例如模数转换器。

Linux Kernel Configuration
Device Drivers  --->
    ...
    <*>     Industrial I/O support --->
        --- Industrial I/O support
        ...
        Analog to digital converters  ---> 
            ...
            <*>  Analog Devices ADXYZ* ADC driver

在这种情况下,Linux 会将您的 ADC 设备功能导出到 /sys 文件系统中的用户空间:

/sys/bus/iio/devices/iio:deviceX

具有可作为文件访问的设备属性:

-r--r--r--    1 root     root          4096 Jan  1 04:18 name
drwxr-xr-x    2 root     root             0 Jan  1 04:18 power
-rw-r--r--    1 root     root          4096 Jan  1 04:18 sampling_frequency
-r--r--r--    1 root     root          4096 Jan  1 04:18 sampling_frequency_available

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-07
    • 2016-01-24
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多