// TI Release: 28xx eCAN programming example
// Release Date: Fri Aug 4 2017
// Copyright:
// Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions 
// are met:
// 
//   Redistributions of source code must retain the above copyright 
//   notice, this list of conditions and the following disclaimer.
// 
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the 
//   documentation and/or other materials provided with the   
//   distribution.
// 
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// 

/*********************************************************************
* Filename: TXABORT.c                                                
*                                                                    
* Description: Illustrates the transmit abort operation using the TRR bit. 	
* 
* A transmission is initiated for two mailboxes. While the first
* mailbox is getting transmitted, the transmission for second mailbox
* is aborted. It is then checked whether the AA bit for the second	
* mailbox is asserted. This example validates that AAIF bit getting
* set in GIF0/GIF1 register is determined by GIL and not MILn bit. 
* Mailboxes 15 & 29 (with standard identifiers ) are used in this example
*          
*
*********************************************************************/

//
// Included Files
//
#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File

// Prototype statements for functions found within this file.

interrupt void eCAN0INT_ISR(void);
interrupt void eCAN1INT_ISR(void);

// Variable declarations

long      i;
int int0count = 0;		// Counter to track the # of level 0 interrupts
int int1count = 0;	    // Counter to track the # of level 1 interrupts

void InitECan(void);

/* 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 */

	InitECan();	
	InitECanGpio();
	
	EALLOW;
    
/* 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;
	IER = 0x0000;
	IFR = 0x0000;

/* Initialize Pie Control Registers To Default State */
        
	InitPieCtrl(); // This function is found in the DSP28_PieCtrl.c file. 
	    
/* Write to the MSGID field  */
    
    ECanaMboxes.MBOX15.MSGID.all = 0x00540000; // Std Identifier (ID = 15)
    ECanaMboxes.MBOX29.MSGID.all = 0x00A40000; // Std Identifier (ID = 29)
    
/* Configure Mailboxes under test as Transmit mailbox */

	ECanaShadow.CANMD.all = ECanaRegs.CANMD.all;	
	ECanaShadow.CANMD.bit.MD15 = 0;
	ECanaShadow.CANMD.bit.MD29 = 0;
	ECanaRegs.CANMD.all = ECanaShadow.CANMD.all; 
	
/* Enable Mailboxes under test */
	
	ECanaShadow.CANME.all = ECanaRegs.CANME.all;	
	ECanaShadow.CANME.bit.ME15 = 1;
	ECanaShadow.CANME.bit.ME29 = 1;	
	ECanaRegs.CANME.all = ECanaShadow.CANME.all; 
	
/* Write to Master Control reg */

	ECanaMboxes.MBOX15.MSGCTRL.bit.DLC = 5;
	ECanaMboxes.MBOX29.MSGCTRL.bit.DLC = 5;
			
/* Write to the mailbox RAM field */
    
     ECanaMboxes.MBOX15.MDL.all = 0x15151515;
	 ECanaMboxes.MBOX15.MDH.all = 0x15151515;
	 
	 ECanaMboxes.MBOX29.MDL.all = 0x29292929;
	 ECanaMboxes.MBOX29.MDH.all = 0x29292929;		 
	 
/* Configure CAN interrupts */ 

 	ECanaShadow.CANGIM.all = ECanaRegs.CANGIM.all;	
    ECanaShadow.CANGIM.bit.AAIM = 1;   // Enable "Abort acknowledge" int 
    
    ECanaShadow.CANGIM.bit.GIL = 0;	   // GIL value determines eCAN(0/1)INT
    								   // Enable the int line chosen by GIL  
    ECanaShadow.CANGIM.bit.I0EN = 1;   // Uncomment this line if GIL = 0       
    ECanaShadow.CANGIM.bit.I1EN = 1;   // Uncomment this line if GIL = 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 'TX-Abort' interrupt can be asserted in either of the eCAN interrupt lines
// Comment out the unwanted line...

	PieCtrlRegs.PIEIER9.bit.INTx5 = 1;  // 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;							// Global enable of interrupts      
    
/* Begin transmitting */

     ECanaShadow.CANTRS.all = 0;			// Set TRS bit for mailboxes 29 and 15
     ECanaShadow.CANTRS.bit.TRS29 = 1;    // MBX 29 will be transmitted first, since the ID
     ECanaShadow.CANTRS.bit.TRS15 = 1;    // is numerically higher...
     ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all;
     
     ECanaShadow.CANTRR.all = 0; 			// MBX 15 will not be transmitted.
     ECanaShadow.CANTRR.bit.TRR15 = 1;     	// Reset mailbox 15
     ECanaRegs.CANTRR.all = ECanaShadow.CANTRR.all; 
             
     while(ECanaRegs.CANTA.bit.TA29 == 0 ) {}  // Wait for TA29 bit to be set..
     
     ECanaShadow.CANTA.all = 0; 			  // See Note 1
     ECanaShadow.CANTA.bit.TA29 = 1;		  // Clear TA29     
     ECanaRegs.CANTA.all = ECanaShadow.CANTA.all;       
    
 	 asm("     ESTOP0");
}

/* --------------------------------------------------- */
/* ISR for PIE INT9.5                          */
/* Connected to HECC0-INTA  eCAN                       */
/* ----------------------------------------------------*/

interrupt void eCAN0INT_ISR(void)  // eCAN
{
   ECanaShadow.CANAA.all = ECanaRegs.CANAA.all ;  // Copy AA reg for inspection
   ECanaShadow.CANGIF0.all = ECanaRegs.CANGIF0.all; // Copy GIF0 reg for inspection
   ECanaShadow.CANGIF1.all = ECanaRegs.CANGIF1.all; // Copy GIF1 reg for inspection
   
   asm (" NOP");									 // Useful to set a BP for reg exam

// Clear AA15 and hence AAIF0
	ECanaShadow.CANAA.all = 0;
	ECanaShadow.CANAA.bit.AA15 = 1;
	ECanaRegs.CANAA.all = ECanaShadow.CANAA.all;
   
   // Re-enable core interrupts and CAN int from PIE module
   PieCtrlRegs.PIEACK.bit.ACK9 = 1;    // Enables PIE to drive a pulse into the CPU
   IER |= 0x0100;					 // Enable INT9 
   EINT;
   int0count++;
   return;
}

/* --------------------------------------------------- */
/* ISR for PIE INT9.6                           */
/* Connected to HECC1-INTA  eCAN                       */
/* ----------------------------------------------------*/

interrupt void eCAN1INT_ISR(void)  // eCAN
{
   ECanaShadow.CANAA.all = ECanaRegs.CANAA.all ;  // Copy TOS reg for inspection
   ECanaShadow.CANGIF0.all = ECanaRegs.CANGIF0.all; // Copy GIF0 reg for inspection
   ECanaShadow.CANGIF1.all = ECanaRegs.CANGIF1.all; // Copy GIF1 reg for inspection  
   
	// Clear AA15 and hence AAIF1
	ECanaShadow.CANAA.all = 0;
	ECanaShadow.CANAA.bit.AA15 = 1;
	ECanaRegs.CANAA.all = ECanaShadow.CANAA.all;
   
   // Re-enable core interrupts and CAN int from PIE module
   PieCtrlRegs.PIEACK.bit.ACK9 = 1;    // Enables PIE to drive a pulse into the CPU
   IER |= 0x0100;					 // Enable INT9 
   EINT;
   int1count++;
   return;
}

/* 
Note 1: Initialize the "shadow-TA register" to zero before setting any bit(s)
in order to clear it (them) in the TA register. Otherwise, some other TAn bit(s)
that is (are) set could be inadvertently cleared.

Note 2: AAIFn bit in GIFn register is cleared by clearing the set AAn bit.
It cannot be cleared by writing a 1 to AAIFn bit. 


*/ 


   




