According to the BCM2711 pin setups[1][2],Raspberry Pi 4B has 5 exported sets of SPI controllers: SPI3, SPI4, SPI0, SPI5 and SPI1. By default, SCLK of SPI4 and CE1_N of SPI1 share the same GPIO7 pin. When the Linux kernel is fired, a device tree and certain overlays are loaded. We can enable multiple SPI controllers like spi0-cs-overlay.dts
in stock firmware[3] does.
We may disable the second chip enable line of SPI0 in first:
/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
And then enable SPI3, SPI4, SPI5 and SPI1 which are already given in stock firmware. The following lines should be added into/boot/config.txt
. Attention must be paid that we should comment out the default spi=on
:
#dtparam=spi=on dtoverlay=spi0-1cs dtoverlay=spi3-1cs dtoverlay=spi4-1cs dtoverlay=spi1-1cs
We can also apply the previous trick to other device tree overlays. Here I added additional three MCP2515 CAN controllers[4]:
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
Log from dmesg
indicated that four CAN controllers were all working smoothly:
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