Beaglebone Black中SPIDEV、设备树和.dtbo名称的问题

3

我在设备树上遇到了一些奇怪的问题。我发现改变.dtbo文件的名称会改变内核的行为!

我修改了/lib/firmware中的BB-SPIDEV1-00A0.dts,使用Angstrom系统:

/*
 * Copyright (C) 2013 CircuitCo
 *
 * Virtual cape for SPI1 on connector pins P9.29 P9.31 P9.30 P9.28
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
/dts-v1/;
/plugin/;

/ {
    compatible = "ti,beaglebone", "ti,beaglebone-black";

    /* identification */
    part-number = "BB-SPI1-01";
    version = "00A0";

    /* state the resources this cape uses */
    exclusive-use =
        /* the pin header uses */
        "P9.31",    /* spi1_sclk */
        "P9.29",    /* spi1_d0 */
        "P9.30",    /* spi1_d1 */
        "P9.28",    /* spi1_cs0 */
            "P9.42",    /* spi1_cs1 */
        /* the hardware ip uses */
        "spi1";

    fragment@0 {
        target = <&am33xx_pinmux>;
        __overlay__ {
            /* default state has all gpios released and mode set to uart1 */
            bb_spi1_pins: pinmux_bb_spi1_pins {
                pinctrl-single,pins = <
                    0x190 0x13  /* mcasp0_aclkx.spi1_sclk,  OUTPUT_PULLUP | MODE3 */
                    0x194 0x33  /* mcasp0_fsx.spi1_d0,      INPUT_PULLUP | MODE3 */
                    0x198 0x13  /* mcasp0_axr0.spi1_d1,     OUTPUT_PULLUP | MODE3 */
                    0x19c 0x13  /* mcasp0_ahclkr.spi1_cs0,      OUTPUT_PULLUP | MODE3 */
                    0x164 0x12  /* eCAP0_in_PWM0_out.spi1_cs1   OUTPUT_PULLUP | MODE2 */
                    0x1A0 0x32  /* Other P42 pin, INPUT_PULLUP */
                >;
            };
        };
    };

    fragment@1 {
        target = <&spi1>;   /* spi1 is numbered correctly */
        __overlay__ {
            status = "okay";
            pinctrl-names = "default";
            pinctrl-0 = <&bb_spi1_pins>;

            #address-cells = <1>;
            #size-cells = <0>;

            spi1_0{
                #address-cells = <1>;
                #size-cells = <0>;

                compatible = "spidev";

                reg = <0>;
                spi-max-frequency = <16000000>;
            };


            spi1_1{
                #address-cells = <1>;
                #size-cells = <0>;

                compatible = "spidev";

                reg = <1>;
                spi-max-frequency = <16000000>;
            };
        };
    };
};

我把它编译成了两个名称:BB-SPIDEV1-00A0.dtbo和BB-SPI1-01-00A0.dtbo。
当我在/sys/devices/bone_capemgr.9/slots中加载其中一个时,spidev的行为会有所不同!
使用BB-SPIDEV1时,spidev1.0正常工作,没有任何问题。但是spidev1.1的片选不起作用!引脚42处于错误的模式,并且该引脚没有与spi1分配。
另一方面,使用BB-SPI1-01(此名称并不重要,给出另一个名称也一样,只要与BB-SPIDEV1不同即可),引脚42被正确分配:
root@beaglebone:/sys/kernel/debug/pinctrl/44e10800.pinmux# cat pinmux-pins | grep spi
pin 89 (44e10964): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins
pin 100 (44e10990): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins
pin 101 (44e10994): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins
pin 102 (44e10998): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins
pin 103 (44e1099c): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins
pin 104 (44e109a0): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins

在良好模式下:
root@beaglebone:/sys/kernel/debug/pinctrl/44e10800.pinmux# cat pins | grep 964
pin 89 (44e10964) 00000012 pinctrl-single 

但是这一次,spidev1.0工作不正常。MISO线路(BBB的输入)只能看到0,即使它是错误的(我用示波器检查过)。那么问题可能是什么呢?提前感谢。

你的dts文件看起来几乎与原始的BB-SPIDEV1-00A0源代码相同,除了缺少一行代码:spi-cpha;,它位于片段1、通道0下的spi-max-frequency之下,并且您的引脚复用存在几个差异:SPI1_SCLK可能是INPUT_PULLUP,此外我没有看到P9_42B(0x1A0)与SPI子系统之间的任何关系 - 您可能将其与具有SPI1_SCLK(模式4)和SPI1_CS1(模式2)的P9_42A(0x164)混淆了。 P9_42B的模式2是'MCASPO_AXR2'。 - TekuConcept
我看到 P9_42B 必须设置为“INPUT”,所以尝试使用模式 4(将其路由到“无”):0x34……或模式 7,即 gpio 0x37。 - TekuConcept
没有任何一种方法起作用...我尝试了模式4、模式7、将SPI1_SCLK设置为INPUT_PULLUP、添加spi-cpha,但行为都相同。第二个芯片选择在启动时并不高,与第一个相反。 - user3714405
但还是感谢您的回复!无论如何,这并没有解决不同名称的问题。 - user3714405
我相信我可能知道问题所在:引脚100-103和89都被混合到启动时的多通道音频串行端口子系统0 [mcasp0]中,作为BB-BONELT-HDMIN叠加层的一部分。要删除HDMI叠加层,请按照此页面底部的说明进行操作:http://tekuconcept.blogspot.com/2014/02/gpio-beaglebone-and-bash.html,然后查看发生了什么。 - TekuConcept
这些已经被禁用了,我在我的uEnv.txt中有这个命令:capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN并且它们已经被卸载了(我可以通过cat $SLOTS看到)。 - user3714405
2个回答

1
嗯嗯,我再次回答我的问题。实际上,问题是:我无法使用SPI通道1(spidev.1.1)的第二个芯片选择。当我尝试这样做时,出现了DTBO名称的问题,并且我发布了这个问题。然而,名称问题尚未解决。
但是,通过更改时钟模式为0x33而不是0x13,已经解决了以下问题:
“但是,这一次spidev1.0不能正常工作。 MISO线(因此BBB的输入)仅看到0,即使它是错误的(我用示波器进行了检查)。 ”
尽管它是一个输出,但将0x33设置为RXACTIVE_PULLUP会更改引脚。必须以这种方式启用才能接收数据。
奇怪的是,0x13在BB-SPIDEV1上完美运行...
感谢TekuConcept关于寄存器的帮助,如果我有额外时间,我将尝试挖掘寄存器。

1
将P9_42B设置为4号模式,高阻抗(0x2C)-否则,默认为4号模式快速下拉。除非该引脚被另一个叠加层修改,否则不需要对P9_42B进行多路复用。
当我访问它们的寄存器时,SPI1(以及SPI0、I2C和GPIO2)寄存器给我带来了总线错误,尽管我在各自的叠加层中将它们的状态设置为“好”。因此,我检查了CM_PER寄存器,确实:IDLEST=3 [disabled]MODULEMODE=0 [disabled]。虽然这些测试是在Debian系统上进行的,但我相信Angstrom和所有其他发行版也是如此。
要启用它们,您需要通过您选择的首选语言访问电源和时钟管理的内存地址:

通过PRU Assembly:
.origin 0
.entrypoint START

START:
    MOV  r0, 0x44E00050 // CM_PER_SPI1_CLKCTRL Register [reset = 30000h / disabled]
    LBBO r1, r0, 0, 4   // load register value
    CLR  r1.t16         // set IDLEST to FUNC
    CLR  r1.t17
    SET  r1.t1          // set MODULEMODE to ENABLE
    SBBO r1, r0, 0, 4   // store value
    HALT

通过Python:
使用Python mmap控制Beaglebone IO

通过C/C++:(与上述Python示例类似)
参考来源:vabi-robotics.blogspot.com

#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>
#include <iostream>
#define CM_PER 0x44E00000 //PG 157

using namespace std;

int main(){
    int fd = open("/dev/mem",O_RDWR | O_SYNC);
    ulong* pinconf1 =  (ulong*) mmap(NULL, 0x0FFF, PROT_READ | PROT_WRITE, MAP_SHARED, fd, CM_PER);

    printf("INFO: %X\n", pinconf1[0x50/4]);
    pinconf1[0x50/4] = 0x00000002;
    printf("INFO: %X\n", pinconf1[0x50/4]); // conf. initialized

    return 0;
}

注意: 如果这不是问题所在,而且一个通道确实是功能正常的,请确保在启用下一个通道之前禁用该通道。同时,确认MCSPI_MODULCTRL寄存器(SPI1: 0x481A0128)中已清除MS位[]、PIN34位[SPIEN用作芯片选择]和SINGLE位[使用多个通道]。


抱歉回复晚了,我不得不阅读你所提到的所有寄存器。当我读取寄存器0x44E00050时,它是3000h(重置),但在使用spidev进行传输期间读取时,它是02h,因此spidev必须在需要时自行启用该寄存器。 - user3714405
关于MCSPI_MODULCTRL寄存器,我无法在传输进行时读取它("总线错误")。当我读取它时,它的值为1h,这意味着:"1h = 仅在主模式下使用一个通道。在强制SPIEN模式下必须设置此位。"实际上,我正在使用一个通道,我只想选择其他芯片选择(在文档中称为SPIEN)。但是我找不到讨论不同芯片选择(SPIEN)及其用途的寄存器。 - user3714405
请在bone上编译以下链接中的*.c文件:https://github.com/TekuConcept/BBB_Backup/tree/master/workspace/BoneMemory,将*.sh脚本加载到终端中(> source script.sh),然后运行命令:"> readm 0x44E00000 0"(从CM_PER_L4LS_CLKSTCTRL寄存器读取),并告诉我它返回的十六进制值。如果该值看起来像0x4102,则原因是ICLK和FCLK被门控,并且设备处于IDLE模式。(ICLK允许访问设备寄存器) - TekuConcept
与以前一样,当我的SPI程序正在运行时,值是不同的。如果未运行,则为0x4102,如果正在运行(表示spidev正在使用),则为0x2004102。 - user3714405
"> writem 0x44E00000 0 0; writem 0x44E00000 50 2;" 然后您就可以访问McSPI接口而无需进行复用。0x481A0000 12C和140 [MCSPI_CHXCONF.FORCE/.EPOL]是控制SPIEN的通道特定寄存器。此外,从寄存器MCSPI_MODULCTRL读取的值为0x4,这意味着该设备默认处于主/芯片选择模式,但也处于SYSTEST模式。 - TekuConcept

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接