Kernel SPIDEV、设备树和带有Beaglebone黑色的.dtbo名称出现问题

Kernel SPIDEV、设备树和带有Beaglebone黑色的.dtbo名称出现问题,kernel,spi,beagleboneblack,device-tree,Kernel,Spi,Beagleboneblack,Device Tree,我对设备树有一些奇怪的问题。我发现更改.dtbo的名称改变了内核的beahvior 我已使用Angstrom修改了/lib/固件中给出的BB-SPIDEV1-00A0.dts: /* * 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 redistribut

我对设备树有一些奇怪的问题。我发现更改.dtbo的名称改变了内核的beahvior

我已使用Angstrom修改了/lib/固件中给出的BB-SPIDEV1-00A0.dts:

/*
 * 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>;
            };
        };
    };
};
在良好模式下:

root@beaglebone:/sys/kernel/debug/pinctrl/44e10800.pinmux# cat pins | grep 964
pin 89 (44e10964) 00000012 pinctrl-single 
但是这次spidev1.0不能正常工作。MISO线(BBB的输入)只能看到0,即使它是假的(我用示波器检查)

那么问题出在哪里呢


提前感谢

将P9_42B设置为模式4 w/高阻抗(0x2C)-否则,默认为模式4快速下拉。除非该引脚由另一个覆盖层修改,否则P9_42B无需进行复用

当我访问它们的寄存器时,SPI1(以及SPI0、I2C和GPIO2)寄存器给了我总线错误,导致设备被禁用,尽管在各自的覆盖中将其状态设置为“OK”。因此,我检查了每个寄存器的CM_,果然:
IDLEST=3[禁用]
MODULEMODE=0[禁用]
。虽然这些测试是在Debian系统上完成的,但我敢肯定Angstrom和所有其他发行版也是如此

要启用它们,您需要通过您选择的首选语言访问用于电源和时钟管理的内存地址:

通过PRU组件:

.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:

通过C/C++:(类似于上面的python示例)
引用自:

#包括
#包括
#包括
#包括
#包括
#根据0x44E00000//157页定义CM_
使用名称空间std;
int main(){
int fd=打开(“/dev/mem”,O_RDWR | O_SYNC);
ulong*pinconf1=(ulong*)mmap(NULL,0x0FFF,保护读取,保护写入,映射共享,fd,CM每);
printf(“信息:%X\n”,pinconf1[0x50/4]);
pinconf1[0x50/4]=0x00000002;
printf(“信息:%X\n”,pinconf1[0x50/4]);//配置已初始化
返回0;
}

注意:如果这不是问题所在,并且一个通道实际上正常工作,请确保在启用下一个通道之前禁用该通道。另外,确认MCSPI模块控制寄存器(SPI1:0x481A0128)中的MS位已清除[主控],PIN34位已清除[SPIEN用作芯片选择],单个位已清除[使用多个通道]

好吧,我再次回答我的问题。实际上,问题是:我无法使用SPI通道1(spidev.1.1)的第二个芯片选择。当我尝试这样做时,dtbo的名字问题出现了,我发布了这个问题。但是,名称问题尚未解决

但问题是

但是这次spidev1.0不能正常工作。MISO线(BBB的输入)只能看到0,即使它是假的(我用示波器检查)

已通过更改时钟模式解决:0x33而不是0x13。虽然它是一个输出,但将其设置为0x33会将引脚更改为RXACTIVE_PULLUP。它必须能够以这种方式接收数据

奇怪的是0x13与BB-SPIDEV1完美配合


感谢TekuConcept对寄存器的帮助,如果我有更多的时间,我将尝试挖掘寄存器。

您的dts看起来与原始BB-SPIDEV1-00A0源几乎相同,只是缺少一行:
spi cpha
位于片段1,通道0,在
spi最大频率下,您的管脚的muxing有几个不同:SPI1_SCLK可能是输入_上拉,而且我没有看到P9_42B(0x1A0)和spi子系统之间的任何关系-您可能将其与具有SPI1_SCLK(模式4)和SPI1_CS1(模式2)的P9_42A(0x164)混合在一起。P9_42B的模式2是'MCASPO_AXR2'。我看到P9_42B必须设置为'INPUT',因此请尝试模式4(将其路由为nothing):0x34…或模式7,即gpio 0x37无任何工作。。。我尝试了模式4,模式7,将SPI1_SCLK设置为输入_上拉,添加spi cpha,同样的行为。第二个芯片选择在开机时并不高,与第一个相反。但是谢谢你的回复!无论如何,这并不能解决不同名称的问题。我相信我可能知道问题所在:引脚100-103和89在启动时作为BB-BONELT-HDMIN覆盖的一部分,都被多路复用到
多声道音频串行端口子系统0
[mcasp0]。要移除HDMI覆盖层,请按照本页底部的说明进行操作:然后看看会发生什么。很抱歉,回答得太晚了,我必须阅读您提到的所有寄存器。当我读取寄存器0x44E00050时,它是3000h(重置),但当a在使用spidev传输期间读取它时,它是02h,因此spidev必须在需要时启用寄存器itslef。关于MCSPI_ModuleCtrl寄存器,如果传输不继续,我无法读取它(“总线错误”)。当我读到它时,它是1h,这意味着:“1h=在主模式下只使用一个通道。这个位必须在Force SPIEN模式下设置。”。事实上,我正在使用一个通道,我只想选择另一个芯片选择(文件中的SPIEN)。但是我找不到关于不同芯片选择(SPIEN)及其用法的寄存器。从骨骼上的以下链接编译*.c文件:,将*.sh脚本加载到终端(>source script.sh),然后运行命令:“>readm 0x44E00000 0”(从CM_PER_L4LS_CLKSTCTRL寄存器读取),并给出它返回的十六进制值。如果该值类似于0x4102,则原因是ICLK和FCLK被选通,并且设备处于空闲模式。(ICLK允许访问设备寄存器)与以前一样,当我的SPI程序正在运行和不运行时,该值是不同的。未运行时为0x4102,正在运行时为0x2004102(表示spidev正在使用)。“>writem 0x44E00000 0;writem 0x44E00000 50 2;”则您将能够访问McSPI接口,而无需“使用”(无需muxing)。0x481A0000 12C和140[MCSPI_CHXCONF.FORCE/.EPOL]是控制SPIEN的通道特定寄存器。另外,从r
.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
#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;
}