📄 candrv.c
字号:
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 + -