📄 mbxwdif.c
字号:
/*********************************************************************
* Filename: MBXWDIF.c
*
* Description: This code illustrates the functionality of the WDIFn bit.
* (WDIF- Write Denied Interrupt Flag)
* The identifier field of a mailbox is written to, while it is enabled.
* This would set WDIFn bit and assert a CAN interrupt.
*
* Last update: 12/24/2002
*********************************************************************/
#include "DSP28_Device.h"
// Prototype statements for functions found within this file.
interrupt void eCAN0INT_ISR(void);
interrupt void eCAN1INT_ISR(void);
// Variable declarations
int int0count = 0; // Counter to track the # of level 0 interrupts
int int1count = 0; // Counter to track the # of level 1 interrupts
long i;
/* 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 the MSGID prior to enabling (Not strictly required as part of test) */
ECanaMboxes.MBOX13.MSGID.all = 0x9555AA13;
/* Write to the mailbox RAM field (Not strictly required as part of test) */
ECanaMboxes.MBOX13.MDRL.all = 0x31313131;
ECanaMboxes.MBOX13.MDRH.all = 0x13131313;
/* Enable Mailbox(es) under test */
ECanaShadow.CANME.all = ECanaRegs.CANME.all;
ECanaShadow.CANME.bit.ME13 = 1;
ECanaRegs.CANME.all = ECanaShadow.CANME.all;
/* Configure CAN interrupts */
ECanaShadow.CANGIM.all = ECanaRegs.CANGIM.all;
ECanaShadow.CANGIM.bit.WDIM = 1; // Enable "Write denied" int
ECanaShadow.CANGIM.bit.GIL = 0; // GIL value determines eCAN(0/1)INT
// Enable the int line chosen by SIL
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.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 'Write-denied' 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 = 0; // Enable INTx.6 of INT9 (eCAN1INT)
/* Configure system interrupts */
IER |= 0x0100; // Enable INT9 of CPU
EINT; // Global enable of interrupts
/* Now attempt to write to the MSGID field of the mailboxes */
ECanaMboxes.MBOX13.MSGID.all = 0x9555AA00;
asm(" NOP"); // Atleast 8 NOPs are needed
asm(" NOP"); // in order for the second write
asm(" NOP"); // to assert another interrupt.
asm(" NOP"); // Otherwise, the second write
asm(" NOP"); // would try to set the "already set"
asm(" NOP"); // WDIF, thereby failing to assert the
asm(" NOP"); // second interrupt.
asm(" NOP");
ECanaMboxes.MBOX13.MSGID.all = 0x9555AA00;
while(1) {}
}
/* --------------------------------------------------- */
/* ISR for PIE INT9.5 */
/* Connected to HECC0-INTA eCAN */
/* ----------------------------------------------------*/
interrupt void eCAN0INT_ISR(void) // eCAN
{
// Clear WDIFO flag bit..
ECanaShadow.CANGIF0.all = ECanaRegs.CANGIF0.all;
ECanaShadow.CANGIF0.bit.WDIF0 = 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
{
// Clear WDIF1 flag bit..
ECanaShadow.CANGIF1.all = ECanaRegs.CANGIF1.all;
ECanaShadow.CANGIF1.bit.WDIF1 = 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;
}
/* When a maskable interrupt request is sent to the CPU the following basic steps
are taken by the device:
1. Set the proper IFR bit
2. Check if interrupt enabled (Is proper IER bit set?)
3. Check if global interrupts enabled (Is INTM cleared?)
If both 2 and 3 are true, then proceed as follows:
4. Clear IFR
5. Store PC, fetch vector, adjust stack, perform context save
6. Clear corresponding IER bit (note this register was part of the context save
before the bit was cleared)
7. Set INTM (mask global interrupts) [note this bit is in ST1 which was part of
the context save before it was set]
8. Execute interrupt service routine
9. Perform context restore (also restores IER and INTM)
10.Continue program execution
By the time we get to the ISR routine, masked interrupts are disabled (INTM is set)
and interrupts from the same vector are also disabled. In this way, no maskable
interrupts will be serviced while we are in the ISR unless we choose to enable them.
In this example ISR, the following instructions would be used if nested interrupts are
to be allowed:
IER |= 0x0100; // Enable INT9
EINT;
What one might choose to do is only accept interrupts from a different
INT line - so the IER instruction might not be enabling the current interrupt, but instead
allow a different interrupt to come through. Basically in this manner one can do software
prioritization by allowing some interrupts to be interrupted themselves.
The PIEACK instruction:
PieCtrlRegs.PIEACK.bit.ACK9 = 1; // Enables PIE to drive a pulse into the CPU
tells the PIE that you are going to allow interrupts from that group to go on to the CPU
(assuming the proper PIER register bit is set). This instruction should be placed in the
routine where you want this to allow this - it might be at the beginning or at the end
as the last thing you do before you exit. If you do not do this you will never receive
another interrupt from that group.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -