serial-bench / CAN / msg #9
A short 1 Mbit/s segment - six nodes, under ten metres, properly terminated this time - logged a trickle of errors that only two of the six nodes reported, and only when traffic was heavy. Nothing in the termination story fit: the reflections were gone. The disagreement was about when, within the bit, each node decided it was looking at a one or a zero.
A CAN controller does not sample at the middle of a bit. It chops the bit into a whole number of time quanta and places a single sample point some way into it, after enough quanta have passed for the signal to settle and for the controller to have resynchronised to the last edge it saw. Where that point sits is a configuration choice, and two parts from two vendors had been left on their defaults.
One bit at 1 Mbit/s is 1000 ns. Inside it the controller runs a prescaled clock that
produces time quanta (Tq), and the bit is SYNC (1 Tq) + TSEG1 + TSEG2. The sample
point falls at the boundary between TSEG1 and TSEG2, so its position as a fraction of the bit
is (1 + TSEG1) / (1 + TSEG1 + TSEG2). Resynchronisation can stretch TSEG1 or
shorten TSEG2 by up to the synchronisation jump width (SJW) on each edge, which is how two
free-running oscillators stay locked to each other.
Node A was a controller clocked at 16 MHz with a prescaler of 1: 16 Tq per bit, laid out as
1 + 13 + 2, so it sampled at 14/16 = 87.5 %. Node B was a different part clocked at
40 MHz with a prescaler of 2: 20 Tq per bit, laid out 1 + 14 + 5, sampling at
15/20 = 75 %. Both are legal, both produce exactly 1 Mbit/s, and they sample the
same bit 125 ns apart.
A node resynchronises on each recessive-to-dominant edge by nudging its own bit boundary, but only by up to the SJW, and only on edges - and a long run of same-value bits gives no edges. CAN stuffs a bit after five identical ones, so the worst case is ten bit times between usable edges. Over those ten bits each oscillator drifts, and the combined drift has to stay inside the shorter of the two phase segments or a node samples in the wrong bit.
When both nodes sample at the same fraction, the whole of their phase-segment budget is available to absorb that drift. When they sample 12.5 % of a bit apart, that 125 ns is spent before the oscillators have done anything, and node B - whose TSEG2 of 5 Tq is 250 ns - had half its reverse margin gone at rest. Add two crystals at the edges of their ±0.3 % tolerance and a run of ten bits, and the far pair of nodes crossed the line under load, which is exactly when frames are long and edges are scarce.
| Bit rate | Prescaler | Tq | Tq/bit | TSEG1 | TSEG2 | Sample | SJW |
|---|---|---|---|---|---|---|---|
| 125 kbit/s | 20 | 500 ns | 16 | 13 | 2 | 87.5 % | 2 |
| 250 kbit/s | 10 | 250 ns | 16 | 13 | 2 | 87.5 % | 2 |
| 500 kbit/s | 5 | 125 ns | 16 | 13 | 2 | 87.5 % | 2 |
| 1 Mbit/s | 5 | 125 ns | 8 | 6 | 1 | 87.5 % | 1 |
The last row is the awkward one. At 40 MHz a 1 Mbit/s bit is only eight quanta, so TSEG2 is a single quantum and SJW can only be 1. That is a coarse bit, and it is the real argument for clocking a 1 Mbit/s node from a frequency that divides into more quanta - 16 or 20 MHz gives 16 or 20 Tq and room for a larger jump width. Node B's 40 MHz part was not the villain; leaving its default 75 % layout on a bus where everyone else sat at 87.5 % was.
I could not read the sample point off the wire directly - it is an internal decision - so I inferred it. With the scope on CAN-H minus CAN-L through the differential probe I measured the recessive-to-dominant edge and the point at which each node started driving its acknowledgement, which is referenced to its own sample clock. The two acknowledging nodes drove the ACK slot 124 ns apart, ±8 ns over 50 frames, which agrees with the 125 ns the configuration predicts to within my analyser's quantisation. That is corroboration, not proof: I am reading a consequence of the sample point, not the sample point itself.
The rule I took away: a sample point is not right or wrong on its own, it is right or wrong relative to the rest of the bus. Before adding a node, read back TSEG1, TSEG2 and the prescaler from every controller already on the segment and make the sample fractions match. CiA recommends 87.5 % precisely so that «match the others» has a default answer.