Unable to send CAN frames on imx6dlsabresd

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Unable to send CAN frames on imx6dlsabresd

Jump to solution
3,071 Views
shengkaikao
Contributor II

Hello!

I'm using imx6dlsabresd board and trying to enable the CAN bus.

My kernel version is 4.1.15

In the device tree imx6qdl-sabresd.dtsi I have included the followings:

reg_can_xcvr: regulator@5 {
compatible = "regulator-fixed";
reg = <5>;
regulator-name = "CAN XCVR";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_flexcan_xcvr>;
gpio = <&gpio4 21 GPIO_ACTIVE_HIGH>;
enable-active-low;
};

&can1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_flexcan1>;
xceiver-supply = <&reg_can_xcvr>;
trx-stby-gpio = <&gpio4 5 GPIO_ACTIVE_LOW>;
status = "okay";

};

pinctrl_flexcan1: flexcan1grp {
fsl,pins = <
MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x1b0b0
MX6QDL_PAD_GPIO_8__FLEXCAN1_RX 0x1b0b0
MX6QDL_PAD_GPIO_19__KEY_COL5 0x1b0b0
>;
};

pinctrl_flexcan_xcvr: flexcan-xcvrgrp {
fsl,pins = <
MX6QDL_PAD_DISP0_DAT0__GPIO4_IO21 0x1b0b0 /* Flexcan XCVR enable */
>;
};

and in imx6qdl.dtsi have included:


can1: flexcan@02090000 {
compatible = "fsl,imx6q-flexcan";
reg = <0x02090000 0x4000>;
interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_CAN1_IPG>,
<&clks IMX6QDL_CLK_CAN1_SERIAL>;
clock-names = "ipg", "per";
stop-mode = <&gpr 0x34 28 0x10 17>;
status = "okay";
};

The CAN bus can be enabled by "ip link set canX up type can bitrate 125000"

However, whenever I tried to send a frame, it failed.

I use "ip -details -statistics link show can0" and it says:

2: can0: <NO-CARRIER,NOARP,UP,ECHO> mtu 16 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 10
link/can promiscuity 0
can state BUS-OFF (berr-counter tx 0 rx 0) restart-ms 0
bitrate 125000 sample-point 0.875
tq 500 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
flexcan: tseg1 4..16 tseg2 2..8 sjw 1..4 brp 1..256 brp-inc 1
clock 30000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0                0               0             1                0                1
RX: bytes packets errors dropped overrun mcast
      16       2            0          0           0            0
TX: bytes packets errors dropped carrier collsns
      0        0             0          0           0            0

then I tun off can0 and turn on again,

2: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can promiscuity 0
can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
bitrate 125000 sample-point 0.875
tq 500 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
flexcan: tseg1 4..16 tseg2 2..8 sjw 1..4 brp 1..256 brp-inc 1
clock 30000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0                0                0            1               0             1
RX: bytes packets errors dropped overrun mcast
      16       2           0         0            0          0
TX: bytes packets errors dropped carrier collsns
       0       0            0         1            0          0

I was sending a frame and it was dropped; instead I received two packets?

I have no idea how to deal with this problem. 

Any help would be greatly appreciated.

Labels (1)
Tags (1)
1 Solution
1,553 Views
shengkaikao
Contributor II

I had found the problem.

The stb pin of the transceiver was not pulled low.

The stb pin is connected to GPIO19, and GPIO19 signal is provided by the regulator.

I thought that the regulator provides power to the transceiver, ie Vcc, before. 

However it turned out to be wrong.

So the right code is as following:

reg_can_xcvr: regulator@5 {

    compatible = "regulator-fixed";
    reg = <5>;
    regulator-name = "CAN XCVR";
    regulator-min-microvolt = <3300000>;
    regulator-max-microvolt = <3300000>;
    pinctrl-names = "default";
    gpio = <&gpio4 5 GPIO_ACTIVE_HIGH>; //this gpio is used to enable the regulator
    enable-active-low;  //this is the actual output of the regulator
};

&can1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_flexcan1>;
    xceiver-supply = <&reg_can_xcvr>;
    //trx-stby-gpio = <&gpio4 5 GPIO_ACTIVE_LOW>;

    //this description is useless in this kernel version (4.1.15), but I don't know why
    status = "okay";
};

pinctrl_flexcan1: flexcan1grp {
    fsl,pins = <
        MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x1b0b0
        MX6QDL_PAD_GPIO_8__FLEXCAN1_RX 0x1b0b0
        MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x1b0b0
    >;
};

View solution in original post

9 Replies
1,554 Views
shengkaikao
Contributor II

I had found the problem.

The stb pin of the transceiver was not pulled low.

The stb pin is connected to GPIO19, and GPIO19 signal is provided by the regulator.

I thought that the regulator provides power to the transceiver, ie Vcc, before. 

However it turned out to be wrong.

So the right code is as following:

reg_can_xcvr: regulator@5 {

    compatible = "regulator-fixed";
    reg = <5>;
    regulator-name = "CAN XCVR";
    regulator-min-microvolt = <3300000>;
    regulator-max-microvolt = <3300000>;
    pinctrl-names = "default";
    gpio = <&gpio4 5 GPIO_ACTIVE_HIGH>; //this gpio is used to enable the regulator
    enable-active-low;  //this is the actual output of the regulator
};

&can1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_flexcan1>;
    xceiver-supply = <&reg_can_xcvr>;
    //trx-stby-gpio = <&gpio4 5 GPIO_ACTIVE_LOW>;

    //this description is useless in this kernel version (4.1.15), but I don't know why
    status = "okay";
};

pinctrl_flexcan1: flexcan1grp {
    fsl,pins = <
        MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x1b0b0
        MX6QDL_PAD_GPIO_8__FLEXCAN1_RX 0x1b0b0
        MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x1b0b0
    >;
};

1,553 Views
amit251291
Contributor IV

Thank you so much Sheng Kai Kao for sharing your final solution. I was facing the same problem but your solution helped me to resolve it. Thanks :smileyhappy:

0 Kudos
1,553 Views
shengkaikao
Contributor II

I found a mistake that
"MX6QDL_PAD_GPIO_19__KEY_COL5 0x1b0b0" should be "MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x1b0b0"

to enable GPIO19 to output signal GPIO4_IO05

and set "trx-stby-gpio = <&gpio4 5 GPIO_ACTIVE_LOW>" to pull low the CAN1_STBY

But the result still remains the same as before.

Does anyone have any idea?

0 Kudos
1,553 Views
igorpadykov
NXP Employee
NXP Employee

Hi Sheng

please check

https://lists.yoctoproject.org/pipermail/meta-freescale/2014-May/008571.html 

also please try to test on sabre ai board, as sabresd does not support

flexcan by default.

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
1,553 Views
shengkaikao
Contributor II

Thanks for your reply.

Since I do not have sabre ai board, I can only test on my sabresd board.

I have already add the codes which is mentioned in the post you gave.

Compared with imx6qdl-sabreauto.dtsi, I do some modification:

reg_can_xcvr: regulator@5 {
compatible = "regulator-fixed";
reg = <5>;
regulator-name = "CAN XCVR";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_flexcan_xcvr>;
gpio = <&gpio4 21 GPIO_ACTIVE_HIGH>;
enable-active-high;
};

&fec {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet>;
phy-mode = "rgmii";
phy-reset-gpios = <&gpio1 25 0>;
fsl,magic-packet;
status = "disabled"; /* pin conflict with flexcan1 */
};

and then try to send a frame again, but the result still remained the same.

root@imx6dlsabresd:~# ip -details -statistics link show can0
2: can0: <NO-CARRIER,NOARP,UP,ECHO> mtu 16 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 10
link/can promiscuity 0
can state BUS-OFF (berr-counter tx 0 rx 0) restart-ms 0
bitrate 125000 sample-point 0.875
tq 500 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
flexcan: tseg1 4..16 tseg2 2..8 sjw 1..4 brp 1..256 brp-inc 1
clock 30000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0                0              0             1                0                1
RX: bytes packets errors dropped overrun mcast
         16       2          0       0             0          0
TX: bytes packets errors dropped carrier collsns
         0         0          0       0             0          0

This time I did one more test.

I turn on the loopback function and the can seemed to work normally in loopback mode.

root@imx6dlsabresd:~# ip -details -statistics link show can0
2: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can promiscuity 0
can <LOOPBACK> state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
bitrate 125000 sample-point 0.875
tq 500 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
flexcan: tseg1 4..16 tseg2 2..8 sjw 1..4 brp 1..256 brp-inc 1
clock 30000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0                0               0             1               0                1
RX: bytes packets errors dropped overrun mcast
       16       2          0        0             0          0
TX: bytes packets errors dropped carrier collsns
       4        1           0        1             0          0

Do you have any ideas what the problem might be?

0 Kudos
1,553 Views
igorpadykov
NXP Employee
NXP Employee

>This time I did one more test.

>I turn on the loopback function and the can seemed to work normally in loopback mode.

then what is the problem, as loopback test is working OK ?

0 Kudos
1,553 Views
shengkaikao
Contributor II

I think the problem might be the can transceiver.

I used loopback mode to test can1, which did not have a transceiver on sabresd board.

However, it also send a frame successfully.

So I guessed loopback mode proved that can worked normally  inside the control host.

Therefore the problem might be the can transceiver.

As for transceiver, the code I added in imx6qdl-sabresd-dtsi is as following:

//create a regulator for transceiver or the system would say "flexcan supply xceiver not found"

reg_can_xcvr: regulator@5 {
    compatible = "regulator-fixed";
    reg = <5>;
    regulator-name = "CAN XCVR";
    regulator-min-microvolt = <3300000>;
    regulator-max-microvolt = <3300000>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_flexcan_xcvr>;
    gpio = <&gpio4 21 GPIO_ACTIVE_HIGH>;
    enable-active-high;
};

&can1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_flexcan1>;
    xceiver-supply = <&reg_can_xcvr>;  //regulator supply for transceiver
    trx-stby-gpio = <&gpio4 5 GPIO_ACTIVE_LOW>;  //pull the transceiver stb pin to be low to operate in normal mode
    status = "okay";
};

//define the output pin. I have checked that no other signals use these pins.

pinctrl_flexcan1: flexcan1grp {
    fsl,pins = <
    MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x1b0b0
    MX6QDL_PAD_GPIO_8__FLEXCAN1_RX 0x1b0b0
    MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x1b0b0
    >;
};

pinctrl_flexcan_xcvr: flexcan-xcvrgrp {
    fsl,pins = <
    MX6QDL_PAD_DISP0_DAT0__GPIO4_IO21 0x1b0b0 // Flexcan XCVR enable
    >;
};

Maybe I loss something or have some error?

0 Kudos
1,553 Views
igorpadykov
NXP Employee
NXP Employee

can transceiver can be found in imx6qdl-sabreauto.dtsi

linux-2.6-imx.git - Freescale i.MX Linux Tree 

0 Kudos
1,553 Views
shengkaikao
Contributor II

I have already read it before and modified from it.

There are two differences between them.

The first difference is that I created one regulator instead of two.

It creates reg_can_en and reg_can_stby, but reg_can_en is the source of reg_can_stby.

Then reg_can_stby is used for transceiver.

So I think create only one regulator would be fine.

The second difference is that in &can1, it has the extra code as below:

pinctrl-assert-gpios = <&max7310_b 3 GPIO_ACTIVE_HIGH>; /* TX */

But the pin assignment is in "pinctrl_flexcan1: flexcan1grp" and it match the schematic.

I have no idea about this description so I didn't add it.

Maybe this is the problem?

If so, what GPIO should I set corresponding to sabresd board?

0 Kudos