When I short CAN_H and CAN_L to test busoff, the hardfault happened and ECR register's value = 0?

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

When I short CAN_H and CAN_L to test busoff, the hardfault happened and ECR register's value = 0?

1,215 Views
liyun
Contributor II

busoff.PNG

Function name:FLEXCAN_IRQHandler

I modified the code in picture to avoid hardfault reset(because CAN2 don't have pretendnetwork function), and the value of ECR register(which is used to count error) is 0, thus Error_IRQHandler can not be executed.

I don't know the reason, help me!Thank you!

0 Kudos
5 Replies

1,190 Views
liyun
Contributor II

liyun_1-1631177838361.png

I found some discriptions in datasheet(red line).

The busoff interrupt is issued, and ERRCNT is setted to 0. If you check the ErrorCounters, the result may be 0, so that 

if (ecr != 0U) will not be established.

I'm not sure it is the reason of that. 

1,186 Views
Senlent
NXP TechSupport
NXP TechSupport

Hi@liyun

    This should be the reason, but you still need to test it.

BR!

      Jim,

     

0 Kudos

1,169 Views
liyun
Contributor II

Hi Senlent

I have passed the test.

Thank you for all the time.

BR!

0 Kudos

1,208 Views
Senlent
NXP TechSupport
NXP TechSupport

Hi@liyun

 Similar to the previous question.

 usually we don't allow customers to modify the driver file.

 RTM_3.0 

void FLEXCAN_IRQHandler(uint8_t instance)
{
    DEV_ASSERT(instance < CAN_INSTANCE_COUNT);

    uint32_t flag_reg = 0;
    CAN_Type * base = g_flexcanBase[instance];
    flexcan_state_t * state = g_flexcanStatePtr[instance];

    /* Get the interrupts that are enabled and ready */
    uint32_t mb_idx = 0;
    flag_reg = FLEXCAN_GetMsgBuffIntStatusFlag(base, mb_idx);

    while ((flag_reg & 1U) == 0U)
    {
        mb_idx++;
        flag_reg = FLEXCAN_GetMsgBuffIntStatusFlag(base, mb_idx);

        if (mb_idx >= FEATURE_CAN_MAX_MB_NUM)
        {
            break;
        }
    }

    /* Check Tx/Rx interrupt flag and clear the interrupt */
    if(flag_reg != 0U)
    {
        if (FLEXCAN_IsRxFifoEnabled(base) && (mb_idx <= FEATURE_CAN_RXFIFO_OVERFLOW))
        {
            FLEXCAN_IRQHandlerRxFIFO(instance, mb_idx);
        }
        else
        {
            /* Check mailbox completed reception */
            if (state->mbs[mb_idx].state == FLEXCAN_MB_RX_BUSY)
            {
            	FLEXCAN_IRQHandlerRxMB(instance, mb_idx);
            }
        }

        /* Check mailbox completed transmission */
        if (state->mbs[mb_idx].state == FLEXCAN_MB_TX_BUSY)
        {
            if (state->mbs[mb_idx].isRemote)
            {
                /* If the frame was a remote frame, clear the flag only if the response was
                 * not received yet. If the response was received, leave the flag set in order
                 * to be handled when the user calls FLEXCAN_DRV_RxMessageBuffer. */
                flexcan_msgbuff_t mb;
                FLEXCAN_LockRxMsgBuff(base, mb_idx);
                FLEXCAN_GetMsgBuff(base, mb_idx, &mb);
                FLEXCAN_UnlockRxMsgBuff(base);

                if (((mb.cs & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) == (uint32_t)FLEXCAN_RX_EMPTY)
                {
                    FLEXCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
                }
            }
            else
            {
                FLEXCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
            }

            state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;

            /* Invoke callback */
            if (state->callback != NULL)
            {
                state->callback(instance, FLEXCAN_EVENT_TX_COMPLETE, mb_idx, state);
            }

            if (state->mbs[mb_idx].state == FLEXCAN_MB_IDLE)
            {
                /* Complete transmit data */
                FLEXCAN_CompleteTransfer(instance, mb_idx);
            }
        }

        if (FLEXCAN_GetMsgBuffIntStatusFlag(base, mb_idx) != 0U)
        {
        	if (FLEXCAN_IsRxFifoEnabled(base) && (mb_idx <= FEATURE_CAN_RXFIFO_OVERFLOW))
        	{
        		if (state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state == FLEXCAN_MB_IDLE)
        		{
                /* In case of desynchronized status of the MB to avoid trapping in ISR
                 * clear the MB flag */
                FLEXCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
        		}
        	}
        	else
        	{
        		if (state->mbs[mb_idx].state == FLEXCAN_MB_IDLE)
				{
					/* In case of desynchronized status of the MB to avoid trapping in ISR
					 * clear the MB flag */
					FLEXCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
				}
        	}
        }
    }
#if (defined(CPU_S32K116) || defined(CPU_S32K118))
    else
    {
#if FEATURE_CAN_HAS_PRETENDED_NETWORKING
		/* The pretending Network Feature is present on all CPUs
		 * only on FLEXCAN Instance 0   */
		if (instance == 0U)
		{
			uint8_t wtof = FLEXCAN_GetWTOF(base);
			uint8_t wumf = FLEXCAN_GetWUMF(base);

			/* Check if wake-up event occurred */
			if ((wtof != 0U) || (wumf != 0U))
			{
				FLEXCAN_WakeUpHandler(instance);
			}
		}
#endif /* FEATURE_CAN_HAS_PRETENDED_NETWORKING */
        uint32_t ecr = FLEXCAN_GetErrorCounters(base);

        /* Check if any error occurred */
        if (ecr != 0U)
        {
            FLEXCAN_Error_IRQHandler(instance);
        }
    }
#endif /* (defined(CPU_S32K116) || defined(CPU_S32K118)) */
    return;
}

 

Here is the same problem, it may be a long time ago, but it should be very helpful for you complete the Bus-off function.

https://community.nxp.com/t5/S32K/s32K144-can-bus-off/td-p/762743 

 

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

 

BR!

      Jim,

0 Kudos

1,202 Views
liyun
Contributor II

Hi Senlent,

Thank you very much and give me 2 examples for learning.

And I knew the differences between RTM_3.0 and RTM_2.0.

I have one more question, connect CAN_H & CAN_L(CAN2), ESR->BOFFINT setted by 1, it means busoff interrupt happened, but because of  ECR = 0(TEC>255, the bus will be busoff state), FLEXCAN_Error_IRQHandler can not be excused, the interrupt flag can not be cleared.

We do not use busoff automatically recovery.

What reasons can led to this status?Thank you.

uint32_t ecr = FLEXCAN_GetErrorCounters(base);

/* Check if any error occurred */
if (ecr != 0U)

{
FLEXCAN_Error_IRQHandler(instance);
}

0 Kudos