⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 candrv.c

📁 vxworks 下 扩展模式的can驱动以及测试代码
💻 C
📖 第 1 页 / 共 2 页
字号:
static int canSendMsg(BYTE port,CANMSG msg)
{
	BYTE v;
	int i, dataPos, frameLen;
	BYTE buf[MAX_MSG_LENGTH];
	int ret=0;


	if(port>1)return 0;
	
	
	v=(msg.dlen&FRAME_DLEN);
	if(msg.sff==0)v|=FRAME_EFF;
	if(msg.rtr)v|=FRAME_RTR;
	
	buf[0] = v;
	
	if(msg.sff){
		buf[1]=msg.id[0];
		buf[2]=msg.id[1];
		dataPos = 3;
		frameLen = msg.dlen + 3;
	}
	else {
		buf[1]=msg.id[0];
		buf[2]=msg.id[1];
		buf[3]=msg.id[2];
		buf[4]=msg.id[3];
		dataPos = 5;
		frameLen = msg.dlen + 5;
	};
	
	for(i=0;i<msg.dlen;i++)
		buf[dataPos + i]=msg.data[i];
	
	/*发送缓冲区是否为空*/
	v=canr(port,StatusReg);
	while((v & TBS_Bit ) != TBS_Bit )
		 v=canr(port,StatusReg);

	/* 填写发送缓冲区*/
	for(i=0;i<frameLen;i++)
			canw(port,TxFrameInfo + i, buf[i]);
	/* 启动发送*/
	canw(port,CommandReg, TR_Bit);
	/*canw(port,CommandReg, 0x10);*/
	while(1)
		{
     	/* 读取状态寄存器 */  
	     v = canr(port, StatusReg); 
    	 if( v & 0x08)	/* 发送失败 */
		{
         		return(SUCCESS);
		}
     		else if( v &0x40)	/* 发送成功 */
			{
        			return(FAILURE );
			}			
		}

}
/*从指定的CAN控制器接收消息包
	port:CAN控制器--0,控制器0;1,控制器1
	msg_ptr:指向消息结构变量,返回消息
返回值:1,成功;0,无消息
*/
static int canReceiveMsg(BYTE port,CANMSG *msg_ptr)
{
	int i,num,j;
	BYTE *tmp;
	BYTE v;
	BYTE buf[MAX_MSG_LENGTH];

	if(port>1)return 0;

	if(canPara[port].mode == IRQ_POLLING){/*查询方式处理*/
		do{
			taskDelay(10);
			v=canr(port,StatusReg);
		}while((v & RBS_Bit)==0x00);
		if((v & RBS_Bit)){
			v=canr(port,RxFrameInfo);
			msg_ptr->dlen=(v&FRAME_DLEN);
			msg_ptr->sff=(v&FRAME_EFF)?0:1;
			msg_ptr->rtr=(v&FRAME_RTR)?1:0;
			if(msg_ptr->sff){
				msg_ptr->id[2]=0;
				msg_ptr->id[3]=0;
				msg_ptr->id[0]=canr(port,RxBuffer1);
				msg_ptr->id[1]=canr(port,RxBuffer2);
				j=RxBuffer3;
			}
			else {
				msg_ptr->id[0]=canr(port,RxBuffer1);
				msg_ptr->id[1]=canr(port,RxBuffer2);
				msg_ptr->id[2]=canr(port,RxBuffer3);
				msg_ptr->id[3]=canr(port,RxBuffer4);
				j=RxBuffer5;
			}
			num=msg_ptr->dlen;
			for(i=0; i<num; i++){
				msg_ptr->data[i]=canr(port,j);
				j++;
			}
			canw(port,CommandReg,RRB_Bit);
			return 1;
		}
		else return 0;
	}	
	else {/*中断方式处理*/
		/*若缓冲区为空,阻塞*/
/*		semTake(sem_can[port],WAIT_FOREVER); */
		
		/* 从消息队列中读取一帧数据*/
		msgQReceive(canMsgQue[port], buf, MAX_MSG_LENGTH, WAIT_FOREVER);
		v=buf[0];
		msg_ptr->dlen=(v&FRAME_DLEN);
		num=msg_ptr->dlen;
		msg_ptr->sff=(v&FRAME_EFF)?0:1;
		msg_ptr->rtr=(v&FRAME_RTR)?1:0;
		if(msg_ptr->sff){
			msg_ptr->id[2]=0;
			msg_ptr->id[3]=0;
			msg_ptr->id[0]=buf[1];
			msg_ptr->id[1]=buf[2];
			j = 3;	/* data start position in frame */
		}
		else {
			msg_ptr->id[0]=buf[1];
			msg_ptr->id[1]=buf[2];
			msg_ptr->id[2]=buf[3];
			msg_ptr->id[3]=buf[4];
			j = 5; /* data start position in frame */
		}
		
		/* copy data from buffer */
		for(i=0; i<num; i++)
			msg_ptr->data[i]=buf[i+j];
		
	}
	return 1;
}
#if FALSE
#define PORT_1_A_ADDR 0x220
#define PORT_1_V_ADDR 0x221
#define PORT_2_A_ADDR 0x222
#define PORT_2_V_ADDR 0x223

/*从指定控制器读取指定寄存器的值
	port:CAN控制器--0,控制器0;1,控制器1
	addr:寄存器地址
返回值:寄存器值
*/
static BYTE canr(BYTE port,int addr)
{
	int ii;
	if(port==0){
		sysOutByte(PORT_1_A_ADDR,addr);
		ii++;
		return (sysInByte(PORT_1_V_ADDR));
	}
	else {
		sysOutByte(PORT_2_A_ADDR,addr);
		ii++;
		return (sysInByte(PORT_2_V_ADDR));
	}
}

/*向控制器的寄存器写入值
	port:CAN控制器--0,控制器0;1,控制器1
	addr:寄存器地址
	v:寄存器值
*/
static void canw(BYTE port,int addr,BYTE v)
{
	int ii;
	if(port==0){
		sysOutByte(PORT_1_A_ADDR,addr);
		ii++;
		sysOutByte(PORT_1_V_ADDR,v);
	}
	else {
		sysOutByte(PORT_2_A_ADDR,addr);
		ii++;
		sysOutByte(PORT_2_V_ADDR,v);
	}
}

#else

/*从指定控制器读取指定寄存器的值
	port:CAN控制器--0,控制器0;1,控制器1
	addr:寄存器地址
返回值:寄存器值
*/
static BYTE canr(BYTE port,int addr)
{
	if(port==0)return XBYTE[addr];
	else return XBYTE[DIST_CAN+addr];
}

/*向控制器的寄存器写入值
	port:CAN控制器--0,控制器0;1,控制器1
	addr:寄存器地址
	v:寄存器值
*/
static void canw(BYTE port,int addr,BYTE v)
{
	if(port==0)XBYTE[addr]=v;
	else XBYTE[DIST_CAN+addr]=v;
}
#endif
/*CAN0 中断服务例程
	
*/
static void can0_isr()
{
	int i;
	BYTE intFlag;	/* 中断寄存器*/
	BYTE statFlag;  /* 状态寄存器*/
	BYTE msgLength;  /* 消息长度*/
	BYTE v;	/* 临时变量*/
	intFlag=canr(CAN0,InterruptReg);/*中断状态值*/
	if( intFlag & RI_Bit || intFlag&DOI_Bit) /*接收中断*/
	{
		do{		
			/* 读取第一个数据*/
			rBuf[CAN0][0] = canr(CAN0, RxFrameInfo);

			msgLength = rBuf[CAN0][0] & FRAME_DLEN;
			if( rBuf[CAN0][0] & FRAME_EFF)
				msgLength += 4;  /* 扩展信息*/
			else
				msgLength += 2;  /* 标准信息*/

			/* 读取剩余数据*/
			for(i=0; i<msgLength; i++)
				rBuf[CAN0][i+1] = canr(CAN0, RxBuffer1 + i);
			/* 释放接收缓冲区*/
			canw(CAN0,CommandReg,RRB_Bit);

			/* 发送数据到消息队列*/
			msgQSend(canMsgQue[CAN0], 
				rBuf[CAN0], 
				MAX_MSG_LENGTH, 
				NO_WAIT, 
				MSG_PRI_NORMAL);

			/* 置信号量*/
/*			semGive(sem_can[CAN0]);*/
		
			statFlag=canr(CAN0,StatusReg);/*控制器接收缓冲区是否为空*/
		}while(statFlag&RBS_Bit);
	}
	else if(intFlag&EI_Bit)
		{/*错误中断*/
			statFlag=canr(CAN0,StatusReg);
			if(statFlag&BS_Bit)
			{/*总线脱离错误,恢复控制器*/
				can_err_no[0]=0x20+CAN0;
				
				v=canr(CAN0,ModeControlReg);
				if(!(v&RM_RR_Bit)){
					canw(CAN0,ModeControlReg,v|RM_RR_Bit);
				}
			
				canw(CAN0,ClockDivideReg, div_reg_val[0]);
				canw(CAN0,RxErrCountReg,0);
				canw(CAN0,TxErrCountReg,0);
				canw(CAN0,ModeControlReg,v&(~RM_RR_Bit));
			}
			else if(statFlag&ES_Bit){/*总线错误*/
				can_err_no[0]=0x22+CAN0;
			}
		}
	    else if(intFlag&ALI_Bit){
			v=canr(CAN0,ArbLostCapReg);
			can_err_no[0]=0x0200|(CAN0<<8)|v;
	    }
	    else if(intFlag&BEI_Bit){
			v=canr(CAN0,ErrCodeCapReg);
			can_err_no[0]=0x0400|(CAN0<<8)|v;
	    }
	    else if(intFlag&WUI_Bit){
		
	    }
	    else if(intFlag&EPI_Bit){
	    	v=canr(CAN0,ErrCodeCapReg);
			can_err_no[0]=0x0600|(CAN0<<8)|v;
	    }


}

/*CAN1 中断服务例程
	
*/
static void can1_isr()
{
	int i;
	BYTE intFlag;	/* 中断寄存器*/
	BYTE statFlag;  /* 状态寄存器*/
	BYTE msgLength;  /* 消息长度*/
	BYTE v;	/* 临时变量*/

	intFlag=canr(CAN1,InterruptReg);/*中断状态值*/
	if( intFlag & RI_Bit || intFlag&DOI_Bit) /*接收中断*/
	{
		do{		
			/* 读取第一个数据*/
			rBuf[CAN1][0] = canr(CAN1, RxFrameInfo);

			msgLength = rBuf[CAN1][0] & FRAME_DLEN;
			if( rBuf[CAN1][0] & FRAME_EFF)
				msgLength += 4;  /* 扩展信息*/
			else
				msgLength += 2;  /* 标准信息*/

			/* 读取剩余数据*/
			for(i=0; i<msgLength; i++)
				rBuf[CAN1][i+1] = canr(CAN1, RxBuffer1 + i);
			/* 释放接收缓冲区*/
			canw(CAN1,CommandReg,RRB_Bit);

			/* 发送数据到消息队列*/
			msgQSend(canMsgQue[CAN1], 
				rBuf[CAN1], 
				MAX_MSG_LENGTH, 
				NO_WAIT, 
				MSG_PRI_NORMAL);

			/* 置信号量*/
/*			semGive(sem_can[CAN1]);*/
		
			statFlag=canr(CAN1,StatusReg);/*控制器接收缓冲区是否为空*/
		}while(statFlag&RBS_Bit);
	}
	else if(intFlag&EI_Bit)
		{/*错误中断*/
			statFlag=canr(CAN1,StatusReg);
			if(statFlag&BS_Bit)
			{/*总线脱离错误,恢复控制器*/
				can_err_no[1]=0x20+CAN1;
				
				v=canr(CAN1,ModeControlReg);
				if(!(v&RM_RR_Bit)){
					canw(CAN1,ModeControlReg,v|RM_RR_Bit);
				}
			
				canw(CAN1,ClockDivideReg, div_reg_val[1]);
				canw(CAN1,RxErrCountReg,0);
				canw(CAN1,TxErrCountReg,0);
				canw(CAN1,ModeControlReg,v&(~RM_RR_Bit));
			}
			else if(statFlag&ES_Bit){/*总线错误*/
				can_err_no[1]=0x22+CAN1;
			}
		}
	    else if(intFlag&ALI_Bit){
			v=canr(CAN1,ArbLostCapReg);
			can_err_no[1]=0x0200|(CAN1<<8)|v;
	    }
	    else if(intFlag&BEI_Bit){
			v=canr(CAN1,ErrCodeCapReg);
			can_err_no[1]=0x0400|(CAN1<<8)|v;
	    }
	    else if(intFlag&WUI_Bit){
		
	    }
	    else if(intFlag&EPI_Bit){
	    	v=canr(CAN1,ErrCodeCapReg);
			can_err_no[1]=0x0600|(CAN1<<8)|v;
	    }

}
/*停止控制器的运行
返回值:1,成功;0,失败
*/
static BYTE canExitHW(BYTE port)
{
	BYTE v;
	v=canr(port,ModeControlReg);
	canw(port,ModeControlReg,v|RM_RR_Bit);
	return 1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -