LAN966x MCAN
SoC Resources
LAN966x SoC supports two instances of CAN-FD(Control Area Network with Flexible Data-Rate) which is compliant with CAN 2.0 Part A and 2.0 Part B.
Kernel configurations
Following kernel config options should be enabled to use LAN966x MCAN:
-
CONFIG_CAN- CAN driver config option. -
CONFIG_CAN_M_CAN- Bosch MCAN config option. -
CONFIG_CAN_M_CAN_PLATFORM- Bosch M_CAN support for io-mapped devices.
Devicetree Configuration
To enable MCAN interface, following configurations are required in device tree:
-
compatiblestring must be set tobosch,m_can. -
regproperty must be set to<0xe081c000 0xfc>and<0x00100000 0x4000>for mcan0,<0xe0820000 0xfc>and<0x00100000 0x8000>for mcan1. -
reg-namesmust be set tom_canandmessage_ram. -
interruptsproperty must be set with interrupt details as<GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>and<GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>.
| MCAN ID | Shared Peripheral Interrupt(int0) | CPU INTR(int0) | Shared Peripheral Interrupt(int1) | CPU INR(int1) |
|---|---|---|---|---|
mcan0 |
104 |
72 |
106 |
74 |
mcan1 |
105 |
73 |
107 |
75 |
- Note
-
Shared peripheral interrupt lines start at index ID32. So, CPU INTR must be calculated as [Shared peripheral interrupt number - 32].
-
interrupt-namesmust be set toint0andint1. -
clocksproperty must be set to<&clks GCK_ID_MCANx>, <&clks GCK_ID_MCANx>, wherexis MCAN ID (0-1). -
clock-namesmust be set tohclkandcclk. -
bosch,mram-cfgproperty must be set to<0x0 0 0 64 0 0 32 32>for mcan0 and<0x4000 0 0 64 0 0 32 32>for mcan1. -
Verify that
CAN_STBYpin of transceiver is set to low. If not, set the GPIO pin mapped toCAN_STBYto low usingstandby-gpiosproperty as<&gpio 54 GPIO_ACTIVE_HIGH>.
-
Example
Following example shows how a CAN controller should be defined in DT:
dtsi file:
can0: can@e081c000 {
compatible = "bosch,m_can";
reg = <MCAN_0_ADDR MCAN_0_SIZE>, <0x00100000 0x4000>;
reg-names = "m_can", "message_ram";
interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "int0", "int1";
clocks = <&clks GCK_ID_MCAN0>, <&clks GCK_ID_MCAN0>;
clock-names = "hclk", "cclk";
assigned-clocks = <&clks GCK_ID_MCAN0>;
assigned-clock-rates = <40000000>;
bosch,mram-cfg = <0x0 0 0 64 0 0 32 32>;
status = "disabled";
};
dts file changes:
&can0 {
pinctrl-0 = <&can0_b_pins>;
pinctrl-names = "default";
standby-gpios = <&gpio 54 GPIO_ACTIVE_HIGH>;
status = "okay";
};
UserSpace
Example on how to use
-
Enable
can-utilsto send/receive data on CAN interface. Usecandumpto show received message from the CAN bus andcansendto send message on CAN bus.
Loopback test
# ifconfig -a
bond0 Link encap:Ethernet HWaddr 92:0D:C6:5E:32:18
BROADCAST MASTER MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
can0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
NOARP MTU:16 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:10
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Interrupt:36
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
sit0 Link encap:IPv6-in-IPv4
NOARP MTU:1480 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: bond0: <BROADCAST,MULTICAST,MASTER> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 92:0d:c6:5e:32:18 brd ff:ff:ff:ff:ff:ff
3: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN mode DEFAULT group default qlen 10
link/can
4: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/sit 0.0.0.0 brd 0.0.0.0
#
# ip link set can0 type can loopback on
#
# ip link show can0
3: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN mode DEFAULT group default qlen 10
link/can
#
# ip link set can0 up type can bitrate 1000000
[ 450.113274] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
#
#
# ifconfig can0
can0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
UP RUNNING NOARP MTU:16 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:10
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Interrupt:36
# candump can0 &
#
#
# ip link show can0
3: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can
# cansend can0 123#1122334455667788
can0 123 [8] 11 22 33 44 55 66 77 88
can0 123 [8] 11 22 33 44 55 66 77 88
#
#
# cansend can0 123#1234123412341234
can0 123 [8] 12 34 12 34 12 34 12 34
can0 123 [8] 12 34 12 34 12 34 12 34
#
Two DUT test
Following example is demostrated on Carrier boards(pcb8309).
- On Sender DUT
-
-
Set bitrate of
can0interface. -
Check if
can0interface is up. -
Use
cansendto send message on CAN bus.
-
# ifconfig can0
can0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
NOARP MTU:16 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:10
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Interrupt:36
#
# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: bond0: <BROADCAST,MULTICAST,MASTER> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 5e:a3:1f:b8:c5:e3 brd ff:ff:ff:ff:ff:ff
3: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN mode DEFAULT group default qlen 10
link/can
4: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether fe:13:e4:88:b1:21 brd ff:ff:ff:ff:ff:ff
5: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether fe:13:e4:88:b1:22 brd ff:ff:ff:ff:ff:ff
6: eth2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether fe:13:e4:88:b1:23 brd ff:ff:ff:ff:ff:ff
7: eth3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether fe:13:e4:88:b1:24 brd ff:ff:ff:ff:ff:ff
8: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/sit 0.0.0.0 brd 0.0.0.0
#
# ip link set can0 up type can bitrate 1000000
[ 1282.198583] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
# ip link show can0
3: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can
#
# cansend can0 5A1#11.22.33.44.55.66.77.88
#
# cansend can0 123#1122334455667788
#
# ifconfig can0
can0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
UP RUNNING NOARP MTU:16 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:10
RX bytes:0 (0.0 B) TX bytes:16 (16.0 B)
Interrupt:36
- On Receiver DUT
-
-
Set bitrate of
can0interface. -
Check if
can0interface is up. -
Use
candumpto receive message sent from Sender on CAN bus.
-
# ip link set can0 up type can bitrate 1000000
[ 174.322126] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
#
# ip link show can0
3: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can
#
#
# candump can0
can0 5A1 [8] 11 22 33 44 55 66 77 88
can0 123 [8] 11 22 33 44 55 66 77 88
^C#
# ifconfig can0
can0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
UP RUNNING NOARP MTU:16 Metric:1
RX packets:2 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:10
RX bytes:16 (16.0 B) TX bytes:0 (0.0 B)
Interrupt:36
Verify that message received on Receiver DUT is same as sent from Sender DUT.