Skip to content

Instantly share code, notes, and snippets.

@pdp7
Last active January 9, 2019 01:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pdp7/c9232831cea1bc544fb9d6d1bd3df905 to your computer and use it in GitHub Desktop.
Save pdp7/c9232831cea1bc544fb9d6d1bd3df905 to your computer and use it in GitHub Desktop.
SPI0 PB-MCP2515.dts

Changed the DT overlay to use SPI0 and wired MCP2515 breakout board to SPI0 on PocketBeagle. The mcp251x driver was able to initialize the device OK!

The mcp251x driver also initialized the MCP2515 device OK when connect to SPI0 on BeagleBone Black.

So why does SPI1 not work?

For SPI0 on PocketBeagle, I used:

PB-MCP2515.dts

debian@beaglebone:/opt/source/bb.org-overlays$ cat src/arm/PB-MCP2515.dts
/dts-v1/;
/plugin/;

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

/ {
        fragment@0 {
                target = <&ocp>;
                __overlay__ {
/* 
M2 J4.20: SWC nINT <-> P2.8 <&gpio1 28 0>, needs GPIO input
M2 J3.6 : SWC_nRESET  <-> P2.32 GPIO 112 / PRU0.2, <&gpio3 16 0>, needs GPIO OUTPUT
M2 J4.9 : SWC_M0  <-> P2.6
M2 J4.28: SWC_M1  <-> P2.18
*/
			P1_12_pinmux { status = "disabled"; };	/* MOSI - gpio0_4 */
			P1_10_pinmux { status = "disabled"; };	/* MISO - gpio0_3 */
			P1_08_pinmux { status = "disabled"; };	/* CLK - gpio0_2 */
			P1_06_pinmux { status = "disabled"; };	/* CS - gpio0_5 */

                        P2_08_pinmux { status = "disabled"; };  /* SWC nINT */
                        P2_32_pinmux { status = "disabled"; };  /* SWC nRESET */
                };
	};


			
        fragment@1 {
                target = <&spi0>;
                __overlay__ {
                        status = "okay";
                        pinctrl-names = "default";
/* 
M2 J4.20: SWC nINT <-> P2.8 <&gpio1 28 0>, needs GPIO input
M2 J3.6 : SWC_nRESET  <-> P2.32 GPIO 112 / PRU0.2, <&gpio3 16 0>, needs GPIO OUTPUT
M2 J4.9 : SWC_M0  <-> P2.6 GPIO 57, needs GPIO OUTPUT
M2 J4.28: SWC_M1  <-> P2.18 GPIO 47, needs GPIO OUTPUT
*/
                        pinctrl-0 = <
                                /* connected to MCP2515 pin 19 _RESET 
                                   hopefully pullup will enable the chip */
                                &P2_32_gpio_pu_pin
                                /* SWC nINT */
                                /* &P2_08_gpio_input_pin is not mode 0x37, so wrong? */
                                &P2_08_default_pin /* this should be mode 0x37 */
                                /* SPI0 */
				&P1_06_spi_cs_pin
				&P1_08_spi_sclk_pin
				&P1_10_spi_pin
				&P1_12_spi_pin
                        >;

                        channel@0{ status = "disabled"; };
                        channel@1{ status = "disabled"; };
                };
        };


        fragment@2 {
		target = <&am33xx_pinmux>;
		__overlay__ {
/*
this was originally for BeagleBone Black and used P8.06

from http://exploringbeaglebone.com/wp-content/uploads/resources/BBBP8Header.pdf
P8_06 3 0x80c/00c 35 GPIO1_3 gpio1[3]

pinctrl-single,pins = < 0x00c 0x37 >;

#0x37 : PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7



for PocketBeagle, Macchina puts nINT on P2.08 (ZCZ ball U18) gpio1_28 
P2_08_default_pin: pinmux_P2_08_default_pin { pinctrl-single,pins = <
AM33XX_IOPAD(0x0878, PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE7) >; }; gpmc_be1n.gpio1_28 

where 0x0878 = PB_P2_08
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/dt-bindings/pinctrl/omap.h#n57
https://github.com/beagleboard/bb.org-overlays/blob/master/tools/pinmux-generator/PocketBeagle.dts#L465-L467
https://github.com/beagleboard/bb.org-overlays/blob/master/tools/pinmux-generator/lib/pinmux.sh#L631
so let's try giving pincntrl-single 0x087 which should be the offset from the 0x0800 base
*/
			mcp2515_int: mcp2515_int {
				pinctrl-single,pins = < 0x087 0x37 >;
			};
		};
	};

	fragment@3 {
		target-path = "/";
		__overlay__ {
			mcp2515_clock: mcp2515_clock {
				compatible = "fixed-clock";
				#clock-cells = <0>;
				clock-frequency = <8000000>;
			};
		};
	};

	fragment@4 {
		target = <&spi0>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			can0: mcp2515@0 {
				status = "okay";
				reg = <0>;
				compatible = "microchip,mcp2515";
				pinctrl-names = "default";
				pinctrl-0 = <&mcp2515_int>;
				spi-max-frequency = <10000000>;
				interrupt-parent = <&gpio1>;
				interrupts = <28 2>;
				clocks = <&mcp2515_clock>;

				mcp251x,oscillator-frequency = <8000000>;
				mcp251x,irq-gpios = <&gpio1 28 0>;
				mcp251x,stay-awake = <1>;
				mcp251x,enable-clkout = <1>;
			};
		};
	};

	__overrides__ {
		oscillator = <&mcp2515_clock>,"clock-frequency:0";
		spimaxfrequency = <&can0>,"spi-max-frequency:0";
		interrupt = <&mcp2515_int>,"pinctrl-single,pins:0",<&can0>,"interrupts:0";
	};

};

dmesg

[   36.889216] IPv6: ADDRCONF(NETDEV_UP): usb0: link is not ready
[   37.183016] IPv6: ADDRCONF(NETDEV_CHANGE): usb0: link becomes ready
[   42.103806] DEBUG SWCAN: mcp251x_can_probe(): spi->chip_select=0x00
[   42.354826] DEBUG SWCAN: mcp251x_can_probe(): spi->irq=0x50
[   42.530893] DEBUG SWCAN: mcp251x_can_probe(): spi->modalias=mcp2515
[   42.781591] DEBUG SWCAN: mcp251x_can_probe(): spi->cs_gpio=0xfffffffe
[   42.964563] DEBUG SWCAN: mcp251x_can_probe(): spi->controller->bus_num=0x00
[   43.270939] DEBUG SWCAN: mcp251x_can_probe(): spi->dev->init_name=(null)
[   43.526138] DEBUG SWCAN: mcp251x_can_probe(): spi->dev->bus->name=spi
[   43.703474] c_can_platform 481cc000.can: c_can_platform device registered (regs=fa1cc000, irq=39)
[   43.726982] DEBUG SWCAN: mcp251x_can_probe(): spi->dev->bus->dev_name=(null)
[   43.779223] c_can_platform 481d0000.can: c_can_platform device registered (regs=fa1d0000, irq=40)
[   43.992895] DEBUG SWCAN: mcp251x_can_probe(): freq = clk_get_rate(clk)
[   44.250869] DEBUG SWCAN: mcp251x_can_probe(): freq=0x7a1200
[   44.407104] DEBUG SWCAN: mcp251x_can_probe(): freq=8000000
[   44.674954] DEBUG SWCAN: mcp251x_can_probe(): net=daa9b000
[   44.792908] DEBUG SWCAN: mcp251x_can_probe(): ret = clk_prepare_enable(clk): 0x00
[   44.963056] DEBUG SWCAN: mcp251x_can_probe(): call mcp251x_power_enable()
[   45.075205] DEBUG SWCAN: mcp251x_can_probe(): call mcp251x_hw_probe()
[   45.274882] DEBUG SWCAN: mcp251x_hw_probe: call mcp251x_hw_reset()
[   45.373637] DEBUG SWCAN: mcp251x_hw_reset(): spriv->spi_tx_buf[0]=0xc0
[   45.634937] DEBUG SWCAN: mcp251x_hw_reset(): call mcp251x_spi_trans(spi, 1)
[   45.778902] DEBUG SWCAN: mcp251x_spi_trans(len=0x01): call spi_message_init()
[   46.002989] DEBUG SWCAN: mcp251x_spi_trans(): call spi_message_add_tail(&t, &m)
[   46.211014] DEBUG SWCAN: mcp251x_spi_trans(): call spi_sync(spi, &m)
[   46.372847] DEBUG SWCAN: mcp251x_spi_trans(): return ret=0x00
[   46.586661] DEBUG SWCAN: mcp251x_hw_reset(): call mcp251x_read_reg(spi, CANSTAT)
[   46.739117] DEBUG SWCAN: mcp251x_read_reg(reg=0x0e): call mcp251x_spi_trans()
[   46.921698] DEBUG SWCAN: mcp251x_spi_trans(len=0x03): call spi_message_init()
[   47.126881] DEBUG SWCAN: mcp251x_spi_trans(): call spi_message_add_tail(&t, &m)
[   47.243076] DEBUG SWCAN: mcp251x_spi_trans(): call spi_sync(spi, &m)
[   47.408906] DEBUG SWCAN: mcp251x_spi_trans(): return ret=0x00
[   47.528872] DEBUG SWCAN: mcp251x_read_reg(): return val=0x80
[   47.706895] DEBUG SWCAN: mcp251x_hw_reset(): reg=0x80
[   47.851419] DEBUG SWCAN: mcp251x_hw_reset(): (reg & CANCTRL_REQOP_MASK)=0x80
[   48.007196] DEBUG SWCAN: mcp251x_hw_probe: ret=0
[   48.114939] DEBUG SWCAN: mcp251x_hw_probe: call mcp251x_read_reg(spi, CANCTRL)
[   48.114963] DEBUG SWCAN: mcp251x_read_reg(reg=0x0f): call mcp251x_spi_trans()
[   48.446946] DEBUG SWCAN: mcp251x_spi_trans(len=0x03): call spi_message_init()
[   48.590916] DEBUG SWCAN: mcp251x_spi_trans(): call spi_message_add_tail(&t, &m)
[   48.810969] DEBUG SWCAN: mcp251x_spi_trans(): call spi_sync(spi, &m)
[   48.938944] DEBUG SWCAN: mcp251x_spi_trans(): return ret=0x00
[   49.039159] DEBUG SWCAN: mcp251x_read_reg(): return val=0x87
[   49.242932] DEBUG SWCAN: mcp251x_hw_probe: ctrl=0x87
[   49.307830] DEBUG SWCAN: mcp251x_hw_probe: ((ctrl & 0x17)=0x07
[   49.462455] mcp251x spi0.0: CANCTRL 0x87
[   49.462467] DEBUG SWCAN: mcp251x_spi_trans(len=0x03): call spi_message_init()
[   49.618942] DEBUG SWCAN: mcp251x_spi_trans(): call spi_message_add_tail(&t, &m)
[   49.814674] DEBUG SWCAN: mcp251x_spi_trans(): call spi_sync(spi, &m)
[   49.962984] DEBUG SWCAN: mcp251x_spi_trans(): return ret=0x00
[   50.114968] mcp251x spi0.0 can2: MCP2515 successfully initialized.
debian@beaglebone:~$ 

NOTE:

the other change made at the same time I switched SPI1 to SPI0, I changed interrupts = <3 2>; to interrupts = <28 2>; based on advise from Robert Nelson

interrupts = <28 IRQMODE>; https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/dt-bindings/interrupt-controller/irq.h#n15 #define IRQ_TYPE_EDGE_FALLING 2

@pdp7
Copy link
Author

pdp7 commented Jan 9, 2019

debian@beaglebone:/opt/source/bb.org-overlays/src/arm$ diff PB-MCP2515-SPI0.dts PB-MCP2515-SPI1.dts 
12,15c12,15
<                         P1_12_pinmux { status = "disabled"; };  /* MOSI - gpio0_4 */
<                         P1_10_pinmux { status = "disabled"; };  /* MISO - gpio0_3 */
<                         P1_08_pinmux { status = "disabled"; };  /* CLK - gpio0_2 */
<                         P1_06_pinmux { status = "disabled"; };  /* CS - gpio0_5 */
---
>                         P2_25_pinmux { status = "disabled"; };  /* MOSI - gpio1_9 */
>                         P2_27_pinmux { status = "disabled"; };  /* MISO - gpio1_8 */
>                         P2_29_pinmux { status = "disabled"; };  /* CLK - gpio0_7 */
>                         P2_31_pinmux { status = "disabled"; };  /* CS - gpio0_19 */
21d20
<             
23c22
<                 target = <&spi0>;
---
>                 target = <&spi1>;
33,37c32,36
<                                /* SPI0 */
<                                &P1_06_spi_cs_pin
<                                &P1_08_spi_sclk_pin
<                                &P1_10_spi_pin
<                                &P1_12_spi_pin
---
>                                /* SPI1 */
>                                &P2_31_spi_cs_pin
>                                &P2_29_spi_sclk_pin
>                                &P2_27_spi_pin
>                                &P2_25_spi_pin
67c66
<         target = <&spi0>;
---
>         target = <&spi1>;

@pdp7
Copy link
Author

pdp7 commented Jan 9, 2019

SPI0

debian@beaglebone:~$ grep -v ^# /boot/uEnv.txt 

uname_r=4.14.78-bone17


enable_uboot_overlays=1
uboot_overlay_addr0=/lib/firmware/PB-MCP2515-SPI0.dtbo
disable_uboot_overlay_emmc=1
disable_uboot_overlay_video=1
disable_uboot_overlay_audio=1
disable_uboot_overlay_wireless=1
disable_uboot_overlay_adc=1
enable_uboot_cape_universal=1

cmdline=coherent_pool=1M net.ifnames=0 quiet



debian@beaglebone:~$ dmesg|tail
[   37.887101] DEBUG SWCAN: mcp251x_hw_probe: ctrl=0x87
[   38.043069] DEBUG SWCAN: mcp251x_hw_probe: ((ctrl & 0x17)=0x07
[   38.151489] mcp251x spi0.0: CANCTRL 0x87
[   38.151501] DEBUG SWCAN: mcp251x_spi_trans(len=0x03): call spi_message_init()
[   38.323142] DEBUG SWCAN: mcp251x_spi_trans(): call spi_message_add_tail(&t, &m)
[   38.519085] DEBUG SWCAN: mcp251x_spi_trans(): call spi_sync(spi, &m)
[   38.685716] DEBUG SWCAN: mcp251x_spi_trans(): return ret=0x00
[   38.848012] mcp251x spi0.0 can0: MCP2515 successfully initialized.
[   45.467440] c_can_platform 481cc000.can: c_can_platform device registered (regs=fa1cc000, irq=39)
[   45.489638] c_can_platform 481d0000.can: c_can_platform device registered (regs=fa1d0000, irq=40)
debian@beaglebone:~$ 

@pdp7
Copy link
Author

pdp7 commented Jan 9, 2019

SPI1

debian@beaglebone:~$ grep -v ^# /boot/uEnv.txt 

uname_r=4.14.78-bone17


enable_uboot_overlays=1
uboot_overlay_addr0=/lib/firmware/PB-MCP2515-SPI1.dtbo
disable_uboot_overlay_emmc=1
disable_uboot_overlay_video=1
disable_uboot_overlay_audio=1
disable_uboot_overlay_wireless=1
disable_uboot_overlay_adc=1
enable_uboot_cape_universal=1

cmdline=coherent_pool=1M net.ifnames=0 quiet



debian@beaglebone:~$ dmesg |tail
[   48.304364] DEBUG SWCAN: mcp251x_spi_trans(len=0x03): call spi_message_init()
[   48.474691] DEBUG SWCAN: mcp251x_spi_trans(): call spi_message_add_tail(&t, &m)
[   48.669091] DEBUG SWCAN: mcp251x_spi_trans(): call spi_sync(spi, &m)
[   48.834216] DEBUG SWCAN: mcp251x_spi_trans(): return ret=0x00
[   48.982617] DEBUG SWCAN: mcp251x_read_reg(): return val=0xcb
[   49.078688] DEBUG SWCAN: mcp251x_hw_probe: ctrl=0xcb
[   49.178718] DEBUG SWCAN: mcp251x_hw_probe: ((ctrl & 0x17)=0x03
[   49.314712] mcp251x spi1.0: CANCTRL 0xcb
[   49.314724] mcp251x spi1.0: Cannot initialize MCP2515. Wrong wiring?
[   49.472386] mcp251x spi1.0: Probe failed, err=19
debian@beaglebone:~$ 

@pdp7
Copy link
Author

pdp7 commented Jan 9, 2019

src/arm/PB-MCP2515-SPI0.dts

/dts-v1/;
/plugin/;

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

/ {
        fragment@0 {
                target = <&ocp>;
                __overlay__ {
                        P1_12_pinmux { status = "disabled"; };  /* MOSI - gpio0_4 */
                        P1_10_pinmux { status = "disabled"; };  /* MISO - gpio0_3 */
                        P1_08_pinmux { status = "disabled"; };  /* CLK - gpio0_2 */
                        P1_06_pinmux { status = "disabled"; };  /* CS - gpio0_5 */
                        P2_08_pinmux { status = "disabled"; };  /* SWC nINT */
                        P2_32_pinmux { status = "disabled"; };  /* SWC nRESET */
                };
        };

            
        fragment@1 {
                target = <&spi0>;
                __overlay__ {
                        status = "okay";
                        pinctrl-names = "default";
                        pinctrl-0 = <
                               /* connected to MCP2515 pin 19 _RESET 
                                  hopefully pullup will enable the chip */
                               &P2_32_gpio_pu_pin
                               /* SWC nINT */
                               &P2_08_default_pin /* this should be mode 0x37 */
                               /* SPI0 */
                               &P1_06_spi_cs_pin
                               &P1_08_spi_sclk_pin
                               &P1_10_spi_pin
                               &P1_12_spi_pin
                        >;

                        channel@0{ status = "disabled"; };
                        channel@1{ status = "disabled"; };
                };
        };


        fragment@2 {
        target = <&am33xx_pinmux>;
        __overlay__ {
            mcp2515_int: mcp2515_int {
                pinctrl-single,pins = < 0x087 0x37 >;
            };
        };
    };

    fragment@3 {
        target-path = "/";
        __overlay__ {
            mcp2515_clock: mcp2515_clock {
                compatible = "fixed-clock";
                #clock-cells = <0>;
                clock-frequency = <8000000>;
            };
        };
    };

    fragment@4 {
        target = <&spi0>;
        __overlay__ {
            #address-cells = <1>;
            #size-cells = <0>;
            can0: mcp2515@0 {
                status = "okay";
                reg = <0>;
                compatible = "microchip,mcp2515";
                pinctrl-names = "default";
                pinctrl-0 = <&mcp2515_int>;
                spi-max-frequency = <10000000>;
                interrupt-parent = <&gpio1>;
                interrupts = <28 2>;
                clocks = <&mcp2515_clock>;

                mcp251x,oscillator-frequency = <8000000>;
                mcp251x,irq-gpios = <&gpio1 28 0>;
                mcp251x,stay-awake = <1>;
                mcp251x,enable-clkout = <1>;
            };
        };
    };

    __overrides__ {
        oscillator = <&mcp2515_clock>,"clock-frequency:0";
        spimaxfrequency = <&can0>,"spi-max-frequency:0";
        interrupt = <&mcp2515_int>,"pinctrl-single,pins:0",<&can0>,"interrupts:0";
    };

};

@pdp7
Copy link
Author

pdp7 commented Jan 9, 2019

src/arm/PB-MCP2515-SPI1.dts

/dts-v1/;
/plugin/;

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

/ {
        fragment@0 {
                target = <&ocp>;
                __overlay__ {
                        P2_25_pinmux { status = "disabled"; };  /* MOSI - gpio1_9 */
                        P2_27_pinmux { status = "disabled"; };  /* MISO - gpio1_8 */
                        P2_29_pinmux { status = "disabled"; };  /* CLK - gpio0_7 */
                        P2_31_pinmux { status = "disabled"; };  /* CS - gpio0_19 */
                        P2_08_pinmux { status = "disabled"; };  /* SWC nINT */
                        P2_32_pinmux { status = "disabled"; };  /* SWC nRESET */
                };
        };

        fragment@1 {
                target = <&spi1>;
                __overlay__ {
                        status = "okay";
                        pinctrl-names = "default";
                        pinctrl-0 = <
                               /* connected to MCP2515 pin 19 _RESET 
                                  hopefully pullup will enable the chip */
                               &P2_32_gpio_pu_pin
                               /* SWC nINT */
                               &P2_08_default_pin /* this should be mode 0x37 */
                               /* SPI1 */
                               &P2_31_spi_cs_pin
                               &P2_29_spi_sclk_pin
                               &P2_27_spi_pin
                               &P2_25_spi_pin
                        >;

                        channel@0{ status = "disabled"; };
                        channel@1{ status = "disabled"; };
                };
        };


        fragment@2 {
        target = <&am33xx_pinmux>;
        __overlay__ {
            mcp2515_int: mcp2515_int {
                pinctrl-single,pins = < 0x087 0x37 >;
            };
        };
    };

    fragment@3 {
        target-path = "/";
        __overlay__ {
            mcp2515_clock: mcp2515_clock {
                compatible = "fixed-clock";
                #clock-cells = <0>;
                clock-frequency = <8000000>;
            };
        };
    };

    fragment@4 {
        target = <&spi1>;
        __overlay__ {
            #address-cells = <1>;
            #size-cells = <0>;
            can0: mcp2515@0 {
                status = "okay";
                reg = <0>;
                compatible = "microchip,mcp2515";
                pinctrl-names = "default";
                pinctrl-0 = <&mcp2515_int>;
                spi-max-frequency = <10000000>;
                interrupt-parent = <&gpio1>;
                interrupts = <28 2>;
                clocks = <&mcp2515_clock>;

                mcp251x,oscillator-frequency = <8000000>;
                mcp251x,irq-gpios = <&gpio1 28 0>;
                mcp251x,stay-awake = <1>;
                mcp251x,enable-clkout = <1>;
            };
        };
    };

    __overrides__ {
        oscillator = <&mcp2515_clock>,"clock-frequency:0";
        spimaxfrequency = <&can0>,"spi-max-frequency:0";
        interrupt = <&mcp2515_int>,"pinctrl-single,pins:0",<&can0>,"interrupts:0";
    };

};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment