Linux: mcp2515 overlay support to SPI bus 1 on RPI 3

Created on 19 Jan 2017  路  47Comments  路  Source: raspberrypi/linux

I tested the additional spi bus 1 on RPI3 after enabling the overlay in config.txt file

dtoverlay=spi1-3cs

the 3 chip selects spi1.0 / spi1.1 / spi1.2, all works fine with an mcp3008 ADC chip, so there is no problem at all with this bus and its corresponding chip selects.

Now, I wanted to write .dts source that supports the functionality of mcp2515 on this additional SPI bus. Very similar to what a contributor before did @petit_miner to the overlay mcp2515-can1-overlay.dts but i changed every spi0 to spi1, the mcp2515 worked but spi0.1 disappeared and the chipselects of "SPI 1" were not properly functioning, that is if connecting the mcp2515 module to spi1.0 or spi1.1 they both works which is not right.

here is my trial, i didn't change much except using spi1 instead of spi0.

the original dts file is found on your repository rpi-4.4.y , this is what i used to modify and recompile

My modifications are:
`

 /*
 * Device tree overlay for mcp251x/can2 on spi1.0
 */
/dts-v1/;
/plugin/;

/ {

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

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

    /* the interrupt pin of the can-controller */
    fragment@2 {
        target = <&gpio>;
        __overlay__ {
            can2_pins: can2_pins {
                brcm,pins = <25>; /* it is the default pin and it will be overriden */
                brcm,function = <0>; /* input */
            };
        };
    };

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


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

`
please what i am doing wrong or what needs to be changed in order to have the mcp2515 overlay correctly uses the spi1.0 / spi1.1 / spi1.2 overlays.

Thanks

I am using Raspbian: Linux raspberrypi 4.4.38-v7+ #938 SMP Thu Dec 15 15:22:21 GMT 2016 armv7l GNU/Linux

Most helpful comment

Oh, that's a shame - it defaults to enabled, so you'll have to explicitly disable it:

dtoverlay=spi1-1cs,cs0_spidev=off

All 47 comments

the mcp2515 worked but spi0.1 disappeared

That's would make sense if you meant "spi0.0", due to fragment@1 - spidev0 is the label for the node that creates spidev0.0, and fragment 1 disable it; just delete fragment 1.

the chipselects of "SPI 1" were not properly functioning

You will need to disable the spidev associated with spi1.0 - you can do this with an overlay parameter:

dtoverlay=spi1-3cs,cs0_spidev=off

Also, fragment 0 is unnecessary because loading the spi1-3cs overlay enables spi1.

In summary:

  1. Delete fragments 0 and 1 (and renumber the others to be neat).
  2. Change dtoverlay=spi1-3cs to dtoverlay=spi1-3cs,cs0_spidev=off.
  3. Reboot and see what happens.

However, see #1484 - it seems that there are interrupt problems when various Aux peripherals (SPI1, SPI2 and UART1) are used together. You may have to disable (or not enable) UART1 - put enable_uart=0 in config.txt, or just don't add enable_uart=1. Alternatively, if you do need a serial port and you can live without Bluetooth for a the experiments, add dtoverlay=pi3-disable-bt to config.txt which tells the Pi3 to use UART0 (ttyAMA0) for console output, just like a Pi2.

I'm hoping to look at the Aux interrupt issue today.

This is incredibly awesome @pelwell . Thank you very much.

I had now SPI0 along with SPI1 working without any issues and i did not disable the UART at all. For the moment i don't need either UART1 or the Blutooth.

I have tested also the mcp2515 Transceiver on the whole chip selects of SPI1 with different overlays and it worked fine.

Just a matter of curiosity, you mentioned SPI2 but actually the SPI 2 bins are assigned to bins which don't exist for the 40 bins RPI3, is this considered for future RPI versions?
is it possible to change the brcm bins in the dts and have SPI 2 assigned to different pins ?

I am grateful to your help and Thank you again !

Regards
Ahmed

SPI2 can be used on a Compute Module on GPIOs 40-45, but sadly the SPI2 function isn't available on GPIOS 0-27.

Thank you !

Hi ahmedawad1
Share please the final Result.
I use three SPI SPI0.0 SPI0.1 and SPI1.0 for the MCP2515.
Thank you.

It is exactly as what what @pelwell mentioned in the summary steps. Follow the dts source code in the first comment, and make the required modifications. Then use a dtc compiler to compile from .dts to dtb or .dtbo according to the Raspbian kernel version that you use. You can see this post on the Raspberry Forum to get to know how to compile it from .dts source file. here

I make mcp2515-can2-overlay.dts

/*

  • Device tree overlay for mcp251x/can2 on spi1.0
    */
    /dts-v1/;
    /plugin/;

/ {

compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709";
/* disable spi-dev for spi1.0 */

/* the interrupt pin of the can-controller */
fragment@0 {
    target = <&gpio>;
    __overlay__ {
        can2_pins: can2_pins {
            brcm,pins = <25>; /* it is the default pin and it will be overriden */
            brcm,function = <0>; /* input */
        };
    };
};

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


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

};

on RPi
sudo apt-get install device-tree-compiler
dtc -@ -I dts -O dtb -o mcp2515-can2.dtbo mcp2515-can2-overlay.dts

Warning (unit_address_vs_reg): Node /fragment@0 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /fragment@1 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /fragment@2 has a unit name, but no reg property

sudo cp mcp2515-can2.dtbo /boot/overlays

in /boot/config.txt
dtparam=spi=on
dtoverlay=mcp2515-can2-overlay,oscillator=16000000,interrupt=25
dtoverlay=spi-bcm2835-overlay

CAN2 was not created.

sudo /sbin/ip link set can2 up type can bitrate 500000

need
dtoverlay=spi1-1cs

your .dts source file looks ok but I think you are missing in the config.txt :

Change dtoverlay=spi1-3cs to dtoverlay=spi1-3cs,cs0_spidev=off

Try it!

I have only one SPI1.0
CE1 and CE2 use for RTS, CTS

@karu2003
Maybe there is can0 not can2,
try ifconfig -a first ,and see what it is.
In my test, CAN0 was created when I connected mcp2515 to spi1 .

Thanks, it works. CAN0 is better. :)

Hello , I'm trying to do the same - connect the Canbus to SPI1 - I think I did everything written here - but it doesn't work,
this is what I have in the config.txt:

dtparam=i2c_arm=on
dtparam=spi=on
dtoverlay=spi1-1cs
dtoverlay=mcp2515-can0,oscillator=8000000,interrupt=12
dtoverlay=spi1-bcm2835-overlay
enable_uart=0
dtoverlay=pi3-disable-bt

the connection are:
int -- 32 (GPIO 12)
sck -- 40 (GPIO 21 , SPI1 SCLS)
si -- 38 (GPIO 20 , SPI1 MOSI)
so -- 35 (GPIO 19 , SPI1 MISO)
cs -- 12 (GPIO 18 , SPI1 CS0)
gnd -- 6 (GND)
vcc - 2 (5V)

but I can't see the can0

why?
what am I missing doing wrong?

Thanks,

dtoverlay=mcp2515-can0,oscillator=8000000,interrupt=12

Shouldn't that be:

dtoverlay=mcp2515-can1,oscillator=8000000,interrupt=12
                     ^

?

And I don't know what spi1-bcm2835 is supposed to do, but it shouldn't be necessary.

this is what I have now :

dtparam=i2c_arm=on
dtparam=spi=on
dtoverlay=spi1-1cs
dtoverlay=mcp2515-can1,oscillator=8000000,interrupt=12
enable_uart=0
dtoverlay=pi3-disable-bt

still doesn't work

maybe my cable connection is wrong?

also I only change the the config.txt - do I need to download something?

Let's debug this systematically. Step 1 - is the spi1-1cs overlay working? Comment out the mcp2515 dtoverlay line and add the cs0_spidev parameter to the spi1-1cs overlay:

dtoverlay=spi1-1cs,cs0_spidev
#dtoverlay=mcp2515-can1,oscillator=8000000,interrupt=12

After rebooting, confirm that /dev/spidev1.0 exists.

yes ,
I get
/dev/spidev0.0 /dev/spidev0.1 /dev/spidev1.0

Step 2 - see if the hardware responds.

  1. Run these steps to install the SPI-Py library:
git clone https://github.com/lthiery/SPI-Py.git
cd SPI-Py
sudo python setup.py install
cd ..
  1. Download the MFRC522_test script from here.

  2. Edit the script to change "/dev/spidev0.0" to "/dev/spidev1.0".

  3. Run:

$ python MFRC522_test.py

and report the output.

You may also need:

  1. Install python-dev and git:
$ sudo apt-get install python-dev git

question :
I have a SPI-Py already(I'm using it for read data from RFID )
so can I only run the MFRC522 script?

Yes - jump straight to 2.

this is the output:
pi@raspberrypi:~ $ python /home/pi/MFRC522-python/test.py
00: 00 00 00 00 00 00 00 00
08: 00 00 00 00 00 00 00 00
10: 54 00 00 00 00 00 00 00
18: 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00
28: 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00
38: 00 00 00 00 00 00 00 00

another small question :
this is for the canbus right?
becasue I also have RFID redaer MFRC522 connected to SPI0 - and it's working

Thanks ,

It's just a simple script that tries to read from various addresses on the device. It should show some kind of life from most devices. The fact that the output isn't all 00s or ffs suggests that the wiring might be OK.

Step 3 - enable the driver.

i. Remove the cs0_spidev parameter and uncomment the mcp2515-can1 overlay.
ii. Reboot, then run:

$ dmesg | grep -i -E "(mcp|spi)"

this is the config now:
dtoverlay=spi1-1cs
dtoverlay=mcp2515-can0,oscillator=8000000,interrupt=12

and after reboot this is what I get:
pi@raspberrypi:~ $ dmesg | grep -i -E "(mcp|spi)"
[ 4.640673] mcp251x spi0.0: Cannot initialize MCP2515. Wrong wiring?
[ 4.640711] mcp251x spi0.0: Probe failed, err=19

And with the mcp2515-can1 overlay?

Nevermind - that's for spi0.1, not spi1.0. You'll need a custom overlay...

when I use this command
dtoverlay=mcp2515-can1,oscillator=8000000,interrupt=12

this is the output I get:
[ 4.455799] mcp251x spi0.1: Cannot initialize MCP2515. Wrong wiring?
[ 4.455834] mcp251x spi0.1: Probe failed, err=19

There's a potentially suitable overlay (mcp2515-can1-0.dtbo) here.

what to do with this dtbo file?

Copy it into /boot/overlays, and use:

dtoverlay=mcp2515-can1-0,oscillator=8000000,interrupt=12

when I try I get permission deny...
how do I change it? I forgot (and I wnat to be sure I'm doing it correct)

sudo cp mcp2515-can1-0.dtbo /boot/overlays

does it mean its working?

pi@raspberrypi:~ $ dmesg | grep -i -E "(mcp|spi)"
[ 4.201993] spi-bcm2835aux 3f215080.spi: chipselect 0 already in use
[ 4.202013] spi_master spi1: spi_device register error /soc/spi@7e215080/spidev@0
[ 4.202029] spi_master spi1: Failed to create SPI device for /soc/spi@7e215080/spidev@0
[ 4.624952] mcp251x spi1.0 can0: MCP2515 successfully initialized.

I think so. From the error message I would guess that you haven't removed the cs0_spidev parameter:
```
dtoverlay=spi1-1cs,cs0_spidev

delete this -> ^^^^^^^^^^^

I will check and let you know if it;s working well ,

but the config.txt is this :

dtparam=i2c_arm=on
dtparam=spi=on

dtoverlay=spi1-1cs
dtoverlay=mcp2515-can1-0,oscillator=8000000,interrupt=12

Oh, that's a shame - it defaults to enabled, so you'll have to explicitly disable it:

dtoverlay=spi1-1cs,cs0_spidev=off

it's seem that you did a GRAET job!
Thank you VERY VERY MUCH!!!!!!!!!!
I have try for 3 days all over the internet to find a solution - nothing (stackoverflow,stackexchange,PI forum,electronic forum ,linux forum)
it's seem that you are the only one that really understadn this

Thanks again!
I will let it work all night and tomorrow let you know

Unfortunately there is no easy way to make an overlay work with more than one of the many combinations of SPI interfaces and chip selects, so a new combination often runs into problems like this. The larger number of wires compared to I2C makes a wiring fault more likely, and differences in the protocol (again compared to I2C) make it harder to tell a configuration error from a hardware issue.

Hello,
maybe its a another topic, but how can I use the mcp2515 in a c application. I cant find a library or driver for it :(

It is the wrong topic - try the Raspberry Pi Forums. But here's a starting point: https://en.wikipedia.org/wiki/SocketCAN

SPI2 can be used on a Compute Module on GPIOs 40-45, but sadly the SPI2 function isn't available on GPIOS 0-27.

Hello,
I have tried the same way to use CAN bus with SPI2. I have already use the default mcp2515-can0(with SPI0.0) device tree file to enable CAN bus communication. However SPI2 just doesn't work.
Here is my pin map for another mcp2515:

  • GPIO40: SPI2-MISO
  • GPIO41: SPI2-MOSI
  • GPIO42: SPI2-SCLK
  • GPIO43: SPI_CE1_N
  • GPIO45: INTERRUPT

I tried the test script on SPI2 and got all zeros:
00: 00 00 00 00 00 00 00 00
08: 00 00 00 00 00 00 00 00
10: 00 00 00 00 00 00 00 00
18: 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00
28: 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00
38: 00 00 00 00 00 00 00 00

The result on SPI0 is OK:
00: 00 00 00 00 00 00 00 00
08: b8 8f 9e eb 00 00 00 00
10: 50 00 00 00 00 00 00 00
18: 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00
28: 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 00 00
38: 00 00 00 00 00 00 00 00

This means SPI0 works OK but SPI2 doesn't.
The dmesg log:

$ dmesg | grep spi
[    4.901209] spi-bcm2835aux 3f2150c0.spi: chipselect 0 already in use
[    4.901234] spi_master spi2: spi_device register error /soc/spi@7e2150c0/spidev@0
[    4.901255] spi_master spi2: Failed to create SPI device for /soc/spi@7e2150c0/spidev@0
[    6.236120] mcp251x spi0.0 can0: MCP2515 successfully initialized.
[    6.251056] mcp251x spi2.0: Cannot initialize MCP2515. Wrong wiring?
[    6.251100] mcp251x spi2.0: Probe failed, err=19

From the results above, SPI2 just doesn't work, is there any reason that may lead to this problem?

By the way , here are my configuration:

  • Below is the config.txt
dtparam=watchdog=on
disable_splash=1
hdmi_blanking=2
dtparam=i2c_arm=off
dtparam=spi=on
dtoverlay=mcp2515-can0, oscillator=16000000, interrupt=25
dtoverlay=spi2-1cs,cs0_pin=43, cs0_spidev=disabled
dtoverlay=mcp2515-can1-spi2, oscillator=16000000, interrupt=45
kernel=vmlinuz-4.14.91-rt49-v7+
start_x=0
  • And below is the dts file
/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709";
    fragment@0 {
        target = <&spi2>;
        __overlay__{
            status = "okay";
        };
    };

    /* the interrupt pin of the can-controller */
    fragment@1 {
        target = <&gpio>;
        __overlay__ {
            can1_pins: can1_pins {
                brcm,pins = <45>;
                brcm,function = <0>; /* input */
            };
        };
    };

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

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

Fragment 3 looks wrong - you've chosen the 1cs version of the spi2 overlay, but can1 is mcp2515@1, which means it is going to try to use the second CS lines (numbering starts from 0). Try using can1: mcp2515@0 { instead.

Also note that fragment 0 is redundant - without the spi2-1cs overlay there would be no spi2 label to target, and with it the node is already enabled.

Fragment 3 looks wrong - you've chosen the 1cs version of the spi2 overlay, but can1 is mcp2515@1, which means it is going to try to use the second CS lines (numbering starts from 0). Try using can1: mcp2515@0 { instead.

Also note that fragment 0 is redundant - without the spi2-1cs overlay there would be no spi2 label to target, and with it the node is already enabled.

Thank you very much for the correction! I have succeeded read data from can bus(can1) with SPI2!
I have set the spidev to be disabled or off :
dtoverlay=spi2-1cs,cs0_pin=43, cs0_spidev=disabled

can0 and can1 work fine but the message still exists:
dmesg | grep spi
[ 4.949327] spi-bcm2835aux 3f2150c0.spi: chipselect 0 already in use
[ 4.949350] spi_master spi2: spi_device register error /soc/spi@7e2150c0/spidev@0
[ 4.949377] spi_master spi2: Failed to create SPI device for /soc/spi@7e2150c0/spidev@0
[ 6.347249] mcp251x spi0.0 can0: MCP2515 successfully initialized.
[ 6.359900] mcp251x spi2.0 can1: MCP2515 successfully initialized.

Hey, so I'm trying to use the SPI1.0 and SPI1.1 for a project with CAN bus.
I have enabled the SPI1 successfully, but when I'm not able to disable spidev on one of the two.
My config.txt :

dtoverlay=spi1-1cs,cs0_spidev=disabled  
dtoverlay=spi1-2cs,cs1_spidev=disabled

When I now type ls /dev/sp* the spidev still shows up on spi1.0

/dev/spidev0.0   /dev/spidev0.1   /dev/spidev1.0

Can you tell me why this happens and how to actually disable spidev for both?

The "-cs" suffix indicates _how many_ chip selects to enable, not _which_ chip select to enable. Loading the second overlay overwrites the first and reactivates spidev1.0.

I think what you want is:

dtoverlay=spi1-2cs,cs0_spidev=disabled,cs1_spidev=disabled

By the way, off also works, i.e. dtoverlay=spi1-2cs,cs0_spidev=off,cs1_spidev=off.

Yes, that managed to fix my issue. Thank you very much for the help!

Was this page helpful?
0 / 5 - 0 ratings