Get CAN Bus working on DB410c via MCP2515

Hey Guys,

I currently try to get CAN Bus working on Dragonboard 410c using an
external hardware based on MCP2515.
Since I am little new to Embedded Systems like DB410c specially in
Device Tree configuration, I need some help there. Further I already
got SPI working on low speed connector (cs pin 18) and did test it
successfully with some application binaries from former projects.
(Big Thx to the user “agross” for his post to the “enable SPI” thread)

Next step is to enable MCP2515 support in the DB410c kernel

Location:
-> Networking support (NET [=y])
  -> CAN bus subsystem support (CAN [=n])
    -> CAN Device Drivers
      -> Platform CAN drivers with Netlink support (CAN_DEV [=n])
        -> CAN SPI interfaces

But what next? How I need to modify the Device Tree and how can I
“connect” a special pin (e.g. GPIO36) on low speed connector as
interrupt line to the mcp251x.c driver? Think the
arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
is the right file for those modifications. I also think that the
modification should look similar to this :

spi@78b7000 {
/* On High speed expansion */
label = "HS-SPI1";
status = "okay";
};

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

spi@78b9000 {
/* On Low speed expansion */
label = "LS-SPI0";
cs-gpios = <&msmgpio 18 0>;
status = "okay";

can0: can0@0 {
  compatible = "microchip,mcp2515";
  reg = <0x0>;
  clocks = <&clk16m>;
  interrupt-parent = <&msmgpio 36>;  # Dont know if that is correct for Int-Pin
  interrupts = <27 0x2>;             # Which Int-Number? From where I can get available Int-Numbers?
  spi-max-frequency = <10000000>;
};

Would be really great if one of the kernel specialists can help me
to get the mcp2515 workin.

Best regards from Germany!

Hi @gc,

I am not expert on device tree and do not have the can device so I have not tested so this is only for your reference.


            interrupt-parent = <&msmgpio>;
            interrupts = <36 0x2>;

I would happy if this works. :slight_smile:

Hey Akira,

seems that the interrupt number is the same like the pin number. I will try that next week.
Get the CAN bus working is the last step for me to go ahead with an industrial project. I stuck on that part because I have not enough knowledge about configuring the device tree :frowning:
Does anyone know a gui software or an eclipse plugin for device tree configuration ?

thank you for that hint, and thx for pushing my tutorial thread into tutorial section :wink:

Hi @gc,

Frank Rowand is making the debugging tool for device tree.
It is not GUI, it should give very useful when the device tree is not working.

These are his slides at the LinuxCon Japan.

Solving Device Tree Issues

Solving Devicetree Issues, part 2.0

Hey Guy´s,

enable the CAN-Bus Support using MCP2515 integrated circuit is much easier than expected. I used the SPI0 on low speed connecter to get the MCP2515 working with DB410c. The interrupt pin is connected to GPIO36.

Very Important:
You need to use a level shifter because all of the DB410c GPIO´s are at 1.8V voltage level and the MCP2515 uses 5.0V logic.

[Kernel modification]
In this step you need to enable some CAN-Bus stuff and the MCP2515 kernel module.

Symbol:CAN_MCP251X[=m]
Type:tristate
Prompt:MicrochipMCP251xSPICANcontrollers
Location:
->Networkingsupport(NET[=y])
  ->CANbussubsystemsupport(CAN[=m])
    ->CANDeviceDrivers
      ->PlatformCANdriverswithNetlinksupport(CAN_DEV[=m])
        ->CANSPIinterfaces

Maybe you also want to enable VCAN as an module.

Symbol:CAN_VCAN[=m]
Type:tristate
Prompt:VirtualLocalCANInterface(vcan)
Location:
->Networkingsupport(NET[=y])
  ->CANbussubsystemsupport(CAN[=m])
    ->CANDeviceDrivers

[Device Tree modification]
To get the CAN-Bus interface working you also need to tell the device tree compiler where you did connected the MCP2515 electronic circuit. In my case I used the MCP2515 interrupt on DB410x GPIO36 and a 16MHz oscillator for the MCP2515.
I also created a device tree file :

~/SnapDragon-Toolchain/Kernel/linux-arrow/arch/arm64/boot/dts/qcom/mcp2515-can.dtsi

/{
        aliases {
                spi0    = &blsp_spi5;
        };

        soc {
                clocks {
                clk16m: oscillator {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <16000000>;
                        };
                };

                spi@78b9000 {
                /* On Low speed expansion */
                label = "LS-SPI0";
                cs-gpios = <&msmgpio 18 0>;
                status = "okay";

                        can0: can0@0 {
                                compatible = "microchip,mcp2515";
                                reg = <0x0>;
                                clocks = <&clk16m>;
                                interrupt-parent = <&msmgpio>;
                                interrupts = <36 0x2>;
                                spi-max-frequency = <10000000>;
                        };

                };
        };
};

Further I did an include of this file in my apq8016-sbc.dtsi. You can see the modifications in the patch file below.

~/SnapDragon-Toolchain/Kernel/linux-arrow/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi

*** orginal/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi   2016-07-04 12:16:30.839125000 +0200
--- patched/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi   2016-07-22 10:23:39.386674999 +0200
***************
*** 19,24 ****
--- 19,26 ----
  #include "apq8016-sbc-soc-pins.dtsi"
  #include "apq8016-sbc-pmic-pins.dtsi"
  #include "msm8916-mdss.dtsi"
+ #include "mcp2515-can.dtsi"
+ 
  / {
        aliases {
                serial0 = &blsp1_uart2;
***************
*** 204,215 ****
                        status = "okay";
                };
  
-               spi@78b9000 {
-              /* On Low speed expansion */
-                       label = "LS-SPI0";
-                       status = "okay";
-               };
- 
                leds {
                        pinctrl-names = "default";
                        pinctrl-0 = <&msmgpio_leds>,
--- 206,211 ----

Please double check your external hardware ! If all software modifications are correct and the DB410c has been flashed with the new kernel (do not forget to install the modules), you should have your CAN-Bus interface after booting the DB410c.

linaro@linaro-alip:~$ sudo iwconfig
wlan0     IEEE 802.11abgn  ESSID:"UbuntuWireless"  
          Mode:Managed  Frequency:2.412 GHz  Access Point: 74:DA:38:65:1C:43   
          Bit Rate=1 Mb/s   Tx-Power=20 dBm   
          Retry short limit:7   RTS thr:off   Fragment thr:off
          Encryption key:off
          Power Management:off
          Link Quality=65/70  Signal level=-45 dBm  
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:3   Missed beacon:0

enx74da381a7e5e  IEEE 802.11bgn  ESSID:"Dragonboard410c"  Nickname:"<WIFI@REALTEK>"
          Mode:Master  Frequency:2.412 GHz  Access Point: 74:DA:38:1A:7E:5E   
          Sensitivity:0/0  
          Retry:off   RTS thr:off   Fragment thr:off
          Encryption key:off
          Power Management:off
          Link Quality:0  Signal level:0  Noise level:0
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

sit0      no wireless extensions.

lo        no wireless extensions.

can0      no wireless extensions.

From there you can easily enable your CAN-Bus interface in userspace with :

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

I am really new to the device tree, so maybe that way is not the best how to integrate external hardware but it is working. If any of the specialists here have some additional hints or advice to improve this, please add it here :wink:

Best Regards, David

Hi gc1,

What kind of level shifter to do you use ? A bidirectional one ? Do you have a specific one that you prefer ?

bill

Hi Bill,

i used the LSF0108RKSR with 1k5 pullup on all SPI pins of MCP2515 and one pullup (10k) on CS line on the dragonboard side.

Best wishes and Merry Christmas :slight_smile:

HI gc1,
Thanks alot for amazing tutorial, this is really helpful. I am new to kernel modification and I was going through the steps mentioned above. I was unable to find the location / files to edit to make following changes :

[Kernel modification]
In this step you need to enable some CAN-Bus stuff and the MCP2515 kernel module.

Symbol:CAN_MCP251X[=m]
Type:tristate
Prompt:MicrochipMCP251xSPICANcontrollers
Location:
->Networkingsupport(NET[=y])
->CANbussubsystemsupport(CAN[=m])
->CANDeviceDrivers
->PlatformCANdriverswithNetlinksupport(CAN_DEV[=m])
->CANSPIinterfaces

Maybe you also want to enable VCAN as an module.

Symbol:CAN_VCAN[=m]
Type:tristate
Prompt:VirtualLocalCANInterface(vcan)
Location:
->Networkingsupport(NET[=y])
->CANbussubsystemsupport(CAN[=m])
->CANDeviceDrivers

Can you please point me to right direction. Thanks in advance.


Roger

hi @rogerthat

You need to rebuild the kernel and install it into your board. Instructions are with the release notes here: http://builds.96boards.org/releases/dragonboard410c/linaro/debian/latest/

Between the step where you make defconfig, and when you make Image.gz, you do one extra step:

make menuconfig

This step starts up an interactive menu system that allows you to turn on kernel features, in this case you want to enable CAN_MCP251X and CAN_VCAN, the Location: shows you the path through the menus to get to these modules.

You also need to make the edits to the device tree files (in directory kernel/arch/arm64/boot/dts/qcom) to describe to the kernel which pins you have connected the MCP2515 chip to. Do this right after the make menuconfig step. Of course you should probably first build and install the kernel without any changes just to make sure you know how to do it.

Hope this helps.

Full Disclosure: I am an employee of Qualcomm Canada, any opinions I may have expressed in this or any other post may not reflect the opinions of my employer.

Hi @ljking,
Thanks for the prompt response and all the help.

I followed the instructions mentioned here : http://builds.96boards.org/releases/dragonboard410c/linaro/debian/latest/

After step : make -j4 Image.gz dtbs KERNELRELEASE=4.9.56-linaro-lt-qcom

i get following output with no error or extended information :

roger@roger-pc:/workspace/codebase/dbKernel/v2/kernel$ make -j4 Image.gz dtbs KERNELRELEASE=4.9.56-linaro-lt-qcom
scripts/kconfig/conf --silentoldconfig Kconfig
make: *** No rule to make target ‘Image.gz’. Stop.

Since no Image.gz is created i am unable to create the dt.img in following steps.

Although packaging and building the modules works perfectly using following commands : make -j4 modules and make modules_install.

  • I tried the build steps using both Linaro GCC cross compiler and generic debian GCC cross compiler as well.
  • i have also tried to save the defconfig using following command : make savedefconfig which is missing in the original link.

I am stuck on this issue and have urgent deadline to follow. Any help will be highly appreciated.

Thanks in advance.


Roger

The message scripts/kconfig/conf --silentoldconfig Kconfig suggests you somehow “lost” the effect of the export ARCH=arm64 you ran earlier (new shell, mistakenling launching in a different tab, etc). If so you are now trying to build an x86 kernel and that is why there is no Image.gz target.

Can you double check the value of ARCH?

I keep forgetting to set ARCH, so I always edit my ~/.bashrc and add the line

export ARCH=arm64

at the bottom of the file. In fact I have a generic setup script that I run once that sets all of the following at the bottom of the .bashrc file so I don’t forget later.

export ARCH=arm64
export PATH=~/bin:$PATH
export MONITOR_PORT=/dev/tty96B0
export JAVA_TOOL_OPTIONS="-Dgnu.io.rxtx.SerialPorts=/dev/tty96B0"
export PYTHONPATH=/usr/local/lib/python3.5/dist-packages:/usr/local/lib/python2.7/site-packages
export CROSS_COMPILE=~/bin/gcc-linaro-6.3.1-2017.02-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-

Full Disclosure: I am an employee of Qualcomm Canada, any opinions I may have expressed in this or any other post may not reflect the opinions of my employer.

Hi @danielt,
It was indeed a multiple terminal issue. Thanks for the prompt response and all the help. You and @ljking are amazing.


Roger

Hi guys,
I am still stuck on this mcp2515 issue. Any help will be highly appreciated. Here is the status:

I have tried compiling the kernel and CAN module multiple times. i have few variants that have successfully compiled. The 3 variants of kernel i have are :

  1. SPI enabled kernel : Following this link : https://www.96boards.org/documentation/consumer/dragonboard410c/guides/enable-spi.md.html

SPI interface enabled and available for use

  1. SPI and MCP2515 enabled kernel : following the instructions from @gc1

SPI interface enabled and available for use. can0 interface missing

  1. SPI from link number 1 above and MCP2515 related changes fused into one

SPI interface enabled and available for use. can0 interface missing

All these kernels have compiled successfully, i have flashed them to the board and transfered the modules into respective directory.

i still don’t have access to can0 even though drivers are present in : ls /lib/modules/4.9.56-linaro-lt-qcom/kernel/drivers/net/can/

can-dev.ko slcan.ko spi vcan.ko

i have included mcp2515.dtsi as mentioned in article above

Here is what i have in sys/bus/spi/devices/spi0.0/

driver modalias of_node power spidev statistics subsystem uevent

net and can related interface are missing, i enabled them during compiling the kernel. here is the .config file at the time of kernel compilation :

cat .config | grep -in “can”
352:CONFIG_ARCH_VULCAN=y
1106:CONFIG_CAN=m
1107:CONFIG_CAN_RAW=m
1108:CONFIG_CAN_BCM=m
1109:CONFIG_CAN_GW=m
1112:# CAN Device Drivers
1114:CONFIG_CAN_VCAN=m
1115:CONFIG_CAN_SLCAN=m
1116:CONFIG_CAN_DEV=m
1117:CONFIG_CAN_CALC_BITTIMING=y
1118:# CONFIG_CAN_LEDS is not set
1119:# CONFIG_CAN_GRCAN is not set
1120:# CONFIG_CAN_XILINXCAN is not set
1121:# CONFIG_CAN_C_CAN is not set
1122:# CONFIG_CAN_CC770 is not set
1123:# CONFIG_CAN_IFI_CANFD is not set
1124:# CONFIG_CAN_M_CAN is not set
1125:# CONFIG_CAN_RCAR is not set
1126:# CONFIG_CAN_RCAR_CANFD is not set
1127:# CONFIG_CAN_SJA1000 is not set
1128:# CONFIG_CAN_SOFTING is not set
1131:# CAN SPI interfaces
1133:CONFIG_CAN_MCP251X=m
1136:# CAN USB interfaces
1138:# CONFIG_CAN_EMS_USB is not set
1139:# CONFIG_CAN_ESD_USB2 is not set
1140:# CONFIG_CAN_GS_USB is not set
1141:# CONFIG_CAN_KVASER_USB is not set
1142:# CONFIG_CAN_PEAK_USB is not set
1143:# CONFIG_CAN_8DEV_USB is not set
1144:# CONFIG_CAN_DEBUG_DEVICES is not set
1530:# CONFIG_SCSI_SCAN_ASYNC is not set

Here is the lsmod output on the dragonboard :

sudo lsmod
Module Size Used by
ctr 16384 4
ccm 20480 2
cmac 16384 1
bnep 24576 2
arc4 16384 2
wcn36xx 73728 0
btqcomsmd 16384 0
btqca 16384 1 btqcomsmd
mac80211 417792 1 wcn36xx
bluetooth 614400 24 btqcomsmd,btqca,bnep
cfg80211 311296 1 mac80211
joydev 20480 0
qcom_wcnss_pil 16384 0
spidev 20480 0
venus_core 61440 0
qcom_camss 81920 0
msm_rng 16384 0
rng_core 20480 1 msm_rng
mdt_loader 16384 2 qcom_wcnss_pil,venus_core
videobuf2_dma_sg 24576 1 qcom_camss
videobuf2_memops 16384 1 videobuf2_dma_sg
v4l2_mem2mem 24576 1 venus_core
videobuf2_v4l2 24576 2 qcom_camss,v4l2_mem2mem
videobuf2_core 45056 4 qcom_camss,venus_core,v4l2_mem2mem,videobuf2_v4l2
videodev 204800 5 qcom_camss,videobuf2_core,venus_core,v4l2_mem2mem,videobuf2_v4l2
media 45056 2 qcom_camss,videodev
ip_tables 24576 0
x_tables 36864 1 ip_tables
i2c_qcom_cci 16384 0

Here is the depmod output from the dragonboard :

sudo depmod -n | grep spi
kernel/drivers/spi/spidev.ko:
kernel/drivers/spi/spi-meson-spifc.ko:
kernel/drivers/net/can/spi/mcp251x.ko: kernel/drivers/net/can/can-dev.ko
alias spi:spidev spidev
alias of:NTClineartechnology,ltc2488C* spidev
alias of:NTClineartechnology,ltc2488 spidev
alias of:NTCrohm,dh2228fvC* spidev
alias of:NTCrohm,dh2228fv spidev
alias acpi*:SPT0003:* spidev
alias acpi*:SPT0002:* spidev
alias acpi*:SPT0001:* spidev
alias of:NTCamlogic,meson-gxbb-spifcC* spi_meson_spifc
alias of:NTCamlogic,meson-gxbb-spifc spi_meson_spifc
alias of:NTCamlogic,meson6-spifcC* spi_meson_spifc
alias of:NTCamlogic,meson6-spifc spi_meson_spifc
alias spi:mcp2515 mcp251x
alias spi:mcp2510 mcp251x
alias spi:at86rf212 at86rf230
alias spi:at86rf233 at86rf230
alias spi:at86rf231 at86rf230
alias spi:at86rf230 at86rf230
alias spi:mrf24j40mc mrf24j40
alias spi:mrf24j40ma mrf24j40
alias spi:mrf24j40 mrf24j40
alias spi:cc2520 cc2520
alias symbol:v4l2_spi_subdev_init v4l2_common
alias symbol:v4l2_spi_new_subdev v4l2_common

Any pointer to resolve this will be highly appreciated.

Thanks in advance.


R

Hey Roger!

whats the state of your issue ? Can you please check the

dmesg | grep -i "MCP25"

output on console. Lets see if your board do the mcp2515 chip init…

If you are totally lost, use my kernel. It is a 4.4.23 based kernel (sorry, maybe a little old)
and I used that one with the 144 image build. My download link is available for 3 days…

DB410-MCP2515.tar.gz

Hope that helps, feedback would be great :wink:

Hey David,

I’m in a similar spot trying to get the MCP2515 working. However the device tree structure is driving me nuts. The version of the qualcomm chipset I’m using has a different format for defining the clocks and the fixed oscillator clock when provided just like in your code always throws a clk error. Do you have working a link to your kernel copy? The one in your last post seems to be broken.

Thanks mate!

Hi AntiDive,

here a new link. Will be there also fore a short time. Please tell me if u downloaded it.

DB410-MCP2515.tar.gz

@ admin
Some time ago when the forum has moved, there occured some ascii conversion fails for
the devicetree example above. I cannot longer edit this to correct them. is there any way
to edit this? There are a lot of > in the text that should not be there…(and they have
not been there when I started that thread :frowning: )
I think a lot of people will stuck on this also.