?? can841.c
字號:
/*--------------------------------------
FILE NAME : can841.C
VERSION : V1.0
--------------------------------------*/
#include "can841.h"
#include <dos.h>
#define IRQ_POLLING 0
#define NULL 0
/*--------------------------------------------------------------------------*/
BYTE gIrq0, gIrq1;
BYTE old_irq0=IRQ_POLLING;
BYTE old_irq1=IRQ_POLLING;
UI gSeg;
int hw_ok=0;
BYTE protocol1=CANBUS_PROTOCOL_20A;/*add by jinzhong*/
BYTE protocol2=CANBUS_PROTOCOL_20A;/*add by jinzhong*/
void interrupt (*old_isr0)();
void interrupt (*old_isr1)();
void interrupt can_isr0();
void interrupt can_isr1();
int can_err_no;
/*------------------------------------------------
0: no error
0x01 : hardware not release.
0x10: seg_addr set error
0x11: hardware not set successful
0x12: irq_no set error
0x20: bus off
------------------------------------------------*/
/*--------------------------------------------------------------------------*/
void interrupt can_isr0();
void interrupt can_isr1();
void can0w(BYTE addr, BYTE v);
void can1w(BYTE addr, BYTE v);
BYTE can0r( BYTE addr);
BYTE can1r( BYTE addr);
void can_reset( BYTE port );
/*--------------------------------------------------------------------------*/
void getIntNo(BYTE irq_no, BYTE * int_no)
{
BYTE int_tbl[16]={
0xff,0xff,0xff,0x0b,0x0c,0x0d,0x0e,0x0f,
0xff,0x71,0x72,0x73,0x74,0xff,0xff,0x77
};
*int_no = int_tbl[irq_no];
}
BYTE g_Data1=0,g_Data2=0;
/*--------------------------------------------------------------------------*/
int canInitHW( UI segment, BYTE irq0, BYTE irq1)
{
BYTE data=0, data2=0;
BYTE int_no;
/*-----------------------
If app. call this function again, error it.
--------------------------*/
/*-----------------------
if( hw_ok!=0)
{
can_err_no=0x1;
return(0);
}
-------------------------*/
if( segment >0xef00 || segment <0xc800 ||(segment%0x100))
{
can_err_no=0x10;
return(0);
}
gSeg=segment;
data=can0r(0);
if( data &0x01)
{
can0w(0,0x60);
if(can0r(0) &0x01)
{
can_err_no=0x10;
return(0);
}
}
can_reset(0);
if(!(can0r(0) &0x01))
{
can_err_no=0x10;
return(0);
}
data=can1r(0);
if( data &0x01)
{
can1w(0,0x60);
if(can1r(0) &0x01)
{
can_err_no=0x10;
return(0);
}
}
can_reset(1);
if(!(can1r(0) &0x01))
{
can_err_no=0x10;
return(0);
}
/*----- irq_set error check. ------------------*/
if( irq0 != 0 && irq0 != 3 && irq0 != 4 && irq0 !=5 && irq0 !=6 && irq0 !=7
&& irq0 !=9 && irq0 !=10 && irq0 !=11 && irq0 !=12 && irq0 != 15)
{
can_err_no=0x12;
return(0);
}
if( irq1 != 0 && irq1 != 3 && irq1 != 4 && irq1 !=5 && irq1 !=6 && irq1 !=7
&& irq1 !=9 && irq1 !=10 && irq1 !=11 && irq1 !=12 && irq1 != 15)
{
can_err_no=0x12;
return(0);
}
if( irq0 == irq1 && irq0 !=IRQ_POLLING)
{
can_err_no=0x12;
return(0);
}
getIntNo(irq0, &data);
if( data == 0xff && irq0 !=0)
{
can_err_no=0x12;
return(0);
}
getIntNo(irq1, &data);
if( data == 0xff && irq1 !=0)
{
can_err_no=0x12;
return(0);
}/*..... irq_set error check. ..................*/
gIrq0=irq0;
if( gIrq0 != old_irq0)
{
/*---- restore old irq int service routine -------*/
if( old_irq0 !=IRQ_POLLING)
{
disable();
getIntNo(old_irq0, &int_no);
setvect(int_no,old_isr0);
enable();
old_irq0 = IRQ_POLLING;
}/*.... restore old irq int service routine .......*/
/*---- set new irq int service routine -------*/
if( gIrq0 != IRQ_POLLING) /* not polling */
{
getIntNo(gIrq0,&int_no);
old_isr0=getvect(int_no);
old_irq0 = gIrq0;
data=inportb(0x21);
data2=inportb(0xA1);
g_Data1 = data;
g_Data2 = data2;
disable();
getIntNo(gIrq0,&int_no);
setvect(int_no,can_isr0);
if(gIrq0 < 8 )
{
outportb(0x21,data&(~(1<<gIrq0)));
outportb(0xA1,data2);
}
else
{
outportb(0x21,data);
outportb(0xA1,data2&(~(1<<(gIrq0-8))));
}
enable();
outportb(0x20,0x20);
outportb(0xA0,0x20);
}
}
gIrq1=irq1;
if( gIrq1 != old_irq1)
{
/*---- restore old irq int service routine -------*/
if( old_irq1 !=IRQ_POLLING)
{
disable();
getIntNo(old_irq1, &int_no);
setvect(int_no,old_isr1);
enable();
old_irq1 = IRQ_POLLING;
}/*.... restore old irq int service routine .......*/
/*---- set new irq int service routine -------*/
if( gIrq1 != IRQ_POLLING) /* not polling */
{
getIntNo(gIrq1, &int_no);
old_isr1=getvect(int_no);
old_irq1 = gIrq1;
data=inportb(0x21);
data2=inportb(0xA1);
g_Data1=data;
g_Data2=data2;
disable();
getIntNo(gIrq1, &int_no);
setvect(int_no,can_isr1);
if(gIrq1 < 8 )
{
outportb(0x21,data&(~(1<<gIrq1)));
outportb(0xA1,data2);
}
else
{
outportb(0x21,data);
outportb(0xA1,data2&(~(1<<(gIrq1-8))));
}
enable();
outportb(0x20,0x20);
outportb(0xA0,0x20);
}
}
hw_ok=1;
return(1);
}
/*--------------------------------------------------------------------------*/
BYTE rBuf0[10], rBuf1[10];
BYTE rBufex0[13];
BYTE rBufex1[13];
CAN_RD_FIFO_T READ_FIFO0,READ_FIFO1;
CAN_RD_FIFO_EX_T READ_FIFO_EX0,READ_FIFO_EX1;
BYTE gSendFlag0, gSendFlag1;
/*--------------------------------------------------------------------------*/
void interrupt can_isr0()
{
unsigned char flag;
long head,temp1,temp2;
int i;
pMSG_STRUCT pcan_msg;
PCAN_MSG_T_EX pcan_msgex;
disable();
if(protocol1==CANBUS_PROTOCOL_20A)
{
flag=can0r(3);
if( flag & 1) /* RIF */
{
head = READ_FIFO0.head;
pcan_msg= (MSG_STRUCT *)&READ_FIFO0.buffer[head];
temp1=can0r(20);
temp2=can0r(21);
pcan_msg->id = temp1;
pcan_msg->id <<= 3;
pcan_msg->id |= temp2>>5;
pcan_msg->rtr = (temp2>>4)&1;
pcan_msg->dlen = temp2&0x0f;
for(i=0; i< pcan_msg->dlen; i++)
pcan_msg->data[i]=can0r(22+i);
for(i=pcan_msg->dlen; i < 8; i++ )
pcan_msg->data[i] = 0;
READ_FIFO0.head += CAN_MSG_LEN;
if(READ_FIFO0.head == RD_FIFO_LEN )
{
READ_FIFO0.status = FIFO_FULL;
READ_FIFO0.head %= RD_FIFO_LEN;
}
if(READ_FIFO0.status == FIFO_FULL )
{
if(READ_FIFO0.head == READ_FIFO0.tail )
{
READ_FIFO0.tail += CAN_MSG_LEN;
if(READ_FIFO0.tail == RD_FIFO_LEN)
{
READ_FIFO0.status = FIFO_OK;
READ_FIFO0.tail %= RD_FIFO_LEN;
}
}
}
/* release receive buffer*/
can0w(1,4);
}
if( flag & 2) /* TIF */
{
gSendFlag0=1;
}
outportb(0x20,0x20);
outportb(0xA0,0x20);
enable();
}
/*add by jinzhong*/
if(protocol1==CANBUS_PROTOCOL_20B)
{
flag=can0r(3);
if( flag & 1) /* RIF */
{
head = READ_FIFO_EX0.head;
pcan_msgex= (CAN_MSG_T_EX *)&READ_FIFO_EX0.buffer[head];
temp1=can0r(16);
pcan_msgex->ff = ( temp1 & 0x80 );
pcan_msgex->dlen = ( temp1 & 0x0f );
pcan_msgex->rtr = ( temp1 >> 6) & 1;
if ( pcan_msgex->ff == PELICAN_SFF )
{
temp2 = can0r(17);
pcan_msgex->id = temp2 << 3;
temp2 = can0r(18);
pcan_msgex->id |= temp2 >> 5;
for ( i = 0; i < pcan_msgex->dlen; i++ )
pcan_msgex->data[i] = can0r(19+i);
}
else
{
temp2 = can0r(17);
pcan_msgex->id = temp2 << 21;
temp2 = can0r(18);
pcan_msgex->id |= temp2 << 13;
temp2 = can0r(19);
pcan_msgex->id |= temp2 << 5;
temp2 = can0r(20);
pcan_msgex->id |= temp2 >> 3;
for ( i = 0; i < pcan_msgex->dlen; i++ )
pcan_msgex->data[i] = can0r(21+i);
}
READ_FIFO_EX0.head += CAN_MSG_EX_LEN;
if(READ_FIFO_EX0.head == RD_FIFO_EX_LEN )
{
READ_FIFO_EX0.status = FIFO_FULL;
READ_FIFO_EX0.head %= RD_FIFO_EX_LEN;
}
if(READ_FIFO_EX0.status == FIFO_FULL )
{
if(READ_FIFO_EX0.head == READ_FIFO_EX0.tail )
{
READ_FIFO_EX0.tail += CAN_MSG_EX_LEN;
if(READ_FIFO_EX0.tail == RD_FIFO_EX_LEN)
{
READ_FIFO_EX0.status = FIFO_OK;
READ_FIFO_EX0.tail %= RD_FIFO_EX_LEN;
}
}
}
/* release receive buffer*/
can0w(1,4);
}
if( flag & 2) /* TIF */
{
gSendFlag0=1;
}
outportb(0x20,0x20);
outportb(0xA0,0x20);
enable();
}
/*end added*/
}
/*--------------------------------------------------------------------------*/
void interrupt can_isr1()
{
unsigned char flag;
int i=0;
long head,temp1,temp2;
pMSG_STRUCT pcan_msg;
PCAN_MSG_T_EX pcan_msgex;
disable();
if(protocol2==CANBUS_PROTOCOL_20A)
{
flag=can1r(3);
if( flag & 1) /* RIF */
{
head = READ_FIFO1.head;
pcan_msg= (MSG_STRUCT *)&READ_FIFO1.buffer[head];
temp1=can1r(20);
temp2=can1r(21);
pcan_msg->id = temp1;
pcan_msg->id <<= 3;
pcan_msg->id |= temp2>>5;
pcan_msg->rtr = (temp2>>4)&1;
pcan_msg->dlen = temp2&0x0f;
for(i=0; i< pcan_msg->dlen; i++)
pcan_msg->data[i]=can1r(22+i);
for(i=pcan_msg->dlen; i < 8; i++ )
pcan_msg->data[i] = 0;
READ_FIFO1.head += CAN_MSG_LEN;
if(READ_FIFO1.head == RD_FIFO_LEN )
{
READ_FIFO1.status = FIFO_FULL;
READ_FIFO1.head %= RD_FIFO_LEN;
}
if(READ_FIFO1.status == FIFO_FULL )
{
if(READ_FIFO1.head == READ_FIFO1.tail )
{
READ_FIFO1.tail += CAN_MSG_LEN;
if(READ_FIFO1.tail == RD_FIFO_LEN)
{
READ_FIFO1.status = FIFO_OK;
READ_FIFO1.tail %= RD_FIFO_LEN;
}
}
}
/* release receive buffer*/
can1w(1,4);
}
if( flag & 2) /* TIF */
{
gSendFlag1=1;
}
outportb(0x20,0x20);
outportb(0xA0,0x20);
enable();
}
/*add by jinzhong*/
if(protocol2==CANBUS_PROTOCOL_20B)
{
flag=can1r(3);
if( flag & 1) /* RIF */
{
head = READ_FIFO_EX1.head;
pcan_msgex= (CAN_MSG_T_EX *)&READ_FIFO_EX1.buffer[head];
temp1=can1r(16);
pcan_msgex->ff = ( temp1 & 0x80 );
pcan_msgex->dlen = ( temp1 & 0x0f );
pcan_msgex->rtr = ( temp1 >> 6) & 1;
if ( pcan_msgex->ff == PELICAN_SFF )
{
temp2 = can1r(17);
pcan_msgex->id = temp2 << 3;
temp2 = can1r(18);
pcan_msgex->id |= temp2 >> 5;
for ( i = 0; i < pcan_msgex->dlen; i++ )
pcan_msgex->data[i] = can1r(19+i);
}
else
{
temp2 = can1r(17);
pcan_msgex->id = temp2 << 21;
temp2 = can1r(18);
pcan_msgex->id |= temp2 << 13;
temp2 = can1r(19);
pcan_msgex->id |= temp2 << 5;
temp2 = can1r(20);
pcan_msgex->id |= temp2 >> 3;
for ( i = 0; i < pcan_msgex->dlen; i++ )
pcan_msgex->data[i] = can1r(21+i);
}
READ_FIFO_EX1.head += CAN_MSG_EX_LEN;
if(READ_FIFO_EX1.head == RD_FIFO_EX_LEN )
{
READ_FIFO_EX1.status = FIFO_FULL;
READ_FIFO_EX1.head %= RD_FIFO_EX_LEN;
}
if(READ_FIFO_EX1.status == FIFO_FULL )
{
if(READ_FIFO_EX1.head == READ_FIFO_EX1.tail )
{
READ_FIFO_EX1.tail += CAN_MSG_EX_LEN;
if(READ_FIFO_EX1.tail == RD_FIFO_EX_LEN)
{
READ_FIFO_EX1.status = FIFO_OK;
READ_FIFO_EX1.tail %= RD_FIFO_EX_LEN;
}
}
}
/* release receive buffer*/
can1w(1,4);
}
if( flag & 2) /* TIF */
{
gSendFlag1=1;
}
outportb(0x20,0x20);
outportb(0xA0,0x20);
enable();
}
/*end added*/
}
/*--------------------------------------------------------------------------*/
void can_reset( BYTE port )
{
BYTE huge *ptr=MK_FP(gSeg,0x100+0x200*port);
BYTE a;
a=*ptr;
*ptr=a;
if(port==0)
{
READ_FIFO0.head = READ_FIFO0.tail = 0;
READ_FIFO0.status = FIFO_OK;
READ_FIFO_EX0.head=READ_FIFO_EX0.tail = 0;
READ_FIFO_EX0.status = FIFO_OK;
}
else
{
READ_FIFO1.head = READ_FIFO1.tail = 0;
READ_FIFO1.status = FIFO_OK;
READ_FIFO_EX1.head=READ_FIFO_EX1.tail = 0;
READ_FIFO_EX1.status = FIFO_OK;
}
delay(100);
}
/*--------------------------------------------------------------------------*/
void can0w(BYTE addr, BYTE v)
{
BYTE huge *ptr;
ptr = MK_FP( gSeg,addr);
*ptr=v;
}
/*--------------------------------------------------------------------------*/
void can1w(BYTE addr, BYTE v)
{
BYTE huge *ptr;
ptr = MK_FP( gSeg,addr+0x200);
*ptr=v;
}
/*--------------------------------------------------------------------------*/
BYTE can0r( BYTE addr)
{
BYTE v;
BYTE huge *ptr;
ptr = MK_FP(gSeg,addr);
v=*ptr;
return(v);
}
/*--------------------------------------------------------------------------*/
BYTE can1r( BYTE addr)
{
BYTE v;
BYTE huge *ptr;
ptr = MK_FP(gSeg,addr+0x200);
v=*ptr;
return(v);
}
/*--------------------------------------------------------------------------*/
BYTE canExitHW()
{
BYTE b1=inportb(0x21);
BYTE b2=inportb(0xA1);
BYTE int_no;
/* reset old isr */
/*outportb(0x21,0xff);*/
disable();
if( old_isr0 != NULL )
{
getIntNo(old_irq0,&int_no);
setvect(int_no,old_isr0);
old_irq0=IRQ_POLLING;
}
if( old_isr1 != NULL )
{
getIntNo(old_irq1,&int_no);
setvect(int_no,old_isr1);
old_irq1=IRQ_POLLING;
}
if(gIrq0!= IRQ_POLLING || gIrq1 != IRQ_POLLING )
{
outportb(0x21,g_Data1);
outportb(0xA1,g_Data2);
}
else
{
outportb(0x21,b1);
outportb(0xA1,b2);
}
enable();
return(1);
}
/*--------------------------------------------------------------------------*/
int canReset( BYTE port )
{
can_reset( port );
return(1);
}
/*--------------------------------------------------------------------------*/
int canConfig( BYTE port, CAN_STRUCT can)
{
BYTE temp=0;
BYTE v=0;
unsigned int tag;
canReset( port );
if( port ==0)
can.protocoltype=protocol1;
else can.protocoltype=protocol2;
if(can.protocoltype==CANBUS_PROTOCOL_20A)
{
/*add by jinzhong*/
if( port==0)
{
can0w(0,1);
v=can0r(0x100);
can0w(0x100,v);
can0w(0,1);
delay(800);
v=can0r(31);
v &=0x7f;
can0w(31,v);
delay(800);
}
else
{
can1w(0,1);
v=can1r(0x100);
can1w(0x100,v);
can1w(0,1);
delay(800);
v=can1r(31);
v &=0x7f;
can1w(31,v);
delay(800);
}
/*end added*/
if( port ==0)
{
if( gIrq0 == IRQ_POLLING)
can0w(0,1);
else
can0w(0,3);/* reset mode and receive irq */
delay(800);
}
else
{
if( gIrq1 == IRQ_POLLING)
can1w(0,1);
else
can1w(0,3);/* reset mode and receive irq */
delay(800);
}
if( port ==0)
{
can0w(6,can.bt0); /* BT0 */
can0w(7,can.bt1); /* BT1 */
delay(500);
temp=can0r(6);
if( temp !=can.bt0)
return(0);
temp=can0r(7);
if( temp !=can.bt1)
return(0);
}
else
{
can1w(6,can.bt0); /* BT0 */
can1w(7,can.bt1); /* BT1 */
delay(500);
temp=can1r(6);
if( temp !=can.bt0)
return(0);
temp=can1r(7);
if( temp !=can.bt1)
return(0);
}
if( port ==0)
{
can0w(4,can.acc_code);/* accept code */
can0w(5,can.acc_mask);/* accept code */
}
else
{
can1w(4,can.acc_code);/* accept code */
can1w(5,can.acc_mask);/* accept code */
}
if( port ==0)
{
can0w(8,0xfa);
}
else
{
can1w(8,0xfa);
}
return(1);
}
/*add by jinzhong*/
if(can.protocoltype==CANBUS_PROTOCOL_20B)
{
if (port==0)
{
can0w(0,1);
v=can0r(0x100);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -