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

📄 candrv.c

📁 vxworks can 驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
		canw(port,ModeControlReg,v);
	}
	canPara[port].mode = cfg.mode;
	/* 设置中断开放情况 */
	v=canr(port,InterruptEnReg);
	if(cfg.mode==IRQ_POLLING)
		v|=TIE_Bit|EIE_Bit|DOIE_Bit;
	else
		v|=RIE_Bit|TIE_Bit|EIE_Bit|DOIE_Bit;
	canw(port,InterruptEnReg,v);
	
	/* 设置位速率 */
	canw(port,BusTiming0Reg ,cfg.bt0);
	canw(port,BusTiming1Reg ,cfg.bt1);
	/*设置接收屏蔽码*/
	canw(port,AcceptCodeReg , cfg.acc_code);
	canw(port,AcceptMaskReg , cfg.acc_mask);
	/* 设置输出控制寄存器,*/
	canw(port,OutControlReg , Tx1Float | Tx0PshPull | NormalMode);
	
	msg_num=msgQNumMsgs(canMsgQue[port]);
	if(msg_num!=0){
		buf=malloc(msg_num);
		msgQReceive(canMsgQue[port], buf, MAX_MSG_LENGTH, WAIT_FOREVER);
		free(buf);
	}
	return 1;
}
/*启动CAN的正常运行
	port:CAN控制器--0,控制器0;1,控制器1
*/	
static void canNormalRun(BYTE port)
{
	BYTE v;
	if(can_err_no[port]==0x10)return;
	canw(port,ClockDivideReg, div_reg_val[port]);
	v=canr(port,ModeControlReg);
	while((v & RM_RR_Bit ) != ClrByte){
		v&=0xfe;
		canw(port,ModeControlReg,v);
		v=canr(port,ModeControlReg);		
	}
}
/*由指定的CAN控制器发送消息包
	port:CAN控制器--0,控制器0;1,控制器1
	msg:要发送的消息
返回值:1,成功;0,失败
*/
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.id[1];
	if(msg.rtr)v|=FRAME_RTR;
	v+=(msg.dlen&FRAME_DLEN);
	buf[1] = v;
	buf[0]=msg.id[0];
	dataPos = 2;
	frameLen = msg.dlen + 2;
	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,TxBuffer1 + 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,RxBuffer2);
			msg_ptr->dlen=(v&FRAME_DLEN);
			msg_ptr->rtr=(v&FRAME_RTR)?1:0;
			msg_ptr->id[1]=v&0xe0;
			msg_ptr->id[0]=canr(port,RxBuffer1);
			num=msg_ptr->dlen;
			for(i=0; i<num; i++){
				msg_ptr->data[i]=canr(port,RxBuffer3+i);
			}
			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[1];
		msg_ptr->dlen=(v&FRAME_DLEN);
		num=msg_ptr->dlen;
		msg_ptr->rtr=(v&FRAME_RTR)?1:0;
		msg_ptr->id[1]=v&0xe0;
		msg_ptr->id[0]=buf[0];
		j = 2;	/* data start position in frame */
		/* copy data from buffer */
		for(i=0; i<num; i++)
			msg_ptr->data[i]=buf[i+j];
		
	}
	return 1;
}
/*从指定控制器读取指定寄存器的值
	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;
}
/*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, RxBuffer1);
			rBuf[CAN0][1] = canr(CAN0, RxBuffer2);
			msgLength = rBuf[CAN0][1] & FRAME_DLEN;

			/* 读取剩余数据*/
			for(i=0; i<msgLength; i++)
				rBuf[CAN0][i+2] = canr(CAN0, RxBuffer3 + 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[CAN0]=0x20+CAN0;
				v=canr(CAN0,ModeControlReg);
				if(!(v&RM_RR_Bit)){
					canw(CAN0,ModeControlReg,v|RM_RR_Bit);
				}
				canw(CAN0,ClockDivideReg, div_reg_val[CAN0]);
				canw(CAN0,ModeControlReg,v&(~RM_RR_Bit));
			}
			else if(statFlag&ES_Bit){/*总线错误*/
				can_err_no[CAN0]=0x22+CAN0;
			}
		}

}

/*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, RxBuffer1);
			rBuf[CAN1][1] = canr(CAN1, RxBuffer2);
			msgLength = rBuf[CAN1][1] & FRAME_DLEN;

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

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

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

}
/*停止控制器的运行
返回值: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 + -