Advanced CAN-FD Debugging: Solving Transceiver Mysteries
Debugging CAN-FD implementations on modern microcontrollers takes more than checking bit timings and error counters. When integrating automotive-grade transceivers with high-performance MCUs, subtle hardware-software interactions can create elusive failure modes: intermittent frame losses, unexpected fault conditions, and mode transition failures.
The challenge: silent failures in production-ready systems
Our multi-sensor edge computing platform hit a real reliability issue: intermittent CAN-FD frame transmission failures that only occurred under high-load conditions. The system combined camera capture, thermal imaging, and proximity sensing, all coordinated via a CAN-FD network running at aggressive data rates to meet real-time processing requirements.
The symptoms were genuinely confusing. Frames appeared to transmit successfully with no FDCAN errors reported. Oscilloscope traces showed silence on the bus during these "successful" transmissions. Error recovery mechanisms triggered sporadically with no clear pattern. And high-load scenarios above roughly 2000 messages per second caused bus-off conditions.
Hardware foundation
The implementation centers on an STM32H562AII6 paired with a CAN-FD transceiver, targeting a 1 Mbit/s nominal rate for reliable arbitration, a 5 Mbit/s data phase for high-throughput sensor data, -40°C to +85°C operation, and industrial reliability with well under 0.01% frame loss.
The transceiver needs precise GPIO control for mode management, unlike simpler transceivers that run in fixed modes:

typedef enum {
TRANSCEIVER_MODE_SLEEP = 0, // Minimal power consumption
TRANSCEIVER_MODE_STANDBY = 1, // Wake-capable, low power
TRANSCEIVER_MODE_LISTEN = 2, // Receive-only operation
TRANSCEIVER_MODE_NORMAL = 3 // Full transceiver operation
} TransceiverMode_t;
static HAL_StatusTypeDef SetTransceiverMode(TransceiverMode_t mode) {
GPIO_PinState stb_pin = GPIO_PIN_SET;
GPIO_PinState en_pin = GPIO_PIN_RESET;
switch (mode) {
case TRANSCEIVER_MODE_NORMAL:
stb_pin = GPIO_PIN_SET; en_pin = GPIO_PIN_SET; break;
case TRANSCEIVER_MODE_LISTEN:
stb_pin = GPIO_PIN_SET; en_pin = GPIO_PIN_RESET; break;
case TRANSCEIVER_MODE_STANDBY:
stb_pin = GPIO_PIN_RESET; en_pin = GPIO_PIN_RESET; break;
case TRANSCEIVER_MODE_SLEEP:
stb_pin = GPIO_PIN_RESET; en_pin = GPIO_PIN_SET;
HAL_Delay(1); // Datasheet-mandated transition delay
break;
}
HAL_GPIO_WritePin(STB_GPIO_Port, STB_Pin, stb_pin);
HAL_GPIO_WritePin(EN_GPIO_Port, EN_Pin, en_pin);
HAL_Delay(10); // Mode stabilization period
return HAL_OK;
}The key insight: atomic GPIO operations with mandatory timing delays prevent transceiver state machine corruption during mode transitions.
Systematic debugging methodology
Phase 1: hardware signal integrity. Oscilloscope analysis revealed signal integrity degradation at high data rates, the original 5 Mbit/s target suffered reflection artifacts causing intermittent bit errors. We settled on conservative timing with increased sample point margins and enabled transceiver delay compensation:

// STM32H5 FDCAN Configuration - Production Optimized
hfdcan1.Init.NominalPrescaler = 16; // 250 MHz / 16 = 15.625 MHz tq
hfdcan1.Init.NominalTimeSeg1 = 13; // Sample point = 87.5%
hfdcan1.Init.NominalTimeSeg2 = 2;
hfdcan1.Init.NominalSyncJumpWidth = 1;
hfdcan1.Init.DataPrescaler = 5; // 250 MHz / 5 = 50 MHz tq
hfdcan1.Init.DataTimeSeg1 = 10; // Sample point = 73%
hfdcan1.Init.DataTimeSeg2 = 4;
hfdcan1.Init.DataSyncJumpWidth = 4; // Maximum tolerance
// Critical: Enable Transceiver Delay Compensation
hfdcan1.Init.TxDelayCompensation = ENABLE;
hfdcan1.Init.TxDelayCompensationOffset = 0x40; // Measured loop delayPhase 2: transceiver state management. The second breakthrough was understanding that the transceiver maintains independent state machines for system control and CAN protocol handling. Improper initialization left the transceiver in undefined states. Mode transitions have to follow datasheet timing precisely, with hardware fault monitoring:
static bool CheckTransceiverFault(void) {
return (HAL_GPIO_ReadPin(FAULT_GPIO_Port, FAULT_Pin) == GPIO_PIN_RESET);
}
int InitializeTransceiverSequence(void) {
// Step 1: Reset to known state
SetTransceiverMode(TRANSCEIVER_MODE_SLEEP);
HAL_Delay(2);
// Step 2: Configure FDCAN peripheral
if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK) return -1;
// Step 3: Enable interrupts and filters
ConfigureFDCANFilters();
HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE);
// Step 4: Start peripheral then activate transceiver
HAL_FDCAN_Start(&hfdcan1);
SetTransceiverMode(TRANSCEIVER_MODE_NORMAL);
HAL_Delay(50);
// Step 5: Verify successful initialization
return CheckTransceiverFault() ? -1 : 0;
}Advanced error handling architecture
A three-tier error detection system combines FDCAN hardware monitoring, transceiver fault signaling, and application-level validation. RX FIFO overflow gets handled by draining and discarding pending messages while incrementing an overflow counter, rather than letting the buffer corrupt:

if (RxFifo0ITs & FDCAN_IT_RX_FIFO0_FULL) {
while (HAL_FDCAN_GetRxFifoFillLevel(hfdcan, FDCAN_RX_FIFO0) > 0) {
FDCAN_RxHeaderTypeDef discardHeader;
uint8_t discardData[64];
HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &discardHeader, discardData);
}
IncrementOverflowCounter();
}Bus-off recovery needs coordination between the FDCAN controller and the transceiver: stop the controller, drop the transceiver to standby, wait out a bus idle period, then restart both fresh:
void HandleFDCANError(void) {
uint32_t ecr = hfdcan1.Instance->ECR;
uint32_t txErrorCount = ecr & 0xFF;
uint32_t rxErrorCount = (ecr >> 8) & 0x7F;
if (hfdcan1.Instance->PSR & FDCAN_PSR_BO) {
HAL_FDCAN_Stop(&hfdcan1);
SetTransceiverMode(TRANSCEIVER_MODE_STANDBY);
HAL_Delay(100);
SetTransceiverMode(TRANSCEIVER_MODE_NORMAL);
HAL_FDCAN_Start(&hfdcan1);
LogErrorRecovery(txErrorCount, rxErrorCount);
}
}CAN-FD payload optimization
CAN-FD's non-linear DLC mapping needs careful payload size handling:
static uint8_t DecodeFDCANDLC(uint32_t dlc) {
const uint8_t dlcMap[16] = {0,1,2,3,4,5,6,7,8,12,16,20,24,32,48,64};
return (dlc <= 15) ? dlcMap[dlc] : 8; // Safe fallback
}Choosing the most efficient DLC for a given payload size reduces bus utilization by roughly 15 to 20% for typical sensor payloads while staying protocol-compliant.
Production validation
The optimized implementation delivered clear, measurable gains. Moving from an unstable 5 Mbps data phase to a stable 3.33 Mbps dropped frame loss at 2k msg/s from 3.2% down to a fraction of a thousandth of a percent. CPU ISR overhead dropped from 85% to 15%. Mode transition time went from undefined to a guaranteed 10ms, and error recovery time dropped from over a second to about 150ms.
Extended validation included 72 hours of continuous stress testing with over a million CAN-FD frames transmitted without CRC errors, temperature cycling from -40°C to +85°C during operation, EMC compliance testing with production cable harnesses, and power supply variation testing under maximum load.
Key implementation insights
Timing precision is critical, transceivers need strict adherence to datasheet timing specs, and conservative margins ensure reliable operation across environmental extremes. State machine coordination matters, since modern transceivers maintain independent control and protocol state machines, and initialization has to account for both hardware reset timing and protocol readiness. Error recovery strategy needs multiple layers, FDCAN monitoring, GPIO fault signaling, and application validation together give comprehensive coverage without a performance penalty. Signal integrity validation with an oscilloscope is essential for production reliability at high CAN-FD speeds. And comprehensive stress testing under real environmental conditions reveals failure modes invisible on the bench.
Why it matters at Hoomanely
This CAN-FD implementation enables reliable sensor data communication in our pet healthcare monitoring systems. The robust networking supports real-time coordination between multiple sensors, cameras, and processing units, critical infrastructure for delivering the precise health insights that help pet owners detect issues early.