Power & Source of Big Ideas

mcp2515 CAN controller via SPI

Moderators: chensy, FATechsupport

I've enabled SPI via UART4 with the help of this post

There is a dst file for NVIDEA Tegra boards here

However I have difficulties to enable the MPC2515 CAN controller via SPI, since I don't know how to bring up the correct DST config.

Here is my config from arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi so far:

Code: Select all

...
        clocks {
                /* 8MHz external crystal oscillator */
                clk8m: mcp251x_osc {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <8000000>;
                };
        };

...
spi1 {
        status = "okay";
        pinctrl-names = "default", "sleep";
        pinctrl-1 = <&spi1_gpio>;

        spidev0: spidev@0 {
                compatible = "rockchip,spidev";
                reg = <0>;
                spi-max-frequency = <10000000>;
                status = "okay";
        };

        can@0 {
                #address-cells = <0x1>;
                #size-cells = <0x0>;
                compatible = "microchip,mcp2515";
                reg = <0x0>;

                clocks = <&clk8m>;
                interrupt-parent = <&tegra_aon_gpio>;
                interrupts = <DAXC03_INT IRQ_TYPE_EDGE_FALLING>;
                spi-max-frequency = <2000000>;

                vdd-supply = <&spmic_ldo5>;
                xceiver-supply = <&spmic_ldo5>;
        };
};


I have wired GPIO4_C5 (GPIO 149) for the interrupt line. The rest (MISO, MOSI, CS and CLK) should be the default ones from the 260 pin spec.
I have no clue what interrupt-parent should look like, how to reference GPIO4_C5 in interrupts, what vdd-supply and xceiver-supply are.
How would the correct dst config look like?
I think more info is needed. Hardware used: SOM-RK3399 with SOM-RK339 Dev-Kit. Wiring infos:

Code: Select all

|MCP2515   | SOM-RK3399 pin         | dev_kit Connector  | Signal name                |
|----------|------------------------|--------------------|----------------------------|
|SCK       | SPI1_CLK (62)          | CON8 pin 7         | GPIO1_B1                   |
|SI        | SPI1_TXD/UART4_TX (58) | UART4 TX           | GPIO1_B0/SPI1_TXD/UART4_TX |
|SO        | SPI1_RXD/UART4_RX (60) | UART4 RX           | GPIO1_A7/SPI1_RXD/UART4_RX |
|CS        | SPI1_CSn0 (56)         | CON8 pin 9         | GPIO1_B2                   |
|INT       | GPIO4_C5/SPDIF_TX (50) | CON8 pin 10        | GPIO4_C5/SPDIF_TX          |


We are using linux 4.4.y and enabled SPI as described in the wiki

We added a DTS description for the MCP2515 like by extending the &spi1 section from arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi like the following:

Code: Select all

/ {
        model = "FriendlyElec boards based on Rockchip RK3399";
        compatible = "friendlyelec,nanopi4",
                   "rockchip,rk3399";
        clocks {
                /* 8MHz external crystal oscillator */
                clk8m: mcp251x_osc {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <8000000>;
                };
        };

...

&spi1 {
        status = "okay";
        pinctrl-names = "default", "sleep";
        pinctrl-1 = <&spi1_gpio>;

        can@0 {
                #address-cells = <0x1>;
                #size-cells = <0x0>;
                compatible = "microchip,mcp2515";
                reg = <0x0>;

                clocks = <&clk8m>;
                interrupt-parent = <&gpio4>;
                interrupts = <149 IRQ_TYPE_EDGE_FALLING>;
                spi-max-frequency = <1000000>;

                //vdd-supply = <&spmic_ldo5>;
                //xceiver-supply = <&spmic_ldo5>;
        };
};


On boot, dmesg tells us:

Code: Select all

[    1.203206] rockchip-spi ff1d0000.spi: no high_speed pinctrl state
[    1.205447] rk_gmac-dwmac fe300000.ethernet: clock input or output? (input).
[    1.206074] rk_gmac-dwmac fe300000.ethernet: TX delay(0x28).
[    1.206592] rk_gmac-dwmac fe300000.ethernet: RX delay(0x11).
[    1.207112] rk_gmac-dwmac fe300000.ethernet: integrated PHY? (no).
[    1.207839] rk_gmac-dwmac fe300000.ethernet: cannot get clock clk_mac_speed
[    1.208469] rk_gmac-dwmac fe300000.ethernet: clock input from PHY
[    1.214014] rk_gmac-dwmac fe300000.ethernet: init for RGMII
...

[    3.905627] CAN device driver interface
[    3.910709] error: hwirq 0x95 is too large for gpio4
[    3.910742] ------------[ cut here ]------------
[    3.910748] WARNING: at kernel/irq/irqdomain.c:347
[    3.910754] Modules linked in: mcp251x(+) can_dev bcmdhd binfmt_misc uio_pdrv_genirq uio sch_fq_codel bnep ip_tables x_tables

[    3.910809] CPU: 2 PID: 327 Comm: systemd-udevd Not tainted 4.4.179 #4
[    3.910815] Hardware name: FriendlyElec SOM-RK3399 (DT)
[    3.910822] task: ffffffc07a2f0000 task.stack: ffffffc07a15c000
[    3.910837] PC is at irq_domain_associate+0x14c/0x1e8
[    3.910844] LR is at irq_domain_associate+0x14c/0x1e8

...


Questions:

Is SPDIF_TX used otherwise or can it be used as interrupt for the MCP2515 CAN module? If yes, what do you recommend as alternative?
How do I correctly reference the interrupt from GPIO4_C5?

How would the correct MCP configuration look like?
So this is the correct dtsi config in arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi

Code: Select all

/ {
        model = "FriendlyElec boards based on Rockchip RK3399";
        compatible = "friendlyelec,nanopi4",
                   "rockchip,rk3399";
        clocks {
                /* 8MHz external crystal oscillator */
                clk8m: mcp251x_osc {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <8000000>;
                };
        };
....
&spi1 {
        status = "okay";
        pinctrl-names = "default", "sleep";
        pinctrl-1 = <&spi1_gpio>;

        can@0 {
                #address-cells = <0x1>;
                #size-cells = <0x0>;
                compatible = "microchip,mcp2515";
                reg = <0x0>;

                clocks = <&clk8m>;
                interrupt-parent = <&gpio4>;
                interrupts = <21 IRQ_TYPE_EDGE_FALLING>;
                spi-max-frequency = <1000000>;

                //vdd-supply = <&spmic_ldo5>;
                //xceiver-supply = <&spmic_ldo5>;
        };
};



The biggest knowledge gap was how to calculate the interrupt number for GPIO4_C5. There is the formula for calculating pin numbers on linux:

Bank * 32 + Port*8 + Pin

Port: A=0; B=1; C=2...

Example GPIO4_C5:

4*32 + 2*8 + 5 = 149

Now for the interrupt config in the dtsi, there is the bank already referenced with the interrupt-parent gpio4. It looks like only the latter part are relevant for the interrupt number:

2*8 + 5 = 21

Who is online

In total there are 8 users online :: 0 registered, 0 hidden and 8 guests (based on users active over the past 5 minutes)
Most users ever online was 2865 on Sun Nov 10, 2019 5:27 am

Users browsing this forum: No registered users and 8 guests