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.

TCAN4550: TCAN4550 buffer FIFO wrong data problem

Part Number: TCAN4550

HI TI Team!

I will try to describe my problem on prototype that we are preparing for mass production.

Let me first quickly describe what we want to achieve. Our CAN protocol is designed like this that in our grid there is master which is always asking and node always replying. Master is usually asking for parameter every 8ms. Parameters are incremented by master if it received answer successfully. Thant means that whole protocol is circling ( N*8ms) and then start owner after last parameter. If MASTER does not get right answer on certain parameter it will ask again after 64ms for 20 times then it will throw error. Answer is from node is created as soon it receive new data.

Software that we are using is your standard code for pooling data:

if (TCAN_Int_Cnt != 0 )
{
  TCAN_Int_Cnt--;

  TCAN4x5x_Device_ReadInterrupts(&dev_ir); // Read the device interrupt register
  TCAN4x5x_MCAN_ReadInterrupts(&mcan_ir); // Read the interrupt register

   if (dev_ir.SPIERR) // If the SPIERR flag is set
  TCAN4x5x_Device_ClearSPIERR(); // Clear the SPIERR flag

  if (mcan_ir.RF0N) // If a new message in RX FIFO 0
  {
    //TCAN4x5x_MCAN_RX_Header MsgHeader = {0}; // Initialize to 0 or you'll get garbage
    uint8_t numBytes = 0; // Used since the ReadNextFIFO function will return how many bytes of data were read
    //rx_data = {0}; // Used to store the received data

    TCAN4x5x_MCAN_ClearInterrupts(&mcan_ir); // Clear any of the interrupt bits that are set.

    numBytes = TCAN4x5x_MCAN_ReadNextFIFO(RXFIFO0, &RXMsgHeader, rx_data); // This will read the next element in the RX FIFO 0

    // numBytes will have the number of bytes it transfered in it. Or you can decode the DLC value in MsgHeader.DLC
    // The data is now in rx_data[], and message specific information is in the MsgHeader struct.
    tcan_msg_ID();
  }
}

iside function "tcan_msg_ID();" is this part of code

else if(0x6A9)
{

  can_msg_buff  = 0;
  can_msg_buff = rx_data[0];

  switch(can_msg_buff)
  {
    case 0x10:
    tcan_msg_ID_ack(STAT_OK,0x255,0x10,0x00,0x00,0x00,0x00);
    break;

    case 0x22:
    tcan_msg_ID_ack(STAT_OK,0x255,0x22,0x00,0x00,0x00,0x00);
    break;

    default:
    tcan_msg_ID_ack(STAT_OK,0x255,can_msg_buff,0x00,0x00,0x00,0x00);
    break;

    ......

    ......

}

void tcan_msg_ID_ack(uint8_t can_Status, uint16_t msg_ID, uint16_t par_ID, uint8_t data_0,uint8_t data_1,uint8_t data_2,uint8_t data_3)
{
TCAN4x5x_MCAN_TX_Header TXMsgHeader = {0};
TXMsgHeader.ID = msg_ID;
tx_data[0] = can_Status;
tx_data[1] = par_ID & 0x00FF;
tx_data[2] = par_ID>>8;
tx_data[3] = data_0;
tx_data[4] = data_1;
tx_data[5] = data_2;
tx_data[6] = data_3;
tx_data[7] = 0x00;

TXMsgHeader.RTR = 0; //Remote Transmission Request flag
TXMsgHeader.XTD = 0; // Extended Identifier flag
TXMsgHeader.ESI = 0; // Error state indicator flag
TXMsgHeader.DLC = MCAN_DLC_8B;
TXMsgHeader.BRS = 1; //Bit rate switch used flag
TXMsgHeader.FDF = 1; //CAN FD Format flag
TXMsgHeader.reserved = 0; //Reserved //1
TXMsgHeader.EFC = 0; //Event FIFO Control flag, to store tx events or not
TXMsgHeader.MM = 0; //Message Marker, used if @c EFC is set to 1 //1

TCAN4x5x_MCAN_WriteTXBuffer(0, &TXMsgHeader, tx_data);
TCAN4x5x_MCAN_TransmitBufferContents(0);
}

System example from.

0x6A9 is a master asking for parameter DB0 = 0x10 
0X255 is node answering on parameter DB0 = 0x01( status OK), DB1 = 0x10

Now lets go to problem. 
It was really hard to reproduce problem but i manage to do it with external PEAK CAN dongle.
These are the settings on PEAK dongle:



Dongle is acting as MASTER in my system. I am sending message 0x6A9 cyclic ever 10ms and message 0x583 every 1ms before and after 06A9 just to create traffic. I am expecting answer on ID 0x255 with parameter 0x40. 
Most of the time answer is right but now and then there is wrong answer. Of course i have set filter in TCA4550 for message 0x583 but i newer replay on it, my software is just listening this message.

Can you explain this behaver?

Regards.

Sebastian

  • Hi Sebastian,

    Thanks for your detailed description of your setup. 

    In the test that returns ID 0x255 with expected parameter 0x40, it appears that some of the messages instead contain 0x03. I'm having trouble connecting the variable in the code, but is this byte supposed to mirror the first byte of the command frame (in this case, the 0x03 from the ID 0x583 frame)? If the data in this dummy frame is changed, does the data in the extra sent frames change as well?

    If so, this may be because the dummy frames are being accepted into the RX fifo along with the filtered frames. The default behavior of the TCAN4550 is to accept all packets into Rx FIFO 0 unless the packet matches a filter, then the action described in the filter will be performed. In this case, you will need to catch the dummy frames in a filter to reject them. 

    I'm not sure why these dummy frames are only showing up some of the time, as it looks like more dummy frames are sent than test frames. I suspect this may be because some of these frames arrive while other events are being managed, so the interrupt pin does not reassert to trigger the service routine. However, 1ms should be sufficient spacing for this. Can you ensure that the RXFIFO has no additional messages available (mcan_ir.RF0N is not set) before waiting for the next interrupt trigger? If a larger delay is used between dummy frames, do more of these false response frames show up?

    Regards,
    Eric Schott

  • Hi Eric,

    Thank you for quick reply.

    Let me expand the code a little bit further: as you can see on first Data Byte of Payload we are using our own parameters(0x10,0x22,0x23,.....).
    if this parameter is outside of range let say 0x45, software will respond with "STAT_ERRADDRESS" in DataByte 0 and parameter number DataByte 1.

    else if(0x6A9)
    {

      can_msg_buff  = 0;
      can_msg_buff = rx_data[0];

      switch(can_msg_buff)
      {
        case 0x10:
        tcan_msg_ID_ack(STAT_OK,0x255,0x10,0x00,0x00,0x00,0x00);
        break;

        case 0x22:
        tcan_msg_ID_ack(STAT_OK,0x255,0x22,0x00,0x00,0x00,0x00);
        break;

        case 0x23:
        tcan_msg_ID_ack(STAT_OK,0x255,0x22,0x00,0x00,0x00,0x00);
        break;

        case 0x24:
        tcan_msg_ID_ack(STAT_OK,0x255,0x22,0x00,0x00,0x00,0x00);
        break;

        case 0x25:
        tcan_msg_ID_ack(STAT_OK,0x255,0x22,0x00,0x00,0x00,0x00);
        break;

        case 0x26:
        tcan_msg_ID_ack(STAT_OK,0x255,0x22,0x00,0x00,0x00,0x00);
        break;

        case 0x32:
        tcan_msg_ID_ack(STAT_OK,0x255,0x22,0x00,0x00,0x00,0x00);
        break;

        default:
        tcan_msg_ID_ack(STAT_ERRADDRESS,0x255,can_msg_buff,0x00,0x00,0x00,0x00);
        break;

    }

    Here is demostration.

    Now lets recreate problem. I will also change "My parameter"  DB0 from 0x03 to 0x04 which is unknown for my software and you will se what happens. If i increase cycling time to 10ms there is less error. If i decrease there is mor error packets.

    New settings. Message 583 and 6A9 are both accepted in FIFO0.

    And result:

    In my software i am newer responding to parameter 0x04 with CAN ID 0x255. That means there is some problem inside buffer. It looks like some indexing problem or something.

    I can also clearly see that in debug that ID i received is 0x6a9 but data payload is from 0x583.

    Regards.

    Seba

  • Hi Seba,

    I'm reviewing this info and will get back to you tomorrow. Thanks for your patience. 

    Regards,
    Eric Schott

  • Hi Eric,

    Is there any news?

    Regards.

    Seba

  • Seba,

    Thank you very much for your patience. We've had some high priority tasks pop up recently so Eric hasn't been able to address. We will try to get a response to you by Monday next week.

    Regards,

    Eric Hackett