
/*--------------------------------------
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);
		  can0w(0x100,v);
		  delay(500);
		  can0w(0,1);
		  delay(500);/*important! wait for the card to change protocol  */
		  v=can0r(31);
		  v |=0x80;
		  can0w(31,v);


	  }
	  else
	  {
		  can1w(0,1);
		  v=can1r(0x100);
		  can1w(0x100,v);
		  delay(500);
		  can1w(0,1);
		  delay(500);
		  v=can1r(31);
		  v |=0x80;
		  can1w(31,v);



	  }

	  if( port ==0)
	  {
		  if( gIrq0 == IRQ_POLLING)
		  {
			  v=can0r(4);
			  v &=0xfe;
			  can0w(4,v);
		  }
		  else
		  {
			  v=can0r(4);
			  v |=0x09;
			  can0w(4,v);/* reset mode and receive irq */

		  }
	  }
	  else
	  {
		  if( gIrq1 == IRQ_POLLING)
		  {
			  v=can1r(4);
			  v &=0xfe;
			  can1w(4,v);

		  }
		  else
		  {
			  v=can1r(4);
			  v |=0x09;
			  can1w(4,v);/* reset mode and receive irq */

		  }
	  }


	  if( port ==0)
	  {
		  can0w(6,can.bt0); /* BT0 */
		  can0w(7,can.bt1); /* BT1 */
		  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 */
		  temp=can1r(6);
		  if( temp !=can.bt0)
			  return(0);
		  temp=can1r(7);
		  if( temp !=can.bt1)
			  return(0);
	  }

	  if( port ==0)
	  {
		  v       = can0r( 0 );
		  if ( can.ssFilterSetting.dwFilterType == 0 )
		  {
			 v |= 0x08;
		  }
		  else
		  {
			  v &= 0xf7;
		  }
		  can0w(0, v);
		  delay(200);
		  can0w(16,can.ssFilterSetting.uchAcceptCode0);/* accept code */
		  can0w(17,can.ssFilterSetting.uchAcceptCode1);/* accept code */
		  can0w(18,can.ssFilterSetting.uchAcceptCode2);/* accept code */
		  can0w(19,can.ssFilterSetting.uchAcceptCode3);/* accept code */
		  can0w(20,can.ssFilterSetting.uchAcceptMask0);/* accept mask */
		  can0w(21,can.ssFilterSetting.uchAcceptMask1);/* accept mask */
		  can0w(22,can.ssFilterSetting.uchAcceptMask2);/* accept mask */
		  can0w(23,can.ssFilterSetting.uchAcceptMask3);/* accept mask */

	  }
	  else
	  {
		  v       = can1r( 0 );
		  if ( can.ssFilterSetting.dwFilterType == 0 )
		  {
			  v |= 0x08;
		  }
		  else
		  {
			  v &= 0xf7;
		  }
		  can1w(0, v);
		  delay(200);
		  tag=can1r(0);
		  can1w(16,can.ssFilterSetting.uchAcceptCode0);/* accept code */
		  tag=can1r(16);
		  can1w(17,can.ssFilterSetting.uchAcceptCode1);/* accept code */
		  tag=can1r(17);
		  can1w(18,can.ssFilterSetting.uchAcceptCode2);/* accept code */
		  can1w(19,can.ssFilterSetting.uchAcceptCode3);/* accept code */
		  can1w(20,can.ssFilterSetting.uchAcceptMask0);/* accept mask */
		  can1w(21,can.ssFilterSetting.uchAcceptMask1);/* accept mask */
		  can1w(22,can.ssFilterSetting.uchAcceptMask2);/* accept mask */
		  can1w(23,can.ssFilterSetting.uchAcceptMask3);/* accept mask */

	  }
	  if( port ==0)
	  {
		  can0w(8,0xfa);
	  }
	  else
	  {
		  can1w(8,0xfa);
	  }
	  return(1);
  }

}
/*--------------------------------------------------------------------------*/
int  canNormalRun( BYTE port )
{
BYTE v;
  if( port ==0)
  {
	v=can0r(0);
	if( v & 1)
	  can0w(0,v&0xfe);

  }
  else
  {
	v=can1r(0);
	if( v & 1)
	  can1w(0,v&0xfe);

  }
  if( port ==0)
  {
	  if( gIrq0 == IRQ_POLLING)
	  {
		  v=can0r(4);
		  v &=0xfe;
		  can0w(4,v);
		  return 1;
	  }
	  else
	  {
		  v=can0r(4);
		  v |=0x09;
		  can0w(4,v);/* reset mode and receive irq */
		  delay(500);
		  return 1;
	  }
  }
  else
  {
	  if( gIrq1 == IRQ_POLLING)
	  {
		  v=can1r(4);
		  v &=0xfe;
		  can1w(4,v);
		  return 1;
	  }
	  else
	  {
		  v=can1r(4);
		  v |=0x09;
		  can1w(4,v);/* reset mode and receive irq */
		  delay(500);
		  return 1;
	  }
  }
return 0;
}
/*--------------------------------------------------------------------------*/
int canSendMsg( BYTE  port, MSG_STRUCT msg)
{
  BYTE v;
  BYTE i;

  if( port==0)
  {
    v=msg.id>>3;
    can0w(10,v);
    v=msg.id &7;
    v<<=5;
    if( msg.rtr ==1)
      v|=0x10;
      v+=msg.dlen;
    can0w(11,v);
    for(i=0;i<msg.dlen; i++)
    {
      can0w(12+i,msg.data[i]);
    }
    can0w(1,1);
    while(1)
    {
      v=can0r(2);
      if( v & 0x40)
      {
	return( 0);
      }
      if( v &0x08)
	return( 1);
    }
  }
  else
  {
    v=msg.id>>3;
    can1w(10,v);
    v=msg.id &7;
    v<<=5;
    if( msg.rtr ==1)
      v|=0x10;
      v+=msg.dlen;
    can1w(11,v);
    for(i=0;i<msg.dlen; i++)
    {
      can1w(12+i,msg.data[i]);
    }
    can1w(1,1);
    while(1)
    {
      v=can1r(2);
      if( v & 0x40)
      {
	return( 0);
      }
      if( v &0x08)
	return( 1);
    }
  }
}

/*add by jinzhong*/
int canSendMsgEx( BYTE  port, CAN_MSG_T_EX msgex)
{
	long v,temp1,temp2;
	BYTE i;

	if( port==0)
	{
		temp1=can0r(2);
		if(temp1 & 0x04)
		{
			if( msgex.ff==PELICAN_SFF)
			{
				temp1=0;
				temp1 |=msgex.dlen;
				if ( msgex.rtr == 1 )
				{
					temp1 |= 1<<6;
				}
				can0w(16,temp1);
				temp1 = 0;
				temp1 = msgex.id>>3;
				can0w(17,temp1);
				temp1 = 0;
				temp1 =  msgex.id & 0x07 ;
				temp1 <<= 5;
				can0w(18,temp1);
				for(i=0;i<msgex.dlen; i++)
				{
					can0w(19+i,msgex.data[i]);
				}
			}
			else
			{
				temp1 = 0;
				temp1 |= msgex.dlen;
				if ( msgex.rtr == 1 )
				{
					temp1 |= 1<<6;
				}
				temp1 |= 1<<7;
				can0w(16,temp1);
				temp1 = msgex.id>>21;
				can0w(17,temp1);
				temp1 =  msgex.id & 0x1fffff ;
				temp1 >>= 13;
				can0w(18,temp1);
				temp1 =  msgex.id & 0x1fff ;
				temp1 >>= 5;
				can0w(19,temp1);
				temp1 =  msgex.id & 0x1f ;
				temp1 <<= 3;
				can0w(20,temp1);
				for(i=0;i<msgex.dlen; i++)
				{
					can0w(21+i,msgex.data[i]);
				}
			}
			can0w(1,1);
			while(1)
			{
				temp1=can0r(2);
				if( temp1 & 0x40)
				{
					return( 0);
				}
				if( temp1 &0x08)
					return( 1);
			}
		}
		else return(0);
	}
	else
	{
		temp2=can1r(2);
		if(temp2 & 0x04)
		{
			if( msgex.ff==PELICAN_SFF)
			{
				temp2=0;
				temp2 |=msgex.dlen;
				if ( msgex.rtr == 1 )
				{
					temp2 |= 1<<6;
				}
				can1w(16,temp2);
				temp2 = 0;
				temp2 = msgex.id>>3;
				can1w(17,temp2);
				temp2 = 0;
				temp2 =  msgex.id & 0x07 ;
				temp2 <<= 5;
				can1w(18,temp2);
				for(i=0;i<msgex.dlen; i++)
				{
					can1w(19+i,msgex.data[i]);
				}
			}
			else
			{
				temp2 = 0;
				temp2 |= msgex.dlen;
				if ( msgex.rtr == 1 )
				{
					temp2 |= 1<<6;
				}
				temp2 |= 1<<7;
				can1w(16,temp2);
				temp2 = msgex.id>>21;
				can1w(17,temp2);
				temp2 =  msgex.id & 0x1fffff ;
				temp2 >>= 13;
				can1w(18,temp2);
				temp2 =  msgex.id & 0x1fff ;
				temp2 >>= 5;
				can1w(19,temp2);
				temp2 =  msgex.id & 0x1f ;
				temp2 <<= 3;
				can1w(20,temp2);
				for(i=0;i<msgex.dlen; i++)
				{
					can1w(21+i,msgex.data[i]);
				}
			}
			can1w(1,1);
			while(1)
			{
				temp2=can1r(2);
				if( temp2 & 0x40)
				{
					return( 0);
				}
				if( temp2 &0x08)
					return( 1);
			}
		}
		else return(0);
	}
}
/*edd added*/
/*--------------------------------------------------------------------------*/
int  canReceiveMsg( BYTE port, MSG_STRUCT *msg_ptr, BYTE * IsEmpty)
{
   BYTE i;
   pMSG_STRUCT pcan_msg;
   MSG_STRUCT msg;
   ULONG head,tail;
   *IsEmpty = 1;
   if( port == 0)
   {
      if( gIrq0 == IRQ_POLLING)
      {
         if( can0r(2)&1)
         {
            rBuf0[0]=can0r(20);
            rBuf0[1]=can0r(21);
            for(i=0; i< (rBuf0[1]&0x0f); i++)
               rBuf0[i+2]=can0r(22+i);
            /* release receive buffer*/
            can0w(1,4);
            msg_ptr->id=rBuf0[0];
            msg_ptr->id <<=3;
            msg_ptr->id |=(rBuf0[1] >>5);
            msg_ptr->rtr =(rBuf0[1]>>4)&1;
            msg_ptr->dlen =rBuf0[1]&0x0f;
            for(i=0;i< msg_ptr->dlen; i++)
               msg_ptr->data[i]=rBuf0[2+i];
            return(1);
         }
         else
            return(0);
      }
      else
      {
         head = READ_FIFO0.head;
         tail = READ_FIFO0.tail;
         if(head == tail)
         return(0);
         pcan_msg= (MSG_STRUCT *)&READ_FIFO0.buffer[tail];
         READ_FIFO0.tail += CAN_MSG_LEN;
         if(READ_FIFO0.tail == RD_FIFO_LEN )
         {
            READ_FIFO0.tail %= RD_FIFO_LEN;
            READ_FIFO0.status = FIFO_OK;
         }
         if(READ_FIFO0.tail == head )
            *IsEmpty = 1;
         else
            *IsEmpty = 0;
         msg = *pcan_msg;
         *((MSG_STRUCT *)msg_ptr) = msg;
         return(1);
      }
   }
   else if(port == 1)
   {
      if( gIrq1 == IRQ_POLLING)
      {
	if( can1r(2)&1)
         {
            rBuf1[0]=can1r(20);
            rBuf1[1]=can1r(21);
            for(i=0; i< ( rBuf1[1]&0x0f); i++)
               rBuf1[i+2]=can1r(22+i);
            can1w(1,4);
            msg_ptr->id=rBuf1[0];
            msg_ptr->id <<=3;
            msg_ptr->id |=(rBuf1[1] >>5);
            msg_ptr->rtr =(rBuf1[1]>>4)&1;
            msg_ptr->dlen =rBuf1[1]&0x0f;
            for(i=0;i< msg_ptr->dlen; i++)
               msg_ptr->data[i]=rBuf1[2+i];
            return(1);
         }
         else
            return(0);
      }
      else
      {
         head = READ_FIFO1.head;
         tail = READ_FIFO1.tail;
         if(head == tail)
         return(0);
         pcan_msg= (MSG_STRUCT *)&READ_FIFO1.buffer[tail];
         READ_FIFO1.tail += CAN_MSG_LEN;
         if(READ_FIFO1.tail == RD_FIFO_LEN )
         {
            READ_FIFO1.tail %= RD_FIFO_LEN;
            READ_FIFO1.status = FIFO_OK;
         }
         if(READ_FIFO1.tail == head )
            *IsEmpty = 1;
         else
            *IsEmpty = 0;
         msg = *pcan_msg;
         *((MSG_STRUCT *)msg_ptr) = msg;
         return(1);
      }
   }
   else
     return( 0);
}
/*--------------------------------------------------------------------------*/
/*--------------------------
---add by jinzhong----------
---------------------------*/
/*--------------------------------------------------------------------------*/
int  canReceiveMsgEx( BYTE port, CAN_MSG_T_EX *msg_ptrex, BYTE * IsEmpty)
{
   BYTE i;
   PCAN_MSG_T_EX pcan_msgex;
   CAN_MSG_T_EX msgex;
   long head,tail;
   long temp1,temp2;
   unsigned int tag1;
   *IsEmpty = 1;
   if( port == 0)
   {
      if( gIrq0 == IRQ_POLLING)
      {
         if( can0r(2)&1)
         {

			 temp1=can0r(16);
			 msg_ptrex->ff   =  temp1 & 0x80 ;
			 msg_ptrex->dlen =  temp1 & 0x0f ;
			 msg_ptrex->rtr  = ( temp1>> 6) & 1;
			 if ( msg_ptrex->ff == PELICAN_SFF )
			 {
				 temp1 = can0r(17);
				 msg_ptrex->id = temp1 << 3;
				 temp1 = can0r(18);
				 msg_ptrex->id |= temp1 >> 5;
				 for ( i = 0; i < msg_ptrex->dlen; i++ )
					 msg_ptrex->data[i] =  can0r(19+i);

			 }
			 else
			 {
				 temp1 = can0r(17);
				 msg_ptrex->id = temp1 << 21;
				 temp1 = can0r(18);
				 msg_ptrex->id |= temp1 << 13;
				 temp1 = can0r(19);
				 msg_ptrex->id |= temp1 << 5;
				 temp1 = can0r(20);
				 msg_ptrex->id |= temp1 >> 3;
				 for ( i = 0; i < msg_ptrex->dlen; i++ )
					 msg_ptrex->data[i] =  can0r(21+i);
			}

            /* release receive buffer*/
            can0w(1,4);
            return(1);
         }
         else
            return(0);
      }
      else
      {
         head = READ_FIFO_EX0.head;
         tail = READ_FIFO_EX0.tail;
         if(head == tail)
         return(0);
         pcan_msgex= (CAN_MSG_T_EX *)&READ_FIFO_EX0.buffer[tail];
         READ_FIFO_EX0.tail += CAN_MSG_EX_LEN;
         if(READ_FIFO_EX0.tail == RD_FIFO_EX_LEN )
         {
            READ_FIFO_EX0.tail %= RD_FIFO_EX_LEN;
            READ_FIFO_EX0.status = FIFO_OK;
         }
         if(READ_FIFO_EX0.tail == head )
            *IsEmpty = 1;
         else
            *IsEmpty = 0;
         msgex = *pcan_msgex;
         *((CAN_MSG_T_EX *)msg_ptrex) = msgex;
         return(1);
      }
   }
   else if(port == 1)
   {
      if( gIrq1 == IRQ_POLLING)
      {
	tag1 = can1r(0);
	if(tag1&1)
	return 0;
	tag1 = can1r(2);
         if( can1r(2)&1)
         {
			 temp2=can1r(16);
			 msg_ptrex->ff   =  temp2 & 0x80 ;
			 msg_ptrex->dlen =  temp2 & 0x0f ;
			 msg_ptrex->rtr  = ( temp2 >> 6) & 1;
			 if ( msg_ptrex->ff == PELICAN_SFF )
			 {
				 temp2 = can1r(17);
				 msg_ptrex->id = temp2 << 3;
				 temp2 = can1r(18);
				 msg_ptrex->id |= temp2 >> 5;
				 for ( i = 0; i < msg_ptrex->dlen; i++ )
					 msg_ptrex->data[i] =  can1r(19+i);

			 }
			 else
			 {
				 temp2 = can1r(17);
				 msg_ptrex->id = temp2 << 21;
				 temp2 = can1r(18);
				 msg_ptrex->id |= temp2 << 13;
				 temp2 = can1r(19);
				 msg_ptrex->id |= temp2 << 5;
				 temp2 = can1r(20);
				 msg_ptrex->id |= temp2 >> 3;
				 for ( i = 0; i < msg_ptrex->dlen; i++ )
					 msg_ptrex->data[i] =  can1r(21+i);
			 }

			 /* release receive buffer*/
			 can1w(1,4);
			 return(1);
         }
         else
            return(0);
      }
      else
      {
         head = READ_FIFO_EX1.head;
         tail = READ_FIFO_EX1.tail;
         if(head == tail)
         return(0);
	 pcan_msgex= (CAN_MSG_T_EX *)&READ_FIFO_EX1.buffer[tail];
         READ_FIFO_EX1.tail += CAN_MSG_EX_LEN;
         if(READ_FIFO_EX1.tail == RD_FIFO_EX_LEN )
         {
            READ_FIFO_EX1.tail %= RD_FIFO_EX_LEN;
            READ_FIFO_EX1.status = FIFO_OK;
         }
         if(READ_FIFO_EX1.tail == head )
            *IsEmpty = 1;
         else
            *IsEmpty = 0;
         msgex = *pcan_msgex;
         *((CAN_MSG_T_EX *)msg_ptrex) = msgex;
         return(1);
      }
   }
   else
     return( 0);
}
int  canSetProtocolType( BYTE port,BYTE protocoltype )
{
	BYTE v;
	if (port==0)
	{
		if(protocoltype==CANBUS_PROTOCOL_20A)
		{
			
			protocol1=CANBUS_PROTOCOL_20A;
			return(1);
		}
		if(protocoltype==CANBUS_PROTOCOL_20B)
		{
			
			protocol1=CANBUS_PROTOCOL_20B;
			return(1);
		}
		else return(0);
	}
	if (port==1)
	{
		if(protocoltype==CANBUS_PROTOCOL_20A)
		{
		
			protocol2=CANBUS_PROTOCOL_20A;
			return(1);
		}
		if(protocoltype==CANBUS_PROTOCOL_20B)
		{
		
			protocol2=CANBUS_PROTOCOL_20B;
			return(1);
		}
		else return(0);
	}
	return(0);
}
