Hi NXP Community,
I'm currently working on enabling CAN FD (no BRS) reception using FlexCAN0 on S32K144. I have successfully configured Classic CAN for both standard and extended IDs, and it works as expected.
However, when switching to CAN FD with BRS = 0, I am unable to receive messages for extended IDs 0x7E0 and 0x7DF. Here's a summary of what I’ve done:
Configuration Details:
FD Mode Enabled (CTRL2.ISOCANFDEN = 1)
BRS Disabled via frame format, but FDCTRL.FDRATE = 1 (still OK per spec)
Message Buffers 4 and 5 configured to receive extended IDs 0x7E0 and 0x7DF
Bit Timing (Nominal = 500 kbps, Data = 2 Mbps)
CBT & FDCBT used for CAN FD mode (via FD features)
What Works:
Issue:
When trying to receive CAN FD frames with BRS = 0, no interrupt or flag is triggered, and nothing is received in MB4/MB5.
Code :
void FLEXCAN0_init(void)
{
#define MSG_BUF_SIZE 18 /* Msg Buffer Size: 2 header + 2 data = 4 words */
uint32_t i = 0;
/* Enable clock to FlexCAN0 */
PCC->PCCn[PCC_FlexCAN0_INDEX] |= PCC_PCCn_CGC_MASK;
/* Enable FD support and allow configuration via CBT */
CAN0->MCR |= CAN_MCR_MDIS_MASK; // Disable module
CAN0->CTRL1 &= ~CAN_CTRL1_CLKSRC_MASK; // CLKsrc=0: Clock Source = SOSCDIV2 (8 MHz)
CAN0->MCR &= ~CAN_MCR_MDIS_MASK; // Enable module (enter Freeze mode)
while (!((CAN0->MCR & CAN_MCR_FRZACK_MASK) >> CAN_MCR_FRZACK_SHIFT)) {}
/* Configure nominal phase: 500 kbps */
CAN0->CBT = CAN_CBT_EPSEG2(12) // EPSEG2 = 12
| CAN_CBT_EPSEG1(18) // EPSEG1 = 18
| CAN_CBT_EPROPSEG(46) // EPROPSEG = 46
| CAN_CBT_ERJW(12); // ERJW = 12
/* Configure data phase: 2 Mbps */
CAN0->FDCBT = CAN_CBT_EPSEG2(3) // FPSEG2 = 3
| CAN_CBT_EPSEG1(7) // FPSEG1 = 7
| CAN_CBT_EPROPSEG(7) // FPROPSEG = 7
| CAN_CBT_ERJW(3); // FRJW = 3
/* Enable FD mode with TDC, 64-byte payload, BRS = 1 */
CAN0->FDCTRL = CAN_FDCTRL_FDRATE_MASK // BRS enabled
| CAN_FDCTRL_MBDSR0(3) // MB payload = 64 bytes
| CAN_FDCTRL_TDCEN_MASK // Transceiver delay compensation
| CAN_FDCTRL_TDCOFF(5); // TDC offset = 5
/* Clear all message buffers */
for (i = 0; i < 128; i++) {
CAN0->RAMn[i] = 0;
}
/* Enable all RXIMR filters */
for (i = 0; i < 16; i++) {
CAN0->RXIMR[i] = 0xFFFFFFFF;
}
CAN0->RXMGMASK = 0x1FFFFFFF;
/* MB4 -> Receive Extended ID 0x7E0 as CAN FD, no BRS */
CAN0->RAMn[4 * MSG_BUF_SIZE + 0] =
(4 << 24) // CODE = 0b0100 (Rx Empty)
| (1 << 21) // IDE = 1 (Extended ID)
| (1 << 20); // EDL = 1 (CAN FD Frame, BRS = 0)
CAN0->RAMn[4 * MSG_BUF_SIZE + 1] = 0x1F800000; // ID = 0x7E0
/* MB5 -> Receive Extended ID 0x7DF as CAN FD, no BRS */
CAN0->RAMn[5 * MSG_BUF_SIZE + 0] =
(4 << 24) // CODE = 0b0100 (Rx Empty)
| (1 << 21) // IDE = 1 (Extended ID)
| (1 << 20); // EDL = 1 (CAN FD Frame, BRS = 0)
CAN0->RAMn[5 * MSG_BUF_SIZE + 1] = 0x1FA00000; // ID = 0x7DF
/* Enable ISO CAN FD CRC support */
CAN0->CTRL2 |= CAN_CTRL2_ISOCANFDEN_MASK;
/* Exit freeze mode */
CAN0->MCR = 0x0000081F;
while ((CAN0->MCR & CAN_MCR_FRZACK_MASK) >> CAN_MCR_FRZACK_SHIFT) {}
while ((CAN0->MCR & CAN_MCR_NOTRDY_MASK) >> CAN_MCR_NOTRDY_SHIFT) {}
}
My Questions:
Is additional configuration required to receive CAN FD frames with BRS = 0?
Are there restrictions in FlexCAN that affect reception of FD frames without bit rate switching?
Does FDCTRL.FDRATE need to be set to 0 when BRS is not used?
How can I debug whether the message is being filtered or discarded?
Tools Used:
Thanks in advance for your help!
Best regards,
Prashanth Kumar M G