The bus-topology is like this. The CAN-bus has termination resistor at the inverter and in the Waveshare USB/CAN dongle.
┌─────────┐ ┌─────────┐ ┌─────────┐
│Waveshare│ │OPi5 Plus│ │ │
│ USB/CAN │◀────────▶│ can1 │◀────────▶│Inverter │
│ │ │ │ │ │
└─────────┘ └─────────┘ └─────────┘
Bus properties The bus-speed is dictated by the inverter, 250 kbit/s.
can1
is configured like this
# ip -d link show dev can1
5: can1: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can promiscuity 0 minmtu 0 maxmtu 0
can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 1
bitrate 250000 sample-point 0.871
tq 30 prop-seg 57 phase-seg1 57 phase-seg2 17 sjw 1
rockchip_canfd: tseg1 1..128 tseg2 1..128 sjw 1..128 brp 1..256 brp-inc 2
clock 198000000 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
Commands used to bring up can1
are
ip link set can1 type can bitrate 250000
ip link set can1 up
i.e. all but bit-rate is kept at default values. listen-only
mode is verified to be off
.
What works
Receiving CAN-frames works as expected
# candump can1
can1 1801F150 [8] 08 04 00 00 00 00 F0 93
can1 1801F150 [8] 09 04 00 00 00 00 F1 42
Sending/receiving frames when can1
is put into loopback mode.
What doesn't work
Sending frames over the CAN bus.
Verification that transmission fails is done both by sniffing the CAN-bus with the Waveshare USB/CAN dongle and by monitoring Linux counters.
The TX queue for can1
fills up quite fast, for example by using cangen
# cangen can1
write: No buffer space available
The error is displayed after 2 seconds, i.e. after 10 messages is queued for transmission.
# ip -s -d link show dev can1
5: can1: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10
link/can promiscuity 0 minmtu 0 maxmtu 0
can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 1
bitrate 250000 sample-point 0.871
tq 30 prop-seg 57 phase-seg1 57 phase-seg2 17 sjw 1
rockchip_canfd: tseg1 1..128 tseg2 1..128 sjw 1..128 brp 1..256 brp-inc 2
clock 198000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
12 0 0 17 18 12 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
RX: bytes packets errors dropped missed mcast
14545088 1818136 0 0 0 0
TX: bytes packets errors dropped carrier collsns
0 0 0 17 0 0
After some time elapses, error-warn
counter and error-pass
will be incremented by 1 and dropped
is incremented by 1 and all queued packets seems to be dropped.
One thing I noticed is that the interrupt counter and RX-packets
counter is incremented as expected after the interface is brought down and then up. But the both those counters are incremented very fast, >1000 times per second, after calling cansend
and packets are queued for transmission.
This behaviour persists for some time, then goes back to normal. Nothing seems to be received while in this "increasing counters very fast" state.
Also tested with can0
interface on the RPi5 Plus, same behaviour.
Anyone have an idea what could be wrong? It's frustrating that the RX path works as expected, but not the TX one.
Edit: found this one, CAN support for Arduino.
Orange Pi 5 labels the CAN-pins CAN1_RX_M0
and CAN1_TX_M0
. TX/RX is also used in the picture above from the control-chip, but CAN uses differential pairs which are labelled CANH
and CANL
above.
Answer
Found the answer to my own question, the two CAN-ports on the Orange Pi 5 Plus is only the controller. One has to add an external transceiver-chip!
Kind of annoying that reception just worked "good enough" when adding the OPi5 to an existing CAN-bus...