
/*********************************************************************************************************************//*-----------------------------------------------------Includes------------------------------------------------------*//*********************************************************************************************************************/#include "MULTICAN.h"/*********************************************************************************************************************//*-------------------------------------------------Global variables--------------------------------------------------*//*********************************************************************************************************************/AppMulticanType g_multican; /* Global MULTICAN configuration and control structure */AppLedType g_led; /* Global LED configuration and control structure *//*********************************************************************************************************************//*---------------------------------------------Function Implementations----------------------------------------------*//*********************************************************************************************************************//* Macro to define Interrupt Service Routine. * This macro: * - defines linker section as .intvec_tc<vector number>_<interrupt priority>. * - defines compiler specific attribute for the interrupt functions. * - defines the Interrupt service routine as ISR function. * * IFX_INTERRUPT(isr, vectabNum, priority) * - isr: Name of the ISR function. * - vectabNum: Vector table number. * - priority: Interrupt priority. Refer Usage of Interrupt Macro for more details. */IFX_INTERRUPT(canIsrTxHandler, 0, ISR_PRIORITY_CAN_TX);IFX_INTERRUPT(canIsrRxHandler, 0, ISR_PRIORITY_CAN_RX);/* Interrupt Service Routine (ISR) called once the TX interrupt has been generated. * Turns on the LED1 to indicate successful CAN message transmission. */void canIsrTxHandler(void){ /* Just to indicate that the CAN message has been transmitted by turning on LED1 */ IfxPort_setPinLow(g_led.led1.port, g_led.led1.pinIndex);}/* Interrupt Service Routine (ISR) called once the RX interrupt has been generated. * Compares the content of the received CAN message with the content of the transmitted CAN message * and in case of success, turns on the LED2 to indicate successful CAN message reception. */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); }}/* Function to initialize MULTICAN module, nodes and message objects related for this application use case */void initMultican(void){ /* ========================================================================================== * CAN module configuration and initialization: * ========================================================================================== * - load default CAN module configuration into configuration structure * * - define the interrupt priority for both interrupt node pointers used in the example * * - initialize CAN module with the modified configuration * ========================================================================================== */ 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:源CAN节点配置和初始化: * ========================================================================================== * - load default CAN node configuration into configuration structure * * - set source CAN node in the "Loop-Back" mode (no external pins will be used) * - assign source CAN node to CAN node 0 * * - initialize the source CAN node with the modified configuration * ========================================================================================== */ IfxMultican_Can_Node_initConfig(&g_multican.canNodeConfig, &g_multican.can); g_multican.canNodeConfig.loopBackMode = TRUE;//将源CAN节点设置为“环回”模式(不使用外部引脚) g_multican.canNodeConfig.nodeId = IfxMultican_NodeId_0;//将源CAN节点分配给CAN节点0 IfxMultican_Can_Node_init(&g_multican.canSrcNode, &g_multican.canNodeConfig); /* ========================================================================================== * Destination CAN node configuration and initialization: * ========================================================================================== * - load default CAN node configuration into configuration structure * * - set destination CAN node in the "Loop-Back" mode (no external pins will be used) * - assign destination CAN node to CAN node 1 * * - initialize the destination CAN node with the modified configuration * ========================================================================================== */ 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); /* ========================================================================================== * Source message object configuration and initialization:源消息对象配置和初始化 * ========================================================================================== * - load default CAN message object configuration into configuration structure * 将默认CAN消息对象配置加载到配置结构中 * - define the message object ID * - define the CAN message ID used during arbitration phase * - define the message object as a transmit message object * - enable interrupt generation in case of CAN message transmission * - define interrupt node pointer to be used * * - initialize the source CAN message object with the modified configuration * ========================================================================================== */ IfxMultican_Can_MsgObj_initConfig(&g_multican.canMsgObjConfig, &g_multican.canSrcNode); g_multican.canMsgObjConfig.msgObjId = SRC_MESSAGE_OBJECT_ID;//源消息的对象ID g_multican.canMsgObjConfig.messageId = CAN_MESSAGE_ID;//仲裁段ID,它决定着数据帧发送的优先级,也决定着其它节点是否会接收这个数据帧 g_multican.canMsgObjConfig.frame = IfxMultican_Frame_transmit;//发送模式 g_multican.canMsgObjConfig.txInterrupt.enabled = TRUE;//发送中断使能 g_multican.canMsgObjConfig.txInterrupt.srcId = TX_INTERRUPT_SRC_ID;//发送中断的服务请求ID,定义要使用的中断节点指针 IfxMultican_Can_MsgObj_init(&g_multican.canSrcMsgObj, &g_multican.canMsgObjConfig); /* ========================================================================================== * Destination message object configuration and initialization: * ========================================================================================== * - load default CAN message object configuration into configuration structure * * - define the message object ID (different than the ID used for source MO) * - define the CAN message ID used during arbitration phase (same as ID used for source MO) * - define the message object as a receive message object * - enable interrupt generation in case of CAN message transmission * - define interrupt node pointer to be used (different than the one used for source MO) * * - initialize the destination CAN message object with the modified configuration * ========================================================================================== */ IfxMultican_Can_MsgObj_initConfig(&g_multican.canMsgObjConfig, &g_multican.canDstNode); g_multican.canMsgObjConfig.msgObjId = DST_MESSAGE_OBJECT_ID;//消息对象ID g_multican.canMsgObjConfig.messageId = CAN_MESSAGE_ID;//仲裁段ID,它决定着数据帧发送的优先级,也决定着其它节点是否会接收这个数据帧 g_multican.canMsgObjConfig.frame = IfxMultican_Frame_receive;//接收模式 g_multican.canMsgObjConfig.rxInterrupt.enabled = TRUE; g_multican.canMsgObjConfig.rxInterrupt.srcId = RX_INTERRUPT_SRC_ID;//定义要使用的中断节点指针(不同于用于源MO的指针) IfxMultican_Can_MsgObj_init(&g_multican.canDstMsgObj, &g_multican.canMsgObjConfig);}/* Function to initialize both TX and RX messages with the default data values. * After initialization of the messages, the TX message will be transmitted. */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, 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 initLed(void){ /* ====================================================================== * Configuration of the pins connected to the LEDs: * ====================================================================== * - define the GPIO port * - define the GPIO pin that is the connected to the LED * - define the general GPIO pin usage (no alternate function used) * - define the pad driver strength * ====================================================================== */ g_led.led1.port = &MODULE_P00; g_led.led1.pinIndex = PIN5; g_led.led1.mode = IfxPort_OutputIdx_general; g_led.led1.padDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; g_led.led2.port = &MODULE_P00; g_led.led2.pinIndex = PIN6; g_led.led2.mode = IfxPort_OutputIdx_general; g_led.led2.padDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1; /* Initialize the pins connected to LEDs to level "HIGH"; will keep the LEDs turned off as default state */ IfxPort_setPinHigh(g_led.led1.port, g_led.led1.pinIndex); IfxPort_setPinHigh(g_led.led2.port, g_led.led2.pinIndex); /* Set the pin input/output mode for both pins connected to the LEDs */ IfxPort_setPinModeOutput(g_led.led1.port, g_led.led1.pinIndex, IfxPort_OutputMode_pushPull, g_led.led1.mode); IfxPort_setPinModeOutput(g_led.led2.port, g_led.led2.pinIndex, IfxPort_OutputMode_pushPull, g_led.led2.mode); /* Set the pad driver mode for both pins connected to the LEDs */ IfxPort_setPinPadDriver(g_led.led1.port, g_led.led1.pinIndex, g_led.led1.padDriver); IfxPort_setPinPadDriver(g_led.led2.port, g_led.led2.pinIndex, g_led.led2.padDriver);}
#ifndef MULTICAN_H_#define MULTICAN_H_ 1/*********************************************************************************************************************//*-----------------------------------------------------Includes------------------------------------------------------*//*********************************************************************************************************************/#include "Ifx_Types.h"#include "IfxMultican_Can.h"#include "IfxMultican.h"#include "IfxPort.h" /* For GPIO Port Pin Control *//*********************************************************************************************************************//*------------------------------------------------------Macros-------------------------------------------------------*//*********************************************************************************************************************/#define SRC_MESSAGE_OBJECT_ID (IfxMultican_MsgObjId)0 /* Source message object ID */#define DST_MESSAGE_OBJECT_ID (IfxMultican_MsgObjId)1 /* Destination message object ID */#define CAN_MESSAGE_ID 0x777 /* Message ID that will be used in arbitration phase */#define TX_INTERRUPT_SRC_ID IfxMultican_SrcId_0 /* Transmit interrupt service request ID */#define RX_INTERRUPT_SRC_ID IfxMultican_SrcId_1 /* Receive interrupt service request ID */#define PIN5 5 /* LED1 used in TX ISR is connected to this pin */#define PIN6 6 /* LED2 used in RX ISR is connected to this pin */#define INVALID_DATA_VALUE (uint32)0xDEADBEEF /* Used to invalidate RX message data content */#define INVALID_ID_VALUE (uint32)0xFFFFFFFF /* Used to invalidate RX message ID value */#define ISR_PRIORITY_CAN_TX 2 /* Define the CAN TX interrupt priority */#define ISR_PRIORITY_CAN_RX 1 /* Define the CAN RX interrupt priority *//*********************************************************************************************************************//*--------------------------------------------------Data Structures--------------------------------------------------*//*********************************************************************************************************************/typedef struct{ IfxMultican_Can can; /* CAN module handle to HW module SFR set */ IfxMultican_Can_Config canConfig; /* CAN module configuration structure */ IfxMultican_Can_Node canSrcNode; /* CAN source node handle data structure */ IfxMultican_Can_Node canDstNode; /* CAN destination node handle data structure */ IfxMultican_Can_NodeConfig canNodeConfig; /* CAN node configuration structure */ IfxMultican_Can_MsgObj canSrcMsgObj; /* CAN source message object handle data structure */ IfxMultican_Can_MsgObj canDstMsgObj; /* CAN destination message object handle data structure */ IfxMultican_Can_MsgObjConfig canMsgObjConfig; /* CAN message object configuration structure */ IfxMultican_Message txMsg; /* Transmitted CAN message structure */ IfxMultican_Message rxMsg; /* Received CAN message structure */} AppMulticanType;typedef struct{ IfxPort_Pin_Config led1; /* LED1 configuration structure */ IfxPort_Pin_Config led2; /* LED2 configuration structure */} AppLedType;/*********************************************************************************************************************//*-----------------------------------------------Function Prototypes-------------------------------------------------*//*********************************************************************************************************************/void canIsrTxHandler(void);void canIsrRxHandler(void);void initMultican(void);void transmitCanMessage(void);void initLed(void);#endif /* MULTICAN_H_ */