AnsweredAssumed Answered

Problems using FlexCAN

Question asked by Andrea Meis on Jan 22, 2014
Latest reply on Feb 26, 2014 by Petr_H

Hello, I'm using two Kwikstik boards connected via CAN bus. I used Processor Expert to program the boards and I have succesfully implemented the examples reported in the "typical usage" section of the CAN_LDD component.

The problem arises when I try to implement a loop cycle:

Each board waits fo a message and then send a message to the other board. If I put a temporization in the loop, everything works as expected. If the "wait" function is commented, no frames are sent and while one board is stuck waiting for the transmission response, the other is stuck waiting for a message. Why does it happen? Shouldn't the FlexCAN re-send the message if an error happens during transmission?

I used Processor Expert to initialize the peripheral with the options descripted in the typical usage (the example that uses interrupts).

Here is the code of the main function of one of the two boards (the other is similar, the order of the transmission and reception phase is just inverted):

.

volatile bool DataFrameTxFlg;

volatile bool DataFrameRxFlg = FALSE;

volatile bool timeElapsed=FALSE;

volatile int timeCounter;

LDD_TDeviceData *MyCANPtr;

LDD_TError Error;

LDD_CAN_TFrame Frame;

uint8_t OutData[4] = {0x00U, 0x01U, 0x02U, 0x03U};                /* Initialization of output data buffer */

uint8_t InpData[8];

 

/*lint -save  -e970 Disable MISRA rule (6.3) checking. */

int main(void)

/*lint -restore Enable MISRA rule (6.3) checking. */

{

int count=0;

 

    /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/

    PE_low_level_init();

    /*** End of Processor Expert internal initialization.                    ***/

 

    MyCANPtr = CAN2_Init(NULL);                                     /* Initialization of CAN2 component */ 

    for(;;) {

 

            /* Initialization of CAN2 component */ 

 

            Frame.MessageID = 0x123U;                                       /* Set Tx ID value - standard */ 

            Frame.FrameType = LDD_CAN_DATA_FRAME;                           /* Specyfying type of Tx frame - Data frame */

            Frame.Length = sizeof(OutData);                                 /* Set number of bytes in data frame - 4B */

            Frame.Data = OutData;

            \\     timeCounter=0;

            \\      timeElapsed=FALSE;

            \\     while(!timeElapsed){}

            DataFrameTxFlg = FALSE;                                         /* Initialization of DataFrameTxFlg */

            Error = CAN2_SendFrame(MyCANPtr, 1U, &Frame);                   /* Sends the data frame over buffer 0 */

            while (!DataFrameTxFlg) {                                       /* Wait until data frame is transmitted */

            }

            \\     timeCounter=0;

            \\     timeElapsed=FALSE;

             \\           while(!timeElapsed){}

            while (!DataFrameRxFlg) {                                       /* Wait until data frame is received */

            }

            DataFrameRxFlg=FALSE;

            Frame.Data = InpData;                                           /* Set pointer to InpData buffer */

            Error = CAN2_ReadFrame(MyCANPtr, 0U, &Frame);                   /* Reads a data frame from buffer 0 and fills Frame structure */    

 

 

            /* Write your local variable definition here */

            OutData[0]=InpData[0]+1;  

            count++;

       

    }

 

 

The event.c's code is the following:

 

extern volatile bool DataFrameTxFlg;

extern volatile bool DataFrameRxFlg;

extern volatile bool timeElapsed;

extern volatile int timeCounter;

 

void CAN2_OnFreeTxBuffer(LDD_TUserData *UserDataPtr, LDD_CAN_TMBIndex BufferIdx)

{

    DataFrameTxFlg = TRUE; /* Set DataFrameTxFlg flag */

}

 

 

 

void CAN2_OnFullRxBuffer(LDD_TUserData *UserDataPtr, LDD_CAN_TMBIndex BufferIdx)

{

    DataFrameRxFlg = TRUE; /* Set DataFrameRxFlg flag */

}

 

 

 

void TI1_OnInterrupt(LDD_TUserData *UserDataPtr)

{

    if(timeCounter>100)

    {

        timeElapsed=TRUE;

        timeCounter=0;

    }

    timeCounter++;

   

}

Outcomes