AnsweredAssumed Answered

S32K148 CAN physical layer issues

Question asked by Michael Kirches on Jul 4, 2019
Latest reply on Jul 9, 2019 by Michael Kirches

Dear community,

 

I have a question regarding the CAN configuration of S32K148.

 

For our current project, we are using CAN interface in combination with a third-party CAN stack. For a first start with CAN, we tried to get the CAN 2.0 example running, which is described in S32K cookbook. This one worked fine, we could send and receive messages.

 

With the integration of the CAN stack, we are now facing issues, which indicate that there's something wrong with the physical layer. From a CAN tracing tool, we try to send a single CAN message to test, if our hardware can receive it. In the tracing view of the CAN tool we can see that the defined message is put on CAN bus, but we also see a lot of error frames, which report about stuff errors and form errors. According to the CAN stack vendor, this is a clear indication, that there's something wrong with the physical layer. Thus I'd like to ask, if you can see a problem in our current CAN configuration:

 

void CAN_port_init()
{
   printf("+++ CAN_port_init\n");
    PCC->PCCn[PCC_PORTE_INDEX] |= PCC_PCCn_CGC_MASK; /* Enable clock for PORTE */
    PORTE->PCR[4] |= PORT_PCR_MUX(5); /* Port E4: MUX = ALT5, CAN0_RX */
    PORTE->PCR[5] |= PORT_PCR_MUX(5); /* Port E5: MUX = ALT5, CAN0_TX */
    printf("--- CAN_port_init\n");
}

void CAN_configure_hw() {
    printf("+++ CAN_configure_hw\n");
    PCC->PCCn[PCC_FlexCAN0_INDEX] |= PCC_PCCn_CGC_MASK;
    CAN0->MCR |= CAN_MCR_MDIS_MASK;
    CAN0->CTRL1 &= ~CAN_CTRL1_CLKSRC_MASK;
    CAN0->MCR &= ~CAN_MCR_MDIS_MASK;
    CAN0->MCR |= CAN_MCR_FRZ_MASK | CAN_MCR_HALT_MASK;
    /* Good practice: wait for FRZACK=1 on freeze mode entry/exit */
    while (!((CAN0->MCR & CAN_MCR_FRZACK_MASK) >> CAN_MCR_FRZACK_SHIFT)) {
    }

/*
* 00 7A 00 03 (values from GENy for configuration: Clock = 8MHz, BaudRate = 500kBaud)

   Checking settings:
    - PRESDIV: 0
    - RJW: 1
    - PSEG1: 7
    - PSEG2: 2
    - PROPSEG: 3

      Sclock = f_canclk / (PRESDIV+1) = 8000000 / 1 = 8MHz
      Tq = (PRESDIV+1) / f_canclk = 1/8000000 = 125ns ( Time Quantum )
      BitTime = (1 + [PSEG1+PROPSEG+2] + [PSEG2+1]) * Tq = (1+12+3) * Tq = 16 * 125ns = 2µs
      BitRate = 1 / BitTime = 1/2µs = 500kBaud (OK)
*
*/

// CAN_TIMING_REGISTER is '#define CAN_TIMING_REGISTER 0x007A0003'
CAN0->CTRL1 = CAN_TIMING_REGISTER; //0x007A0003;

 for (int i = 0; i < 128; i++) {
   /* CAN0: clear 32 msg bufs x 4 words/msg buf = 128 words*/
    CAN0->RAMn[i] = 0; /* Clear msg buf word */
}
for (int 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 */

 CAN0->MCR = 0x0000001F; /* Negate FlexCAN 1 halt state 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) */
 printf("--- CAN_configure_hw\n");
}

void CAN_init()
{
   printf("+++ CAN_init\n");
   CAN_configure_hw();

   // Calls to third party CAN stack...

   printf("--- CAN_init\n");
}

 

In order to initialize CAN, we call methods  CAN_port_init and CAN_init as described above. 

 

Do you see anything which could lead to error frames with the above configuration? Any help would be appreciated.

 

Kind Regards,

Michael

Outcomes