Help: Can't disable S32k116 bus off auto recovery

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Help: Can't disable S32k116 bus off auto recovery

712 Views
wubt01
Contributor I

Dear Expert
The MCU I am using is s32k116, because I want to do bus-off fast recovery/slow recovery, so I need to turn off the bus-off auto recovery.
My CAN module settings are as follows:

void CAN0_init(void)
{
uint8_t databyte;

/* Enable clock for PORTE */
PCC->PCCn[PCC_PORTE_INDEX] |= PCC_PCCn_CGC_MASK;

#if 0 //Pinchi 20181213 change to 116 SBC board
// for V04 of hardware board
/* Port B0: MUX = ALT5, CAN0_RX */
PORTB->PCR[0U] |= PORT_PCR_MUX(5U);

/* Port B1: MUX = ALT5, CAN0_TX */
PORTB->PCR[1U] |= PORT_PCR_MUX(5U);
#else
// for V05 of hardware board
/* Port E4: MUX = ALT5, CAN0_RX */
PORTE->PCR[4U] |= PORT_PCR_MUX(5U);

/* Port E5: MUX = ALT5, CAN0_TX */
PORTE->PCR[5U] |= PORT_PCR_MUX(5U);
#endif


/* CGC=1: enable clock to FlexCAN0 */
PCC->PCCn[PCC_FlexCAN0_INDEX] |= PCC_PCCn_CGC_MASK;

/* To access the memory mapped registers */
/* Enter disable mode (hard reset). */
if(((CAN0->MCR & CAN_MCR_MDIS_MASK) >> CAN_MCR_MDIS_SHIFT) == 0U)
{
/* Clock disable (module) */
CAN0->MCR = (uint32_t)((CAN0->MCR & ~CAN_MCR_MDIS_MASK) | CAN_MCR_MDIS(1U));

/* Wait until disable mode acknowledged */
while (((CAN0->MCR & CAN_MCR_LPMACK_MASK) >> CAN_MCR_LPMACK_SHIFT) == 0U) {}
}

/* Select a source clock for the FlexCAN engine */
CAN0->CTRL1 = (uint32_t)((CAN0->CTRL1 & ~CAN_CTRL1_CLKSRC_MASK) | CAN_CTRL1_CLKSRC(0U));

/* Enter the freeze mode */
CAN0->MCR &= ~CAN_MCR_MDIS_MASK;

CAN0->MCR = (CAN0->MCR & ~CAN_MCR_FRZ_MASK) | CAN_MCR_FRZ(1U);
CAN0->MCR = (CAN0->MCR & ~CAN_MCR_HALT_MASK) | CAN_MCR_HALT(1U);

/* Wait for entering the freeze mode */
while (!((CAN0->MCR & CAN_MCR_FRZACK_MASK) >> CAN_MCR_FRZACK_SHIFT)) {}

/* Reset the FLEXCAN */
CAN0->MCR = (uint32_t)((CAN0->MCR & ~CAN_MCR_SOFTRST_MASK) | CAN_MCR_SOFTRST(1U));

/* Wait for reset cycle to complete */
while (((CAN0->MCR & CAN_MCR_SOFTRST_MASK) >> CAN_MCR_SOFTRST_SHIFT) != 0U) {}

/* Clear MB region */
for (databyte = 0U; databyte < 128U; databyte++)
{
CAN0->RAMn[databyte] = 0U;
}

/* Clear RXIMR region */
for (databyte = 0U; databyte < 32U; databyte++)
{
CAN0->RXIMR[databyte] = 0U;
}

/* Disable all MB interrupts */
CAN0->IMASK1 = 0U;

/* Clear all MB interrupt flags */
CAN0->IFLAG1 = (uint32_t)CAN_IMASK1_BUF31TO0M_MASK;

/* Disable can fd */
CAN0->MCR = (uint32_t)((CAN0->MCR & ~CAN_MCR_FDEN_MASK) | CAN_MCR_FDEN(0UL));

/* Enable the use of extended bit time definitions */
CAN0->CBT = (uint32_t)(CAN0->CBT | CAN_CBT_BTF(0UL));

/* Disable the Stuff Bit Count */
#if (0)
CAN0->CTRL2 = (uint32_t)((CAN0->CTRL2 & ~CAN_CTRL2_ISOCANFDEN_MASK) | CAN_CTRL2_ISOCANFDEN(0UL));
#else
//CAN0->CTRL2 = (uint32_t)(0x40000000U) ;
CAN0->CTRL2 = (uint32_t)(0) ;
#endif // #if (0)
/* enabling warning enable interrupt for tx and rx passive errors*/
CAN0->MCR = (uint32_t)(CAN0->MCR | CAN_MCR_WRNEN(1U));
CAN0->CTRL1 = (uint32_t)(CAN0->CTRL1 | CAN_CTRL1_RWRNMSK(1U) | CAN_CTRL1_TWRNMSK(1U));
/* Set operation mode as normal */
CAN0->MCR = (uint32_t)((CAN0->MCR & ~CAN_MCR_SUPV_MASK) | CAN_MCR_SUPV(0U));
CAN0->CTRL1 = (uint32_t)((CAN0->CTRL1 & ~CAN_CTRL1_LOM_MASK) | CAN_CTRL1_LOM(0U));
CAN0->CTRL1 = (uint32_t)((CAN0->CTRL1 & ~CAN_CTRL1_LPB_MASK) | CAN_CTRL1_LPB(0U));

/* Set the maximum number of MBs*/
CAN0->MCR = (uint32_t)((CAN0->MCR & ~CAN_MCR_MAXMB_MASK) | \
((CANT_MAXMB_CNT << CAN_MCR_MAXMB_SHIFT) & CAN_MCR_MAXMB_MASK));


/* Sets the FlexCAN time segments for setting up bit rate */
CAN0->CTRL1 = (uint32_t)(((CAN0->CTRL1) & ~((CAN_CTRL1_PROPSEG_MASK | CAN_CTRL1_PSEG2_MASK |
CAN_CTRL1_PSEG1_MASK | CAN_CTRL1_PRESDIV_MASK) |
CAN_CTRL1_RJW_MASK)));

//sample rate 75%
CAN0->CTRL1 = (uint32_t)(((CAN0->CTRL1) | (CAN_CTRL1_PROPSEG(6U) | //7U
CAN_CTRL1_PSEG2(3U) | //1U
CAN_CTRL1_PSEG1(3U) | // 4U
CAN_CTRL1_PRESDIV(PRESDIV) |
CAN_CTRL1_RJW(4U)))); //1U

/* Sets the CAN error and busoff error interrupts masks */
CAN0->CTRL1 = (uint32_t)((CAN0->CTRL1)&~((CAN_CTRL1_ERRMSK_MASK )|(CAN_CTRL1_BOFFMSK_MASK)));

CAN0->CTRL1 = (uint32_t)((CAN0->CTRL1)|(CAN_CTRL1_ERRMSK(1)|(CAN_CTRL1_BOFFMSK(1))));

/* Disable auto recovery*/
CAN0->CTRL1 |=(uint32_t)((CAN_CTRL1_BOFFREC_MASK));
CAN0->CTRL1 |=(uint32_t)CAN_CTRL1_BOFFREC(1);
CAN0->CTRL2 |= CAN_CTRL2_BOFFDONEMSK(1);

/* Sets the individual masking for each MB */
CAN0->MCR=(uint32_t)((CAN0->MCR & ~CAN_MCR_IRMQ_MASK)|(CAN_MCR_IRMQ(1U)));

/* Sets the self reception disable */
CAN0->MCR=(uint32_t)((CAN0->MCR & ~CAN_MCR_SRXDIS_MASK)|(CAN_MCR_SRXDIS(1U)));


/* Configure Rx Id filtering */
Enable_ID_filter();

/* Configure Rx msg objects*/
CAN0_ConfRxMsgObj();

/* Configure Tx msg objects*/
CAN0_ConfTxMsgObj();

/* Exit freeze mode */
CAN0->MCR = (uint32_t)((CAN0->MCR & ~CAN_MCR_HALT_MASK) | CAN_MCR_HALT(0U));
CAN0->MCR = (uint32_t)((CAN0->MCR & ~CAN_MCR_FRZ_MASK) | CAN_MCR_FRZ(0U));

/* Wait till exit freeze mode */
while (((CAN0->MCR & CAN_MCR_FRZACK_MASK) >> CAN_MCR_FRZACK_SHIFT) != 0U) {}

/* Enable receive buffer interrupts */
Clr_Pending_IRQ(CAN0_ORed_0_31_MB_IRQn);
Enable_IRQ(CAN0_ORed_0_31_MB_IRQn);
Set_IRQ_Priority(CAN0_ORed_0_31_MB_IRQn,IRQ_PRIORITY);

/* Enable error interrupt */
Clr_Pending_IRQ(CAN0_ORed_Err_Wakeup_IRQn);
Enable_IRQ(CAN0_ORed_Err_Wakeup_IRQn);

Set_IRQ_Priority(CAN0_ORed_Err_Wakeup_IRQn,IRQ_PRIORITY);
}

I set the CAN0->CTRL1 |=(uint32_t)CAN_CTRL1_BOFFREC(1);

However, I found that the setting has no effect, the following picture shows the can tx signal I measured with an oscilloscope. You can see that it still sends out the signal at 3.6ms at the bus off status.
This problem has been bothering me for a long time, please help me to solve this problem.
Thanks.

BT

wubt01_0-1695624675465.png

 

0 Kudos
Reply
3 Replies

701 Views
Senlent
NXP TechSupport
NXP TechSupport

Hi@wubt01

please have a try below sentence.

CAN0->CTRL1 |= 0x40;

and then check if the rigister CRTL1->BOFFREC is set or not.

0 Kudos
Reply

652 Views
wubt01
Contributor I

Hi @Senlent

The register date from bit 15~0 are "1100 1100 0100 0110" (0xCC, 0x46).

It means  the rigister CRTL1->BOFFREC is set to 1.

Could you please tell me, when a bus off occurs, are there any other register settings that need to be done in the handler?

Thanks.

BT

0 Kudos
Reply

645 Views
Senlent
NXP TechSupport
NXP TechSupport

Hi@wubt01

we have some demo about bus-off test.

https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K144-FlexCAN-TX-RX-Error-ISR-test-S32DS2... 

You can check whether BOFFREC is 1 in the debugging interface.

When you turn off auto bus-off recovery, you need to manually recover the CAN module after a bus-off event occurs. This is the only difference.

 

0 Kudos
Reply