AnsweredAssumed Answered

S32K144 CAN FD DEMO

Question asked by Koorosh Hajiani on Jan 27, 2019
Latest reply on Jan 30, 2019 by Petr Stancik

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,

Outcomes