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

📄 lpmwakeup.c

📁 TI公司28XDSP控制永磁同步电机PMSM 系统调试源码之六
💻 C
字号:
/*********************************************************************
* Filename: LPMwakeup.c                                                
*                                                                    
* Description: This example illustrates the ability of the CAN module to enter
  and exit low-power mode  (automatically).

  The PDR bit of node A is set to force it into low-power mode. The PDA
  bit is read back to ensure that it is indeed in low-power mode. 
  An attempt is made to write to mailbox 9 RAM while the CAN module
  is in low-power mode, to ensure that the write fails..
  After a while, node B transmits a packet to "wake-up" node A. The PDA bit
  is again read back to ensure that node A is indeed out of low-power mode.
  After wakeup, WUIFn bit must be set as appropriate 
  
* Last update: 12/25/2002
*********************************************************************/

#include "DSP28_Device.h"


// Variable declarations

int PDA_STATUS = 0;
int int0count = 0;		// Counter to track the # of level 0 interrupts
int int1count = 0;	    // Counter to track the # of level 1 interrupts
long      i;
void InitECan(void);

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

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  = 0x9FFFFF00; // MBX0 is a Tx MBX
    ECanaMboxes.MBOX1.MSGID.all  = 0x9FFFFF01; // MBX1 is a Tx MBX
    ECanaMboxes.MBOX2.MSGID.all  = 0x9FFFFF02; // MBX2 is a Tx MBX
    ECanaMboxes.MBOX3.MSGID.all  = 0x9FFFFF03; // MBX3 is a Tx MBX
    ECanaMboxes.MBOX4.MSGID.all  = 0x9FFFFF04; // MBX9 is a Tx MBX
    ECanaMboxes.MBOX5.MSGID.all  = 0x9FFFFF05; // MBX5 is a Tx MBX
    ECanaMboxes.MBOX6.MSGID.all  = 0x9FFFFF06; // MBX6 is a Tx MBX
    ECanaMboxes.MBOX7.MSGID.all  = 0x9FFFFF07; // MBX7 is a Tx MBX
    ECanaMboxes.MBOX8.MSGID.all  = 0x9FFFFF08; // MBX8 is the RCV MBX
    ECanaMboxes.MBOX9.MSGID.all  = 0x9FFFFF09; // MBX9 is a Tx MBX

/* Enable Mailboxes under test */
	
	ECanaShadow.CANME.all = 0;	
	ECanaShadow.CANME.bit.ME0 = 1;
	ECanaShadow.CANME.bit.ME1 = 1;
	ECanaShadow.CANME.bit.ME2 = 1;
	ECanaShadow.CANME.bit.ME3 = 1;
	ECanaShadow.CANME.bit.ME4 = 1;
	ECanaShadow.CANME.bit.ME5 = 1;
	ECanaShadow.CANME.bit.ME6 = 1;
	ECanaShadow.CANME.bit.ME7 = 1;
	ECanaShadow.CANME.bit.ME8 = 1;
	ECanaShadow.CANME.bit.ME9 = 1;	
	ECanaRegs.CANME.all = ECanaShadow.CANME.all; 
		    
/* Write to the mailbox RAM a known data */
	ECanaRegs.CANMD.all = 0x0;
	ECanaMboxes.MBOX0.MDRH.all = 0x00000000;
	ECanaMboxes.MBOX0.MDRL.all = 0x00000000;
	ECanaMboxes.MBOX1.MDRH.all = 0x11111111;
	ECanaMboxes.MBOX1.MDRL.all = 0x11111111;
	ECanaMboxes.MBOX2.MDRH.all = 0x22222222;
	ECanaMboxes.MBOX2.MDRL.all = 0x22222222;
	ECanaMboxes.MBOX3.MDRH.all = 0x33333333;
	ECanaMboxes.MBOX3.MDRL.all = 0x33333333;
	ECanaMboxes.MBOX4.MDRH.all = 0x44444444;
	ECanaMboxes.MBOX4.MDRL.all = 0x44444444;
	ECanaMboxes.MBOX5.MDRH.all = 0x55555555;
	ECanaMboxes.MBOX5.MDRL.all = 0x55555555;
	ECanaMboxes.MBOX6.MDRH.all = 0x66666666;
	ECanaMboxes.MBOX6.MDRL.all = 0x66666666;
	ECanaMboxes.MBOX7.MDRH.all = 0x77777777;
	ECanaMboxes.MBOX7.MDRL.all = 0x77777777;
	
	ECanaMboxes.MBOX8.MDRH.all = 0x88888888; // MBOX8 = 18181818 after wakeup.
	ECanaMboxes.MBOX8.MDRL.all = 0x88888888;
	ECanaMboxes.MBOX9.MDRH.all = 0x99999999;
	ECanaMboxes.MBOX9.MDRL.all = 0x99999999;
		           
/* Configure Receive mailbox  */

	ECanaShadow.CANMD.all = 0x0;
	ECanaShadow.CANMD.bit.MD8 = 1;
	ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;	

/* Write to MCF of Transmit  mailboxes */ // Write 00000000 to MCF

	ECanaMboxes.MBOX0.MCF.bit.DLC = 8;
    ECanaMboxes.MBOX1.MCF.bit.DLC = 8;
    ECanaMboxes.MBOX2.MCF.bit.DLC = 8;
    ECanaMboxes.MBOX3.MCF.bit.DLC = 8;
    ECanaMboxes.MBOX4.MCF.bit.DLC = 8;
    ECanaMboxes.MBOX5.MCF.bit.DLC = 8;
    ECanaMboxes.MBOX6.MCF.bit.DLC = 8;
    ECanaMboxes.MBOX7.MCF.bit.DLC = 8;
    ECanaMboxes.MBOX9.MCF.bit.DLC = 8;	
	    
/* Configure CAN interrupts */ 
	
 	ECanaShadow.CANGIM.all = 0;	
    ECanaShadow.CANGIM.bit.WUIM = 1;  // Enable "Wakeup" int 
    ECanaShadow.CANGIM.bit.GIL = 1;	 // SIL value determines HECC(0/1)INT
    ECanaShadow.CANGIM.bit.I0EN = 1;   // Enable the int line chosen by SIL
    ECanaShadow.CANGIM.bit.I1EN = 1;   // Enable the int line chosen by SIL
    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 'Wakeup' 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   	               
 	
/* Configure WUBA */	
	
	ECanaRegs.CANMC.bit.WUBA = 1; // Set WUBA = 1 so that node can "wakeup"
   
    ECanaShadow.CANTRS.all = 0x000002FF;
    ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all; 	// Initiate a transmit for
    										// all Tx mailboxes
   
    while(ECanaRegs.CANTRS.all !=0) {}    	// Loop here until all mailboxes are 
    										// transmitted    	
    										 
/* Drive the CAN module into low power mode by setting the PDR bit */   
   
   ECanaRegs.CANMC.bit.PDR = 1 ; // Set PDR = 1 
     
	while (ECanaRegs.CANES.bit.PDA != 1) {}     // Loop here if PDA != 1
	PDA_STATUS = ECanaRegs.CANES.bit.PDA;
	
/* Attempt to write to MBX9 RAM to verify if LPM has indeed been entered */

	ECanaMboxes.MBOX9.MDRH.all = 0x01234567;  // This data should not be
	ECanaMboxes.MBOX9.MDRL.all = 0x89ABCDEF;  // written into the MBX RAM
	
    while(ECanaRegs.CANRMP.bit.RMP8 ==0 ) {}  // Wait for data to wakeup...
     
/* Now node B transmits the same data twice; the first data "wakes up"
the 28x , the second data is stored in MBX8. It is verfied whether 
the second data is received and stored in MBX8 */

/* Read PDA bit to make sure it is 0 */
	
	PDA_STATUS = ECanaRegs.CANES.bit.PDA;
	
	asm (" ESTOP0");

}

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

interrupt void eCAN0INT_ISR(void)  // eCAN
{
   ECanaShadow.CANTA.all  = 0x000002FF;
   // Clear WUIF0 flag bit..
   ECanaShadow.CANGIF0.all = ECanaRegs.CANGIF0.all;
   ECanaShadow.CANGIF0.bit.WUIF0 = 1;
   ECanaRegs.CANGIF0.all = ECanaShadow.CANGIF0.all;
   int0count++;						// Interrupt counter
   
   // 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;
   return;
}

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

interrupt void eCAN1INT_ISR(void)  // eCAN
{
   ECanaShadow.CANTA.all  = 0x000002FF;
   // Clear WUIF1 flag bit..
   ECanaShadow.CANGIF1.all = ECanaRegs.CANGIF1.all;
   ECanaShadow.CANGIF1.bit.WUIF1 = 1;
   ECanaRegs.CANGIF1.all = ECanaShadow.CANGIF1.all;
   int1count++;						// Interrupt counter
   
   // 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;
   return;
}


/* 

OBSERVATIONS:

The following can be observed while executing this example:
> 1. Setting PDR = 1, puts the module in LPM
> 2. Write to mailbox RAM fails when CAN is in LPM.
> 3. CAN module wakes up, when node B transmits a frame twice. The first
> frame wakes up the CAN. The second frame is correctly received by the
> configured mailbox. The first dataframe may generate an error frame if,
> there are only 2 nodes in the network (28x and CANalyzer, for example).
> Apart from CANalyzer, the only other node is in LPM and there is no node to
> generate an ACK for the frame CANalyzer transmits to wakeup.
> 4. The WUBA bit works as intended.
> 5. The WUIFn bit is correctly set upon wakeup.
> 6. The CAN module exits LPM when PDR bit is cleared to zero.

> Atleast 80 NOPs are needed after the statement that sets the 
> TRS bit before the statement that sets the PDR bit =1. Only then is the
> data in mailbox RAM is transmitted BEFORE the CAN module goes into LPM mode
> Otherwise, the data is transmitted AFTER the CAN module wakes up.
> To ensure all mailboxes have transmitted before putting the CAN module in 
> LPM, the CANTRS register may be checked.

CANalyzer configuration file: LPMWAKE.cfg
*/ 

⌨️ 快捷键说明

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