/*********************************************************************
* Filename: RXINT_A.c                                               
*                                                                    
* Description: This is a simple example of how data may be received  	
* using interrupts. it also illustrates the ability of the CAN module 
* to service multiple interrupts  automatically. 

*********************************************************************/

#include "DSP280x_Device.h"

// Prototype statements for functions found within this file.

interrupt void eCAN0INT_ISR(void);
interrupt void eCAN1INT_ISR(void);

// Variable declarations

long int0count = 0;		// Counter to track the # of level 0 interrupts
long int1count = 0;	    // Counter to track the # of level 1 interrupts
long      i;
void InitECan(void);
int	MIV = 0; // Stores the mailbox # that needs to be serviced.
long      RXCOUNT = 0;

/* Create a shadow register structure for the CAN control registers. This is
 needed, since, only 32-bit access is allowed to these registers. 16-bit access
 to these registers could potentially corrupt the register contents. This is
 especially true while writing to a bit (or group of bits) among bits 16 - 31 */

struct ECAN_REGS ECanaShadow;

main() 
{

/* Kill Watchdog, Init PLL, Enable peripheral clocks */

	InitSysCtrl();
	
/* Initialize the CAN module */

	InitECana(); 
	InitECanGpio();
    EALLOW;

	
/* Configure GPIO pin */

	GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0;
	GpioCtrlRegs.GPADIR.bit.GPIO0 = 1;	
	GpioDataRegs.GPACLEAR.bit.GPIO0 = 1;
 	SysCtrlRegs.XCLK.bit.XCLKOUTDIV = 2;

/* Initialize PIE vector table To a Known State: */
	// The PIE vector table is initialized with pointers to shell "Interrupt 
    // Service Routines (ISR)".  The shell routines are found in DSP28_DefaultIsr.c.
	// Insert user specific ISR code in the appropriate shell ISR routine in 
    // the DSP28_DefaultIsr.c file.
    
    // InitPieVectTable();	 // uncomment this line if the shell ISR routines are needed
    
    // This function is found in DSP28_PieVect.c. It populates the PIE vector table
    // with pointers to the shell ISR functions found in DSP28_DefaultIsr.c. This 
    // function is not useful in this code because the user-specific ISR is present
    // in this file itself. The shell ISR routine in the DSP28_DefaultIsr.c file is
    // not used. If the shell ISR routines are needed, uncomment this line and add 
    // DSP28_PieVect.c & DSP28_DefaultIsr.c files to the project

/* Disable and clear all CPU interrupts: */

	DINT;			// Note that InitPieCtrl() enables interrupts 
	IER = 0x0000;
	IFR = 0x0000;

/* Initialize Pie Control Registers To Default State */
        
	InitPieCtrl(); // This function is found in the DSP28_PieCtrl.c file.        	
	EALLOW;
	DINT;			// Disable interrupts again (for now)
	
/*  Note: If writing only to the 11-bit identifier as by
	"ECanaMboxes.MBOX1.MSGID.bit.STDMSGID = 1;", IDE, AME & AAM bit fields also
	need to be initialized. Otherwise, they may assume random values. This could
	be done by just initializing the entire register to zero first and then writing
	the STD MSG ID. */
    
    ECanaMboxes.MBOX1.MSGID.all = 0;
    ECanaMboxes.MBOX2.MSGID.all = 0;
    ECanaMboxes.MBOX3.MSGID.all = 0;
    ECanaMboxes.MBOX4.MSGID.all = 0;
    ECanaMboxes.MBOX5.MSGID.all = 0;
    ECanaMboxes.MBOX6.MSGID.all = 0;
    ECanaMboxes.MBOX7.MSGID.all = 0;
    ECanaMboxes.MBOX8.MSGID.all = 0;
    ECanaMboxes.MBOX9.MSGID.all = 0;
    ECanaMboxes.MBOX10.MSGID.all = 0;
    ECanaMboxes.MBOX11.MSGID.all = 0;
    ECanaMboxes.MBOX12.MSGID.all = 0;
    ECanaMboxes.MBOX13.MSGID.all = 0;
    ECanaMboxes.MBOX14.MSGID.all = 0;
    ECanaMboxes.MBOX15.MSGID.all = 0;
    ECanaMboxes.MBOX16.MSGID.all = 0;
    ECanaMboxes.MBOX17.MSGID.all = 0;
    ECanaMboxes.MBOX18.MSGID.all = 0;
    ECanaMboxes.MBOX19.MSGID.all = 0;
    ECanaMboxes.MBOX20.MSGID.all = 0;
    ECanaMboxes.MBOX21.MSGID.all = 0;
    ECanaMboxes.MBOX22.MSGID.all = 0;
    ECanaMboxes.MBOX23.MSGID.all = 0;
    ECanaMboxes.MBOX24.MSGID.all = 0;
    ECanaMboxes.MBOX25.MSGID.all = 0;
    ECanaMboxes.MBOX26.MSGID.all = 0;
    ECanaMboxes.MBOX27.MSGID.all = 0;
    ECanaMboxes.MBOX28.MSGID.all = 0;
    ECanaMboxes.MBOX29.MSGID.all = 0;
    ECanaMboxes.MBOX30.MSGID.all = 0;
    ECanaMboxes.MBOX31.MSGID.all = 0;
    ECanaMboxes.MBOX0.MSGID.all = 0;   
	
/* Write to the MSGID field - MBX number is written as its MSGID */
	
    ECanaMboxes.MBOX1.MSGID.bit.STDMSGID = 1;
    ECanaMboxes.MBOX2.MSGID.bit.STDMSGID = 2;
    ECanaMboxes.MBOX3.MSGID.bit.STDMSGID = 3;
    ECanaMboxes.MBOX4.MSGID.bit.STDMSGID = 4;
    ECanaMboxes.MBOX5.MSGID.bit.STDMSGID = 5;
    ECanaMboxes.MBOX6.MSGID.bit.STDMSGID = 6;
    ECanaMboxes.MBOX7.MSGID.bit.STDMSGID = 7;
    ECanaMboxes.MBOX8.MSGID.bit.STDMSGID = 8;
    ECanaMboxes.MBOX9.MSGID.bit.STDMSGID = 9;
    ECanaMboxes.MBOX10.MSGID.bit.STDMSGID = 10;
    ECanaMboxes.MBOX11.MSGID.bit.STDMSGID = 11;
    ECanaMboxes.MBOX12.MSGID.bit.STDMSGID = 12;
    ECanaMboxes.MBOX13.MSGID.bit.STDMSGID = 13;
    ECanaMboxes.MBOX14.MSGID.bit.STDMSGID = 14;
    ECanaMboxes.MBOX15.MSGID.bit.STDMSGID = 15;
    ECanaMboxes.MBOX16.MSGID.bit.STDMSGID = 16;
    ECanaMboxes.MBOX17.MSGID.bit.STDMSGID = 17;
    ECanaMboxes.MBOX18.MSGID.bit.STDMSGID = 18;
    ECanaMboxes.MBOX19.MSGID.bit.STDMSGID = 19;
    ECanaMboxes.MBOX20.MSGID.bit.STDMSGID = 20;
    ECanaMboxes.MBOX21.MSGID.bit.STDMSGID = 21;
    ECanaMboxes.MBOX22.MSGID.bit.STDMSGID = 22;
    ECanaMboxes.MBOX23.MSGID.bit.STDMSGID = 23;
    ECanaMboxes.MBOX24.MSGID.bit.STDMSGID = 24;
    ECanaMboxes.MBOX25.MSGID.bit.STDMSGID = 25;
    ECanaMboxes.MBOX26.MSGID.bit.STDMSGID = 26;
    ECanaMboxes.MBOX27.MSGID.bit.STDMSGID = 27;
    ECanaMboxes.MBOX28.MSGID.bit.STDMSGID = 28;
    ECanaMboxes.MBOX29.MSGID.bit.STDMSGID = 29;
    ECanaMboxes.MBOX30.MSGID.bit.STDMSGID = 30;
    ECanaMboxes.MBOX31.MSGID.bit.STDMSGID = 31;
    ECanaMboxes.MBOX0.MSGID.bit.STDMSGID = 32;
    
/* Zero out the mailboxes */

	ECanaMboxes.MBOX0.MDH.all = 0;
	ECanaMboxes.MBOX0.MDL.all = 0;
	ECanaMboxes.MBOX1.MDH.all = 0;
	ECanaMboxes.MBOX1.MDL.all = 0;
	ECanaMboxes.MBOX2.MDH.all = 0;
	ECanaMboxes.MBOX2.MDL.all = 0;
	ECanaMboxes.MBOX3.MDH.all = 0;
	ECanaMboxes.MBOX3.MDL.all = 0;
	ECanaMboxes.MBOX4.MDH.all = 0;
	ECanaMboxes.MBOX4.MDL.all = 0;
	ECanaMboxes.MBOX5.MDH.all = 0;
	ECanaMboxes.MBOX5.MDL.all = 0;
	ECanaMboxes.MBOX6.MDH.all = 0;
	ECanaMboxes.MBOX6.MDL.all = 0;
	ECanaMboxes.MBOX7.MDH.all = 0;
	ECanaMboxes.MBOX7.MDL.all = 0;
	ECanaMboxes.MBOX8.MDH.all = 0;
	ECanaMboxes.MBOX8.MDL.all = 0;
	ECanaMboxes.MBOX9.MDH.all = 0;
	ECanaMboxes.MBOX9.MDL.all = 0;
	ECanaMboxes.MBOX10.MDH.all = 0;
	ECanaMboxes.MBOX10.MDL.all = 0;
	ECanaMboxes.MBOX11.MDH.all = 0;
	ECanaMboxes.MBOX11.MDL.all = 0;
	ECanaMboxes.MBOX12.MDH.all = 0;
	ECanaMboxes.MBOX12.MDL.all = 0;
	ECanaMboxes.MBOX13.MDH.all = 0;
	ECanaMboxes.MBOX13.MDL.all = 0;
	ECanaMboxes.MBOX14.MDH.all = 0;
	ECanaMboxes.MBOX14.MDL.all = 0;
	ECanaMboxes.MBOX15.MDH.all = 0;
	ECanaMboxes.MBOX15.MDL.all = 0;
	ECanaMboxes.MBOX16.MDH.all = 0;
	ECanaMboxes.MBOX16.MDL.all = 0;
	ECanaMboxes.MBOX17.MDH.all = 0;
	ECanaMboxes.MBOX17.MDL.all = 0;
	ECanaMboxes.MBOX18.MDH.all = 0;
	ECanaMboxes.MBOX18.MDL.all = 0;
	ECanaMboxes.MBOX19.MDH.all = 0;
	ECanaMboxes.MBOX19.MDL.all = 0;
	ECanaMboxes.MBOX20.MDH.all = 0;
	ECanaMboxes.MBOX20.MDL.all = 0;
	ECanaMboxes.MBOX21.MDH.all = 0;
	ECanaMboxes.MBOX21.MDL.all = 0;
	ECanaMboxes.MBOX22.MDH.all = 0;
	ECanaMboxes.MBOX22.MDL.all = 0;
	ECanaMboxes.MBOX23.MDH.all = 0;
	ECanaMboxes.MBOX23.MDL.all = 0;
	ECanaMboxes.MBOX24.MDH.all = 0;
	ECanaMboxes.MBOX24.MDL.all = 0;
	ECanaMboxes.MBOX25.MDH.all = 0;
	ECanaMboxes.MBOX25.MDL.all = 0;
	ECanaMboxes.MBOX26.MDH.all = 0;
	ECanaMboxes.MBOX26.MDL.all = 0;
	ECanaMboxes.MBOX27.MDH.all = 0;
	ECanaMboxes.MBOX27.MDL.all = 0;
	ECanaMboxes.MBOX28.MDH.all = 0;
	ECanaMboxes.MBOX28.MDL.all = 0;
	ECanaMboxes.MBOX29.MDH.all = 0;
	ECanaMboxes.MBOX29.MDL.all = 0;
	ECanaMboxes.MBOX30.MDH.all = 0;
	ECanaMboxes.MBOX30.MDL.all = 0;
	ECanaMboxes.MBOX31.MDH.all = 0;
	ECanaMboxes.MBOX31.MDL.all = 0;	
	
/* Configure Mailboxes as Receive mailboxes */

	ECanaShadow.CANMD.all = ECanaRegs.CANMD.all;	
	ECanaShadow.CANMD.all = 0xFFFFFFFF;
	ECanaRegs.CANMD.all = ECanaShadow.CANMD.all; 
	
/* Enable Mailboxes */
	
	ECanaShadow.CANME.all = ECanaRegs.CANME.all;	
	ECanaShadow.CANME.all = 0xFFFFFFFF;
	ECanaRegs.CANME.all = ECanaShadow.CANME.all; 
		 
	 ECanaRegs.CANMIM.all = 0xFFFFFFFF;	

/* Configure CAN interrupts */ 

	ECanaShadow.CANMIL.all = 0xFFFFFFFF ; // Interrupts asserted on eCAN1INT
	//ECanaShadow.CANMIL.all  = 0x00000000 ; // Interrupts asserted on eCAN0INT	
	ECanaRegs.CANMIL.all = ECanaShadow.CANMIL.all;
	
	ECanaShadow.CANMIM.all  = 0xFFFFFFFF;   // Enable interrupts for all mailboxes
    ECanaRegs.CANMIM.all = ECanaShadow.CANMIM.all;
    
    ECanaShadow.CANGIM.all = 0;	
    // ECanaShadow.CANGIM.bit.I0EN = 1;   // Enable eCAN1INT or eCAN0INT 
    ECanaShadow.CANGIM.bit.I1EN = 1;
    ECanaRegs.CANGIM.all = ECanaShadow.CANGIM.all;
    
/* Reassign ISRs. i.e. reassign the PIE vector for ECAN0INTA_ISR and ECAN0INTA_ISR 
   to point to a different ISR than the shell routine found in DSP28_DefaultIsr.c.
   This is done if the user does not want to use the shell ISR routine but instead
   wants to embed the ISR in this file itself. */
	
	PieVectTable.ECAN0INTA = &eCAN0INT_ISR;
	PieVectTable.ECAN1INTA = &eCAN1INT_ISR;	
    
/* Configure PIE interrupts */    
  
	PieCtrlRegs.PIECTRL.bit.ENPIE = 1;  // Enable vector fetching from PIE block	
	
	PieCtrlRegs.PIEACK.bit.ACK9 = 1;    // Enables PIE to drive a pulse into the CPU

// The interrupt can be asserted in either of the eCAN interrupt lines
// Comment out the unwanted line...

	PieCtrlRegs.PIEIER9.bit.INTx5 = 0;  // Enable INTx.5 of INT9 (eCAN0INT)
	PieCtrlRegs.PIEIER9.bit.INTx6 = 1;  // Enable INTx.6 of INT9 (eCAN1INT)
	
/* Configure system interrupts */
	
	IER |= 0x0100;					// Enable INT9 of CPU
	EINT;
    
/* Begin receiving */

    while(1){}   

}
/* --------------------------------------------------- */
/* ISR for PIE INT9.5  (MBX30)                         */
/* Connected to eCAN0-INTA  eCAN                       */
/* ----------------------------------------------------*/

interrupt void eCAN0INT_ISR(void)  // eCAN
{
   int0count++;
  
   PieCtrlRegs.PIEACK.bit.ACK9 = 1;    // Enables PIE to drive a pulse into the CPU
   IER |= 0x0100;					// Enable INT9 
   EINT;
   return;
}

/* --------------------------------------------------- */
/* ISR for PIE INT9.6 (MBX5)                           */
/* Connected to eCAN1-INTA  eCAN                       */
/* ----------------------------------------------------*/

interrupt void eCAN1INT_ISR(void)  // eCAN
{
   
   MIV = ECanaRegs.CANGIF1.bit.MIV1; 
   
   switch(MIV)
   {case 1:
   		ECanaShadow.CANRMP.all = 0;
   		ECanaShadow.CANRMP.bit.RMP1 = 1;
   		ECanaRegs.CANRMP.all = ECanaShadow.CANRMP.all ;
   		break;}
         
   int1count++;
   
   PieCtrlRegs.PIEACK.bit.ACK9 = 1;    // Enables PIE to drive a pulse into the CPU
   IER |= 0x0100;					// Enable INT9 
   EINT;
   return;
}

/* 

* It can be verified that every time a mailbox interrupt is asserted,
* bits[0..4] of the "Global Interrupt Flag" Register contains the 
* mailbox number causing the interrupt. If more interrupt flags are 
* pending, it contains the mailbox number with the highest priority.
* This is done as follows: Disable interrupts and let many mailboxes
* transmit messages. Now enable interrupts. A core level interrupt is
* asserted and upon entering the ISR, examine MIVn bits. It 
* reflects the mailbox number with higher priority.
*/

/* 
The CANalyzer is made to transmit to all the mailboxes using the assigned STD IDs  

All 32 mailboxes are allowed to receive and then the interrupts enabled
A counter in the ISR counts the # of times an interrupt was asserted.
This program runs on Node B. CANalyzer is used as node A in this example.
All mailboxes are configured as receive mailboxes. Each mailbox
has a different ID. All mailboxes in node A are allowed to transmit
in a sequence to mailboxes in node B. Once the cycle is complete,
the cycle is started all over again. 

This program loops forever. The # of times the receive loop is executed
is stored in the RXCOUNT value.

*/ 

    
