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 = <®_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.
Solved! Go to Solution.
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 = <®_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
>;
};
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 = <®_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
>;
};
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:
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?
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!
-----------------------------------------------------------------------------------------------------------------------
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?
>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 ?
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 = <®_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?
can transceiver can be found in imx6qdl-sabreauto.dtsi
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?