
Introduction
This article discusses implementing CAN on Aurix TC275 microcontroller using the KIT_AURIX_TC275_LITE evaluation board. The implementation is based on Infineon’s official example project MULTICAN_1_KIT_TC275_LK, with a focus on modifying it to disable Loop-Back mode in order to enable communication with external CAN devices.
In the original example, MULTICAN_1_KIT_TC275_LK demonstrates the use of the MultiCAN module for internal CAN data transmission. It establishes communication between CAN Node 0 and CAN Node 1 within the same board by using Loop-Back mode. While this setup is useful for verifying internal functionality, Loop-Back mode shall be disabled to allow actual CAN communication with external nodes or devices.
CAN Transmission
The CAN transmission implementation in the official code example can be summarized in steps below:
- CAN Initialization – Provided in
initMultican()- CAN module configuration and initialization
- Source CAN node configuration and initialization
- Source message object configuration and initialization (CanID, Enabling Interrupt for CAN transmission…)
- CAN message transmission – Provided in
transmitCanMessage() - Interrupt Service Routine – Provided in
canIsrTxHandler()to turn on the LED1 when a TX interrupt is generated and the CAN transmission is successful.
void initMultican(void)
{
/* CAN module configuration and initialization */
IfxMultican_Can_initModuleConfig(&g_multican.canConfig, &MODULE_CAN);
g_multican.canConfig.nodePointer[TX_INTERRUPT_SRC_ID].priority = ISR_PRIORITY_CAN_TX;
g_multican.canConfig.nodePointer[RX_INTERRUPT_SRC_ID].priority = ISR_PRIORITY_CAN_RX;
IfxMultican_Can_initModule(&g_multican.can, &g_multican.canConfig);
/* Source CAN node configuration and initialization */
IfxMultican_Can_Node_initConfig(&g_multican.canNodeConfig, &g_multican.can);
g_multican.canNodeConfig.loopBackMode = TRUE;
g_multican.canNodeConfig.nodeId = IfxMultican_NodeId_0;
IfxMultican_Can_Node_init(&g_multican.canSrcNode, &g_multican.canNodeConfig);
/* Source message object configuration and initialization */
IfxMultican_Can_MsgObj_initConfig(&g_multican.canMsgObjConfig, &g_multican.canDstNode);
g_multican.canMsgObjConfig.msgObjId = DST_MESSAGE_OBJECT_ID;
g_multican.canMsgObjConfig.messageId = CAN_MESSAGE_ID;
g_multican.canMsgObjConfig.frame = IfxMultican_Frame_receive;
g_multican.canMsgObjConfig.rxInterrupt.enabled = TRUE;
g_multican.canMsgObjConfig.rxInterrupt.srcId = RX_INTERRUPT_SRC_ID;
IfxMultican_Can_MsgObj_init(&g_multican.canDstMsgObj, &g_multican.canMsgObjConfig);
...
}
...According to the board user manual, the AURIX™ TC275 Lite-Kit contains a CAN interface via the CAN Transceiver TLE9251V. It is connected to CAN node 0 and is in stand-by mode by default. The transceiver can be switched to normal operating mode by setting the transceiver pin STB (signal name #NEN) low from the CPU.

So the steps for implementation would be:
- CAN Initialization – Provided in
initMultican()- CAN module configuration and initialization
- Source CAN node configuration and initialization
- Source message object configuration and initialization
- CAN Pins configuration
- Enable CAN transceiver
- CAN message transmission – Provided in
transmitCanMessage() - Interrupt Service Routine – Provided in
canIsrTxHandler()
void initMultican(void)
{
/* CAN module configuration and initialization */
...
/* Source CAN node configuration and initialization */
IfxMultican_Can_Node_initConfig(&g_multican.canNodeConfig, &g_multican.can);
g_multican.canNodeConfig.loopBackMode = FALSE;
g_multican.canNodeConfig.nodeId = IfxMultican_NodeId_0;
/* CAN Pins configuration */
g_multican.canNodeConfig.rxPin=&IfxMultican_RXD0B_P20_7_IN;
g_multican.canNodeConfig.txPin=&IfxMultican_TXD0_P20_8_OUT;
IfxMultican_Can_Node_init(&g_multican.canSrcNode, &g_multican.canNodeConfig);
/* Enable CAN transceiver (TLE9251V): STB/#NEN low = normal mode */
IfxPort_setPinModeOutput(&MODULE_P20, 6, IfxPort_OutputMode_pushPull, IfxPort_OutputIdx_general);
IfxPort_setPinLow(&MODULE_P20, 6); // Drive #NEN low to enable transceiver
...
}
...CAN Receiving
Concerning CAN data receiving, the same principle applies with some few customisations. The steps involved in the official code example can be summarized in steps below:
- CAN Initialization – Provided in
initMultican()- CAN module configuration and initialization
- Destination CAN node configuration and initialization
- Destination message object configuration and initialization (CanID, Enabling Interrupt for CAN transmission…)
- CAN message receiving in interrupt mode – Managed in
canIsrTxHandler()to turn on the LED2 when an RX interrupt is generated and the CAN frame is successfully received.
/* Interrupt Service Routine (ISR) called once the RX interrupt has been generated. */
void canIsrRxHandler(void)
{
IfxMultican_Status readStatus;
/* Read the received CAN message and store the status of the operation */
readStatus = IfxMultican_Can_MsgObj_readMessage(&g_multican.canDstMsgObj, &g_multican.rxMsg);
/* If no new data has been received, report an error */
if( !( readStatus & IfxMultican_Status_newData ) )
{
while(1)
{
}
}
/* If new data has been received but with one message lost, report an error */
if( readStatus == IfxMultican_Status_newDataButOneLost )
{
while(1)
{
}
}
/* Finally, check if the received data matches with the transmitted one */
if( ( g_multican.rxMsg.data[0] == g_multican.txMsg.data[0] ) &&
( g_multican.rxMsg.data[1] == g_multican.txMsg.data[1] ) &&
( g_multican.rxMsg.id == g_multican.txMsg.id ) )
{
/* Turn on the LED2 to indicate correctness of the received message */
IfxPort_setPinLow(g_led.led2.port, g_led.led2.pinIndex);
}
}
void initMultican(void)
{
/* CAN module configuration and initialization */
...
/* Source CAN node configuration and initialization */
IfxMultican_Can_Node_initConfig(&g_multican.canNodeConfig, &g_multican.can);
g_multican.canNodeConfig.loopBackMode = TRUE;
g_multican.canNodeConfig.nodeId = IfxMultican_NodeId_1;
IfxMultican_Can_Node_init(&g_multican.canDstNode, &g_multican.canNodeConfig);The official code example configures CAN node 1 for receiving, and turns on LED2 when a specific frame is received. To receive CAN frames from external devices, the CAN node 0 shall be configured for that task instead of CAN node 1.
This section will implement a receiving use case that replies a specific CAN frame to the sender on “Rx CanID + 1” and turns on LED2 when a frame is received successfully.
/* Interrupt Service Routine (ISR) called once the RX interrupt has been generated. */
void canIsrRxHandler(void)
{
IfxMultican_Status readStatus;
/* Read the received CAN message */
readStatus = IfxMultican_Can_MsgObj_readMessage(&g_multican.canDstMsgObj, &g_multican.rxMsg);
/* If no new data, just return and do nothing */
if (!(readStatus & IfxMultican_Status_newData))
{
return;
}
/* If one message was lost, optionally log or blink LED, but do not halt */
if (readStatus == IfxMultican_Status_newDataButOneLost)
{
// Example: blink LED1 briefly to indicate error
IfxPort_setPinLow(g_led.led1.port, g_led.led1.pinIndex);
IfxPort_setPinHigh(g_led.led1.port, g_led.led1.pinIndex);
}
/* Replies with a frame in "Rx CanID + 1" */
g_multican.canMsgObjConfig.messageId = g_multican.rxMsg.id + 1;
replyCanMessage();
/* Indicate reception via LED2 */
IfxPort_setPinLow(g_led.led2.port, g_led.led2.pinIndex);
}
/* Function to initialize MULTICAN module, nodes and message objects related for this application use case */
void initMultican(void)
{
/* CAN module configuration and initialization */
...
/* Source CAN node configuration and initialization */
...
/* Destination CAN node configuration and initialization */
IfxMultican_Can_Node_initConfig(&g_multican.canNodeConfig, &g_multican.can);
g_multican.canNodeConfig.loopBackMode = FALSE;
g_multican.canNodeConfig.nodeId = IfxMultican_NodeId_0;
g_multican.canNodeConfig.rxPin=&IfxMultican_RXD0B_P20_7_IN;
g_multican.canNodeConfig.txPin=&IfxMultican_TXD0_P20_8_OUT;
IfxMultican_Can_Node_init(&g_multican.canDstNode, &g_multican.canNodeConfig);
/* Source message object configuration and initialization */
IfxMultican_Can_MsgObj_initConfig(&g_multican.canMsgObjConfig, &g_multican.canSrcNode);
g_multican.canMsgObjConfig.msgObjId = SRC_MESSAGE_OBJECT_ID;
//g_multican.canMsgObjConfig.messageId = CAN_MESSAGE_ID;
g_multican.canMsgObjConfig.frame = IfxMultican_Frame_transmit;
g_multican.canMsgObjConfig.txInterrupt.enabled = TRUE;
g_multican.canMsgObjConfig.txInterrupt.srcId = TX_INTERRUPT_SRC_ID;
IfxMultican_Can_MsgObj_init(&g_multican.canSrcMsgObj, &g_multican.canMsgObjConfig);
/* Source message object configuration and initialization */
IfxMultican_Can_MsgObj_initConfig(&g_multican.canMsgObjConfig, &g_multican.canDstNode);
g_multican.canMsgObjConfig.msgObjId = DST_MESSAGE_OBJECT_ID;
g_multican.canMsgObjConfig.messageId = 0; // Set to 0 to receive frames from all CanIDs
g_multican.canMsgObjConfig.frame = IfxMultican_Frame_receive;
g_multican.canMsgObjConfig.rxInterrupt.enabled = TRUE;
g_multican.canMsgObjConfig.rxInterrupt.srcId = RX_INTERRUPT_SRC_ID;
g_multican.canMsgObjConfig.acceptanceMask = 0; // Standard ID mask
IfxMultican_Can_MsgObj_init(&g_multican.canDstMsgObj, &g_multican.canMsgObjConfig);
}
void transmitCanMessage(void)
{
/* Define the content of the data to be transmitted */
const uint32 dataLow = 0xC0CAC01A;
const uint32 dataHigh = 0xBA5EBA11;
/* Invalidation of the RX message */
IfxMultican_Message_init(&g_multican.rxMsg,
INVALID_ID_VALUE,
INVALID_DATA_VALUE,
INVALID_DATA_VALUE,
g_multican.canMsgObjConfig.control.messageLen);
/* Initialization of the TX message */
IfxMultican_Message_init(&g_multican.txMsg,
g_multican.canMsgObjConfig.messageId = CAN_MESSAGE_ID,
dataLow,
dataHigh,
g_multican.canMsgObjConfig.control.messageLen);
/* Send the CAN message with the previously defined TX message content */
while( IfxMultican_Status_notSentBusy ==
IfxMultican_Can_MsgObj_sendMessage(&g_multican.canSrcMsgObj, &g_multican.txMsg) )
{
}
}
void replyCanMessage(void)
{
/* Define the content of the data to be transmitted */
const uint32 dataLow = 0xA0A0A0;
const uint32 dataHigh = 0x11223344;
/* Invalidation of the RX message */
IfxMultican_Message_init(&g_multican.rxMsg,
INVALID_ID_VALUE,
INVALID_DATA_VALUE,
INVALID_DATA_VALUE,
g_multican.canMsgObjConfig.control.messageLen);
/* Initialization of the TX message */
IfxMultican_Message_init(&g_multican.txMsg,
g_multican.canMsgObjConfig.messageId,
dataLow,
dataHigh,
g_multican.canMsgObjConfig.control.messageLen);
/* Send the CAN message with the previously defined TX message content */
while( IfxMultican_Status_notSentBusy ==
IfxMultican_Can_MsgObj_sendMessage(&g_multican.canSrcMsgObj, &g_multican.txMsg) )
{
}
}Demo
References
Infineon-aurix-multican-1-kit-tc275-lk-tr-training-en.pdf










Leave a Reply