AnsweredAssumed Answered

CAN over XCP

Question asked by Nitin verma on Oct 17, 2016
Unable to Run CAN and XCP together for longer duration,gives an Timeout Error after certain period of time, Independently both CAN and XCP works fine. Problem is mainly happening during CAN transmission and XCP request comes and it also tries for transmission.We are working on Evaluation Board S32K144.
Below are the two API's which we are using to send cyclic CAN messages and also for XCP transmission at the time of XCP request.
FLEXCAN_DRV_ConfigTxMb(FSL_CAN, 10UL, &Tx_Info_Cfg, CANTXID);
 
FLEXCAN_DRV_Send(FSL_CAN, 10UL, &Tx_Info_Cfg, CANTXID, CANTxData[CANTXID].data);
 
Note: Message Buffer 10 is used for CAN cyclic transmission and 11 is used XCP transmission with ID 13.
Since we have only one interrupt which is common for both TX and Rx and also we are using same API for CAN and XCP, We are unable to run both CAN and XCP together for longer duration.
 
Case1: If we are transmiting CAN message and we get an XCP request, In this situation if priority is given to XCP first and then for CAN, XCP never gives an timeout error but we are losing CAN messages for that particular period.
Case2: If we are transmiting CAN message and we get an XCP request, In this situation if priority is given to CAN first and then for XCP, We will get all the CAN messages but XCP gives timeout error.
Please find below the Interrupt Function where XCP command is called inside FIFO reception and XcpSendCallback is called inside Transmission Completion.
/*FUNCTION**********************************************************************
*
* Function Name : FLEXCAN_DRV_IRQHandler
* Description : Interrupt handler for FLEXCAN.
* This handler read data from MB or FIFO, and then clear the interrupt flags.
* This is not a public API as it is called whenever an interrupt occurs.
*
*END**************************************************************************/
void FLEXCAN_DRV_IRQHandler(uint8_t instance)
{
volatile uint32_t flag_reg;
uint32_t temp;
uint32_t lau32_vXCPByte[2] = {0,0};
CAN_Type * base = g_flexcanBase[instance];
flexcan_state_t * state = g_flexcanStatePtr[instance];
uint8 lu8_viteration = 0u;
uint8 lau_vXCPdata[8] = {0u,0u,0u,0u,0u,0u,0u,0u};

 

 

// Disable FlexCAN interrupts.
INT_SYS_DisableIRQ(g_flexcanWakeUpIrqId[instance]);
INT_SYS_DisableIRQ(g_flexcanErrorIrqId[instance]);
INT_SYS_DisableIRQ(g_flexcanBusOffIrqId[instance]);
INT_SYS_DisableIRQ(g_flexcanOredMessageBufferIrqId[instance]);

 

/* Get the interrupts that are enabled and ready */
flag_reg = ((FLEXCAN_HAL_GetAllMsgBuffIntStatusFlag(base)) & CAN_IMASK1_BUF31TO0M_MASK) & (base->IMASK1);

 

/* Check Tx/Rx interrupt flag and clear the interrupt */
if(flag_reg)
{
if ((flag_reg & 0x20) && (BITBAND_ACCESS32(&(base->MCR), CAN_MCR_RFEN_SHIFT)))
{
if (state->fifo_message != NULL)
{
/* Get RX FIFO field values */
FLEXCAN_HAL_ReadRxFifo(base, state->fifo_message);

 

/* Reception of XCP */
if(CAN_XCP_RX_ID == state->fifo_message->msgId)
{
for(lu8_viteration=0u;lu8_viteration<8;lu8_viteration++)
{
lau_vXCPdata[lu8_viteration] = state->fifo_message->data[FLEXCAN_SWAP_BYTES_IN_WORD_INDEX1(lu8_viteration)];
}

lau32_vXCPByte[0] = (uint32)(lau_vXCPdata[0]|(((lau_vXCPdata[1]<< 8u) & 0x0000FF00))|((lau_vXCPdata[2]<< 16u) & 0x00FF0000)|((lau_vXCPdata[3]<< 24u) & 0xFF000000));

lau32_vXCPByte[1] = (uint32)(lau_vXCPdata[4]|(((lau_vXCPdata[5]<< 8u) & 0x0000FF00))|((lau_vXCPdata[6]<< 16u) & 0x00FF0000)|((lau_vXCPdata[7]<< 24u) & 0xFF000000));

 

XcpCommand(&lau32_vXCPByte[0]);

 

else
{
; /*do nothing*/
}

 

/* Complete receive data */
FLEXCAN_DRV_CompleteRxMessageFifoData(instance);
FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, flag_reg);
}
}
else
{
/* Check mailbox completed reception */
temp = (1 << state->rx_mb_idx);
if ((temp & flag_reg) && state->isRxBusy)
{
/* Unlock RX message buffer and RX FIFO*/
FLEXCAN_HAL_LockRxMsgBuff(base, state->rx_mb_idx);
/* Get RX MB field values*/
FLEXCAN_HAL_GetMsgBuff(base, state->rx_mb_idx, state->mb_message);
/* Unlock RX message buffer and RX FIFO*/
FLEXCAN_HAL_UnlockRxMsgBuff(base);

 

/* Complete receive data */
FLEXCAN_DRV_CompleteRxMessageBufferData(instance);
FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, temp & flag_reg);
}
}

 

/* Check mailbox completed transmission */
/* XCPTRANSMISSION_COMPLETED  is a Macro with value  0x00000800u because the buffer used is 11 */
temp = (1 << state->tx_mb_idx);
if((XCPTRANSMISSION_COMPLETED == (temp & flag_reg)) && (SET == (state->isTxBusy)))
{
/* Complete transmit data */
FLEXCAN_DRV_CompleteSendData(instance);
FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, temp & flag_reg);
/* This callback function is for XCP. */
XcpSendCallBack();

 

}
else
{
; /*do nothing*/
}

 

/* CYCLICCANTRANSMISSION_COMPLETED is a Macro with value 0x00000400u because the buffer used is 10 */

if((CYCLICCANTRANSMISSION_COMPLETED == (temp & flag_reg)) && (SET == (state->isTxBusy)))
{

 

/* Complete transmit data */
FLEXCAN_DRV_CompleteSendData(instance);
FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, temp & flag_reg);

/* This callback function transmits the remaining ID's. */
CANTxCallBack();
}
else
{
; /*do nothing*/
}

 

}

 

/* Acknowledge Error detected and bus is in passive state
* then reset the states || Bus off */
if(((base->ESR1 & ACKERR) && (base->ESR1 & FLTCONF))
|| (base->ESR1 & FLTCONF1))
{
FLEXCAN_DRV_CompleteSendData(instance);
}
else
{
; /*do nothing*/
}

 

/* Clear all other interrupts in ERRSTAT register (Error, Busoff, Wakeup) */
FLEXCAN_HAL_ClearErrIntStatusFlag(base);

 

// Enable FlexCAN interrupts.
INT_SYS_EnableIRQ(g_flexcanWakeUpIrqId[instance]);
INT_SYS_EnableIRQ(g_flexcanErrorIrqId[instance]);
INT_SYS_EnableIRQ(g_flexcanBusOffIrqId[instance]);
INT_SYS_EnableIRQ(g_flexcanOredMessageBufferIrqId[instance]);

 

return;
}
Kindly help me in debugging this issue.
Thanks,
Nitin

Outcomes