/**
 * \file CISR16X1.C
 * 
 * \author Axel Wolf, SCI Cupertino
 * \author Dr. Jens Barrenscheen, HL MC PD, Munich
 * \author Hubert Piontek, University of Ulm
 *
 * Interrupt service routine for the CAN module. Not being used by the publisher/subscriber library at the moment.
 *
 * Most of this is based von the Infineon/Siemens Application Note AP2922.
 * Some additions made at University of Ulm, February 2003.
 *
 * This CAN driver is mainly meant to be used by the publisher/subscriber
 * library developed at the University of Ulm, 1999-2003.
 */

/*********************************************************************
 * ISR name:		"CANIR16X.C"                                     *
 * Compiler used:	BSO/Tasking C166                                 *
 * Task:		CAN ISR for Siemens ApNote AP2922                    *
 *			"'C' CAN Driver Routines for the C166 family'            *
 *                                                                   * 
 * Last modifications:	April 29nd 1997                              *
 * Authors:		Axel Wolf,  SCI Cupertino                            *
 *			Dr. Jens Barrenscheen, HL MC PD, Munich                  *
 *********************************************************************/

#include <REG167.H>	     /* register definitions C167            */
#include "CANR_16X.H"	 /* CAN register definitions             */

/**
 * Interrupt service routine for the CAN controller.
 *
 * \warning This is probably no very useful at the moment. It is still
 *          the original from Siemens/Infineon and not even indented properly.
 */
void canint (void) interrupt CAN_INTERRUPT
{
   /* -------------------------------- local  byte/word/bit data: -- */
   unsigned char status, intid;
   unsigned char download_data_buf[8]={0,0,0,0,0,0,0,0};
   unsigned char buf_no=0;		/* contains actual MO 15 buffer (0/1)*/
   unsigned char mo15_db_buf[2][8]={{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}};
					/* storage for MO15 buffer 1/2 data */
   unsigned long mo15_id[2]={0,0};	/* storage for MO15 buffer 1/2 id */ 
   unsigned char mo15_dlc[2]={0,0};	/* storage for MO15 buffer 1/2 dlc */
   /* -------------------------------- program: -------------------- */
while (intid=IR)	/* reload intid with IR, continue loop if intid != 0 */
   {
      status=SR;	/* copy status register to status variable */
      SR=0;		/* clear status register */
      switch (intid)
      {
	case 1:				/* Status Change Interrupt */
	   if (CR & 0x04)		/* if SIE is set (status interrupts) */
	   {
		if (status & 0x08) {}	/* transmit interrupt */
		if (status & 0x10) {}	/* receive interrupt */
		if (status & 0x07) {}	/* CAN bus error interrupt */
	   }
	   if (CR & 0x08)		/* if EIE is set (error interrupts) */
	   {
		if (status & 0x40) {}	/* error counter warning */
		if (status & 0x80)	/* bus off situation */
		   CR = (CR & 0xfe);	/* recover from BOFF (clear INIT) */
	   }
	   break;

	case 2:				/* Message 15 receive Interrupt */
	   rd_mo15_16x(mo15_db_buf[buf_no],&mo15_id[buf_no],&mo15_dlc[buf_no]);
			/* read id, dlc & data from MO 15, reset INTPND */

//	   if (mo15_id[buf_no]==TEST_IDENTIFIER)
//	   {
//		def_mo_16x(14, 0, mo15_id[buf_no], 1, mo15_dlc[buf_no], 0, 0);
		   /* Define message object 14 for data frame transmission */
		   /* MO=14,xtd=no,id=MO15,dir=tr,dlc=MO15,TXIE=no,RXIE=no */

//		ld_modata_16x(14, mo15_db_buf[buf_no]);
		   /* load data bytes of MO14 with data just read from MO 15 */

//		send_mo_16x(14); /* Transmit message 14 (sends data frame) */
//	   }

	   if (buf_no==0) buf_no=1; else buf_no=0;   /* swap MO15 buffer # */
	   break;

	case 3:				/* Message 1 Interrupt */
	   if (status & 0x10)		/* if receive interrupt... (RXOK=1)*/  
	   {
		/* whatever you want to do, but first you have to */
		/* enable Message Object 1 for the generation of */
		/* receive interrupts (MO1_RXIE_BIT = 1 in MAIN) */
	   }
	   if (status & 0x08)		/* if transmit interrupt... (TXOK=1)*/
	   {
		/* whatever you want to do, but first you have to */
		/* enable Message Object 1 for the generation of */
		/* transmit interrupts (MO1_TXIE_BIT = 1 in MAIN) */
	   }
	   break;

	case 4:				/* Message 2 Interrupt */

	   if (status & 0x10)		/* if receive interrupt... (RXOK=1)*/  
	   {
	   /* read data, reset INTPND: */
		rd_modata_16x(2, download_data_buf);
	   /* load data bytes of MO 3 with data just read from MO 2: */
		ld_modata_16x(3, download_data_buf);
	   /* Transmit message 3 (sends data frame): */
	   	send_mo_16x(3);
	   }
	   if (status & 0x08){}		/* if transmit interrupt... (TXOK=1)*/
	   break;

	case 5:				/* Message 3 Interrupt */
	   if (status & 0x10){}	/* if receive interrupt... (RXOK=1)*/  
	   if (status & 0x08){}	/* if transmit interrupt... (TXOK=1)*/
	   break;
	case 6:				/* Message 4 Interrupt */
	   if (status & 0x10){}	/* if receive interrupt... (RXOK=1)*/  
	   if (status & 0x08){}	/* if transmit interrupt... (TXOK=1)*/
	   break;

	/* ..... */

	case 16:			/* Message 14 Interrupt */
	   if (status & 0x10){}	/* if receive interrupt... (RXOK=1)*/  
	   if (status & 0x08){}	/* if transmit interrupt... (TXOK=1)*/
	   break;
      }
   }
/*------------------------------------ end: --------------------- */
}