Microchip mcp2515, can over spi, not working. Wrong device tree overlay?

Hi!

I’m trying to get mcp2515 to work. It is a can over spi chip and I can’t seem to get the device tree overlay right. I made a simple c driver using spidev to check if my hardware was right. Using that driver I can read/write to registers so I’m assuming my hardware is correct. The chip is connected to an external 20mhz oscillator. I’ve been stuck for this for a week now, and really need some help to get this to work.

What I have tried so far:
A lot of variations on the devicetree overlay posted below.
Hooked up an oscilloscope, and there is no data going in either direction.
Bought a sparkfun can breakoutboard, and some hex converters, but same problem (so hardware is probably right)

I think there is something worng with the way I define the clock or the interrupts, but honestly, I’ve never done anything this advanced in the device tree overlay, just the regular stuff where there are a lot of resources on the internet, like getting i2c,uart,spi etc. to work.

Devicetree documentation for this chip: http://lxr.free-electrons.com/source/Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt?v=4.4
Driver: https://github.com/beagleboard/linux/blob/698027482f34f2559d648a2994df98b6a98873ab/drivers/net/can/spi/mcp251x.c

After enabling the driver lsmod tells me can_dev is loaded and used by mcp251x.
cat /sys/bus/spi/devices/*/modalias returns spi:mcp2515.

ip a show no can devices.

This is my device tree overlay for the chip:

`

/dts-v1/;
/plugin/;

/ {
        compatible = "ti,beaglebone", "ti,beaglebone-black";

        /* identification */
        part-number = "BB-MIKRO-01";

        /* state the resources this cape uses */
        exclusive-use =
                /* the pin header uses */
                "P9.25",        /* spi irq: gpio3_21 */
                "P9.31",        /* spi: spi1_sclk */
                "P9.29",        /* spi: spi1_d0 */
                "P9.30",        /* spi: spi1_d1 */
                "P9.28",        /* spi: spi1_cs0 */
                /* the hardware IP uses */
                "gpio3_21",
                "spi1";

        clocks{
                extclk: oscillator {
                        compatible="fixed-clock";
                        #clock-cells = <0>;
                        clock-frequency=<20000000>;
                };
        };

        fragment@0 {
                target = <&am33xx_pinmux>;
                __overlay__ {
                        spi1_pins: pinmux_spi1_pins {
                                pinctrl-single,pins = <
                                        0x190 0x33      /* mcasp0_aclkx.spi1_sclk, RX_ENABLED | PULLUP | MODE3 */
                                        0x194 0x33      /* mcasp0_fsx.spi1_d0, RX_ENABLED | PULLUP | MODE3 */
                                        0x198 0x13      /* mcasp0_axr0.spi1_d1, OUTPUT_PULLUP | MODE3 */
                                        0x19c 0x13      /* mcasp0_ahclkr.spi1_cs0, OUTPUT_PULLUP | MODE3 */
                                        0x1ac 0x37      /* mcasp0_ahclkx.gpio3_21, RX_ENABLED | PULLUP | MODE7 */
                                >;
                        };
                };
        };

        fragment@2 {
              target = <&spi1>;

                __overlay__ {
                        #address-cells = <1>;
                        #size-cells = <0>;

                        status    = "okay";
                        pinctrl-names   = "default";
                        pinctrl-0       = <&spi1_pins>;
                        ti,pio-mode; /* disable dma when used as an overlay, dma gets stuck at 160 bits... */

                        can0: can@1 {
                                compatible = "microchip,mcp2515";
                                reg = <0>; /* cs0 */
                                mode = <0>;

                                spi-max-frequency = <10000000>;
                                clocks=<&extclk>;
                                interrupt-parent = <&gpio3>;
                                interrupts = <21 0x02>;
                        };

                };
        };

};

`


dmesg after enabling it on boot with uEnv.txt:

I haven’t really looked yet at your overlay, but two immediate thoughts:

  1. why on earth are you using an spi can controller when there are two built-in CAN controllers already on the beaglebone?
  2. you have cape-universal enabled, this conflicts with pretty much every overlay (remove the cape_universal=enable from cmdline in your /boot/uEnv.txt

BTW I made some utils to make the process of writing overlays less painful: https://github.com/mvduin/overlay-utils
It lets you write them as device tree fragments and automatically converts them to the structure requires for overlays. It also includes macros that make pinmux much easier to read. No support for overlay metadata though, I didn’t bother since the new configfs mechanism to load overlays ignores it anyway.

Matthijs

  1. Haha! It does? Must have missed it when I looked on the pinmap.
  2. Tried to disable universal cape, makes no difference.

Anyways. I still want to get it to work. Have spent so much time on it, and I would hate to just let it go. Even though I probably won’t use it. I also need to get a spi to uart chip (max14830) to work, which has almost the same configuration so I’m hoping that solving this issue, will also solve the max14830.

I will try out your tool, looks very promising :wink: Thanks for the help.

fredag 19. august 2016 15.42.06 UTC+2 skrev Matthijs van Duin følgende:

The clocks node is definitely wrong. Every top-level node in an overlay file is treated as a fragment (names like fragment@0 are conventional but not actually important), but your clocks-node has no target property nor an overlay child node, so it accomplishes nothing.

Matthijs

  1. Haha! It does? Must have missed it when I looked on the pinmap.
  2. Tried to disable universal cape, makes no difference.

Anyways. I still want to get it to work. Have spent so much time on it, and I would hate to just let it go. Even though I probably won’t use it. I also need to get a spi to uart chip (max14830) to work, which has almost the same configuration so I’m hoping that solving this issue, will also solve the max14830.

I will try out your tool, looks very promising :wink: Thanks for the help.

Well, you’re device tree would simply be for SPI anyway. Since thats the bus you’re using. Also, so you know the mcp2515 driver already exists, so I forget whatexactly the module name is, but something like $ sudo modprobe mcp25xx should just work.

https://github.com/msperl/mcp2515/blob/master/mcp2515.c there it is.

By the way, the mcp2515 has a built in transceiver. The CANBUS controller on the am335x does not. the MCP2515 is also more cost efficient. So don’t let anyone make you feel bad for going that route.

Something I noticed about your device tree file. First, the mcp251x.c / mcp2515.c driver would be loaded as a module in a device tree. I see no “status=okay” so the driver would never load. Honestly I’ve yet to setup SPI on the beaglebone in ~3.5 years. So I’m no expert. However if I were you. I would at least initially setup, and use universal-io to mux your pins. https://github.com/cdsteinkuehler/beaglebone-universal-io . It is far simpler, and easier to use than a raw device tree source file.

So, universal io is already installed, and loaded by default on the stick 4.4 debian images. The only thing you may have to do is download via wget config-pin, chmod +x it then move it to the appropriate /bin directory.

Then you just:

$ sudo config-pin PX.XX spi

etc, etc.

After chatting in the IRC channel with Matthijs I was encouraged to not use overlays, and just make my own dtb. I have tried that now, but it doesn’t seem to work properly. I’ve enabled spi0 and spi1. And used the spi_loopback to see that my dtb was working, then i expanded it by adding a clock node and adding the mcp in the spi config. Also, the max14830 not working, maybe the same issue? Anyways, this is my dtb:

`

/*

Hi,

Did you ever get the MCP2515 working over SPI? I’m attempting that now, but I’m not sure where to start.

Thanks,
Mark

Hi!

I got it to work, but not using the mainline driver. I bought a cape from towertech to be sure that my hardware was correct. They shipped the device with some modified version of the driver. Got some help in the beagle irc chat to try to find the origin of that driver. IIRC the driver was based on a driver from many years ago, but it works. I have not tested it over a long period, but it seems to work. I am currently trying to get it to work with the mainline driver, but its not my top priority right now. There has been several changes to the mainline driver since I tried to use it the last time, so i hope it will work next time I try it. With the towertech driver I managed to get it to work, both by using a overlay and just making my own DT. Should be instructions on how to compile if you download from these links. And I think there is a dto in the zip as well. If I get it to work with the mainline, I will update this thread.

Btw. Some other guy on irc did not get this driver to work with his old rev of the can cape. I think I have rev5. Should work with that.

TT3201 driver for Debian 7.x / Kernel 3.x
<https://dl.dropboxusercontent.com/u/2883083/TowerTech/towertech-tt3201-rev5.tar.gz>

tirsdag 14. februar 2017 16.11.56 UTC+1 skrev Mark K Cowan følgende:

I solved it with my own devicetree overlay, loaded after the BB-SPIDEV0 overlay. It’s available at https://github.com/battlesnake/beaglebone-spi0-mcp2515

Hello Mark, thank you for sharing your overlay file. I am trying to
get a MCP2515 working with the BeagleBone Black on SPI0 with the
4.14.78-bone17 kernel.

Would it be possible for to document how you had the MCP2515 wired to
the P8/P9 headers on the BeagleBone Black?

Also, I would be curious to know what kernel version you were using
with this Device Tree Overlay.

I am trying to get this working with u-boot overlays [0] as the cape
manager driver has been deprecated [1].

thanks!
drew

[0] https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#U-Boot_Overlays
[1] https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Where_did_the_slots_file_go.3F

For anyone else finding this, the discussion/development is continued on Github

To followup, here is a GitHub gist which shows how I was able to wire
the MCP2515 to SPI0 on the BeagleBone Black and successfully observe
the mcp251x
initialize it and load the can0 interface:
https://gist.github.com/pdp7/20dddbeffe83082e3c94ab0903563783
(also attached)

Photos of MCP2515 breakout board wired to SPI0 on the BeagleBone Black:
https://photos.app.goo.gl/1UUAHhRngzwiVWha9

add this to /boot/uEnv.txt:

uboot_overlay_addr0=/lib/firmware/BB-SPIDEV0-00A0.dtbo
uboot_overlay_addr1=/lib/firmware/MCP2515.dtbo

grab the MCP2515 overlay and install it:

cd /opt/source/bb.org-overlays/
wget https://github.com/battlesnake/beaglebone-spi0-mcp2515/blob/master/MCP2515.dts
sudo ./install.sh

After rebooting, the mcp251x driver should initialize the MCP2515
device and these commands from the Macchina documentation should work:

sudo ip link set can0 type can bitrate 500000 listen-only on
sudo ifconfig can0 up

Thanks,
Drew

beaglebone-black-mcp2515-breakout-board-md.txt (25.2 KB)

fyi - I have created a pull request to add this dts:
https://github.com/beagleboard/bb.org-overlays/pull/101

-drew