This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TX/RX problem with DCAN

Hello,

I have a problem with can bus on Beaglebone black. I am using TI kernel on my BBB. Output of uname -a is as follows,

Linux am335x-evm 3.12.10-ti2013.12.01 #36 Sat Jul 25 12:45:12 EEST 2015 armv7l GNU/Linux

I am trying to send and receive can messages with can0. I was able to bring up can0 following this guide,

http://processors.wiki.ti.com/index.php/AM335X_DCAN_Driver_Guide

I have another board which sends can messages with the same bitrate continuously. I am sure that it can send/receive the messages since I tested this with two of them as one of them is receiver and the other one is sender.

When I run the candump, I can't see any packets on the screen. Output is as follows,

root@am335x-evm:~# ip link set can0 type can bitrate 50000 triple-sampling on
root@am335x-evm:~# ip link set can0 up
root@am335x-evm:~# candump can0
interface = can0, family = 29, type = 3, proto = 1

I added following lines in am335x-boneblack.dts file to configure the can0

dcan0_pins: dcan0_pins {
pinctrl-single,pins = <
0x178 0x12
0x17C 0x32
>;
};

&dcan0 {

#address-cells = <1>;
#size-cells = <0>;

pinctrl-names = "default";

pinctrl-0 = <&dcan0_pins>;
status = "okay";
};
I got the dts file changes from this webpage,

I also tried to send can messages from BBB, I can see the signal with oscilloscope at can0 tx pin but receiving fails at receiver side.

My can trasnciever is sn65hvd233dr.

I am stuck with this after working several days. I would be happy if anyone can give some clue or suggest some tests to progress. Thank you.

  • Hello Kara Murat,

    Could you check if yout DCAN driver is enabled in Linux?

    Check with menuconfig, as in the picture:

    Best regards,

    Yanko

  • Yanko thank you for your reply. Yes I enabled the driver. I also tried this with kernel 3.14 insted of 3.12 but still no luck. I get the following output as statictic after setting can0 up and running transmitter board for several seconds.

    root@am335x-evm:~# ip link set can0 type can bitrate 50000 triple-sampling on
    root@am335x-evm:~# ip link set can0 up

    root@am335x-evm:~# candump can0
    interface = can0, family = 29, type = 3, proto = 1
    ^C

    root@am335x-evm:~# ip -d -s link show can0
    2: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN mode DEFAULT qlen 10
    link/can promiscuity 0
    can <TRIPLE-SAMPLING> state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
    bitrate 50000 sample-point 0.875
    tq 1250 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
    c_can: tseg1 2..16 tseg2 1..8 sjw 1..4 brp 1..1024 brp-inc 1
    clock 19200000
    re-started bus-errors arbit-lost error-warn error-pass bus-off
    0 0 0 0 0 0
    RX: bytes packets errors dropped overrun mcast
    0 0 0 0 0 0
    TX: bytes packets errors dropped carrier collsns
    0 0 0 0 0 0

    And other statistic info,

    root@am335x-evm:~# cat /proc/net/can/stats

    0 transmitted frames (TXF)
    0 received frames (RXF)
    0 matched frames (RXMF)

    0 % total match ratio (RXMR)
    0 frames/s total tx rate (TXR)
    0 frames/s total rx rate (RXR)

    0 % current match ratio (CRXMR)
    0 frames/s current tx rate (CTXR)
    0 frames/s current rx rate (CRXR)

    0 % max match ratio (MRXMR)
    0 frames/s max tx rate (MTXR)
    0 frames/s max rx rate (MRXR)

    0 current receive list entries (CRCV)
    1 maximum receive list entries (MRCV)

    When I filtered "can" out of dmesg,

    root@am335x-evm:~# dmesg | grep can
    [ 0.191569] of_get_named_gpio_flags: can't parse gpios property of node '/fixedregulator@0[0]'
    [ 0.384361] of_get_named_gpio_flags: can't parse gpios property of node '/ocp/serial@44e09000[0]'
    [ 1.215944] vcan: Virtual CAN interface driver
    [ 1.228059] c_can_platform 481cc000.d_can: c_can_platform device registered (regs=fa1cc000, irq=68)
    [ 1.394756] of_get_named_gpio_flags: can't parse gpios property of node '/ocp/mmc@48060000[0]'
    [ 1.452112] of_get_named_gpio_flags: can't parse gpios property of node '/ocp/mmc@481d8000[0]'
    [ 1.452130] of_get_named_gpio_flags: can't parse gpios property of node '/ocp/mmc@481d8000[0]'
    [ 1.639880] can: controller area network core (rev 20120528 abi 9)
    [ 1.653980] can: raw protocol (rev 20120528)
    [ 1.659663] can: broadcast manager protocol (rev 20120528 t)
    [ 3.112945] of_get_named_gpio_flags: can't parse gpios property of node '/ocp/usb@47400000/usb-phy@47401b00[0]'
    [ 3.352369] can_dev: exports duplicate symbol alloc_can_err_skb (owned by kernel)
    [ 213.167708] c_can_platform 481cc000.d_can can0: setting BTR=1c17 BRPE=0000

    This is my kernel confguration for can

    CAN [=y]
    CAN_RAW [=y]
    CAN_BCM [=y]
    CAN_GW [=y]
    CAN_DEV [=y]
    CAN_TI_HECC [=y]
    CAN_C_CAN [=y]
    CAN_C_CAN_PLATFORM [=y]
    CAN_CALC_BITTIMING [=y]

  • Hello Kara Murat,

    I assume that your problem is caused by the fact that DCAN's pins in dts file are not defined correctly.

    See in am335x-boneblack.dts file:

     &am33xx_pinmux {

    :

             dcan0_pins: dcan1_pins {
                            pinctrl-single,pins = <
                            0x178 (PIN_INPUT_PULLUP | MUX_MODE2) /*UART1_TXD.dcan1_rx*/
                            0x184 (PIN_OUTPUT_PULLUP | MUX_MODE2) /*UART1_RXD.dcan1_tx*/
               >;
             };

    &dcan0 {
                    status = "okay";
                    pinctrl-names = "default";
                    pinctrl-0 = <&dcan0_pins>;
     };

    According this definitions DCAN0 uses DCAN1 pins. 

    I suggest you applying some modifications in your am335x-boneblack.dts file.

    DCAN pins are muxed on following balls:

    dcan0_rx -> UART1_RTSN -> MuxMode 2

    dcan0_tx -> UART1_CTSN -> MuxMode 2

    dcan0_rx -> UART0_TXD -> MuxMode 2

    dcan0_tx -> UART0_RXD -> MuxMode 2

    dcan0_rx -> MII1_TXD2 -> MuxMode 1

    dcan0_tx -> MII1_TXD3 -> MuxMode 1

    dcan1_rx -> MMC0_CMD -> MuxMode 4

    dcan1_tx -> MMC0_CLK -> MuxMode 4

    dcan1_rx -> UART0_RTSn -> MuxMode 2

    dcan1_tx -> UART0_CTSn -> MuxMode 2

    dcan1_rx -> UART1_TXD -> MuxMode 2

    dcan1_tx -> UART1_RXD -> MuxMode 2

    Your modifications must include definitions for dcan0_pins. For example:

     dcan0_pins: dcan0_pins { 
                            pinctrl-single,pins = <

    // Here use some of registers listed above.
                            0x178 (PIN_INPUT_PULLUP | MUX_MODE2) /*UART0_TXD.dcan0_rx*/
                            0x184 (PIN_OUTPUT_PULLUP | MUX_MODE2) /*UART0_RXD.dcan0_tx*/
               >;
             };

    Add following in am33xx_pinmux:

     &am33xx_pinmux {

    :

             dcan0_pins: dcan0_pins { 
                            pinctrl-single,pins = <
                            0x178 (PIN_INPUT_PULLUP | MUX_MODE2) /*UART0_TXD.dcan0_rx*/
                            0x184 (PIN_OUTPUT_PULLUP | MUX_MODE2) /*UART0_RXD.dcan0_tx*/
               >;
             };

    dcan1_pins: dcan1_pins { 
                            pinctrl-single,pins = <
                            0x178 (PIN_INPUT_PULLUP | MUX_MODE2) /*UART1_TXD.dcan1_rx*/
                            0x184 (PIN_OUTPUT_PULLUP | MUX_MODE2) /*UART1_RXD.dcan1_tx*/
               >;
             };

    &dcan0 { 
                    status = "okay";
                    pinctrl-names = "default";
                    pinctrl-0 = <&dcan0_pins>;
     };

    &dcan1 { 
                    status = "okay";
                    pinctrl-names = "default";
                    pinctrl-0 = <&dcan1_pins>;
     };

    Best regards,

    Yanko

  • Yanko I am confused after your reply. What am335x-boneblack.dts file do you mean? Configuration is which you said wrong is not the same as mine. I checked beaglebone black reference and TI pinmux tool. DCAN pins for can0 which I used in my configuration(please see my first post) seems correct. Do you mean an error in board support package?

  • Kara Murat, 

    I only suggest you an approach to solve your issue. In our e2e forum we support only TI' SW releases.

    Please send me your dts files.

    Could you check DCAN pins state with oscilloscope?

    Best regards,

    Yanko

  • Hello Yanko,

    When I use cansend at beaglebone black, I can see the tx signal at can tx pin but receive fails at receiver side. When I send can messages from transmitter board, my beaglebone black doesn't send ack. 

    My am335x-boneblack.dts file is as follows. I changed ony this dts file.

    /*
     * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License version 2 as
     * published by the Free Software Foundation.
     */
    /dts-v1/;
    
    #include "am33xx.dtsi"
    #include "am335x-bone-common.dtsi"
    
    &ldo3_reg {
    	regulator-min-microvolt = <1800000>;
    	regulator-max-microvolt = <1800000>;
    	regulator-always-on;
    };
    
    &mmc1 {
    	vmmc-supply = <&vmmcsd_fixed>;
    };
    
    &mmc2 {
    	vmmc-supply = <&vmmcsd_fixed>;
    	pinctrl-names = "default";
    	pinctrl-0 = <&emmc_pins>;
    	bus-width = <8>;
    	ti,non-removable;
    	status = "okay";
    };
    
    &am33xx_pinmux {
    	nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins {
    		pinctrl-single,pins = <
    			0x1b0 0x03      /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */
    			0xa0 0x08       /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
    			0xa4 0x08       /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
    			0xa8 0x08       /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
    			0xac 0x08       /* lcd_data3.lcd_data3, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
    			0xb0 0x08       /* lcd_data4.lcd_data4, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
    			0xb4 0x08       /* lcd_data5.lcd_data5, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
    			0xb8 0x08       /* lcd_data6.lcd_data6, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
    			0xbc 0x08       /* lcd_data7.lcd_data7, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
    			0xc0 0x08       /* lcd_data8.lcd_data8, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
    			0xc4 0x08       /* lcd_data9.lcd_data9, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
    			0xc8 0x08       /* lcd_data10.lcd_data10, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
    			0xcc 0x08       /* lcd_data11.lcd_data11, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
    			0xd0 0x08       /* lcd_data12.lcd_data12, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
    			0xd4 0x08       /* lcd_data13.lcd_data13, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
    			0xd8 0x08       /* lcd_data14.lcd_data14, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
    			0xdc 0x08       /* lcd_data15.lcd_data15, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
    			0xe0 0x00       /* lcd_vsync.lcd_vsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
    			0xe4 0x00       /* lcd_hsync.lcd_hsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
    			0xe8 0x00       /* lcd_pclk.lcd_pclk, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
    			0xec 0x00       /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
    		>;
    	};
    	nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins {
    		pinctrl-single,pins = <
    			0x1b0 0x03      /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */
    		>;
    	};
    	spi0_pins: pinmux_spi0_pins {
    		pinctrl-single,pins = <
    		        0x150 (PIN_INPUT_PULLUP | MUX_MODE0)   /* spi0_sclk.spi0_sclk */
    		        0x154 (PIN_INPUT_PULLUP | MUX_MODE0)    /* spi0_d0.spi0_d0 */
    		        0x158 (PIN_OUTPUT_PULLUP | MUX_MODE0)    /* spi0_d1.spi0_d1 */
    		        0x15C (PIN_OUTPUT_PULLUP | MUX_MODE0)    /* spi0_cs0.spi0_cs0 */
    		>;
    	};
    	dcan0_pins: dcan0_pins {
    		pinctrl-single,pins = <
    	    		0x178 0x12
    	    		0x17C 0x32
    		>;
    	};
    };
    
    &i2c0 {
    	hdmi1: hdmi@70 {
    	      compatible = "nxp,tda998x";
    	      reg = <0x70>;
    	};
    };
    
    &lcdc {
    	pinctrl-names = "default", "off";
    	pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
    	pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
    	status = "okay";
    	hdmi = <&hdmi1>;
    	display-timings {
    		1280x720P60 {
    		   clock-frequency = <74250000>;
    		   hactive = <1280>;
    		   vactive = <720>;
    		   hfront-porch = <110>;
    		   hback-porch = <220>;
    		   hsync-len = <40>;
    		   vback-porch = <5>;
    		   vfront-porch = <20>;
    		   vsync-len = <5>;
    		   hsync-active = <1>;
    		   vsync-active = <1>;
    		};
    		640x480P60 {
    		   clock-frequency = <25200000>;
    		   hactive = <640>;
    		   vactive = <480>;
    		   hfront-porch = <16>;
    		   hback-porch = <48>;
    		   hsync-len = <96>;
    		   vback-porch = <31>;
    		   vfront-porch = <11>;
    		   vsync-len = <2>;
    		   hsync-active = <0>;
    		   vsync-active = <0>;
    		};
    	};
    };
    
    &dcan0 {            
                 pinctrl-names = "default";
                 pinctrl-0 = <&dcan0_pins>;
                 status = "okay";
    };
    
    &spi0 {
                	pinctrl-names = "default";
                	pinctrl-0 = <&spi0_pins>;
    		clock-frequency = <1000000>;
    		status = "okay";
                 	spidev:spidev@0{
                                compatible        = "spidev";
                                reg               = <0>;
                                spi-max-frequency = <10000000>;
                    };	
    };

  • Hello Kara Murat,

    My next suggestion about your DCAN issue is related with the following note:

    On AM335x EVM only D_CAN1 is supported. Hence in arch/arm/mach-omap2/board-am335xevm.c only D_CAN1 is support is enabled by default. To add support for D_CAN0 on your custom board, follow these steps.

    Add pinmux configurations

    Add a pinmux_config structure in your custom AM335x board file for instance 0. AM335x SoC provides multiple options for D_CAN0 pins. Refer to the schematic of your board to find which exact D_CAN0 pins are connected to the transceiver. In the example below, we assume pin UART0 RXD (primary function) is used as D_CAN0 TX pin and UART0 TXD (primary function) is used as D_CAN0 RX pin.

    static struct pinmux_config d_can0_pin_mux[] = {
           {"uart0_rxd.d_can0_tx", OMAP_MUX_MODE2 | AM33XX_PULL_ENBL},
           {"uart0_txd.d_can0_rx", OMAP_MUX_MODE2 | AM33XX_PIN_INPUT_PULLUP},
           {NULL, 0},
    };
    

    Now, call the setup_pin_mux() API to affect these mux configurations. This has to be done inside the d_can_init() API inarch/arm/mach-omap2/board-am335xevm.c, which is called from the board initialization code.

    setup_pin_mux(d_can0_pin_mux);
    

    Registering platform device

    Next, the D_CAN0 platform device needs to be registered. For this, just call am33xx_d_can_init() with instance number argument passed as 0. This also needs to be done in the board initialization sequence.

    am33xx_d_can_init(0);
    

    You are now all set to test the second D_CAN instance. Note that the CAN instance which is registered first appears as can0irrespective of which instance number it corresponds to. The second CAN instance appears as can1.

    I suggest you to check DCAN test modes in register D_CAN_TEST              0x14    /* Test register */ 

    Take a look on DCAN driver for AM335x in the link - arago-project.org/.../projects;a=blob;f=drivers/net/can/d_can/d_can.c;h=d31b019920d3dd0620bdf43fe68ca8be6ff774e0;hb=c88141aa2110dd4378004bd24405091e91383b61

    D_CAN_CTL_TEST          BIT(7)  /* Test mode enable */

    132 /* D_CAN Test register bit fields */
    133 #define D_CAN_TEST_RDA          BIT(9)  /* RAM direct access enable */
    134 #define D_CAN_TEST_EXL          BIT(8)  /* External loopback mode */
    135 #define D_CAN_TEST_RX           BIT(7)  /* Monitors the reveive pin */
    136 #define D_CAN_TEST_TX           (0x3 << 5)      /* Control of CAN_TX pin */
    137 #define D_CAN_TEST_LBACK        BIT(4)  /* Loopback mode */
    138 #define D_CAN_TEST_SILENT       BIT(3)  /* Silent mdoe */
    static void d_can_test_mode(struct net_device *dev)
    703         struct d_can_priv *priv = netdev_priv(dev);
    705         /* Test mode is enabled in this step & the specific TEST bits
    706          * are enabled accordingly */
    707         d_can_write(priv, D_CAN_CTL, D_CAN_CTL_EIE |
    708                         D_CAN_CTL_IE1 | D_CAN_CTL_IE0 | D_CAN_CTL_TEST);
    710         if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
    711                 /* silent mode : bus-monitoring mode */
    712                 d_can_write(priv, D_CAN_TEST, D_CAN_TEST_SILENT);
    713         } else if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
    714                 /* loopback mode : useful for self-test function */
    715                 d_can_write(priv, D_CAN_TEST, D_CAN_TEST_LBACK);
    716         } else {
    717                 /* loopback + silent mode : useful for hot self-test */
    718                 d_can_write(priv, D_CAN_TEST, D_CAN_TEST_LBACK |
    719                                 D_CAN_TEST_SILENT);
    720         }
    I think that you can apply several test to check the functionality of DCAN module.
    Take a look on section 23.3.8.3 Test Modes in TRM:

    The DCAN module provides several test modes which are mainly intended for production tests or self test. For all test modes, the Test bit in the CTL register needs to be set to one. This enables write access to the test register (TEST).

    TEST Register in DCAN module provides: all test modes, the test bit in CAN control register needs to be set to one. If test bit is set, the RDA, EXL, Tx1, Tx0, LBack and Silent bits are writable. Bit Rx monitors the state of pin CAN_RX and therefore is only readable. All test register functions are disabled when test bit is cleared. The test register is only writable if test bit in CAN control register is set. Setting Tx[1:0] other than '00' will disturb message transfer. When the internal loop-back mode is active (bit LBack is set), bit EXL will be ignored.

    Best regards,

    Yanko