⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 moto.c

📁 TMS320LF2812DSP CAN总线方案。
💻 C
字号:
/*********************************************************************
* Filename: MOTO.c                                                
*                                                                    
* Description: This example illustrates the "MOTO" feature.
* 
* Deliberately let a transmit mailbox timeout and check whether the
* corresponding interrupt flag (MTOFn) and TOSn is set.
* Mailbox 0 is used in this example
*
* Last update: 12/26/2002
*********************************************************************/

#include "DSP28_Device.h"

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

// Prototype statements for functions found within this file.

interrupt void eCAN0INT_ISR(void);
interrupt void eCAN1INT_ISR(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;

void InitECan(void);

main() 

{

/* Initialize the CAN module */

	InitECan();

/* 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.MBOX0.MSGID.all  = 0x9555AA00; 
     
 /* Configure Mailbox under test as Tx */

	ECanaRegs.CANMD.all = 0; 		// All mailboxes are made transmit..
	
/* Enable Mailbox under test */
	
	ECanaShadow.CANME.all = ECanaRegs.CANME.all;	
	ECanaShadow.CANME.bit.ME0 = 1;
	ECanaRegs.CANME.all = ECanaShadow.CANME.all; 
	
/* Write to Master Control field */
 
    ECanaMboxes.MBOX0.MCF.bit.DLC = 8;
        
/* Write to the mailbox RAM field */
    
     ECanaMboxes.MBOX0.MDRL.all = 0x9555AAA0;
	 ECanaMboxes.MBOX0.MDRH.all = 0x89ABCDEF;
		           
/* Configure CAN interrupts */ 

	ECanaShadow.CANMIL.all = ECanaRegs.CANMIL.all;	
	ECanaShadow.CANMIL.bit.MIL0 = 0 ; // MBOX0 asserts MTOF0 (eCAN0INT)
	//ECanaShadow.CANMIL.bit.MIL0 = 1 ;  // MBOX0 asserts MTOF1 (eCAN1INT)
	ECanaRegs.CANMIL.all = ECanaShadow.CANMIL.all;
	
	ECanaShadow.CANGIM.all = 0;	
    ECanaShadow.CANGIM.bit.I0EN = 1;     // Enable eCAN0INT 
    ECanaShadow.CANGIM.bit.I1EN = 1;	 // Enable eCAN1INT
    ECanaShadow.CANGIM.bit.MTOM = 1;	 // Enable MBX Timeout interrupt
    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.PIECRTL.bit.ENPIE = 1;  // Enable vector fetching from PIE block	
	
	PieCtrlRegs.PIEACK.bit.ACK9 = 1;    // Enables PIE to drive a pulse into the CPU

// The 'MOTO' 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   
	
/* Write to MOTO reg of Mailbox under test */

	ECanaMOTORegs.MOTO0 = 0x8D; // It was experimentally determined that  
						// this value would let MBX0 to timeout...MOTS0 contains
						// 8Eh after transmission is complete..See Note 1

/* Enable time-out function for the mailbox */
    	 	
    ECanaShadow.CANTOC.all = 0;	
	ECanaShadow.CANTOC.bit.TOC0 = 1;
	ECanaRegs.CANTOC.all = ECanaShadow.CANTOC.all; 
	
/* Clear the "Time Stamp Counter"  */

	ECanaRegs.CANTSC = 0; 

/* Begin transmitting */       
     		 	
     ECanaShadow.CANTRS.all = 0; 	
     ECanaShadow.CANTRS.bit.TRS0 = 1;     // Set TRS for mailbox under test       
     ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all;     
     
     for(i=0; i<9999999; i++) 	// A very long loop. Code loops here when CAN module transmits
	 	{ asm(" NOP"); }        // the data and executes the ISR
	 
	 asm(" ESTOP0");									 // Code stops here after transmission

}

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

interrupt void eCAN0INT_ISR(void)  // eCAN
{
   ECanaShadow.CANTOS.all = ECanaRegs.CANTOS.all ;  // Copy TOS reg for inspection
   ECanaShadow.CANGIF0.all = ECanaRegs.CANGIF0.all; // Copy GIF0 reg for inspection
     
   while(ECanaRegs.CANTA.bit.TA0 != 1 ) {}   		 //  TAn bit set?


// Clear TAn  
   ECanaShadow.CANTA.all = 0; 			// Initialize TA to zero before setting any  
   ECanaShadow.CANTA.bit.TA0 = 1 ;		// bit in order to clear it. Otherwise, some
   							// other TAn bit that is set could be inadvertently cleared
   ECanaRegs.CANTA.all =  ECanaShadow.CANTA.all ;   // Clear TAn bit

// Clear MTOF0   
   // MTOF0 cannot be manually cleared. It is automatically cleared when TOSn is cleared, 
   // which is automatically cleared when the message is successfully transmitted.
   

// Re-enable PIE and Core interrupts   
   PieCtrlRegs.PIEACK.bit.ACK9 = 1;    	// Enables PIE to drive a pulse into the CPU
   IER |= 0x0100;					 	// These 2 lines allow for nested interrupts 
   EINT;								// Strictly not needed for this example.
   int0count++;
   return;
}

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

interrupt void eCAN1INT_ISR(void)  // eCAN
{
   ECanaShadow.CANTOS.all = ECanaRegs.CANTOS.all ;  // Copy TOS reg for inspection
   ECanaShadow.CANGIF1.all = ECanaRegs.CANGIF1.all; // Copy GIF1 reg for inspection
  
   while(ECanaRegs.CANTA.bit.TA0 != 1 ) {}   		 // TAn bit set?
   
// Clear TAn  
   ECanaShadow.CANTA.all = 0; 			// Initialize TA to zero before setting any  
   ECanaShadow.CANTA.bit.TA0 = 1 ;		// bit in order to clear it. Otherwise, some
   							// other TAn bit that is set could be inadvertently cleared
   ECanaRegs.CANTA.all =  ECanaShadow.CANTA.all ;   // Clear TAn bit

// Clear MTOF1   
   // MTOF1 cannot be manually cleared. It is automatically cleared when TOSn is cleared, 
   // which is automatically cleared when the message is successfully transmitted.
   
// Re-enable PIE and Core interrupts   
   PieCtrlRegs.PIEACK.bit.ACK9 = 1;    // Enables PIE to drive a pulse into the CPU
   IER |= 0x0100;					 // Enable INT9 
   EINT;
   int1count++;
   return;
}

/* Notes:

The TOS.n bit will be cleared upon (eventual) successful transmission.
The only way to ascertain if a time-out occured is to copy TOS and GIFn
registers in the ISR to check if the relevant bits were set when the 
ISR was just entered. 

It can be verified that whether the MTOF bit gets set in GIF0 or GIF1 
depends on the value of MILn. 

This example is useful to check that MTOFn gets cleared if TOSn is cleared. 

Note 1: TSC does not start running until the bit timing registers
are configured. After configuration, it is a free running timer clocked by the 
bit rate clock of the CAN module. The delay between the last instruction 
that configures the bit timing to the instruction that initiates transmission will
therefore affect this "experimentally determined" value. Since the counter runs at
the bit clock rate, the fastest bit clock rate is 1 uS, which equates to 150 CPU
clock cycles (@ 150 MHz SYSCLKOUT). Therefore adding/deleting a few instructions 
will not make a significant change. A delay loop would.

*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -