📄 main.c
字号:
/* main.c - Software vector mode program using C isr */
/* Jan 15, 2004 S.Mihalik -- Copyright Freescale, 2004. All Rights Reserved */
/* Feb 9, 2004 S.M. - removed unused cache init & enabled eMIOS FREEZE */
/* Mar 4, 2004 S.M. - added software interrupt 7 code */
/* May 19,2006 S.M.- renamed SWirq7Ctr to SWirq4Ctr for consistency */
/* Aug 12 2006 S.M. - made i volatile (to get fewer Nexus messages in loop) */
/* Jul 17 2007 SM - Passed IVPR value from link file, used relevant names */
/* for MPC551x bit fields & registers, invoked SW interrupt*/
/* on even count eMIOS Ch 0 ISRs, changed timeout to 1 msec*/
/* and changed EMIOS_MCR[PRE] & EMIOS Chan 0 A Register values */
/* Copyright Freescale Semiconductor, In.c 2007 All rights reserved. */
/* Notes: */
/* 1. MMU not initialized; must be done by debug scripts or BAM */
/* 2. SRAM not initialized; must be done by debug scripts or in a crt0 type file */
/* 3. Cache is not used */
#include "mpc563m.h" /* Use proper include file like mpc5510.h or mpc5554.h */
extern IVOR4Handler();
extern uint32_t __IVPR_VALUE; /* Interrupt Vector Prefix value from link file*/
extern const vuint32_t IntcIsrVectorTable[];
int emiosCh0Ctr = 0; /* Counter for eMIOS channel 0 interrupts */
int SWirq4Ctr = 0; /* Counter for software interrupt 4 */
asm void initIrqVectors(void) {
lis r3, __IVPR_VALUE@h /* IVPR value is passed from link file */
ori r3, r3, __IVPR_VALUE@l
mtivpr r3
/* The following two lines are required for MPC555x, and are not used for MPC551x*/
li r3, IVOR4Handler@l /* IVOR4 = lower half of handler address */
mtivor4 r3
}
void initINTC(void) {
/* Use the first 3 or next 3 lines for MPC551x or MPC555x: */
/* INTC.MCR.B.HVEN_PRC0 = 0;*/ /* MPC551x Proc'r 0: initialize for SW vector mode */
/* INTC.MCR.B.VTES_PRC0 = 0; */ /* MPC551x Proc'r 0: default vector table 4B offsets */
/* INTC.IACKR_PRC0.R = (uint32_t) &IntcIsrVectorTable[0]; */ /* MPC551x: ISR table base */
INTC.MCR.B.HVEN = 0; /* MPC555x: initialize for SW vector mode */
INTC.MCR.B.VTES = 0; /* MPC555x: Use default vector table 4B offsets */
INTC.IACKR.R = (uint32_t) &IntcIsrVectorTable[0]; /* MPC555x: INTC ISR table base */
}
void initEMIOS(void) {
EMIOS.MCR.B.GPRE= 11; /* Divide sysclk by (11+1) for eMIOS clock */
EMIOS.MCR.B.GPREN = 1; /* Enable eMIOS clock */
EMIOS.MCR.B.GTBE = 1; /* Enable global time base */
EMIOS.MCR.B.FRZ = 1; /* Enable stopping channels when in debug mode */
/* Following for MPC551x only: */
/*EMIOS.UCDIS.R = 0; */ /* Ensure all channels are enabled */
/* Use one of the following two lines: */
/*INTC.PSR[58].R = 1; */ /* MPC551x: Raise eMIOS chan 0 IRQ priority = 1 */
INTC.PSR[51].R = 1; /* MPC555x: Raise eMIOS chan 0 IRQ priority = 1 */
EMIOS.CH[0].CADR.R = 999; /* Period will be 999+1 = 1000 channel clocks */
/* Use one of the next two lines: MCB mode is not in all MPC555x devices */
EMIOS.CH[0].CCR.B.MODE = 0x50; /* MPC551x or MPC563x: Mod. Counter Buffered (MCB) */
/*EMIOS.CH[0].CCR.B.MODE = 0x10;*/ /* MPC555x: Modulus Counter (MC), internal clock */
EMIOS.CH[0].CCR.B.BSL = 0x3; /* Use internal counter */
EMIOS.CH[0].CCR.B.UCPREN = 1; /* Enable prescaler; uses default divide by 1 */
EMIOS.CH[0].CCR.B.FREN = 1; /* Stop (freeze) channel registers when in debug mode */
EMIOS.CH[0].CCR.B.FEN=1; /* Flag enables interrupt */
}
void initSwIrq4(void) {
INTC.PSR[4].R = 2; /* Software interrupt 4 IRQ priority = 2 */
}
void enableIrq(void) {
/* Use one of the following two lines to lower the INTC current priority */
/*INTC.CPR_PRC0.B.PRI = 0; */ /* MPC551x Proc'r 0: Lower INTC's current priority */
INTC.CPR.B.PRI = 0; /* MPC555x: Lower INTC's current priority */
asm(" wrteei 1"); /* Enable external interrupts */
}
void main (void) {
vuint32_t i = 0; /* Dummy idle counter */
initIrqVectors(); /* Initialize exceptions: only need to load IVPR */
initINTC(); /* Initialize INTC for software vector mode */
initEMIOS(); /* Initialize eMIOS channel 0 for 1KHz IRQ, priority 2 */
initSwIrq4(); /* Initialize software interrupt 4 */
enableIrq(); /* Ensure INTC current prority=0 & enable IRQ */
while (1) {
i++;
}
}
void emiosCh0ISR(void) {
emiosCh0Ctr++; /* Increment interrupt counter */
if ((emiosCh0Ctr & 1)==0) { /* If emiosCh0Ctr is even*/
INTC.SSCIR[4].R = 2; /* then nvoke software interrupt 4 */
}
EMIOS.CH[0].CSR.B.FLAG=1; /* Clear channel's flag */
}
void SwIrq4ISR(void) {
SWirq4Ctr++; /* Increment interrupt counter */
INTC.SSCIR[4].R = 1; /* Clear channel's flag */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -