
#include <plib.h>                      //调用通用头文件
#include "Ecan.h"




unsigned char RX_SID_Msg_Flag = 0;     //接收标志位
unsigned char RX_EID_Msg_Flag = 0;

CanMsgBuffer *TxMessage;               //发送结构指针
CanMsgBuffer *RxMessage;               //接收结构指针
  
unsigned char TXbuffer[8];             //发送数据缓冲区
unsigned char RXbuffer[8];             //接收数据缓冲区

unsigned char Can1MsgFiFo[3 * 2 * 16]; //FIFO 缓冲区
                                       //报文空间 ----> 16 Byte
                                       //报文数量 ----> 2个
                                       //缓冲区数 ----> 3个
		                               
		                               
//-------------------------------------------------------------------------------
//  SID 接收  配置 ->仅接收标准标识符报文
//-------------------------------------------------------------------------------
void Write_SID_Filter(unsigned short SendSID)
{
	C1FLTCON0bits.FSEL0 = 1;  //存储 use FIFO 1
	C1FLTCON0bits.MSEL0 = 0;  //屏蔽 use Mask 0
	C1RXF0bits.SID  = SendSID&0x7FF; //过滤 0x100
	C1RXF0bits.EXID = 0;             //标准 SID
	C1RXM0bits.SID  = SendSID&0x7F8; //屏蔽 低3位,接收8个 ID报文
	C1RXM0bits.MIDE = 1;      //匹配过滤器 MSG
	C1FLTCON0bits.FLTEN0 = 1; //使能过滤器 0
}

//-------------------------------------------------------------------------------
//  EID 接收  配置 ->仅接收扩展标识符报文
//-------------------------------------------------------------------------------
void Write_EID_Filter(unsigned int SendEID)
{	
	C1FLTCON0bits.FSEL1 = 2;  //存储 use FIFO 2
	C1FLTCON0bits.MSEL1 = 1;  //屏蔽 use Mask 1
	C1RXF1bits.SID  = (SendEID>>18)&0x7FF;  //11 bit 
	C1RXF1bits.EID  = SendEID&0x3FFFF;      //18 bit
	C1RXF1bits.EXID = 1;                    //扩展 EID
	C1RXM1bits.SID  = (SendEID>>18)&0x7FF;  //11 bit   屏蔽 低3位 接收8个ID报文
	C1RXM1bits.EID  = SendEID&0x3FFF8;      //18 bit 
	C1RXM1bits.MIDE = 1;      //匹配过滤器 MSG
	C1FLTCON0bits.FLTEN1 = 1; //使能过滤器 1
}

//-------------------------------------------------------------------------------
//  CAN 比特率  配置      FBaud = 250Kb/S
//-------------------------------------------------------------------------------
void Write_CAN_Baud(void)      //FTQ = N * FBuad  N = 10
{                          	   //FBaud = 250K
	C1CFGbits.BRP = 7;         //BRP = 40000000/(2*FTQ)-1 = 7
	                           	                
	C1CFGbits.SJW = 0;         //同步跳转 1 TQ 	                
	C1CFGbits.SAM = 1;         //总在在采样点采样3次
	C1CFGbits.SEG2PH = 4;      //相位缓冲段2位 3TQ
	C1CFGbits.SEG1PH = 5;      //相位缓冲段1位 3TQ
	C1CFGbits.PRSEG = 3;       //传播时间段位  3TQ
}
	
//-------------------------------------------------------------------------------
//  CAN 初始化                FBaud = 250Kb/S
//-------------------------------------------------------------------------------
void CAN_Init(void)
{
	C1CONbits.ON = 1;          //使能CAN模块
	C1CONbits.REQOP = 0x04;         //请求配置模式
	while(C1CONbits.OPMOD != 0x04); //确认配置模式

	C1FIFOBA = KVA_TO_PA(Can1MsgFiFo); //虚拟地址转物理地址

	Write_CAN_Baud();              //比特率 250kb/S

	Write_SID_Filter(0x100);       //SID 初始化 接收(0x100 - 0x107)
	Write_EID_Filter(0x1FFFFF00);  //EID 初始化 接收(0x1FFFFF00 - 0x1FFFFF07)
	
	C1FIFOCON0bits.FSIZE = 1;      //报文深度  2
	C1FIFOCON0bits.TXEN  = 1;      //FIFO0->发送
	
	C1FIFOCON1bits.FSIZE = 1;      //报文深度  2
	C1FIFOCON1bits.TXEN  = 0;      //FIFO1->接收
	
	C1FIFOCON2bits.FSIZE = 1;      //报文深度  2
	C1FIFOCON2bits.TXEN  = 0;      //FIFO2->接收
		
	C1FIFOINT1bits.RXNEMPTYIE = 1; //FIFO 1 接收非空中断
	C1FIFOINT2bits.RXNEMPTYIE = 1; //FIFO 2 接收非空中断
	
	C1INTbits.RBIE = 1;            //接收中断允许
	C1INTbits.TBIE = 0;            //发送中断禁止
	
	IPC11bits.CAN1IP = 4;          //CAN1 中断
	IPC11bits.CAN1IS = 1;
	IEC1bits.CAN1IE = 1;
	
//	C1CONbits.REQOP = 0x2;         //请求环回模式   单个节点 测试,使能语句
//	while (C1CONbits.OPMOD!=0x2);  //确认环回模式

	C1CONbits.REQOP = 0x0;         //请求正常模式   多个节点 测试,使能语句
	while (C1CONbits.OPMOD!=0x0);  //确认正常模式 
}  

//-------------------------------------------------------------------------------
//  CAN 发送 SID 报文
//-------------------------------------------------------------------------------
void CAN_TX_SID_Message(unsigned short MsgSID)
{
	TxMessage = PA_TO_KVA1(C1FIFOUA0);  //获取报文地址
	
	TxMessage->CMSGSID.SID = MsgSID&0x7FFF;  //发送 ID
	TxMessage->CMSGEID.IDE = 0;         //标准报文
	TxMessage->CMSGEID.DLC = 0x08;      //数据长度 8 Byte
	
	TxMessage->CMSGDATA0.Byte0 = 0x01;  //CMSGDAT0
	TxMessage->CMSGDATA0.Byte1 = 0x02;
	TxMessage->CMSGDATA0.Byte2 = 0x04;
	TxMessage->CMSGDATA0.Byte3 = 0x08;
	
	TxMessage->CMSGDATA1.Byte4 = 0x0A;  //CMSGDAT1
	TxMessage->CMSGDATA1.Byte5 = 0x0C;
	TxMessage->CMSGDATA1.Byte6 = 0x0E;
	TxMessage->CMSGDATA1.Byte7 = TXbuffer[7]++;
	
	_LATE7 = 1;                         //LED指示
	
	C1FIFOCON0SET = 0x00002000;         //UINC = 1
	C1FIFOCON0SET = 0x00000008;         //请求发送
}

//-------------------------------------------------------------------------------
//  CAN 发送 SID 报文
//-------------------------------------------------------------------------------
void CAN_TX_EID_Message(unsigned int SendEID)
{
	TxMessage = PA_TO_KVA1(C1FIFOUA0);  //获取报文地址
	
	TxMessage->CMSGSID.SID = (SendEID>>18)&0x7FF;  //11 bit 
	TxMessage->CMSGEID.EID = SendEID&0x3FFFF;      //18 bit
	
	TxMessage->CMSGEID.IDE = 1;         //标准报文
	TxMessage->CMSGEID.DLC = 0x08;      //数据长度 8 Byte
	
	TxMessage->CMSGDATA0.Byte0 = 0x10;  //CMSGDAT0
	TxMessage->CMSGDATA0.Byte1 = 0x20;
	TxMessage->CMSGDATA0.Byte2 = 0x40;
	TxMessage->CMSGDATA0.Byte3 = 0x80;
	
	TxMessage->CMSGDATA1.Byte4 = 0xA0;  //CMSGDAT1
	TxMessage->CMSGDATA1.Byte5 = 0xC0;
	TxMessage->CMSGDATA1.Byte6 = 0xE0;
	TxMessage->CMSGDATA1.Byte7 = TXbuffer[7]++;
	
	_LATE6 = 1;                         //LED指示
	
	C1FIFOCON0SET = 0x00002000;         //UINC = 1
	C1FIFOCON0SET = 0x00000008;         //请求发送
}

//-------------------------------------------------------------------------------
//  CAN 接收报文处理
//-------------------------------------------------------------------------------
void CAN1RxMsgProcess(void)
{
	if(RX_SID_Msg_Flag == 1)               //FIFO0 收到报文
	{
		RxMessage = (CanMsgBuffer *)(PA_TO_KVA1(C1FIFOUA1));
		
		RXbuffer[0] = RxMessage->CMSGDATA0.Byte0;  //CMSGDAT0
		RXbuffer[1] = RxMessage->CMSGDATA0.Byte1;
		RXbuffer[2] = RxMessage->CMSGDATA0.Byte2;
		RXbuffer[3] = RxMessage->CMSGDATA0.Byte3; 
		
		RXbuffer[4] = RxMessage->CMSGDATA1.Byte4;  //CMSGDAT1
		RXbuffer[5] = RxMessage->CMSGDATA1.Byte5; 
		RXbuffer[6] = RxMessage->CMSGDATA1.Byte6;
		RXbuffer[7] = RxMessage->CMSGDATA1.Byte7;
			
		RX_SID_Msg_Flag = 0;
		
		C1FIFOCON1SET = 0x00002000;        //UINC = 1  已读
		C1FIFOINT1bits.RXNEMPTYIE = 1;     //接收缓冲区中断
	}
	
	if(RX_EID_Msg_Flag == 1)               //FIFO2 收到报文
	{
		RxMessage = (CanMsgBuffer *)(PA_TO_KVA1(C1FIFOUA2));
		
		RXbuffer[0] = RxMessage->CMSGDATA0.Byte0;  //CMSGDAT0
		RXbuffer[1] = RxMessage->CMSGDATA0.Byte1;
		RXbuffer[2] = RxMessage->CMSGDATA0.Byte2;
		RXbuffer[3] = RxMessage->CMSGDATA0.Byte3; 
		
		RXbuffer[4] = RxMessage->CMSGDATA1.Byte4;  //CMSGDAT1
		RXbuffer[5] = RxMessage->CMSGDATA1.Byte5; 
		RXbuffer[6] = RxMessage->CMSGDATA1.Byte6;
		RXbuffer[7] = RxMessage->CMSGDATA1.Byte7;
		
		RX_EID_Msg_Flag = 0;

		C1FIFOCON2SET = 0x00002000;        //UINC = 1  已读
		C1FIFOINT2bits.RXNEMPTYIE = 1;     //接收缓冲区中断
	}		
}	
//-------------------------------------------------------------------------------
//  CAN1 中断函数  注意中断编号
//-------------------------------------------------------------------------------
void __attribute__((vector(46)))__attribute__((interrupt(IPL4)))_CAN1Interrupt(void)
{
	if(C1INTbits.RBIF == 1)                   //接收中断 
	{
		if(C1FIFOINT1bits.RXNEMPTYIF == 1)    //FIFO 1
		{
			_LATE1 = 1;                       //LED指示
			RX_SID_Msg_Flag = 1;              //收到报文
			C1FIFOINT1bits.RXNEMPTYIE = 0;    //中断禁止
		}
		if(C1FIFOINT2bits.RXNEMPTYIF == 1)    //FIFO 2
		{
			_LATE0 = 1;                       //LED指示
			RX_EID_Msg_Flag = 1;              //收到报文
			C1FIFOINT2bits.RXNEMPTYIE = 0;    //中断禁止
		}
		C1INTbits.RBIF = 0;
	}
	
	if(C1INTbits.TBIF == 1)                   //发送中断
	{
		_LATE0 = !_LATE0;
		C1INTbits.TBIF = 0;
	}	
	IFS1bits.CAN1IF = 0;
}

	

//-------------------------------------------------------------------------------

