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,
Solved! Go to Solution.
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
HELLO can you help me ? S32K144 CAN Demo Example can not run?? Your QQ?? Thank you very much!!
Hello,
If the data is wrong be aware that the msg_buff data are organized as Big Endian Data_B0, Data_B1, Data_B2, Data_B3.. to be received correctly you need to revert endianess of the data if the frame is received in Message Buffer.
Second configure Rx as inactive the code of the MB is 0 not 4;
CAN0->RAMn[ 4*MSG_BUF_SIZE + 0] = 0xC0000000; /* Msg Buf 4, word 0: Enable for reception */
Then after configure the ID of the RxMsg Buff; you need to set the MB as Rx Empty code 0b0100
CAN0->RAMn[ 4*MSG_BUF_SIZE + 0] = 0xC8000000; /* Msg Buf 4, word 0: Enable for reception */
Actually I receive the CAN FD frame sent by CANALYZER very cleanly ,EVERYTHING IS OK WITH THE RECEPTION,
I kept getting transmit error that's when my code is trying to send to CANALYZER.
again I'm using the CAN FD demo in design studio as the reference.
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
Petr,
I followed your suggestion and It seems it is working.
Thanks for your help.
Thanks for your response,
I'll do what you're suggesting however let me ask you, why this is not effecting the reception and only transmission?
Thanks,
Hi Koorosh,
most probably you got bit error(s) in data phase and this can only happen during transmission.
TDC, if enabled, is effective only during the data phase of transmitted FD frames having the BRS bit set.
BR, Petr