How can i configure 2 mcp2518 chips on pico mini b?

  • You can refer to other DTS files using `mcp251x` to modify the DTS. Execute the following command under `<sdk>/sysdrv/source/kernel/arch/arm/boot/dts/` to check the DTS configurations using `mcp251x`:

    Code: Select all

    grep -nr "mcp251"
    
    Based on the references, you can roughly configure it as follows:

    Code: Select all

    &spi0 {
        pinctrl-names = "default";
        pinctrl-0 = <&spi0_pins_a>,
                    <&spi0_cs0_pins_a>;
        status = "okay";
    
        spidev@0x00 {
            compatible = "spidev";
            spi-max-frequency = <1200000>;
            reg = <0>;
        };
        
        can@1 {
            compatible = "microchip,mcp2515"; // Driver source does not support matching with mcp2518
            reg = <1>;
            interrupt-parent = <&gpioX>; // such as: gpio0
            interrupts = <RK_PXX IRQ_TYPE_EDGE_FALLING>; // such as: RK_PA0 IRQ_TYPE_EDGE_FALLING
            spi-max-frequency = <10000000>; // 10M
        };
    };
    
    Since I haven't used `mcp2518` and am not familiar with its interrupt pin usage, the details require further debugging and adjustments. Additionally, the kernel may need to have CAN support enabled.
  • I was finally able to load the module into the kernel with the following configuration, but it fails in the last step:

    1. Compile busybox/buildroot
    ./build.sh lunch
    ./build.sh

    2. Add CAN support to the kernel, include MCP251X driver
    ./build.sh clean kernel
    cd sysdrv/source/kernel
    cp ./arch/arm/configs/luckfox_rv1106_linux_defconfig .config
    make ARCH=arm menuconfig

    Networking support ---> CAN bus subsystem support ---> select Raw CAN Protocol and go to CAN Device drivers ---> CAN SPI interfaces ---> select `Microchip MCP251x and MCP25625 SPI CAN controllers` as modules (M)

    make ARCH=arm savedefconfig
    cp defconfig ./arch/arm/configs/luckfox_rv1106_linux_defconfig

    3. Go back to sdk root folder, and modify buildroot
    cd sysdrv/source/buildroot/buildroot-2023.02.6

    make luckfox_pico_defconfig
    make menuconfig
    Target packages ---> Networking applications ---> select can-utils
    make savedefconfig
    make

    4. Go dts folder
    cd sysdrv/source/kernel/arch/arm/boot/dts

    5. Modify `rv1103g-luckfox-pico-mini.dts`
    Chage
    /* SPI0_M0 */
    &spi0 {
    status = "disabled";
    ...

    To:

    /* SPI0_M0 */
    &spi0 {
    status = "okay";
    ...

    6. Modify `rv1103-luckfox-pico-ipc.dtsi`

    Add this after DHT11 section:

    can0: mcp2515@0 {
    compatible = "microchip,mcp2515";
    reg = <0 0>;
    clocks = <&clk_mcp2515>;
    clock-names = "mcp2515";
    spi-max-frequency = <10000000>;
    interrupt-parent = <&gpio0>;
    interrupts = <RK_PA4 GPIO_ACTIVE_LOW>;
    vdd-supply = <&vcc_3v3>;
    xceiver-supply = <&vcc_3v3>;
    };

    clk_mcp2515: clk_mcp2515 {
    compatible = "fixed-clock";
    #clock-cells = <0>;
    clock-frequency = <8000000>;
    };

    Change SPI configuraton from:

    // SPI
    &spi0 {
    pinctrl-0 = <&spi0m0_clk &spi0m0_miso &spi0m0_mosi &spi0m0_cs0>;
    #address-cells = <1>;
    #size-cells = <0>;

    spidev@0 {
    compatible = "rockchip,spidev";
    spi-max-frequency = <50000000>;
    reg = <0>;
    };
    fbtft@0{
    compatible = "sitronix,st7789v";
    reg = <0>;
    spi-max-frequency = <20000000>;
    fps = <30>;
    buswidth = <8>;
    debug = <0x7>;
    led-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>;//BL
    dc-gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_HIGH>; //DC
    reset-gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_LOW>; //RES
    };
    };

    to:

    &spi0 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&spi0m0_clk &spi0m0_miso &spi0m0_mosi &spi0m0_cs0>;

    mcp2515@0 {
    compatible = "microchip,mcp2515";
    reg = <0 0>;
    spi-max-frequency = <10000000>;
    interrupts = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
    interrupt-parent = <&gpio0>;
    clocks = <&clk_mcp2515>;
    clock-names = "mcp2515";
    };
    };

    7. Build all
    ./build.sh lunch
    ./build.sh

    8. Burn the firmware to the board
    sudo ./rkflash.sh update

    9. Connections

    Pico mini b - MCP2515
    SPI0_CS0_M0 -> CS
    SPI0_CLK_M0 -> SCLK
    SPI0_MOSI_M0 -> SI
    SPI0_MISO_M0 -> SO
    GPIO0_A4_d -> INT

    10. Power on and connect to the board

    11. Load the module in the kernel
    cd /oem/usr/ko
    insmod mcp251x.ko

    12. Check dmesg:
    dmesg | grep -E 'can|spi|mcp251x'

    Output:
    [ 0.126339] can: controller area network core
    [ 0.126456] can: raw protocol
    [ 0.126468] can: broadcast manager protocol
    [ 0.126486] can: netlink gateway - max_hops=1
    [ 0.371569] ubi0: scanning is finished
    [ 6.574255] ubi4: scanning is finished
    [ 7.841856] ubi5: scanning is finished
    [ 105.192216] mcp251x spi0.0 can0: MCP2515 successfully initialized.

    13. Setting up CAN (Here it fails!!!!!)

    ip link set can0 up type can bitrate 1000000
    it says:
    ip: either "dev" is duplicate, or "type" is garbage

    if you only run:
    ip link set can0 up

    the dmesg says:
    [ 3849.858662] mcp251x spi0.0 can0: bit-timing not yet defined
    [ 3849.858717] mcp251x spi0.0: unable to set initial baudrate!

    How can I set this up now, I feel like I'm so close to achieving it?
  • Based on the information you provided, it seems you have completed most of the work. The current issue arises when starting the CAN device.

    Code: Select all

    [ 3849.858662] mcp251x spi0.0 can0: bit-timing not yet defined
    [ 3849.858717] mcp251x spi0.0: unable to set initial baudrate!
    
    Based on the driver source code at kernel/drivers/net/can/spi/mcp251x.c, the issue occurs when calling open_candev.

    Code: Select all

    /* Common open function when the device gets opened.
     *
     * This function should be called in the open function of the device
     * driver.
     */
    int open_candev(struct net_device *dev)
    {
    	struct can_priv *priv = netdev_priv(dev);
    
    	if (!priv->bittiming.bitrate) {
    		netdev_err(dev, "bit-timing not yet defined\n");
    		return -EINVAL;
    	}
    
    	/* For CAN FD the data bitrate has to be >= the arbitration bitrate */
    	if ((priv->ctrlmode & CAN_CTRLMODE_FD) &&
    	    (!priv->data_bittiming.bitrate ||
    	     priv->data_bittiming.bitrate < priv->bittiming.bitrate)) {
    		netdev_err(dev, "incorrect/missing data bit-timing\n");
    		return -EINVAL;
    	}
    
    	/* Switch carrier on if device was stopped while in bus-off state */
    	if (!netif_carrier_ok(dev))
    		netif_carrier_on(dev);
    
    	return 0;
    }
    EXPORT_SYMBOL_GPL(open_candev);
    
    
    The main issue is that bittiming.bitrate does not have a valid value set. I found an blogshttps://blog.csdn.net/flymachine/articl ... ls/7251061,that might be helpful to you.
  • Hello,

    I am trying to setup the Luckfox Pico Pro following all the steps in this thread but I am not able to make it works. I am following the Luckfox SDK Builroot configuration and these are the steps I take:

    1. Compiled buildroot:
    ./build.sh lunch
    ./build.sh


    2. Added CAN support to the kernel, include MCP251X driver:
    (As described above)

    3. Went back to sdk root folder, and modify buildroot:
    - (As decribed above) but also selected "iproute2"

    4. Went to dts folder: cd sysdrv/source/kernel/arch/arm/boot/dts

    5. As long as I am using Luckfox Pico Pro, I modified `rv1106g-luckfox-pico-pro.dts` with the instructions above.

    6. As long as I am using Luckfox Pico Pro, I modified `rv1106-luckfox-pico-pro-max-ipc.dtsi` with the instructions above.
    (Here I am not sure if this is the correct file to modify)
    I changed the gpio interrupt from this:

    Code: Select all

    can0: mcp2515@0 {
    ...
    interrupt-parent = <&gpio0>;
    interrupts = <RK_PA4 GPIO_ACTIVE_LOW>;
    ...
    };
    to this:

    Code: Select all

    can0: mcp2515@0 {
    ...
    interrupt-parent = <&gpio1>;
    interrupts = <RK_PC7 GPIO_ACTIVE_LOW>;
    ...
    };
    And also changed SPI configuraton from this:

    Code: Select all

    mcp2515@0 {
    ...
    interrupts = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
    interrupt-parent = <&gpio0>;
    ...
    };
    to this:

    Code: Select all

    mcp2515@0 {
    ...
    interrupts = <&gpio1 RK_PC7 GPIO_ACTIVE_LOW>;
    interrupt-parent = <&gpio1>;
    ...
    };
    7. I went back to main SDK folder and built all:
    ./build.sh lunch
    ./build.sh


    8. Using SocToolKit.exe I flahed the SPI NAND of Luckfox PIco Pro

    9. I Connected the pins as follow:

    Pico Pro - MCP2515
    SPI0_CS0_M0 -> CS
    SPI0_CLK_M0 -> SCLK
    SPI0_MOSI_M0 -> SI
    SPI0_MISO_M0 -> SO
    GPIO1_C7_d -> INT

    10. Load the module in the kernel (Here I have the problem)
    - cd /oem/usr/ko
    In this path there is no file called mcp251x.ko so I cannot run command "insmod mcp251x.ko"

    11. When checking dmesg:
    dmesg | grep -E 'can|spi|mcp251x'

    it shows:
    [ 0.463973] can: controller area network core
    [ 0.464069] can: raw protocol
    [ 0.464082] can: broadcast manager protocol
    [ 0.464098] can: netlink gateway - max_hops=1
    [ 0.935736] ubi0: scanning is finished
    [ 2.120253] ubi4: scanning is finished
    [ 2.296265] ubi5: scanning is finished

    However, If I run: ip link set can0 up type can bitrate 1000000
    it says: RTNETLINK answers: Invalid argument
    And after that, if I run again dmesg | grep -E 'can|spi|mcp251x'
    it says:
    [ 0.463973] can: controller area network core
    [ 0.464069] can: raw protocol
    [ 0.464082] can: broadcast manager protocol
    [ 0.464098] can: netlink gateway - max_hops=1
    [ 0.935736] ubi0: scanning is finished
    [ 2.120253] ubi4: scanning is finished
    [ 2.296265] ubi5: scanning is finished
    [ 66.587824] mcp251x spi0.0: failed to acquire irq 0
    [ 66.587855] A link change request failed with some changes committed already. Interface can0 may have been left with an inconsistent configuration, please check.


    I really would appreciate any help on this regard. Thanks in advance for your time and consideration.
    Regards.
    Last edited by DhSufi on 2025-02-03 12:52, edited 1 time in total.
  • yeisonint wrote: 2024-12-21 5:56 I was finally able to load the module into the kernel with the following configuration, but it fails in the last step:

    1. Compile busybox/buildroot
    ./build.sh lunch
    ./build.sh

    2. Add CAN support to the kernel, include MCP251X driver
    ./build.sh clean kernel
    cd sysdrv/source/kernel
    cp ./arch/arm/configs/luckfox_rv1106_linux_defconfig .config
    make ARCH=arm menuconfig

    Networking support ---> CAN bus subsystem support ---> select Raw CAN Protocol and go to CAN Device drivers ---> CAN SPI interfaces ---> select `Microchip MCP251x and MCP25625 SPI CAN controllers` as modules (M)

    make ARCH=arm savedefconfig
    cp defconfig ./arch/arm/configs/luckfox_rv1106_linux_defconfig

    3. Go back to sdk root folder, and modify buildroot
    cd sysdrv/source/buildroot/buildroot-2023.02.6

    make luckfox_pico_defconfig
    make menuconfig
    Target packages ---> Networking applications ---> select can-utils
    make savedefconfig
    make

    4. Go dts folder
    cd sysdrv/source/kernel/arch/arm/boot/dts

    5. Modify `rv1103g-luckfox-pico-mini.dts`
    Chage
    /* SPI0_M0 */
    &spi0 {
    status = "disabled";
    ...

    To:

    /* SPI0_M0 */
    &spi0 {
    status = "okay";
    ...

    6. Modify `rv1103-luckfox-pico-ipc.dtsi`

    Add this after DHT11 section:

    can0: mcp2515@0 {
    compatible = "microchip,mcp2515";
    reg = <0 0>;
    clocks = <&clk_mcp2515>;
    clock-names = "mcp2515";
    spi-max-frequency = <10000000>;
    interrupt-parent = <&gpio0>;
    interrupts = <RK_PA4 GPIO_ACTIVE_LOW>;
    vdd-supply = <&vcc_3v3>;
    xceiver-supply = <&vcc_3v3>;
    };

    clk_mcp2515: clk_mcp2515 {
    compatible = "fixed-clock";
    #clock-cells = <0>;
    clock-frequency = <8000000>;
    };

    Change SPI configuraton from:

    // SPI
    &spi0 {
    pinctrl-0 = <&spi0m0_clk &spi0m0_miso &spi0m0_mosi &spi0m0_cs0>;
    #address-cells = <1>;
    #size-cells = <0>;

    spidev@0 {
    compatible = "rockchip,spidev";
    spi-max-frequency = <50000000>;
    reg = <0>;
    };
    fbtft@0{
    compatible = "sitronix,st7789v";
    reg = <0>;
    spi-max-frequency = <20000000>;
    fps = <30>;
    buswidth = <8>;
    debug = <0x7>;
    led-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>;//BL
    dc-gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_HIGH>; //DC
    reset-gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_LOW>; //RES
    };
    };

    to:

    &spi0 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&spi0m0_clk &spi0m0_miso &spi0m0_mosi &spi0m0_cs0>;

    mcp2515@0 {
    compatible = "microchip,mcp2515";
    reg = <0 0>;
    spi-max-frequency = <10000000>;
    interrupts = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
    interrupt-parent = <&gpio0>;
    clocks = <&clk_mcp2515>;
    clock-names = "mcp2515";
    };
    };

    7. Build all
    ./build.sh lunch
    ./build.sh

    8. Burn the firmware to the board
    sudo ./rkflash.sh update

    9. Connections

    Pico mini b - MCP2515
    SPI0_CS0_M0 -> CS
    SPI0_CLK_M0 -> SCLK
    SPI0_MOSI_M0 -> SI
    SPI0_MISO_M0 -> SO
    GPIO0_A4_d -> INT

    10. Power on and connect to the board

    11. Load the module in the kernel
    cd /oem/usr/ko
    insmod mcp251x.ko

    12. Check dmesg:
    dmesg | grep -E 'can|spi|mcp251x'

    Output:
    [ 0.126339] can: controller area network core
    [ 0.126456] can: raw protocol
    [ 0.126468] can: broadcast manager protocol
    [ 0.126486] can: netlink gateway - max_hops=1
    [ 0.371569] ubi0: scanning is finished
    [ 6.574255] ubi4: scanning is finished
    [ 7.841856] ubi5: scanning is finished
    [ 105.192216] mcp251x spi0.0 can0: MCP2515 successfully initialized.

    13. Setting up CAN (Here it fails!!!!!)

    ip link set can0 up type can bitrate 1000000
    it says:
    ip: either "dev" is duplicate, or "type" is garbage

    if you only run:
    ip link set can0 up

    the dmesg says:
    [ 3849.858662] mcp251x spi0.0 can0: bit-timing not yet defined
    [ 3849.858717] mcp251x spi0.0: unable to set initial baudrate!

    How can I set this up now, I feel like I'm so close to achieving it?
    So did you make it work? I'm currently stuck at almost the same step with similar issue. Using Ubuntu image from luckfox, trying to make mcp2515 work
  • DhSufi wrote: 2025-02-03 0:23 Hello,

    I am trying to setup the Luckfox Pico Pro following all the steps in this thread but I am not able to make it works. I am following the Luckfox SDK Builroot configuration and these are the steps I take:

    ......
    6. If you are using Luckfox Pico Pro, it is correct to modify rv1106-luckfox-pico-pro-max-ipc.dtsi

    10. There is no mcp251x.ko because you use "Y" in kernel menuconfig to compile the driver directly into the kernel, and you can also see that the driver has been successfully loaded from the subsequent kernel print logs, which is normal.


    The error you are currently encountering is "mcp251x spi0.0: failed to acquire irq 0" and the corresponding source code is

    Code: Select all

    
    	ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,
    
    				   flags | IRQF_ONESHOT, dev_name(&spi->dev),
    
    				   priv);
    
    	if (ret) {
    
    		dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
    
    		goto out_close;
    
    	}
    
    
    Most likely, it is a problem with the device tree settings
  • Crocodile wrote: 2025-02-05 3:08 The error you are currently encountering is "mcp251x spi0.0: failed to acquire irq 0" and the corresponding source code is

    Code: Select all

    
    	ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,
    
    				   flags | IRQF_ONESHOT, dev_name(&spi->dev),
    
    				   priv);
    
    	if (ret) {
    
    		dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
    
    		goto out_close;
    
    	}
    
    
    Most likely, it is a problem with the device tree settings

    Thank you so much for your help. Following your advice I was able to make it run but with a curious behaviour. I think I am not properly defining the INT pin in the device tree settings. This Is what I did:

    1. Following your tip, in the file 'rv1106-luckfox-pico-pro-max-ipc.dtsi' I changed my previous SPI configuraton from this:

    Code: Select all

    mcp2515@0 {
    ...
    interrupts = <&gpio1 RK_PC7 GPIO_ACTIVE_LOW>;
    interrupt-parent = <&gpio1>;
    ...
    };
    
    to this:

    Code: Select all

    mcp2515@0 {
    ...
    interrupts = <RK_PC7 GPIO_ACTIVE_LOW>;
    interrupt-parent = <&gpio1>;
    ...
    };
    
    (I deleted the "&gpio1" in the interrupt)

    2. I run the command:
    ip link set can0 up type can bitrate 1000000
    And the Luckfox Pico Pro recognized the mcp2515 module and I was able to run my command:
    'cansend can0 1200FD0F#0570000007019554'

    However it only works once. Only the first time. After that if I try to send more messages, they are not sent and if I keep trying I got the error:
    [root@luckfox root]# cansend can0 02800FFD#FFFF80177FFF00EF
    write: No buffer space available


    Also, when using the command 'candump can0' I am not receiving any message.
    I did some research and it seems to be some problem with the INT pin, but I am not sure about that.

    I also tried:
    • I double checked the wiring.
    • I double checked the wires electrical continuity with multimeter.
    • I tried to change the pin with
      'RK_PC6 GPIO_ACTIVE_LOW'
      'RK_PC5 GPIO_ACTIVE_LOW'
      'RK_PC4 GPIO_ACTIVE_LOW'
      'RK_PD2 GPIO_ACTIVE_LOW'.
    • I tried the mcp2515 module in my rspbrry pi Zero and rspbrry pi 4B and it worked as expected.
    • I tried to connect the mcp2515 voltage to 5V and 3.3V
    • I tried a second Luckfox Pico Pro board
    But after all of that I was not able to make it work. It only works the first cansend message
    Again, I really would appreciate any insight in this regard. And of course I am sorry for any inconvenience caused and really thankful for your patience.
    Regards.
  • Your device tree seems to have some issues. It is recommended to modify it as follows:

    Code: Select all

    mcp2515@0 {
    ...
    interrupts = <RK_PC7 IRQ_TYPE_LEVEL_LOW>;
    interrupt-parent = <&gpio1>;
    ...
    };
    
    Alternatively, you can use another triggering method, referring to <SDK>/sysdrv/source/kernel/include/dt-bindings/interrupt-controller/irq.h.
  • That was exactly the problem. Now everything is working!!! Thanks a lot for all the help!!