/*********************************************************************************************************************/
/*-----------------------------------------------------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_ */