📄 lpmwakeup.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 + -