Linux MCP2515 CAN via SPI on OrangePI5Pro (rockchip rk3588)

These steps activate the ‘MCP2515 CAN via SPI’ driver on Linux (OrangePI5Pro / rockchip rk3588)

tested with linux kernel: uname -a
Linux orangepi5pro 6.1.43-rockchip-rk3588 #1.0.2 SMP Tue May 7 15:40:55 CST 2024 aarch64 aarch64 aarch64 GNU/Linux

Pinout:

GPIO1_B2 SPIO_MOSI_M2
GPIO1_B1 SPIO_MISO_M2
GPIO1_B3 SPIO_CLK_M2
GPIO1_B4 SPIO_CS0_M2
GPIO1_A6 SPIO_INT

1. Create DTS file (/boot/rk3588-spi0-m2-cs0-mcp2515-16mhz.dts)

This DTS file:

  • instructs the rockchip pinctrl to ‘de-pull’ the interrupt pin
  • instructs the the rockchip SPI which frequency, which MISO/MOSI/CLK/CS pins and which interrupt pin to use
  • instructs the linux mcp2515 which oscillator frequency to use
/dts-v1/;
/plugin/;

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/rockchip.h>
#include <dt-bindings/interrupt-controller/irq.h>

/ {
    metadata {
        title = "Enable MCP2515 with 8MHz external clock on SPI0-M2 over CS0";
        /*compatible = "radxa,rock-5b", "radxa,rock-5b-plus", "radxa,nx5-io", "radxa,cm5-rpi-cm4-io";*/
        compatible = "xunlong,orangepi-5-pro", "rockchip,rk3588";
        category = "misc";
        exclusive = "GPIO1_B2", "GPIO1_B1", "GPIO1_B3", "GPIO1_B4", "GPIO1_A6";
        description = "Provide support for Microchip MCP2515 SPI CAN controller.\nAssumes 16MHz external clock.\nUses Pin 31 (GPIO1_A6) for INT.";
    };
};

&spi0 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&spi0m2_pins &spi0m2_cs0>;
    #address-cells = <1>;
    #size-cells = <0>;
    max-freq = <1000000>;

    can0: mcp2515@0 {
        status = "okay";
        compatible = "microchip,mcp2515";
        reg = <0>;
        spi-max-frequency = <1000000>;

        pinctrl-names = "default";
        pinctrl-0 = <&mcp2515_int_pins>;

        interrupt-parent = <&gpio1>;
        interrupts = <RK_PA6 IRQ_TYPE_EDGE_FALLING>;

        clocks = <&can0_osc>;
        vdd-supply = <&vcc_3v3_s3>;
        xceiver-supply = <&vcc_3v3_s3>;
    };
};

&pinctrl {
    mcp2515 {
        mcp2515_int_pins: mcp2515-int-pins {
            rockchip,pins = <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
        };
    };
};

&{/} {
    can0_osc: can0-osc {
        compatible = "fixed-clock";
        #clock-cells = <0>;
        clock-frequency  = <16000000>;
    };
};

2. Compile DTS file to DTB overlay file

First we relocate the include files to the actual system Linux header files. Then we compile the DTS to DTB overlay file.

sudo apt-get install linux-headers-generic

cpp -nostdinc -I /usr/src/linux-headers-5.15.0-140/include -undef -x assembler-with-cpp rk3588-spi0-m2-cs0-mcp2515-16mhz.dts > rk3588-spi0-m2-cs0-mcp2515-16mhz.dtso

dtc -@ -I dts -O dtb -o /boot/dtb/rockchip/overlay/rk3588-spi0-m2-cs0-mcp2515-16mhz.dtbo rk3588-spi0-m2-cs0-mcp2515-16mhz.dtso

3. Activate compiled DTB overlay in kernel

sudo nano /boot/orangepiEnv.txt

verbosity=1
bootlogo=true
extraargs=cma=128M
overlay_prefix=rk3588
fdtfile=rockchip/rk3588s-orangepi-5-pro.dtb
rootdev=UUID=9223cf12-5acd-4190-bd54-f83a43f74a88
rootfstype=ext4
overlays=spi0-m2-cs0-mcp2515-16mhz

4. Reboot and start CAN interface

sudo ip link set can0 type can bitrate 1000000

That’s it – Congratulations! 🙂

 

A blog on projects with robotics, computer vision, 3D printing, microcontrollers, car diagnostics, localization & mapping, digital filters, LiDAR and more