Understanding CAN FD: From Theory to Production-Ready Implementation
A Guide to CAN Controllers, Transceivers, and Bus Configuration
Introduction
When our team at Hoomanely began developing iot devices for building a pet environment platform, we faced a critical challenge: transmitting high-resolution sensor data between multiple ECUs with microsecond-level timing precision were We needed CAN FD.
But here's the thing about CAN FD—it's not just "CAN, but faster." The jump to 8 Mbit/s data rates and 64-byte payloads requires understanding three interconnected layers: the CAN controller (protocol engine), the transceiver (physical layer interface), and the bus itself (differential signaling medium). Get one wrong, and your bus won't work. Get all three right, and you have a robust, deterministic communication backbone.
This guide distills embedded experience and real production debugging into a practical reference. You'll learn not just what CAN FD is, but how to configure it correctly the first time, with battle-tested code and concrete examples from our STM32H5 +MCP2517FD+ TJA1463 implementation.
What is CAN FD?
CAN FD (Controller Area Network with Flexible Data-rate) is the evolution of Classical CAN, designed to overcome two major limitations: payload size and bandwidth.
Evolution Comparison
| Feature | Classical CAN | CAN FD |
|---|---|---|
| Max Bitrate | 1 Mbit/s | 8 Mbit/s |
| Max Payload Size | 8 bytes | 64 bytes |
| CRC | 15 bits | Up to 21 bits |
| Real-World Impact | Fragmented, high latency | Atomic, low-latency communication |
Real-World Impact at Hoomanely
Our platform uses CAN FD to stream camera metadata (timestamps, exposure settings, calibration data) alongside LiDAR point cloud summaries to a central fusion ECU. With CAN FD's 64-byte payload, it's a single atomic message—reducing latency and eliminating reassembly bugs.
Key Insight: CAN FD isn't about raw speed alone. It's about atomic message integrity and reduced bus arbitration overhead.
The Three-Layer Stack: How CAN FD Really Works
Think of CAN FD as a three-layer system where each component has a distinct job:

Why This Matters:
- Controller bugs: Manifest as timing errors, incorrect CRC, or arbitration failures
- Transceiver bugs: Manifest as no bus activity, thermal shutdowns, or mode control issues
- Bus bugs: Manifest as reflections, impedance mismatches, or EMI-induced errors
Most debugging time is spent at boundaries: Controller→Transceiver timing, Transceiver→Bus impedance matching.
Layer 1: The CAN Controller Deep Dive
Core Responsibilities
The CAN controller is a hardware state machine implementing the ISO 11898-1:2015 protocol. Key functions:
- Bit Timing & Sampling
- Divides each bit into time quanta (tq)
- Defines sample point location (typically 75-87.5% of bit time)
- Adjusts phase with Synchronization Jump Width (SJW)
- Arbitration (CSMA/CD)
- Monitors bus during transmission
- Loses arbitration gracefully (transmitter becomes receiver)
- Dominant bit (0) overwrites recessive bit (1)
- Bit Stuffing
- Inserts complement bit after 5 consecutive identical bits
- Maintains clock synchronization across nodes
- Automatic destuffing on receive
- CRC Calculation
For engineers implementing custom CAN FD stacks, it's important to note that CAN FD uses different CRC polynomials and calculates CRC over bit-stuffed data fields. The CRC length and polynomial vary by payload size (17-bit for ≤16 bytes, 21-bit for >16 bytes). Proper handling of CRC with bit stuffing and frame delimiters is critical for reliable frame validation.
- 17-bit CRC for payloads ≤16 bytes
- 21-bit CRC for payloads >16 bytes
- Polynomial: x²¹ + x¹⁹ + x¹⁸ + x¹⁷ + x¹⁶ + ... (ISO 11898-1:2015)
- Error Detection
- Bit error (read ≠ transmitted)
- Stuff error (>5 consecutive identical bits)
- CRC error (received CRC ≠ calculated CRC)
- Form error (fixed-format fields violated)
- ACK error (no ACK from any receiver)
- TX/RX Buffering
- Decouples application timing from bus timing
- FIFO or priority-based queues
- Prevents message loss during burst traffic
Bit Timing: The Critical Math
Every CAN FD bit is divided into time quanta (tq). The bit structure:
1 bit = Sync_Seg + Prop_Seg + Phase_Seg1 + Phase_Seg2
Where:
- Sync_Seg = 1 tq (always fixed)
- Prop_Seg = Propagation delay (cable + transceiver)
- Phase_Seg1 = First phase buffer
- Phase_Seg2 = Second phase buffer
- SJW (Synchronization Jump Width) = Max phase adjustmentSample point location:
Sample Point (%) = (Sync_Seg + Prop_Seg + Phase_Seg1) / Total_bit_time × 100%Many modern CAN controllers implement automatic resynchronization to compensate for minor oscillator drift, improving bit timing stability in multi-node networks. However, this does not fully eliminate the need for precise clock source selection and manual bit timing validation with measurement equipment, especially when using RC oscillators or mixed clock domains.
Design targets:
- Nominal phase (arbitration): Sample point at 75-80%
- Data phase (high-speed payload): Sample point at 80-87.5%
- SJW: Typically 1-2 tq (allows minor clock drift correction)
Transmit Delay Compensation (TDC)
The Problem:
At high bitrates (>2 Mbit/s), the transceiver loop delay (TXD → CANH/CANL → RXD) becomes significant relative to the bit time:
Example at 5 Mbit/s:
- Bit time = 200ns
- Typical transceiver delay = 120ns
- Delay = 60% of bit time!If the controller samples RXD at the normal sample point (87.5%), it's sampling its own delayed transmission instead of the bus state. This causes false bit errors.
The Solution: Secondary Sample Point (SSP)
TDC introduces a secondary sample point during transmission that accounts for the loop delay:
SSP = Sample_Point + TDC_Offset
Where TDC_Offset compensates for transceiver delayMeasuring TDC Offset (Oscilloscope method):
- Set up dual-channel scope:
- CH1: TXD (controller output)
- CH2: RXD (controller input)
- Transmit test frame at target bitrate (e.g., 5 Mbit/s)
- Measure edge delay:
TXD edge (falling) → RXD edge (falling) = Loop_delay_ns- Convert to tq units:
TDC_Offset_tq = Loop_delay_ns / tq_period_nsExample measurement:
Loop delay measured = 125ns
tq period = 12.5ns (at 80 MHz FDCAN clock with DBRP=1)
TDC_Offset = 125ns / 12.5ns = 10 tqCAN Transceiver Deep Dive
Core Responsibilities
The transceiver bridges the digital (controller) and analog (bus) worlds:
- Differential Driver
- Converts TXD (3.3V logic) to CANH/CANL differential pair
- Dominant bit: CANH=3.5V, CANL=1.5V (Vdiff=+2V)
- Recessive bit: CANH=2.5V, CANL=2.5V (Vdiff=0V)
- Differential Receiver
- Converts CANH/CANL differential voltage to RXD logic
- Threshold typically ±0.9V (hysteresis for noise immunity)
- ESD Protection
- Protects internal circuits from electrostatic discharge
- Typical rating: ±8 kV contact discharge (IEC 61000-4-2)
- Fault Detection
- Thermal shutdown (Tj > 165°C)
- Short circuit detection (CANH/CANL shorted)
- Open load detection (no termination)
- Under voltage lockout (UVLO)
- Mode Control
- Sleep: Lowest power (~100 µA), no bus monitoring
- Standby: Wake-capable (~5 mA), RXD monitoring only
- Normal: Full TX/RX operation (~50 mA)
- (Some models) Listen-only: RX without ACK transmission
- Loop Delay Symmetry
- TXD→CANH/CANL delay (transmit delay)
- CANH/CANL→RXD delay (receive delay)
- Critical for TDC: Asymmetry should be <20ns
Case Study: NXP TJA1463
Why we chose TJA1463 for HCAM1:
Unlike SPI-controlled transceivers TJA1463 uses simple GPIO pins:
| Mode | EN Pin | STB_N Pin | Current Draw | Use Case |
|---|---|---|---|---|
| Sleep | X | LOW | 100 µA | System off, no wake needed |
| Standby | LOW | HIGH | 5 mA | Wake-capable, monitoring RXD |
| Normal | HIGH | HIGH | 50 mA | Full TX/RX operation |
| Listen-Only | LOW | HIGH + special | 5 mA | Bus monitoring/sniffing |
Note on Listen-Only Mode: Some CAN transceivers, including the TJA1463, require specific hardware pin configurations or controller support for listen-only operation. This mode might not be enabled merely by setting GPIO pins live; instead, it sometimes needs controller filter configuration and dedicated hardware setup on startup to avoid transmitting ACK signals or errors during bus monitoring.
Critical Timing Requirements (from TJA1463 datasheet Rev 5.1):
- t_startup: >1.5 ms after VBAT power-up before first mode change
- t_moch: <50 µs for mode transitions (Normal ↔ Standby ↔ Sleep)
- t_gotosleep: >24 µs with EN=HIGH, STB_N=LOW to enter Sleep
- t_silent: <2 µs after mode change for bus to settle
Common Transceiver Issues & Root Causes
| Problem | Symptom | Root Cause | Solution |
|---|---|---|---|
| No bus activity | FDCAN TX successful, but CANH/CANL idle | Transceiver stuck in Sleep/Standby | Verify EN=HIGH, STB_N=HIGH for Normal mode |
| ERR_N constantly LOW | GPIO reads 0 | Thermal shutdown or short circuit | Check bus termination (should be 60Ω); add heat sink if Tj>125°C |
| Intermittent TX | Random message loss | Incomplete mode transitions | Add 10ms delays after GPIO changes |
| High bit errors | CRC failures | VIO mismatch with MCU | Set TJA1463 VIO pin = MCU I/O voltage (1.8V for STM32H5 low-power mode) |
| Bus-Off after minutes | Controller enters Bus-Off state | Thermal drift in loop delay | Enable TJA1463 SIC; verify TDC filter window |
Why Differential Signaling?
CAN uses differential signaling where data is encoded in the voltage difference between CANH and CANL, not absolute voltage levels. This provides three critical advantages:
- Common-Mode Noise Rejection
- EMI, ground bounce, and power supply noise affect both wires equally
- Differential receiver subtracts common-mode voltage: V_diff = V_CANH - V_CANL
- Noise cancels out: (V_signal + V_noise) - (V_signal + V_noise) = 0
- No Ground Reference Required
- Voltage measured between wires, not to chassis ground
- Eliminates ground loop issues in multi-ECU systems
- Allows long cable runs without ground offset problems
- Extended Cable Length
- Lower signal swing (±2V vs. ±5V for single-ended) reduces EMI emissions
- Twisted pair construction cancels magnetic field coupling
- Achievable distances: 40m @ 1 Mbit/s, 1 km @ 50 kbit/s
Transmission Line Theory: Why 120Ω?
A CAN bus is a transmission line—a long conductor where signal propagation delay is significant relative to bit time. Without proper termination, reflections cause:
- Ringing (oscillations on edges)
- False bit detection (receiver interprets reflection as bit transition)
- Reduced noise margins
Characteristic impedance (Z₀): For twisted pair cable, Z₀ depends on geometry:
Z₀ = (L/C)^0.5
Where:
L = inductance per unit length (~500 nH/m)
C = capacitance per unit length (~50 pF/m)
→ Z₀ ≈ 120Ω (typical for CAN cable)Termination requirement: Place a resistor equal to Z₀ at both ends of the bus (not at every node!):
ECU1 ----[120Ω]----+---- bus ----+----[120Ω]---- ECU2
| |
ECU3 ECU4
(stub) (stub)Total resistance measured across CANH-CANL:
Two 120Ω in parallel = 60ΩVerification procedure:
- Power off all ECUs
- Measure CANH-CANL resistance with DMM
- Expected: 60Ω ±5%
- If 120Ω: Missing one terminator
- If 40Ω: Three terminators (remove one)
- If open circuit: No terminators or broken bus
Systematic Debugging Guide
Scenario 1: "I send messages but nothing appears on the bus"
Symptoms:
- FDCAN transmit buffer empties (TX successful flag set)
- Oscilloscope shows no activity on CANH/CANL
- No errors reported by controller
- ERR_N pin may or may not be asserted
Root Causes (in order of likelihood):
- Transceiver stuck in Sleep/Standby mode (80% of cases)
- VIO mismatch (10% of cases)
- Disconnected TXD/RXD traces (5% of cases)
- Missing transceiver power (5% of cases
Scenario 2: "High bit error rate and Bus-Off states"
Symptoms:
- CRC errors in received frames (visible in PSR register)
- Transmit Error Counter (TEC) climbing rapidly (>96)
- Controller enters Bus-Off state (stops all communication)
- Intermittent message loss
Root Causes:
- Incorrect bit timing (50% of cases)
- Sample point too early/late
- Missing TDC configuration
- Clock frequency mismatch
- Termination problems (30% of cases)
- Missing terminator (120Ω instead of 60Ω)
- Extra terminator (40Ω instead of 60Ω)
- Wrong resistor value (e.g., 100Ω or 150Ω)
- Cable too long for bitrate (15% of cases)
- Propagation delay exceeds bit time margin
- Stub length >30cm causing reflections
- EMI/noise coupling (5% of cases)
- Unshielded cable in noisy environment
- Ground loop issues
Scenario 3: "Intermittent communication failures"
Symptoms:
- Communication works for minutes/hours, then stops
- Random message loss (no consistent pattern)
- ERR_N pin occasionally asserts then clears
- Errors correlate with temperature changes or mechanical vibration
Root Causes:
- Thermal issues (40% of cases)
- Transceiver junction temperature exceeds 125°C
- Inadequate PCB copper or airflow
- High ambient temperature (-40°C to +85°C automotive)
- Power supply problems (30% of cases)
- VCC/VBAT drooping during high current events
- Insufficient bulk capacitance
- Ground bounce on digital supply
- Connector intermittency (20% of cases)
- Loose crimp connections
- Vibration-induced disconnects
- Corrosion on terminals
- EMI coupling (10% of cases)
- Inadequate cable shielding
- Ground loops in multi-ECU systems
- Switching noise from DC-DC converters
Battle-Tested Lessons from the Field
Measure Before You Trust
The Problem: Calculated bit timing looks correct on paper, but bus communication fails intermittently at high bitrates.
The Lesson: Clock sources have tolerance (±1-2% for crystal, ±3-5% for RC oscillator). This affects bit timing accuracy.
What We Do:
- Verify clock with frequency counter (not just oscilloscope FFT)
- Measure actual bit width on RXD pin with 100 MHz+ scope
- Calculate error:
(Measured - Expected) / Expected × 100% - Adjust if error >2% (may need different prescaler or clock source)
Example:
Expected bit time @ 5 Mbit/s: 200ns
Measured bit time: 204ns
Error: +2% → Acceptable (within ±2.5% ISO 11898-1 tolerance)
If measured 210ns:
Error: +5% → FAIL—recalculate with actual clock frequencyTransceiver Mode Control is Critical
The Problem: Spent 2 days debugging "no bus output" before discovering transceiver was in Standby mode despite correct FDCAN configuration.
The Lesson: The FDCAN controller can transmit perfectly, but if the transceiver isn't in Normal mode, nothing reaches the bus.
What We Do:
- Always verify GPIO states before blaming controller
- Add diagnostic functions that print EN/STB_N/ERR_N pin states
- Use 10ms delays after mode changes (datasheet says 50µs, but PCB parasitics matter)
- Monitor ERR_N pin in main loop for hardware faults
Production Checklist:
Before starting FDCAN peripheral:
☑ TJA1463_Init() called with 10ms power-on delay
☑ Transceiver in Standby mode
☑ ERR_N pin not asserted (GPIO reads HIGH)
Before transmitting:
☑ TJA1463_SetMode(NORMAL) called
☑ 50ms delay for bus stabilization
☑ ERR_N still not assertedConclusion
CAN FD is not "CAN, but faster." It's a carefully engineered evolution that requires understanding three interdependent layers:
- Controller (Protocol Engine): Bit timing, arbitration, error detection, TDC
- Transceiver (Physical Interface): Mode control, loop delay, fault detection
- Bus (Transmission Line): Impedance matching, termination, topology
Key Success Factors:
✓ Measure, don't assume: Verify bit timing with oscilloscope
✓ Mode control matters: Transceiver must be in Normal mode for TX
✓ DLC is non-linear: Use lookup table for >8 byte payloads
✓ Layer boundaries hide bugs: Monitor controller, transceiver, and bus independently
✓ Test incrementally: Loopback → Single node → Multi-node
✓ TDC is mandatory: At >2 Mbit/s, loop delay compensation required
✓ Real-world limits: Use 50-70% of theoretical max bus length/bitrate
✓ EMI is real: Twisted pair + shielding.
Resources & References
Datasheets & Standards:
- STM32H5 Reference Manual (RM0481) - FDCAN chapter
- NXP TJA1463 Datasheet Rev. 5.1
- ISO 11898-1:2015 - CAN FD specification
- Bosch CAN FD Specification v1.0 (April 2012)
Application Notes:
- AN5348: STM32H5 FDCAN configuration (ST Microelectronics)
- AN13606: TJA1463 design guidelines (NXP)
Recommended Tools:
- Oscilloscope: ≥100 MHz bandwidth, 1 GSa/s (for 5 Mbit/s analysis)
- CAN Analyzer: Kvaser Leaf Pro HS v2, PEAK PCAN-USB FD, Intrepid neoVI
- Multimeter: For termination verification (±0.1Ω resolution)
Author's Note
This guide is the reference I wish I'd had when starting with CAN FD. If it saves you even one week of oscilloscope-induced headaches, it's been worth writing.
Questions? Connect with me on LinkedIn or visit hoomanely.com to learn more about our platform.
Found this helpful? Share it with your embedded systems network.