树莓派CM4的SPI接口调试

文章讲述了在CM4核心板上配置SPI接口以使用CAN总线时遇到的问题,包括厂家提供的BSP包不适用于Ubuntu系统,以及SPI0被其他功能占用导致的冲突。作者通过设备树和dtbo文件的修改尝试解决SPI1上的CAN总线初始化失败的问题,最终成功解决芯片未进入配置模式和芯片选择已占用的错误。
摘要由CSDN通过智能技术生成

CM4核心板配合自己画的底板,或者配合厂家给的底板,是需要自己调配40个扩展的接口的,其中,SPI接口的设置如果不合适,就会出现一系列问题,这里列出我在调试由SPI1引出的CAN总线时遇到的一些问题。

以厂家的底板举例,其解决接口问题的方法是为客户提供BSP包,但是这个包并不实用与Ubuntu系统,也就导致常规的CAN总线调取方法不一定好使。CM4默认调取的CAN总线是从SPI0走的,而厂家将SPI0分配给了其他接口,而且还把GPIO11分给了蜂鸣器,这就导致,我在直接使用SPI0尝试使用CAN总线的时候,开机会有蜂鸣,我还以为是哪里出fatal error了,排查半天发现是开机的时候调用SPI0导致蜂鸣器初始化,所以响了一下。

使用的是这篇文章里的方法:https://blog.csdn.net/j353838430/article/details/119486631

//在Ubuntu中安装好如下两个工具(可能会出现一些需要更新、没有pip3指令等安装的小问题,这里就不列出了)
sudo apt install can-utils
pip3 install cantools
//树莓派连接到电脑并使用rpiboot读取其emmc,在config.txt中添加如下的语句
dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25
dtoverlay=spi1-1cs

这种方法启动CAN总线会出现以下问题:

mcp251x spi0.0: MCP251x didn’t enter in conf mode after reset
mcp251x spi0.0: Probe failed, err=16
mcp251x: probe of spi0.0 failed with error -16

各种搜索后,没有很明确的答案,最靠谱的是输入电压高了,但也不好解决,便搁置了。

在了解到设备树以后,在老师的引导下,我开始了对dtbo的修改,尝试从设备树层面对SPI接口进行修改。

首先是从https://github.com/raspberrypi/linux/tree/rpi-5.4.y/arch/arm/boot/dts/overlays下载mcp2515-can0-overlay.dts,dtbo是不能直接进行修改的,需要修改dts文件,并在Ubuntu系统中进行编译后,得到我们想要的dtbo文件,这个后面会讲到。(上述网站时而可以裸连,时而得科学上网,很怪)(整个rpi-5.4.y压缩包我放在网盘了,自取:https://pan.baidu.com/s/1vVtvJv8CdxEDdyVmyyseCg?pwd=ttok

在与can1文件对比后,可以大致得到这个mcp2515-can0-overlay.dts文件的大致修改方法(到这里还没有完全调试好,先别抄)

/*
 * Device tree overlay for mcp251x/can0 on spi0.0
 */

/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2835";
    /* disable spi-dev for spi1.0 */
    fragment@0 {
        target = <&spi1>;//这里从spi0改成spi1
        __overlay__ {
            status = "okay";
        };
    };

    fragment@1 {
    target = <&spidev0>;//这里禁止spidev0的占用
    __overlay__ {
        status = "disabled";
    };
    };

    /* the interrupt pin of the can-controller */

    fragment@2 {
    target = <&spidev1>;//这里还禁止了spidev1的占用
    __overlay__ {
        status = "disabled";
    };
    };

    /* the interrupt pin of the can-controller */

    fragment@3 {
        target = <&gpio>;
        __overlay__ {
            can0_pins: can0_pins {
                brcm,pins = <25>;
                brcm,function = <0>; /* input */
            };
        };
    };

    /* the clock/oscillator of the can-controller */
    fragment@4 {
        target-path = "/";
        __overlay__ {
            /* external oscillator of mcp2515 on SPI1.0 */
            can0_osc: can0_osc {
                compatible = "fixed-clock";
                #clock-cells = <0>;
                clock-frequency  = <16000000>;
            };
        };
    };

    /* the spi config of the can-controller itself binding everything together */
    fragment@5 {
        target = <&spi1>;
        __overlay__ {
            /* needed to avoid dtc warning */
            #address-cells = <1>;
            #size-cells = <0>;
            can0: mcp2515@0 {
                reg = <0>;
                compatible = "microchip,mcp2515";
                pinctrl-names = "default";
                pinctrl-0 = <&can0_pins>;
                spi-max-frequency = <10000000>;
                interrupt-parent = <&gpio>;
                interrupts = <25 8>; /* IRQ_TYPE_LEVEL_LOW */
                clocks = <&can0_osc>;
            };
        };
    };
    __overrides__ {
        oscillator = <&can0_osc>,"clock-frequency:0";
        spimaxfrequency = <&can0>,"spi-max-frequency:0";
        interrupt = <&can0_pins>,"brcm,pins:0",<&can0>,"interrupts:0";
    };
};

到这里,前面的报错解决了,但又出现了新的问题:

spi-bcm2835 20204000.spi: chipselect 1 already in use
spi_master spi0: spi_device register error /soc/spi@7e204000/spidev@1
spi_master spi0: Failed to create SPI device for /soc/spi@7e204000/spidev@1

这个问题甚至找不到解决方法,只能科学一下,才在论坛里找到了这篇回复:https://forums.raspberrypi.com/viewtopic.php?t=321065

在这篇回复里,版主回答了关于dev的命名与禁用问题,最后解决其实把config.txt中的

dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25
dtoverlay=spi1-1cs

改为:

dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25,dtoverlay=spi-bcm2835
dtoverlay=spi1-1cs,cs0_spidev=off

主要是利用cs0_spidev=off这句来禁用所有spidev

之后,老师给出了一些指导,原来我的修改还是有疏漏,对于spi1,其spidev的命名有变化,需要进行如下的修改才对,前面的是错误示范,约等于没改。

/*
 * Device tree overlay for mcp251x/can0 on spi0.0
 */

/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2835";
    /* disable spi-dev for spi1.0 */
    fragment@0 {
        target = <&spi1>;
        __overlay__ {
            status = "okay";
        };
    };

    fragment@1 {
    target = <&spidev0>;
    __overlay__ {
        status = "disabled";
    };
    };


    fragment@2 {
    target = <&spidev1>;
    __overlay__ {
        status = "disabled";
    };
    };

    fragment@3 {
    target-path = "spi1/spidev@0";
    __overlay__ {
        status = "disabled";
    };
    };

    fragment@4 {
    target-path = "spi1/spidev@1";
    __overlay__ {
        status = "disabled";
    };
    };

    /* the interrupt pin of the can-controller */

    fragment@5 {
        target = <&gpio>;
        __overlay__ {
            can0_pins: can0_pins {
                brcm,pins = <25>;
                brcm,function = <0>; /* input */
            };
        };
    };

    /* the clock/oscillator of the can-controller */
    fragment@6 {
        target-path = "/";
        __overlay__ {
            /* external oscillator of mcp2515 on SPI1.0 */
            can0_osc: can0_osc {
                compatible = "fixed-clock";
                #clock-cells = <0>;
                clock-frequency  = <16000000>;
            };
        };
    };

    /* the spi config of the can-controller itself binding everything together */
    fragment@7 {
        target = <&spi1>;
        __overlay__ {
            /* needed to avoid dtc warning */
            #address-cells = <1>;
            #size-cells = <0>;
            can0: mcp2515@0 {
                reg = <0>;
                compatible = "microchip,mcp2515";
                pinctrl-names = "default";
                pinctrl-0 = <&can0_pins>;
                spi-max-frequency = <10000000>;
                interrupt-parent = <&gpio>;
                interrupts = <25 8>; /* IRQ_TYPE_LEVEL_LOW */
                clocks = <&can0_osc>;
            };
        };
    };
    __overrides__ {
        oscillator = <&can0_osc>,"clock-frequency:0";
        spimaxfrequency = <&can0>,"spi-max-frequency:0";
        interrupt = <&can0_pins>,"brcm,pins:0",<&can0>,"interrupts:0";
    };
};

ok,完事儿,ifconfig -a出现下面这样就好了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值