Jump to content

MCP2515 CAN Controller on Allwinner D1 (MangoPi Mqpro)


Fran A100
Go to solution Solved by Fran A100,

Recommended Posts

Hi Guys!

 

This is my fist post on this forum. I have been spending a lot of time these days to make the MCP2515 CAN Controller on the RISCV computer, but I am not able to make it work even if everything seems to be on place. It is obvious that I am not understanding something correclty and that is why is not working. I am using the MangoPi Mqpro that has the SPI port on the 40 pin connector.

Right now is not possible to add overlays on mangopi with the arbiam, but I managed to upload my custom overlays using the grub and Ubuntu, that part is not relevant for the topic. Let's assume for the topic that I am able to upload overlays and they are correctly applied on device tree.

 

### Connections

 

The SPI interface is defined as follows, extracted from /sys/kernel/debug/pinctrl/2000000.pinctrl/pinmux-pins:

pin 106 (PD10): device 4026000.spi function spi1 group PD10
pin 107 (PD11): device 4026000.spi function spi1 group PD11
pin 108 (PD12): device 4026000.spi function spi1 group PD12
pin 109 (PD13): device 4026000.spi function spi1 group PD13
pin 110 (PD14): device 4026000.spi function spi1 group PD14
pin 111 (PD15): device 4026000.spi function spi1 group PD15
pin 112 (PD16): device 2000c00.pwm function pwm group PD16
pin 113 (PD17): device spi1.0 function irq group PD17


 

Basically is connected to the SPI interface of the MCP2515, and the interrupt is connected to PD17.

 

SPI_INT PD17
SPI_SCK PD11
SPI_SI PD12
SPI_SO PD13
SPI_CS PD10

 

The overlay that I am applying is the next one:

/dts-v1/;
/plugin/;

/ {
	compatible = "allwinner,d1-nezha\0allwinner,sun20i-d1";

	fragment@0 {
		target-path = "/clocks";
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <1>;
            /* External crystal oscillator on the board */
			can0_osc_fixed: can0_osc_fixed {
				compatible = "fixed-clock";
                #clock-cells = <0>;
                clock-frequency  = <8000000>;
                phandle = <0x81>;
			};
		};
	};

	fragment@1 {
		target = <&pinctrl>; // pinctrl@2000000
		__overlay__ {
			can0_pin_irq: can0_pin_irq {
				pins = "PD17";
                function = "irq";
                phandle = <0x85>;
			};
		};
	};

	fragment@2 {
		target = <&spi>;   //spi@4026000
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";
			mcp2515 {
				reg = <0>;		// SPI 1
                compatible = "microchip,mcp2515";
                pinctrl-names = "default";
                pinctrl-0 = <0x85>;
                spi-max-frequency = <10000000>;
                interrupt-parent = <0x22>; // pinctrl@2000000
                interrupts = <0 113 2>; // IRQ LINE, try with <0 65 2>
                clocks = <0x81>;
                status = "okay";
			};
		};
	};
};

 

However when I boot up I look to the interrupts and there is nothing related to the irq line for the CAN/spi, output of /proc/interrupts:

           CPU0       
  2:      79503  sun20i-intc  75 Edge      timer@2050000
  3:          0  sun20i-intc 109 Edge      5500000.hdmi, dw-hdmi-cec
  4:          0  sun20i-intc  25 Edge      mv64xxx_i2c
  5:          0  RISC-V INTC   5 Edge      riscv-timer
  6:         14  sun20i-intc  68 Edge      sun8i-ce-ns
  7:          0  sun20i-intc  47 Edge      ohci_hcd:usb3
 74:          0  sun20i-intc  31 Edge      sun6i-spi
 78:       5926  sun20i-intc  74 Edge      ths
 79:          0  sun20i-intc  50 Edge      ohci_hcd:usb4
 80:          0  sun20i-intc  46 Edge      ehci_hcd:usb1
 81:       1336  sun20i-intc  18 Edge      ttyS1
 82:     189890  sun20i-intc  57 Edge      sunxi-mmc
 83:          0  sun20i-intc  82 Edge      1c0e000.video-codec
 84:          0  sun20i-intc  80 Edge      2010000.iommu
 85:          0  sun20i-intc 107 Edge      5470000.lcd-controller
 88:          0  sun20i-intc  49 Edge      ehci_hcd:usb2
 89:          0  sun20i-intc 160 Edge      7090000.rtc
 90:          2  sun20i-intc  27 Edge      mv64xxx_i2c
 98:          0  sun20i-intc  45 Edge      musb-hdrc.2.auto
101:       8630  sun20i-intc  56 Edge      sunxi-mmc
109:          0  sun20i-intc  66 Edge      3002000.dma-controller
111:          4  sun20i-intc  32 Edge      sun6i-spi
112:          0  sun20i-intc  77 Edge      sun4i-a10-lradc-keys
113:          0  sun20i-intc 106 Edge      5461000.lcd-controller
114:          7  sun20i-intc 167 Edge      sunxi-ir
119:          0  sun20i-intc  36 Edge      2008000.led-controller
204:          1  sunxi_pio_edge  84 Edge      usb0-vbus-det
205:          1  sunxi_pio_edge  85 Edge      usb0-id-det
254:          1  sunxi_pio_edge 134 Edge      4020000.mmc cd
IPI0:         0  Rescheduling interrupts
IPI1:         0  Function call interrupts
IPI2:         0  CPU stop interrupts
IPI3:         0  IRQ work interrupts
IPI4:         0  Timer broadcast interrupts


Some outputs from the Kernel:

 

[   52.133406] CAN device driver interface
[   52.918270] mcp251x spi1.0 can0: MCP2515 successfully initialized.
[ 1163.417322] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
[ 1182.919088] can: controller area network core
[ 1182.919249] NET: Registered PF_CAN protocol family
[ 1183.000429] can: raw protocol

 

And after booting I run the next:

$ sudo ip link set can0 up type can bitrate 500000
$ sudo ifconfig can0 up
$ sudo cansend can0 5A1#00.01.02.03.04

 

This configuration is not working because when I try to connect, I am not receiving anything.

 

I suppose that I am not configuring correctly the interrupt line of the IRQ of SPI. My knowledge on this is very narrow, and I am not able to understand what is failing. All the feedback is totally welcome. I can give more documentation if my explanation is not complete enought.

 

Thanks!

 

 

Edited by Fran A100
Link to comment
Share on other sites

14 минут назад, Fran A100 сказал:
74:          0  sun20i-intc  31 Edge      sun6i-spi

 

15 минут назад, Fran A100 сказал:
111:          4  sun20i-intc  32 Edge      sun6i-spi

This is an interrupt for SPI

But I don't see the mcp251x driver here.

43 минуты назад, Fran A100 сказал:
compatible = "microchip,mcp2515";

This line should cause the driver to load.

 

Check the presence of the module in the kernel:

grep -n CONFIG_CAN_MCP251X /boot/conf* 

 

Check the correct application of the overlay in the dts:

dtc --sort -I fs -O dts  /sys/firmware/devicetree/base > $HOME/device_tree.txt

 

Link to comment
Share on other sites

1 час назад, Fran A100 сказал:

Some outputs from the Kernel:

 

[   52.133406] CAN device driver interface
[   52.918270] mcp251x spi1.0 can0: MCP2515 successfully initialized.
[ 1163.417322] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
[ 1182.919088] can: controller area network core
[ 1182.919249] NET: Registered PF_CAN protocol family
[ 1183.000429] can: raw protocol

Good! The driver is loaded.

After you try to connect, no error messages appear in dmesg?

Link to comment
Share on other sites

The overlay is not described quite correctly. Make in the image and likeness with this:

Скрытый текст
 /dts-v1/;
/plugin/;
/ {
    compatible = "allwinner,sun8i-r40";

    fragment@0 {
        target-path = "/aliases";

        __overlay__ {
            spi0 = "/soc/spi@1c05000";
        };
    };

    fragment@1 {
        target = <0xffffffff>;

        __overlay__ {
            pinctrl-names="default","default";
            #address-cells = <0x01>;
            #size-cells = <0x00>;
            status = "okay";
            pinctrl-0 = <&spi0_pc_pins>;
            pinctrl-1 = <&spi0_cs0_pc_pin>;
            spidev@0 {
                compatible = "armbian,spi-dev";
                status = "okay";
                reg = <0x00>;
                spi-max-frequency = <0xf4240>;
            };
        };
    };

    fragment@2 {
        target = <&pio>;
        __overlay__ {
            spi0_pc_pins: spi0-pc-pins {
                pins = "PC0", "PC1", "PC2";
                function = "spi0";
            };
            spi0_cs0_pc_pin: spi0-cs0-pc-pin {
                pins = "PC23";
                function = "spi0";
            };        
        };
    };
    
    __fixups__ {
        spi0 = "/fragment@1:target:0";
    };
}; 

 

This should be described in a separate fragment

pinctrl-0 = <&spi0_pc_pins>;
pinctrl-1 = <&spi0_cs0_pc_pin>;

Link to comment
Share on other sites

  • Solution

Finally I made it! Thanks a lot for the help but it was something else. The final overlay is the next one:

 

/dts-v1/;
/plugin/;

/ {
	compatible = "allwinner,d1-nezha\0allwinner,sun20i-d1";

	fragment@0 {
		target-path = "/clocks";
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <1>;
            /* External crystal oscillator on the board */
			can0_osc_fixed: can0_osc_fixed {
				compatible = "fixed-clock";
                #clock-cells = <0>;
                clock-frequency  = <8000000>;
                phandle = <0x81>;
			};
		};
	};

	fragment@1 {
		target = <&pinctrl>; // pinctrl@2000000
		__overlay__ {
			can0_pin_irq: can0_pin_irq {
				pins = "PD17";
                function = "irq";
                phandle = <0x85>;
                bias-pull-up;
			};
		};
	};

	fragment@2 {
		target = <&spi>;   //spi@4026000
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";
			mcp2515 {
				reg = <0>;		// SPI 1
                compatible = "microchip,mcp2515";
                pinctrl-names = "default";
                pinctrl-0 = <0x85>;
                spi-max-frequency = <10000000>;
                interrupt-parent = <0x22>; // pinctrl@2000000
                interrupts = <3 17 8>; // IRQ LINE, try with <0 65 2>
                clocks = <0x81>;
                status = "okay";
			};
		};
	};
};

 

I learnt some things about the interrupts field:

* The part of interrupts is like this, <BANK NUMBER TYPE_INTERRUPT>
* BANK is like, A -> 0, B-> 1, C->2, D->3
* NUMBER, PD17 -> 17
* TYPE_INTERRUPT, is described here

Link to comment
Share on other sites

Hi!

 

Normally in a normal SBC you add an overlay with something like /boot/uEnv.txt etc... But this is not done yet. The workarround I made to work is to use Ubuntu (from oficial webpage of ubuntu, I used the Lichee version, or even the one shipped for the lichee that has the wifi driver already installedd), that is prepared also for running the mangoPi) and change group. My explanation:

 

On the default installation of ubuntu, the only way to add overlays is with grub. The default ubuntu is configured to load the devicetree overlays with grub. So if we want to add overlays, we need to change the grub.

To add a new entry on the grub we need to go to `/etc/grub.d/40_custom` and there we put the entry we want. The best way is to copy the same information that is in /boot/grub/grub.cfg regarding to the OS, like:

 

menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-90836834-7e07-48ca-b0f9-29880429770d' {
        load_video
        insmod gzio
        if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
        insmod part_gpt
        insmod ext2
        search --no-floppy --fs-uuid --set=root 90836834-7e07-48ca-b0f9-29880429770d
        echo    'Loading Linux 5.19.0-1015-allwinner ...'
        linux   /boot/vmlinuz-5.19.0-1015-allwinner root=/dev/mmcblk0p1 ro  quiet splash
        echo    'Loading device tree blob...'
        devicetree      /boot/dtb
}

 

My modified version would be:
 

menuentry 'UbuntuWithOverlays' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'ubuntu-custom-overlay'' {
    load_video
    insmod gzio
    if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
    insmod part_gpt
    insmod ext2
    search --no-floppy --fs-uuid --set=root 90836834-7e07-48ca-b0f9-29880429770d
    echo    'Loading Linux 5.17.0-1003-allwinner ...'
    linux    /boot/vmlinuz-5.17.0-1003-allwinner root=LABEL=cloudimg-rootfs ro  quiet splash
    echo    'Loading initial ramdisk ...'
    initrd    /boot/initrd.img-5.17.0-1003-allwinner
    echo    'Loading device tree blob...'
    devicetree    /boot/overlay/my_overlay.dtb
}

 

To make that entry the default in grub you need to add `GRUB_DEFAULT="ubuntu-custom-overlay"` to `/etc/default/grub`.

After some testing I realized that there can be only one command of devicetree, it is not supported the overlays, the comfiguration is cleaned in every devicetree command. But you can get the original devicetree, modify and put it in the command, that works.


Dont forget to do `update-grub` after.

 

To get the device tree blob that comes with the board, you need to run `dtc -I fs /proc/device-tree`

 

PD: In this post I confuse Overlay with the device tree configuration. There is no overlay, is a complete device tree blob, have that in mind.

Link to comment
Share on other sites

10.08.2023 в 16:49, Fran A100 сказал:

Hi!

 

Normally in a normal SBC you add an overlay with something like /boot/uEnv.txt etc... But this is not done yet. The workarround I made to work is to use Ubuntu (from oficial webpage of ubuntu, I used the Lichee version, or even the one shipped for the lichee that has the wifi driver already installedd), that is prepared also for running the mangoPi) and change group. My explanation:

Many many thanks you ! :) 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines