Other Parts Discussed in Thread: TCAN4550
Hi,
I am experiencing a problem while receiving messages with payloads greater than 32 bytes. Some info:
- Setup with three devices (MCU1 + TCAN1044, MCU2 + TCAN4550, PeakCAN in Listen mode), so I can be sure that TCAN4550 is acknowledging the message.
- Tx messages are generated correctly by MCU2 + TCAN4550, even messages with 64 bytes of payload (FD + BRS)
- The problem consists in the payload extracted from the TCAN4550 by MCU2 being different from the payload in the message.
In the table below I list the increasingly complex PDOs I have generated from MCU1 and how they are received on MCU2:

Below are the 2 messages that cannot be read. the yellow part is the change with respect to the previous message, so I'm quite confident that TCAN4550 actually received those messages, but it is failing to provide their correct content.
Message 1 – 48 bytes wrongly received – this happens each time the PDO with CAN ID 0x228 is received (with payload of 48 bytes)

Message 2 – 64 bytes wrongly received – this happens each time the PDO with CAN ID 0x228 is received (with payload of 64 bytes)

The PDO is read from FIFO RX 1, and apparently everything is working fine until I extract the payload of messages with a payload size of 48 or more.
I can see looping extracting messages from the 5 FIFO elements of FIFO RX 1, whose element size is set to 64 bytes. Message ID and DLC are correct.
I've added the initialization code: I’m using the TCAN4550 library provided by TI.
I'm also adding the resulting configuration from the init code:
Any idea on what could possibily go wrong ?
/** **************************************************************************
* @brief Init CAN peripheral.
* @param NodeID id of the peripheral that has to be initialised
* @return void
************************************************************************** */
bool CAN_enablePeripheral(uint8_t NodeID) {
// Note : this function has been derived from the InitCAN procedure from TI code
// local variables
bool bSuccess = true;
TCAN4x5x_Device_ClearSPIERR(); // Clear any SPI ERR flags that might be set as a result of our pin mux changing during MCU startup
// Step one attempt to clear all interrupts
TCAN4x5x_Device_Interrupt_Enable dev_ie = {0}; // Initialize to 0 to all bits are set to 0.
TCAN4x5x_Device_ConfigureInterruptEnable(&dev_ie); // Disable all non-MCAN related interrupts for simplicity
TCAN4x5x_Device_Interrupts dev_ir = {0}; // Setup a new MCAN IR object for easy interrupt checking
TCAN4x5x_Device_ReadInterrupts(&dev_ir); // Request that the struct be updated with current DEVICE (not MCAN) interrupt values
if (dev_ir.PWRON) // If the Power On interrupt flag is set
TCAN4x5x_Device_ClearInterrupts(&dev_ir); // Clear it because if it's not cleared within ~4 minutes, it goes to sleep
// Configure the CAN bus speeds
TCAN4x5x_MCAN_Nominal_Timing_Simple TCANNomTiming = {0}; // 1 Mbps arbitration with a 40 MHz crystal ((40E6 / 1) / (32 + 8) = 1E6)
TCANNomTiming.NominalBitRatePrescaler = 1; // Sampling point @1 Mbit/s = 32 / (32 + 8) = 80%
TCANNomTiming.NominalTqBeforeSamplePoint = 32;
TCANNomTiming.NominalTqAfterSamplePoint = 8;
#if CAN_FD_SUPPORT
#if CANFD_DATA_BITRATE == 8
#if CANFD_DATA_TIMING_RAW
TCAN4x5x_MCAN_Data_Timing_Raw TCANDataTiming = {0}; // 8 Mbps CAN FD requires the raw initializer, which includes the transmitter delay compensation
TCANDataTiming.DataBitRatePrescaler = 0; // 1 Syn + 1(+1) Propagation and TimeSeg1 + 1(+1) TimeSeg2 = 5
TCANDataTiming.DataTimeSeg1andProp = 1; // 40E6 / 5 = 8E6 = 8 Mbit/s
TCANDataTiming.DataTimeSeg2 = 1;
TCANDataTiming.DataSyncJumpWidth = 1;
// Transceiver delay compensation: tloop = 125 ns
TCANDataTiming.TDCOffset = 5;
TCANDataTiming.TDCFilter = 3;
#else // CANFD_DATA_TIMING_RAW
// Simple mode for setting
TCAN4x5x_MCAN_Data_Timing_Simple TCANDataTiming = {0}; // 8 Mbps CAN FD with a 40 MHz crystal (40E6 / (4 + 1) = 8E6), sample point 80%
TCANDataTiming.DataBitRatePrescaler = 1;
TCANDataTiming.DataTqBeforeSamplePoint = 4;
TCANDataTiming.DataTqAfterSamplePoint = 1;
#endif // CANFD_DATA_TIMING_RAW
#else
/* Support for other bit rates */
#endif
#endif // CAN_FD_SUPPORT
// Configure the MCAN core settings
TCAN4x5x_MCAN_CCCR_Config cccrConfig = {0}; // Remember to initialize to 0, or you'll get random garbage!
#if CAN_FD_SUPPORT
cccrConfig.FDOE = 1; // CAN FD mode enable
cccrConfig.BRSE = 1; // CAN FD Bit rate switch enable
// cccrConfig.DAR = 1; // Disable Automatic Retransmission (debug)
#endif
// Configure the default CAN packet filtering settings
TCAN4x5x_MCAN_Global_Filter_Configuration gfc = {0};
gfc.RRFE = 1; // Reject remote frames (TCAN4x5x doesn't support this)
gfc.RRFS = 1; // Reject remote frames (TCAN4x5x doesn't support this)
gfc.ANFE = TCAN4x5x_GFC_REJECT; // Default behavior if incoming message doesn't match a filter is to reject for extended ID messages (29 bit IDs)
gfc.ANFS = TCAN4x5x_GFC_REJECT; // Default behavior if incoming message doesn't match a filter is to reject for standard ID messages (11 bit IDs)
/* ************************************************************************
* In the next configuration block, we will set the MCAN core up to have:
* - n. FDCAN_nStandardFilters SID filter elements
* - n. FDCAN_nExtendedFilters XID Filter element
* - 5 RX FIFO 0 elements
* - RX FIFO 0 supports data payloads up to 64 bytes
* - 5 RX FIFO 1 elements
* - RX FIFO 1 supports data payloads up to 64 bytes
* - RX Buffer will not have any element, but we still set their data payload sizes, even though it's not required
* - No TX Event FIFOs
* - 5 Transmit buffers supporting up to 64 bytes of data payload
*/
/**
* Setup MCAN core in order to have:
*
* - Rx filters according to the structures in the local file
* - Rx FIFO 0 typically hosts NMT and SDO messages (up to 5 entries in the FIFO)
* - Rx FIFO 1 typically hosts PDO messages (up to 5 entries in the FIFO)
*/
TCAN4x5x_MRAM_Config MRAMConfiguration = {0};
MRAMConfiguration.SIDNumElements = FDCAN_nStandardFilters; // Standard ID number of elements, you MUST have a filter written to MRAM for each element defined
MRAMConfiguration.XIDNumElements = FDCAN_nExtendedFilters; // Extended ID number of elements, you MUST have a filter written to MRAM for each element defined
MRAMConfiguration.Rx0NumElements = 5; // RX0 Number of elements
MRAMConfiguration.Rx0ElementSize = MRAM_64_Byte_Data; // RX0 data payload size
MRAMConfiguration.Rx1NumElements = 5; // RX1 number of elements
MRAMConfiguration.Rx1ElementSize = MRAM_64_Byte_Data; // RX1 data payload size
MRAMConfiguration.RxBufNumElements = 0; // RX buffer number of elements
MRAMConfiguration.RxBufElementSize = MRAM_64_Byte_Data; // RX buffer data payload size
MRAMConfiguration.TxEventFIFONumElements = 0; // TX Event FIFO number of elements
MRAMConfiguration.TxBufferNumElements = 5; // TX buffer number of elements
MRAMConfiguration.TxBufferElementSize = MRAM_64_Byte_Data; // TX buffer data payload size
/* Configure the MCAN core with the settings above, the changes in this block are write protected registers, *
* so it makes the most sense to do them all at once, so we only unlock and lock once */
TCAN4x5x_MCAN_EnableProtectedRegisters(); // Start by making protected registers accessible
TCAN4x5x_MCAN_ConfigureCCCRRegister(&cccrConfig); // Enable FD mode and Bit rate switching
TCAN4x5x_MCAN_ConfigureGlobalFilter(&gfc); // Configure the global filter configuration (Default CAN message behavior)
TCAN4x5x_MCAN_ConfigureNominalTiming_Simple(&TCANNomTiming);// Setup nominal/arbitration bit timing
#if CAN_FD_SUPPORT
#if CANFD_DATA_TIMING_RAW
TCAN4x5x_MCAN_ConfigureDataTiming_Raw(&TCANDataTiming); // Setup CAN FD timing (raw settings)
#else // CANFD_DATA_TIMING_RAW
TCAN4x5x_MCAN_ConfigureDataTiming_Simple(&TCANDataTiming); // Setup CAN FD timing (simple settings)
#endif // CANFD_DATA_TIMING_RAW
#endif // CAN_FD_SUPPORT
TCAN4x5x_MRAM_Clear(); // Clear all of MRAM (Writes 0's to all of it)
TCAN4x5x_MRAM_Configure(&MRAMConfiguration); // Set up the applicable registers related to MRAM configuration
TCAN4x5x_MCAN_DisableProtectedRegisters(); // Disable protected write and take device out of INIT mode
// Set the interrupts we want to enable for MCAN
TCAN4x5x_MCAN_Interrupt_Enable mcan_ie = {0}; // Remember to initialize to 0, or you'll get random garbage!
mcan_ie.RF0NE = 1; // RX FIFO 0 new message interrupt enable
TCAN4x5x_MCAN_ConfigureInterruptEnable(&mcan_ie); // Enable the appropriate registers
CAN_initCANopenFilters(NodeID); // Init filters
if (bSuccess)
{
// Configure the TCAN4550 Non-CAN-related functions
TCAN4x5x_DEV_CONFIG devConfig = {0}; // Remember to initialize to 0, or you'll get random garbage!
devConfig.SWE_DIS = 0; // Keep Sleep Wake Error Enabled (it's a disable bit, not an enable)
devConfig.DEVICE_RESET = 0; // Not requesting a software reset
devConfig.WD_EN = 0; // Watchdog disabled
devConfig.nWKRQ_CONFIG = 0; // Mirror INH function (default)
devConfig.INH_DIS = 0; // INH enabled (default)
devConfig.GPIO1_GPO_CONFIG = TCAN4x5x_DEV_CONFIG_GPO1_MCAN_INT1; // MCAN nINT 1 (default)
devConfig.FAIL_SAFE_EN = 0; // Failsafe disabled (default)
devConfig.GPIO1_CONFIG = TCAN4x5x_DEV_CONFIG_GPIO1_CONFIG_GPO; // GPIO set as GPO (Default)
devConfig.WD_ACTION = TCAN4x5x_DEV_CONFIG_WDT_ACTION_nINT; // Watchdog set an interrupt (default)
devConfig.WD_BIT_RESET = 0; // Don't reset the watchdog
devConfig.nWKRQ_VOLTAGE = 0; // Set nWKRQ to internal voltage rail (default)
devConfig.GPO2_CONFIG = TCAN4x5x_DEV_CONFIG_GPO2_NO_ACTION; // GPO2 has no behavior (default)
devConfig.CLK_REF = 1; // Input crystal is a 40 MHz crystal (default)
devConfig.WAKE_CONFIG = TCAN4x5x_DEV_CONFIG_WAKE_BOTH_EDGES;// Wake pin can be triggered by either edge (default)
TCAN4x5x_Device_Configure(&devConfig); // Configure the device with the above configuration
TCAN4x5x_Device_SetMode(TCAN4x5x_DEVICE_MODE_NORMAL); // Set to normal mode, since configuration is done. This line turns on the transceiver
TCAN4x5x_MCAN_ClearInterruptsAll(); // Resets all MCAN interrupts (does NOT include any SPIERR interrupts)
CAN_DriverEnable(); // Enable Hw driver
}
// At this step, return the status of initialization
return (bSuccess);
} // end CAN_enablePeripheral







