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!