Can receive issue.

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

Can receive issue.

1,576 Views
赵子成
Contributor IV

Hi, everyone,

Now I use the S32K146, I use SDK code. I found that the function of FLEXCAN_DRV_Receive can only be used in main function, if I use FLEXCAN_DRV_Receive in other function, when S32K146 receive can frame, it will reset. I don't know the reason, or someone encounter the same problem?

Thanks.

0 Kudos
6 Replies

1,139 Views
alexandrunan
NXP Employee
NXP Employee

This was a functional example based on your code provided.

The driver flow is next configure the receiving MB with FLEXCAN_DRV_Receive; then wait the completion for receiving with  FLEXCAN_DRV_GetTransferStatus to be success, this function only checks the status of the MB configured.

If you multiple call in a loop FLEXCAN_DRV_Receive you can hit in the middle of a receive process, brake the flow of the driver state.

And yes the CAN interrupt is a nesting interrupt.

0 Kudos

1,139 Views
赵子成
Contributor IV

Hi Alexandru

It seems that If I config the CAN interrupt to non-nesting interrupt, this issue can be solved.

0 Kudos

1,139 Views
alexandrunan
NXP Employee
NXP Employee

Can you share the code of function from which you called the FLEXCAN_DRV_Receive that failed and what version of SDK did you use ?!

0 Kudos

1,139 Views
赵子成
Contributor IV

Hi  Alexandru,

1、I use FLEXCAN_DRV_Receive in main like that:

int main(void)
{flexcan_msgbuff_t canData;

......

while(1)

{

if(FLEXCAN_DRV_Receive(INST_CANCOM1, 0, &canData) == STATUS_SUCCESS)

{
PINS_DRV_TogglePins(PTE, (1 << 11));
}

}

}

This is OK.

2、If I use FLEXCAN_DRV_Receive like that:

{flexcan_msgbuff_t canData;

......

while(1)

{

if(CANIF_Recv() > 0)

{
PINS_DRV_TogglePins(PTE, (1 << 11));
}

}

}

And CANIF_Recv is defined in another C file:

UINT16 CANIF_Recv(void)
{
flexcan_msgbuff_t stCanData;
UINT8 i;

if(FLEXCAN_DRV_Receive(0, 0, &stCanData) == STATUS_SUCCESS)

{

return 1;

}

else
{
return 0;
}

When S32K146 received can frame, software will enter DefaultISR.

I also supply my can initial code as follow:

flexcan_data_info_t dataInfo =
{
.data_length = 8U,
.enable_brs = 0,
.fd_enable = 0,
.fd_padding = 0U
};

FLEXCAN_DRV_Init(INST_CANCOM1, &canCom1_State, &canCom1_InitConfig0);
dataInfo.msg_id_type = FLEXCAN_MSG_ID_STD;

FLEXCAN_DRV_ConfigRxMb(0, 0, &dataInfo, 1);
FLEXCAN_DRV_SetRxMbGlobalMask(INST_CANCOM1, FLEXCAN_MSG_ID_STD, 0);
FLEXCAN_DRV_Receive(INST_CANCOM1, 0, &canData);

The SDK Version is S32K146_SDK_gcc0.8.6.

0 Kudos

1,139 Views
alexandrunan
NXP Employee
NXP Employee

Hello,

I figure what is causing the defaultISR, you kind miss use the driver, when you receive the first message and is proccesed by receiving ISR if you receive a second message you will trigger again the same isr and causing fault, because the FLEXCAN_DRV_Receive arm again the isr and will mess the state-machine of the driver.  

The correct usage will be :

uint16_t CANIF_Recv(void)
{


if(FLEXCAN_DRV_GetTransferStatus(0,0)==STATUS_SUCCESS)
{
return 1;
}
else
{
return 0;
}
}
void func(void)
{
flexcan_msgbuff_t stCanData;
FLEXCAN_DRV_Receive(0, 0, &stCanData);
while(1)
{
if(CANIF_Recv() > 0)
{
PINS_DRV_TogglePins(PTE, (1 << 11));
}
}

}

And when you want to receive another frame call again func()...

0 Kudos

1,139 Views
赵子成
Contributor IV

Hi ,Alexandru

I don't know what is difference between my first usage and my second usage about FLEXCAN_DRV_Receive. The only diffenence is that the first usage, FLEXCAN_DRV_Receive is called in main func , and the second is FLEXCAN_DRV_Receive is called in CANIF_Recv func. 

You means the CAN interrupt is a nesting interrupt?

If I call  func() , that means it will enter the loop. So I can't write "while(1)" in func().

      I am sorry I need your detail explaination. I still don't understand.

0 Kudos