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-Q1: Sending CAN messages wit Payload all zero generate issues TCAN4550

Part Number: TCAN4550-Q1
Other Parts Discussed in Thread: TCAN4550

Tool/software:

Hi all,

I am developing a board using the TCAN4550 for expansion wit CAN FD.

My application consists of a device retransmitting CAN Frames between multiple CAN Ports like a router. So far I am testing retransmisison between the CAN module of TCAN4550 and an integrated DCAN Module of my uC (TMS570LS1227ZWT).

My routine consists briefly of:

-> CAN Reg 3 ISR Handler:

- read new message

- copy relevant infos (DLC, Extended ID flag, payload) into a temporary buffer

- retransmit the message on the TCAN module

I found an issue whenever my payload data is set to all 0, in particular i see that the TCAN is sending randomly the message multiple times instead of once (I checked and there is no spurious messages received on CAN3 or entries in the CAN 3 ISR). This result in the TCAN module sending out the message multiple times and randomly stop after a while throwing a PEA error and setting flags for Bus Off.

the issue is not present if at least one bit of the payload data is different than 0.

Below I report my MRAM configuration as well as ISR handler routine.

how can I send frames with data all zero without issues? I can tell is linked to the payload since if I force a static payload different than 0 or just send messages with a payload different than 0 the issue is not happening anymore.

The routines for writing are the one of the TCAN4550 Demo Node 1 for TMS570

SPI is set up to 18Mhz, crystal of TCAN4550 is 40MHz, uC frequency is set to 180MHz.

I already tested retransmission at above 50% of bus load without any issue, so it doesn't seems related to any physical layer issue.

CAN 3 IRS Handler:

 if(node == canREG3)
{
received_frames[CAN_PORT_3]++;
if(CAN_Ports[CAN_PORT_3].Forward_To > 0)
{
// Get ID
if(CAN_Ports[CAN_MODULE_3].IDExtended)
{
CAN_Receive_Buffer[CAN_PORT_3][CAN_Transmit_queue_index_rx[CAN_PORT_3]].frame_id = canGetID(canREG3,messageBox)>>0U;
CAN_Receive_Buffer[CAN_PORT_3][CAN_Transmit_queue_index_rx[CAN_PORT_3]].IDExtended = 1;
}
else
{
CAN_Receive_Buffer[CAN_PORT_3][CAN_Transmit_queue_index_rx[CAN_PORT_3]].frame_id = canGetID(canREG3,messageBox)>>18U;
CAN_Receive_Buffer[CAN_PORT_3][CAN_Transmit_queue_index_rx[CAN_PORT_3]].IDExtended = 0;
}
// Get Data
CAN_Receive_Buffer[CAN_PORT_3][CAN_Transmit_queue_index_rx[CAN_PORT_3]].dlc = (uint8_t)canGetPacketData(canREG3, messageBox, CAN_Receive_Buffer[CAN_PORT_3][CAN_Transmit_queue_index_rx[CAN_PORT_3]].data);

// This is needed to track whether a message cannot be sent at a time and for so the corresponding flag is still set
header.DLC = CAN_Receive_Buffer[CAN_PORT_3][CAN_Transmit_queue_index_rx[CAN_PORT_3]].dlc; // Set the DLC to be equal to or less than the data payload (it is ok to pass a 64 byte data array into the WriteTXFIFO function if your DLC is 8 bytes, only the first 8 bytes will be read)
header.ID = CAN_Receive_Buffer[CAN_PORT_3][CAN_Transmit_queue_index_rx[CAN_PORT_3]].frame_id; // Set the ID. #1 board use 0x128, #2 board use 0x158
header.XTD = CAN_Receive_Buffer[CAN_PORT_3][CAN_Transmit_queue_index_rx[CAN_PORT_3]].IDExtended;

TCAN45xStatus[9] = MCAN_WriteTXFIFO(CAN4_msb_tx_index, &header, CAN_Receive_Buffer[CAN_PORT_3][CAN_Transmit_queue_index_rx[CAN_PORT_3]].data);

if(TCAN45xStatus[9]>0)
{
AHB_WRITE_B_FL_32(M_CAN_TXBAR, TCAN45xStatus[9]); // Now we can send the TX FIFO element 1 data that we had queued up earlier but didn't send.
DataTxCount++;

}
if(++CAN_Transmit_queue_index_rx[CAN_PORT_3]>=RX_BUFFER_LEN)
{
CAN_Transmit_queue_index_rx[CAN_PORT_3] = 0;
}
if(++CAN4_msb_tx_index>20)
{
CAN4_msb_tx_index = 0;
}

// Debug
TCAN45xStatus[0] = AHB_READ_B_FL_32(SPI_STATUS);
TCAN45xStatus[1] = AHB_READ_B_FL_32(DEV_IR);
TCAN45xStatus[2] = AHB_READ_B_FL_32(0x0824);
MCAN_ReadInterruptRegister(&MCAN_IR); // Read the interrupt register
}

MRAM config

#define TCAN_NominalBitRatePrescaler 1
#define TCAN_NominalTimeSeg1andProp 32
#define TCAN_NominalTimeSeg2 8
#define TCAN_NominalSyncJumpWidth 8

#define TCAN_DataBitRatePrescaler 1
#define TCAN_DataTimeSeg1andProp 32
#define TCAN_DataTimeSeg2 8
#define TCAN_DataSyncJumpWidth 8

/* TCAN MRAM configuration */
#define MRAM_SIDNumElements 1 //Standard ID number of elements
#define MRAM_XIDNumElements 1 //Extended ID number of elements
#define MRAM_Rx0NumElements 64 //RX0 Number of elements
#define MRAM_Rx0ElementSize MRAM_8_Byte_Data //RX0 FIFO data payload size (Use the defines)
#define MRAM_Rx1NumElements 0 //RX1 number of elements
#define MRAM_Rx1ElementSize MRAM_8_Byte_Data //RX1 FIFO data payload size (use the defines)
#define MRAM_RxBufNumElements 0 //RX buffer number of elements
#define MRAM_RxBufElementSize MRAM_8_Byte_Data //RX buffer data payload size (use the defines)
#define MRAM_TxEventFIFONumElements 0 //TX Event FIFO number of elements
#define MRAM_TxBufferNumElements 21 //TX buffer number of elements
#define MRAM_TxBufferElementSize MRAM_8_Byte_Data //TX buffer data payload size (use the defines)

If anyone could give me a hint it would really be appreciated, thanks!

  • I update the thread to say that I was able to replicate the issue by changing the payload size (DLC) of the message header.

    It seems that  using a DLC of more than 8 bytes helps in avoiding the message transmission to stop. However, I don't understand why. I checked the TXFQS register to check that there are fifos available and I use the put index as a reference for the fifo to use, but this does not change. As you may understand, since I need to dinamically change the DLC of a message, I cannot afford to use a Payload of more than 8bytes

  • Hi Alberto,

    I apologize for the delayed response due to the Holidays.

    Do I understand that you are using 1Mbps for both your CAN Nominal (Arbitration) and Data bit rates with an 80% sample point?

    Are you sending classical CAN messages or CAN FD messages?

    I found an issue whenever my payload data is set to all 0, in particular i see that the TCAN is sending randomly the message multiple times instead of once (I checked and there is no spurious messages received on CAN3 or entries in the CAN 3 ISR). This result in the TCAN module sending out the message multiple times and randomly stop after a while throwing a PEA error and setting flags for Bus Off.

    the issue is not present if at least one bit of the payload data is different than 0.

    The PEA is a Protocol Error in the Arbitration phase of the message.  This means that a fixed or required bit was not correctly sampled.  If an error such as the PEA occurs during transmission, the TCAN4550 will try to re-transmit the message until it is successfully transmitted without error. This is likely why you see the message being sent "randomly" multiple times, and eventually entering a Bus Off condition when the Transmit Error Counter (TEC) exceeds the max limit.

    The errors may be due to a bit timing and sample point location issue between the TCAN4550 and the other receiving nodes on the CAN bus.  However, it could be an error with the contents of the message buffer itself.  Can you provide the TX Message Buffer contents that are being loaded into the TCAN4550's MRAM TX Buffer element?

    Could you try to read back and log the various Status, Interrupt, and Error Counter registers? (0x000C, 0x0820, 0x0824 or 0x1050, 0x1040, 0x1044)

    Do you have a total of 60 ohms worth of bus termination resistance between CANH and CANL (two sets of 120 ohms)?

    Can you capture any scope plots of the CAN messages that are generating errors? 

    The CAN protocol uses Bit Stuffing which limits the number of consecutive 1's or 0's that are transmitted to 5 and the device will automatically insert or stuff a single bit of opposite polarity in between long strings of consecutive bits.  In your case, an all zero data payload will result in a long string of dominant bits and the device will insert or stuff a single recessive bit after every 5 dominant bits.  It is possible then to see errors come from this single recessive bit failing to reach the full recessive level if the bit rate is too fast, or the bus loading and termination doesn't allow it enough time to reach the required recessive voltage.

    Changing a single data bit will result in additional recessive bits in the data portion of the message and break up the bit stuffing.  However, I would expect the error to occur in the data phase instead of the arbitration phase of the message as you are indicating. The information in the Protocol Status Register (PSR 0x1044) may be able to provide additional information with an error code.

    Have you tried the inverse with a data field of all ones?

    Have you tried with a slower CAN bit rate configuration or different sample point locations?

    It seems that  using a DLC of more than 8 bytes helps in avoiding the message transmission to stop. However, I don't understand why.

    This again may point to a bit sampling or timing configuration issue and a different DLC value results in different bits in the message header. 

    Regards,

    Jonathan