This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CAN Rx FIFO

Other Parts Discussed in Thread: TM4C1294KCPDT

Hi,

I am using TM4C1294KCPDT for my project and am having problems receiving all the CAN messages.

I tried receive data using the FIFO. Here I am seeing a strange behavior. I configured FIFO with 16 objects, and using interrupt in No16 .

The messages are received from 1 to 16. But after that the next message(s) always land in 16. It does not use objects 1-15 afterwords. How to solve this issue? Basically I want a FIFO with 16 objects which can receive all the CAN messages.

I used the CANStatusGet API with the CAN_STS_NEWDAT parameter after read out of the FIFO but before accept more data to verify that the NEWDAT bits are clear in objects 1-15.

If I slow down the transmit speed delay 7ms every 16 frames from the transmittor, it works OK.

I found there are words in datasheet:

Until all of the preceding message objects have been released by clearing the NEWDAT bit, all further messages for this FIFO buffer are written into
the last message object of the FIFO buffer and therefore overwrite previous messages.

But when I received the interrupt, the Data in No16 message box was overwrite by the last data.

It seems that the cpu is slow than the CAN core. I closed all the interrupt except can, but the phenomenon is the same.

I used the same code in the CPU(TMS570LS3713), it worked fine but in TM4C1294 the data was overwritten.

Now, My Init code:

void CanRecvMsgBoxInit()
{
    tCANMsgObject sCANMessage = {0};
    uint32_t i = 0;

    /* mailbox 1-16 FIFO recv, 1-15 disable interrupt, 16 enable interrupt */
    sCANMessage.ui32MsgID = 0x00360000;
    sCANMessage.ui32MsgIDMask =0x00FF0000;
    sCANMessage.ui32Flags = (MSG_OBJ_USE_ID_FILTER | MSG_OBJ_FIFO|\
                                MSG_OBJ_EXTENDED_ID);
    sCANMessage.ui32MsgLen = 8;
    for(i=canMESSAGE_BOX1;i<canMESSAGE_BOX16;i++)
    {
        CANMessageSet(CAN0_BASE, i, &sCANMessage, MSG_OBJ_TYPE_RX);
    }
    /* mailbox 16  FIFO  last msg box, enable interrupt */
    sCANMessage.ui32Flags = (MSG_OBJ_RX_INT_ENABLE | \
                            MSG_OBJ_USE_ID_FILTER | \
                            MSG_OBJ_EXTENDED_ID);
    sCANMessage.ui32MsgLen = 8;
    CANMessageSet(CAN0_BASE, canMESSAGE_BOX16, &sCANMessage, MSG_OBJ_TYPE_RX);

    /* mailbox 17  recv last frame,enable interrupt*/
    sCANMessage.ui32MsgID = 0x00370000;
    sCANMessage.ui32MsgIDMask = 0x00ff0000;
    sCANMessage.ui32Flags = (MSG_OBJ_RX_INT_ENABLE | \
                            MSG_OBJ_USE_ID_FILTER | \
                            MSG_OBJ_EXTENDED_ID);
    CANMessageSet(CAN0_BASE, canMESSAGE_BOX17, &sCANMessage, MSG_OBJ_TYPE_RX);

    return ;
}
Recv read message code:

uint32_t CanRecvPkt(uint8_t *pucDataBuf, uint32_t ui32Status)
{
    uint32_t ulRet = 0;
    uint32_t i = 0;
    tCANMsgObject sCANMessage;
    uint32_t ui32Flags = 0;
    uint8_t pucMsgData[8] = {0};

    for(i=canMESSAGE_BOX1;i<canMESSAGE_BOX18;i++)
    {
        memset(&sCANMessage, 0, sizeof(tCANMsgObject));
        sCANMessage.pui8MsgData = pucMsgData;
        CANMessageGet(CAN0_BASE, i, &sCANMessage, 1);
        ui32Flags = sCANMessage.ui32Flags;
        if(ui32Flags & MSG_OBJ_NEW_DATA)
        {
            memcpy(pucDataBuf+(i-1)*8,pucMsgData,8);
        }
    }

return 0;

}

Can anybody tell me why this happened, how to fix it.

  • Two questions
    What's your bit rate?
    What's your packet rate?

    Robert
  • What's your bit rate?

    The bit rate is 1M .


    What's your packet rate?

    I use the tms570ls3173 send the packet, the frequence of the 570 is 40M. In 570 I used the for loop to send the packet, no delay between any frame.

    TM4C1294 receive packet, the frequence of the 1294 is 120M.

  • Stop highlighting your replies please, the built in quoting mechanism is quite sufficient.

    OK, you don't know how fast you are going. That's not a good thing. Hopefully you have a PC based CAN adapter to help testing, if not that should be high on your list of deficiencies to correct.

    This type of transfer is ill suited to CAN, you've left no room for errors and if used in production this may well be a source of problem.

    Now according to your highlighted section of manual you have to empty the last FIFO element before the next packet starts arriving in it. I figure you may have 6 to 20 uS to do that. You need to measure how long your read takes.

    So what are you doing to read? You read 17 message boxes performing the equivalent of 3 memcpy for each plus one memcpy for each full box plus one on function entry plus overhead. So 17*3+2 =53 memcpy or 424 bytes in 6 uS. At a rough guess 70 to 140 MB/s bandwidth. I don't know how close that is to the chip's limits but that starting to be significant bandwidth.

    I would not be surprised if this performed better without a FIFO and it certainly could be optimized but the first thing you need to do is measure. You cannot expect to fix a performance problem without actually measuring performance.

    Robert
  • Bravo, Robert!  

    Forum protocol, diagnostic tools, in-depth analysis (w/calculations) and the "necessity of measurement" - all "rolled into one!"  (and highlight free!)

    Poster's (wishing/hoping) to "cost-reduce" w/minimal effort (i.e. re-use past code, make no measurements) often land (rocky shores).   You've quite well outlined a more successful alternative...

    Re-use of past code - built for "another" MCU - usually demands serious review to insure that MCU mechanisms are consistent & that all key/critical timings remain w/in spec...    (measurement usually provides such needed confirmation - far trumps "wish/hope" - even worse, "blind expectation!")