根据 BCM2711 引脚图[1][2]的设置,树莓派 4B 默认引出的 40Pin 可以添加多组 SPI 总线控制器:SPI3、SPI4、SPI0、SPI5 和 SPI1。默认情况下, SPI4 的 SCLK 和 SPI1 的 CE1_N 存在冲突。如果要启用多个 SPI,需要在内核启动时,加载对应的 Device Tree Overlay,仿照默认的 spi0-cs-overlay.dts
[3],我们可以设置对应的多个 SPI 控制器。
我们首先修改默认的 SPI0,使得其只保留一条片选线,并用 dtc 命令编译:
/dts-v1/; /plugin/; / { compatible = "brcm,bcm2835"; fragment@0 { target = <&spi0_cs_pins>; frag0: __overlay__ { brcm,pins = <8>; }; }; fragment@1 { target = <&spi0>; frag1: __overlay__ { cs-gpios = <&gpio 8 1>; status = "okay"; }; }; __overrides__ { cs0_pin = <&frag0>,"brcm,pins:0", <&frag1>,"cs-gpios:4"; }; };
# compile dtc -I dts -O dtb -o spi0-1cs.dtbo spi0-1cs.dts # copy to boot partition sudo cp spi0-1cs.dtbo /boot/overlays
树莓派的官方镜像已经提供了 SPI3,SPI4,SPI5 和 SPI1,我们只需修改 /boot/config.txt
,注意,我们要取消注释默认的 spi=on
:
#dtparam=spi=on dtoverlay=spi0-1cs dtoverlay=spi3-1cs dtoverlay=spi4-1cs dtoverlay=spi1-1cs
同样,我们可以参考树莓派的默认 dts 编译多个 SPI 从设备描述,比如我根据位于 spi0.0
的 MCP2515 [4] 编译了 spi3.0
、spi4.0
和 spi1.0
的 3个 CAN控制器,并同样修改 /boot/config.txt
:
dtoverlay=mcp2515-can0,oscillator=8000000,interrupt=24 dtoverlay=mcp2515-can3,oscillator=8000000,interrupt=25 dtoverlay=mcp2515-can4,oscillator=8000000,interrupt=26 dtoverlay=mcp2515-can1,oscillator=8000000,interrupt=27
查看 dmesg 日志,可以看到 4 个 MCP2515 控制器已经正常工作:
pi@raspberrypi:~$ dmesg | grep spi [ 4.387592] spi-bcm2835 fe204600.spi: no tx-dma configuration found - not using dma mode [ 4.391881] spi-bcm2835 fe204600.spi: chipselect 0 already in use [ 4.391898] spi_master spi3: spi_device register error /soc/spi@7e204600/spidev@0 [ 4.391915] spi_master spi3: Failed to create SPI device for /soc/spi@7e204600/spidev@0 [ 4.392332] spi-bcm2835 fe204800.spi: no tx-dma configuration found - not using dma mode [ 4.394967] spi-bcm2835 fe204800.spi: chipselect 0 already in use [ 4.394982] spi_master spi4: spi_device register error /soc/spi@7e204800/spidev@0 [ 4.394999] spi_master spi4: Failed to create SPI device for /soc/spi@7e204800/spidev@0 [ 4.419969] spi-bcm2835aux fe215080.spi: chipselect 0 already in use [ 4.419986] spi_master spi1: spi_device register error /soc/spi@7e215080/spidev@0 [ 4.420005] spi_master spi1: Failed to create SPI device for /soc/spi@7e215080/spidev@0 [ 5.351820] mcp251x spi0.0 can0: MCP2515 successfully initialized. [ 5.368085] mcp251x spi3.0 can1: MCP2515 successfully initialized. [ 5.379651] mcp251x spi4.0 can2: MCP2515 successfully initialized. [ 5.390782] mcp251x spi1.0 can3: MCP2515 successfully initialized.
[1] https://elinux.org/RPi_BCM2711_GPIOs
[2] https://www.raspberrypi.org/documentation/usage/gpio/
[3] https://github.com/raspberrypi/linux/blob/rpi-5.4.y/arch/arm/boot/dts/overlays/spi0-cs-overlay.dts
[4] https://github.com/raspberrypi/linux/blob/rpi-5.4.y/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts