Hi,
I'm running the CAN FD DEMO on a S32K144 eval board.
I noticed this line of code :
CAN0->RAMn[ 4*MSG_BUF_SIZE + 0] = 0xC4000000; in the init routine never actually write to location it intends to write.
In other word using design studio embSysRegister view tab, that location is always read 0x00000000.
I don't know if this is by design or not .but I'm getting ERROR FRAMES.
USING CANALYZER I SEND A MESSAGE WITH ID 0X511 and it calls
FLEXCAN0_receive_msg ();
but populates it with wrong set of data however the ID is received correctly.
the line of code is from the following init routine in the demo example:
void FLEXCAN0_init(void) {
#define MSG_BUF_SIZE 18 /* Msg Buffer Size. (2 words hdr + 16 words data = 18 words) */
uint32_t i=0;
PCC->PCCn[PCC_FlexCAN0_INDEX] |= PCC_PCCn_CGC_MASK; /* CGC=1: enable clock to FlexCAN0 */
CAN0->MCR |= CAN_MCR_MDIS_MASK; /* MDIS=1: Disable module before selecting clock */
CAN0->CTRL1 |= CAN_CTRL1_CLKSRC_MASK; /* CLKSRC=1: Clock Source = BUSCLK (40 MHz) */
CAN0->MCR &= ~CAN_MCR_MDIS_MASK; /* MDIS=0; Enable module config. (Sets FRZ, HALT)*/
while (!((CAN0->MCR & CAN_MCR_FRZACK_MASK) >> CAN_MCR_FRZACK_SHIFT)) {}
/* Good practice: wait for FRZACK=1 on freeze mode entry/exit */
CAN0->CBT = 0x802FB9EF; /* Configure nominal phase: 500 KHz bit time, 40 MHz Sclock */
/* Prescaler = CANCLK / Sclock = 80 MHz / 40 MHz = 2 */
/* EPRESDIV = Prescaler - 1 = 2 - 1 = 1 */
/* EPSEG2 = 15 */
/* EPSEG1 = 15 */
/* EPROPSEG = 46 */
/* ERJW = 15 */
/* EPRESDIV= 3 CAN0->CBT= 0x80685CE7 koor*/
/* BITRATEn =Fcanclk /( [(1 + (EPSEG1+1) + (EPSEG2+1) + (EPROPSEG + 1)] x (EPRESDIV+1)) */
/* = 80 MHz /( [(1 + ( 15 +1) + ( 15 +1) + ( 46 + 1)] x ( 1 +1)) */
/* = 80 MHz /( [1+16+16+47] x 2) = 80 MHz /(80x2) = 500 Kz */
CAN0->FDCBT = 0x00131CE3; /* Configure data phase: 2 MHz bit time, 40 MHz Sclock */
/* Prescaler = CANCLK / Sclock = 80 MHz / 40 MHz = 2 */
/* FPRESDIV = Prescaler - 1 = = 2 - 1 = 1 */
/* FPSEG2 = 3 */
/* FPSEG1 = 7 */
/* FPROPSEG = 7 */
/* FRJW = 3 */
/* BITRATEf =Fcanclk /( [(1 + (FPSEG1+1) + (FPSEG2+1) + (FPROPSEG)] x (FPRESDIV+!)) */
/* = 80 MHz /( [(1 + ( 7 +1) + ( 3 +1) + ( 7 )] x ( 1 +1)) */
/* = 80 MHz /( [1+8+4+7] x 2) = 80 MHz /(20x2) = 80 MHz / 40 = 2 MHz */
CAN0->FDCTRL =0x80038500; /* Configure bit rate switch, data size, transcv'r delay */
/* BRS=1: enable Bit Rate Swtich in frame's header */
/* MBDSR1: Not applicable */
/* MBDSR0=3: Region 0 has 64 bytes data in frame's payload */
/* TDCEN=1: enable Transceiver Delay Compensation */
/* TDCOFF=5: 5 CAN clocks (300us) offset used */
for(i=0; i<128; i++ ) { /* CAN0: clear 128 words RAM in FlexCAN 0 */
CAN0->RAMn[i] = 0; /* Clear msg buf words. All buffers CODE=0 (inactive) */
}
for(i=0; i<16; i++ ) { /* In FRZ mode, init CAN0 16 msg buf filters */
CAN0->RXIMR[i] = 0xFFFFFFFF; /* Check all ID bits for incoming messages */
}
CAN0->RXMGMASK = 0x1FFFFFFF; /* Global acceptance mask: check all ID bits */
/* Message Buffer 4 - receive setup: */
CAN0->RAMn[ 4*MSG_BUF_SIZE + 0] = 0xC4000000; /* Msg Buf 4, word 0: Enable for reception */
/* EDL=1: Extended Data Length for CAN FD */
/* BRS = 1: Bit Rate Switch enabled */
/* ESI = 0: Error state */
/* CODE=4: MB set to RX inactive */
/* IDE=0: Standard ID */
/* SRR, RTR, TIME STAMP = 0: not applicable */
#ifdef NODE_A /* Node A receives msg with std ID 0x511 */
CAN0->RAMn[ 4*MSG_BUF_SIZE + 1] = 0x14440000; /* Msg Buf 4, word 1: Standard ID = 0x511 */
#else /* Node B to receive msg with std ID 0x555 */
CAN0->RAMn[ 4*MSG_BUF_SIZE + 1] = 0x15540000; /* Msg Buf 4, word 1: Standard ID = 0x555 */
#endif
/* PRIO = 0: CANFD not used */
CAN0->CTRL2 |= CAN_CTRL2_ISOCANFDEN_MASK; /* Enable CRC fix for ISO CAN FD */
CAN0->MCR = 0x0000081F; /* Negate FlexCAN 1 halt state & enable CAN FD for 32 MBs */
while ((CAN0->MCR && CAN_MCR_FRZACK_MASK) >> CAN_MCR_FRZACK_SHIFT) {}
/* Good practice: wait for FRZACK to clear (not in freeze mode) */
while ((CAN0->MCR && CAN_MCR_NOTRDY_MASK) >> CAN_MCR_NOTRDY_SHIFT) {}
/* Good practice: wait for NOTRDY to clear (module ready) */
// CAN0->RAMn[ 4*MSG_BUF_SIZE + 0] = 0xC4000000;
}
Thanks,
Hi,
tx error can be easily caused by incorrect bit timing setting. You should have similar setting on CANAnalyzer too, at least have same sample point as you have on MCU side for nominal and data phase.
Also TDC is not needed for 2Mbps bitrate and if it is enabled TDCOFF should be properly set. So try either
- disable TDC, set TDCEN=0
or
- set TDCOFF around 20
BR, Petr