CAN bus MCP2515 on VIM4

Which system do you use? Android, Ubuntu, OOWOW or others?

Ubuntu 22.04

Which version of system do you use? Khadas official images, self built images, or others?

Khadas official image

Please describe your issue below:

Hi everyone,
I want to connect the Khadas VIM4 to a MCP2515 chip for CAN bus communication.

The only documentation I have found is a forum page, but it is about the VIM3 board:

Does anyone have any information to do the same thing for the VIM4?

In the default configuration of the kernel the CAN modules and the MCP251x drivers are already activated, I can use modprobe to activate them in the stock image. So do I have to use fenix to rebuild the image or can I just compile a dts file into a dts in a stock image and get it working? What should be exact content of the dts file?

Thank you in advance

Hello @grilloandrea6

You can make the modifications of dts with Fenix and do
make kernel-dtb

This will create a board installable packages, which you can then install to update the dtb with your modifications.

just some heads up information that can save you time:

  • VIM4 SPI is spicc0, and it’s interrupt number 183

you can try this dts and follow the rest of the steps to enable the functionality…

/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/meson-t7-gpio.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
/ {
	fragment@0 {
 		target = <&spicc0>;

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

  			can0: mcp2515@0 {
  				spi-max-frequency = <100000000>;
  				compatible = "microchip,mcp2515";
  				reg = <0>;
  				interrupt-parent = <&gpio_intc>;
  				interrupts = <183 IRQ_TYPE_LEVEL_LOW>; 
  				clock-frequency = <12000000>;
  				status = "okay";
  			};
		};
	};
};

Hello,
thank you very much for the fast response.

I have managed to compile the file and make the system read it. The steps I followed are below, they are a bit different from what I read online, I write them here so you can correct me if I did something wrong, or they can just be useful for other people:

  • The directory to which I added the can.dts file is /fenix/build/linux/arch/arm64/boot/dts/amlogic
  • I added the line “dtb-y += can.dtb” to the Makefile in the same directory.
  • I compiled the whole linux kernel and created deb files using the command “NO_GIT_UPDATE=1 make kernel-deb” as I couldn’t find a Makefile rule for ‘kernel-dtb’.
  • Installing the deb package was not sufficient, the dtb file is not in the right directory and with the right name. So I had to copy it to the ‘/boot/overlays/kvim4.dtb.overlays/’ and modify the extension to dtbo instead of just dtb. Then I added can to the ‘/boot/overlays/kvim4.dtb.overlay.env’ file.

Some more information I would need:

  • I guess that the 183 interrupt number is the reference to a specific pin of the GPIO, but I do not know which one, so I didn’t know to which pin I have to connect the interrupt pin of the mcp2515.
  • I tried to enable the overlay and boot the system without the mcp2515 connected, and I got the following error in the dmesg log:
    mcp251x: probe of spi1.0 failed with error -34
    Which seems to be related to a frequency error. What I would expect from a system booting without anything connected is the following (from other working boards):
	mcp251x spi0.0: MCP251x didn't enter in conf mode after reset
	mcp251x spi0.0: Probe failed, err=110
	mcp251x: probe of spi0.0 failed with error -110

Is the error I am getting normal?

Also, my final goal would be to have 2 MCP2515 chips connected to the same SPI with different Chip Select and Interrupt pins, is it possible to do it?

Thank you very much in advance.

PS
in your code there’s a missing } parenthesis at the end :slight_smile:

@grilloandrea6 the interrupt pin is essentially the SPI MISO pin, are you sure your wiring is correct ?
If you are sure your wiring is proper, then please check if you are able to detect the device node from your intended application.

The MCP2515 has 4 pins for SPI but also has another interrupt pin which should be connected and interfaced directly to the mcp251x driver.

@grilloandrea6 I see, can you share the wiring of your module, please share the connections you have used.

This is the wiring I would do:

MCP2515 | VIM4
sck | 25 - sclk
mosi | 36 - mosi
miso | 37 - miso
cs | 26 - ss0
int | ???

I do not know to which pin do I have to connect the interrupt pin of the MCP2515, which should be a “normal” GPIO pin chosen by the configuration of the interrupt in the dts file.

Thank you

@grilloandrea6 I have checked, the spi frequency may have been set too high, can you check this dts?

/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/meson-t7-gpio.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
/ {
	fragment@0 {
 		target = <&spicc0>;

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

  			can0: mcp2515@0 {
  				spi-max-frequency = <2000000>;
  				compatible = "microchip,mcp2515";
  				reg = <0>;
  				interrupt-parent = <&gpio_intc>;
  				interrupts = <183 IRQ_TYPE_LEVEL_LOW>; 
  				clock-frequency = <12000000>;
  				status = "okay";
  			};
		};
	};
};

MCP2515 has addition INT pin that send interrupt when CAN data received (not the same as spicc0 interrupt).

So it is needed to connect addition wiring line from INT MCP2515 pin to any free VIM’s GPIO.

I couldn’t find full Amlogic A311D2 datasheet (for VIM4), but in A311D (for VIM3) see 8-34 table that shows:
CBUS [76:61] = gpioA [15:0]

So if used GPIOA_15 (pin 22) for INT, use
interrupts = <76 IRQ_TYPE_LEVEL_LOW>;

Maybe A311D2 chip registers different, I don’t know.

Thank you for the information.
Now I understood where to look for this information in the datasheet, it should be the table 7-236, I found the datasheet here: https://dl.khadas.com/products/vim4/datasheet/a311d2-datasheet-rev-c-0.2-.pdf

I have tried the updated dts with lower spi frequency, but I still get the following error:
mcp251x: probe of spi1.0 failed with error -34
Is it right that it is probing for spi1.0, shouldn’t it be spi0?
Thank you

@grilloandrea6 not sure, I don’t have the same bus chip to test on my side.

I assume you have also added the spi0 node to fdt overlays, have you done so ?

It seems to incorrect SPI configuration. In case for VIM3 spicc1 (not spicc0) was configured.
can.dts

...
target = <&spicc1>;
...

spi.dts

/dts-v1/;
/plugin/;

/ {
   fragment@0 {
       target = <&spicc1>;

       __overlay__ {
           status = "okay";
       };
   };
   
   fragment@1 {
	target = <&pwm_ef>;

	__overlay__ {
	};
   };

   fragment@2 {
   	   target = <&uart_C>;

   	   __overlay__ {
   		   status = "disabled";
   	   };
   };
};

In A311D2 datasheet I did not found chapter “GPIO Interrupt”, so configuration of gpio Interrupt maybe more complicated.
Despite this MCP2515 will work without this pin, but only as CAN data sender.
In right SPI configuration and wiring dmesg will out:

mcp251x spi1.0 can0: MCP2515 successfully initialized.

Yes, spi0 is activated.
I realized that there are some more errors in the dmesg log:

[    5.972893] meson-spicc fe050000.spi: chipselect 0 already in use
[    5.973019] spi_master spi1: spi_device register error /soc/apb4@fe000000/spi@50000/spidev@0
[    5.974104] spi_master spi1: Failed to create SPI device for /soc/apb4@fe000000/spi@50000/spidev@0
[    9.902790] mcp251x: probe of spi1.0 failed with error -34

Does it mean that something else is trying to use the SPI bus?
I tried to flash again a fresh Ubuntu image, so I haven’t activated anything else, and got the same error.

EDIT:
Also, SPI works if I don’t activate the CAN overlay. But if I activate CAN, I got the above errors and the /dev/spidev1.0 is not there anymore.