📄 mpc107epic.c
字号:
* If a vector has no handlers attached to it, a logMsg is generated.** NOMANUAL** RETURNS: N/A**/void mpc107EpicIntHandlerExec ( UCHAR intVec ) { INT_HANDLER_DESC * pCurrHandler; /* call each respective interrupt handler */ if ((pCurrHandler = sysIntTbl [intVec]) == NULL) { logMsg ("uninitalized PIC interrupt vector %x\r\n", intVec, 0,0,0,0,0); } else { /* call Each respective chained interrupt handler */ while (pCurrHandler != NULL) { (*pCurrHandler->vec) (pCurrHandler->arg); pCurrHandler = pCurrHandler->next; } } }/***************************************************************************** mpc107EpicIntHandler - handles the EPIC interrupts to the CPU** This routine handles interrupts originating from the embedded interrupt* controller.* This handler is entered from the 0x500 exception.** This routine is entered with CPU external interrupts enables.** Since the EPIC is the primary interrupt controller this driver* first initiates an Epic acknowledge call and reads the vector* put out by the EPIC. Subsequent vectors have to be obtained if* an external interrupt controller is connected to one of the* EPIC handlers.** This routine then processes the interrupt by calling all the interrupt* service routines chained to the vector.** Finally, this routine re-arms the interrupt at the PIC by performing an* PIC EOI for the EPIC.** RETURNS: N/A**/void mpc107EpicIntHandler (void) { int dontCare; UCHAR epicIntVec; int oldLevel; /* clear int, return the vector for highest IRQ */ epicIntVec = mpc107EpicIntAck ();#ifdef INCLUDE_WINDVIEW WV_EVT_INT_ENT (epicIntVec);#endif /* block all lower priority interrupts */ oldLevel = mpc107EpicCurTaskPrioSet (epicIntVec); if (oldLevel == MPC107_EPIC_INV_PRIO_ERROR) { return; } /* Allow external interrupts to the CPU. */ CPU_INT_UNLOCK (_PPC_MSR_EE); mpc107EpicIntHandlerExec (epicIntVec); /* * Disable External Interrupts * External Interrupts will be re-enabled in the kernel's wrapper * of this Interrupt. */ CPU_INT_LOCK (&dontCare); mpc107EpicEOI (); /* signal end of interrupt on EPIC */ mpc107EpicCurTaskPrioSet (oldLevel); /* Allow the next interrupt to occur */ }/***************************************************************************** mpc107EpicCurTaskPrioSet - set the priority of the current task.** NOTES** mpc107EpicCurTaskPrioSet sets the priority of the Processor Current Task* Priority register to the value of the prioNum parameter. This function* should be called after mpc107EpicInit() to lower the priority of the processor* current task. Note that valid priority values are 0 through 15 (15 being* the highest priority)** NOMANUAL** RETURNS: previous priority of the task.*/ULONG mpc107EpicCurTaskPrioSet ( int prioNum ) { ULONG oldPrio; if ((prioNum < MPC107_EPIC_PRIORITY_MIN) || (prioNum > MPC107_EPIC_PRIORITY_MAX)) { /* * If the Priority number is less than "0" * and more than "15" return an error */ return (MPC107_EPIC_INV_PRIO_ERROR); } /* Read the Processor Current Task Priority Register */ oldPrio = MPC107EUMBBARREAD (MPC107_EPIC_PROC_CTASK_PRI_REG); /* Set the Processor Current Task Proirity Register with the new Priority */ MPC107EUMBBARWRITE (MPC107_EPIC_PROC_CTASK_PRI_REG, prioNum); /* Return the previous Priority of the task */ return (oldPrio); }/***************************************************************************** mpc107EpicIntEnableVect - enable an EPIC interrupt, given its IVPR** This function clears the mask bit of an external, an internal or* a Timer register to enable the interrupt.** NOMANUAL** RETURNS: OK ,or an error code if the IVPR passed is invalid.*/int mpc107EpicIntEnableVect ( int srcAddr /* address offset of the Vector Priority register */ ) { ULONG srcVal; int errCode; errCode = mpc107EpicsrcAddrCheck (srcAddr); /* Check if the IVPR is valid */ if (errCode != MPC107_EPIC_INV_INTER_SOURCE) /* If the IVPR is valid */ { /* Read the Interrupt/Vector Priority Register */ srcVal = MPC107EUMBBARREAD (srcAddr); srcVal &= ~(MPC107_EPIC_IVPR_INTR_MSK); /* * clear the mask bit in the Interrupt/Vector Priority * Register to Enable the interrupt */ MPC107EUMBBARWRITE(srcAddr, srcVal); return (OK); } else { /* Return an error if the IVPR passed is invalid */ return (errCode); } }/***************************************************************************** mpc107EpicIntDisableVect - disable an EPIC interrupt, given its IVPR** This function sets the mask bit of an external, an internal or* a Timer register to disable the interrupt.** NOMANUAL** RETURNS: OK, or an error code if the IVPR passed in was invalid.*/int mpc107EpicIntDisableVect ( int srcAddr /* address offset of the Vector Priority register */ ) { ULONG srcVal; int errCode; errCode = mpc107EpicsrcAddrCheck (srcAddr); /* Check if the IVPR is valid */ if (errCode != MPC107_EPIC_INV_INTER_SOURCE) /* If the IVPR is valid */ { /* Read the Interrupt/Vector Priority Register */ srcVal = MPC107EUMBBARREAD (srcAddr); srcVal |= MPC107_EPIC_IVPR_INTR_MSK; /* * Set the mask bit in the Interrupt/Vector Priority * Register to disable the interrupt */ MPC107EUMBBARWRITE (srcAddr, srcVal); return OK; } else { /* Return an error if the IVPR passed is invalid */ return (errCode); } }/***************************************************************************** mpc107EpicIntAck - read the IACK register and return vector** NOTES** mpc107EpicIntAck reads the Interrupt acknowldge register and return* the vector number of the highest pending interrupt.** NOMANUAL** RETURNS: the vector number of the highest priority pending interrupt.*/int mpc107EpicIntAck(void) { return (MPC107EUMBBARREAD (MPC107_EPIC_PROC_INT_ACK_REG)); }/***************************************************************************** mpc107EpicEOI - signal end of interrupt on the EPIC** NOTES** mpc107EpicEOI writes 0x0 to the EOI register to signal end of interrupt.* This function is usually called after an interrupt routine is served.** NOMANUAL** RETURNS: N/A*/void mpc107EpicEOI(void) { MPC107EUMBBARWRITE (MPC107_EPIC_PROC_EOI_REG, 0x0); }/***************************************************************************** mpc107EpicsrcAddrCheck - check if the IVPR address passed in is* internal or external** NOTES** Check if the address of a vector priority register is of an internal* interrupt vector or an external interrupt vector.** NOMANUAL** RETURNS: EPIC_INTERNAL_INTERRUPT for internal interrupt sources,* or EPIC_EXTERNAL_INTERRUPT for external ones, or* EPIC_INV_INTER_SOURCE if an invalid IVPR was passed.*/STATUS mpc107EpicsrcAddrCheck ( ULONG srcAddr /* address offset of the Vector Priority register */ ) { switch(srcAddr) { case MPC107_EPIC_TM0_VEC_REG: case MPC107_EPIC_TM1_VEC_REG: case MPC107_EPIC_TM2_VEC_REG: case MPC107_EPIC_TM3_VEC_REG: case MPC107_EPIC_I2C_INT_VEC_REG: case MPC107_EPIC_DMA0_INT_VEC_REG: case MPC107_EPIC_DMA1_INT_VEC_REG: case MPC107_EPIC_MSG_INT_VEC_REG: return (MPC107_EPIC_INTERNAL_INTERRUPT); case MPC107_EPIC_SR_INT0_VEC_REG: case MPC107_EPIC_SR_INT1_VEC_REG: case MPC107_EPIC_SR_INT2_VEC_REG: case MPC107_EPIC_SR_INT3_VEC_REG: case MPC107_EPIC_SR_INT4_VEC_REG: case MPC107_EPIC_SR_INT5_VEC_REG: case MPC107_EPIC_SR_INT6_VEC_REG: case MPC107_EPIC_SR_INT7_VEC_REG: case MPC107_EPIC_SR_INT8_VEC_REG: case MPC107_EPIC_SR_INT9_VEC_REG: case MPC107_EPIC_SR_INT10_VEC_REG: case MPC107_EPIC_SR_INT11_VEC_REG: case MPC107_EPIC_SR_INT12_VEC_REG: case MPC107_EPIC_SR_INT13_VEC_REG: case MPC107_EPIC_SR_INT14_VEC_REG: case MPC107_EPIC_SR_INT15_VEC_REG: return (MPC107_EPIC_EXTERNAL_INTERRUPT); default: return (MPC107_EPIC_INV_INTER_SOURCE); } }/***************************************************************************** mpc107EpicIntSourceSet - set interrupt parameters for an interrupt register** This function sets the interrupt parameters for an External Interrupt* Source Vector Priority register, an Internal Interrupt Source Vector* Priority register, or a Global Timer register. The interrupt parameters* can only be set when the current source is not in-request or in-service,* which is determined by the Activity bit. This routine reads the Activity* bit; if the value of this bit is 1 (in-request or in-service), it returns* error; otherwise, it sets the value of the parameters to the register* offset defined in srcAddr.*** NOMANUAL** RETURNS: OK ,or ERROR if <srcAddr> is not valid or <priority> is not valid .*/STATUS mpc107EpicIntSourceSet ( ULONG srcAddr, /* address Offset of the source interrupt register */ int polarity, /* polarity of the external interrupt */ int sense, /* Level Sensitive Interrupt (0), */ /* Edge Sensitive Interrupt (1) */ int priority, /* priority of the interrupt (0 to 15)*/ int vector /* vector number (0 to 128)*/ ) { ULONG srcVal; ULONG errCode; errCode = mpc107EpicsrcAddrCheck(srcAddr);/* Check If IVPR is valid */ if (errCode == MPC107_EPIC_INV_INTER_SOURCE) { /* Return an error if the IVPR passed is invalid */ return (errCode); } srcVal = MPC107EUMBBARREAD(srcAddr); if (srcVal & MPC107_EPIC_IVPR_INTR_ACTIVE) { return (MPC107_EPIC_INTER_IN_SERVICE); /* interrupt in process */ } /* polarity and sense doesn't apply to internal interrupts */ if (errCode == MPC107_EPIC_INTERNAL_INTERRUPT) { polarity = 0; sense = 0; } /* erase previously set polority, sense, prority and vector values */ srcVal &= ~(MPC107_EPIC_IVPR_INTR_POLARITY | MPC107_EPIC_IVPR_INTR_SENSE | MPC107_EPIC_IVPR_PRIORITY_MSK | MPC107_EPIC_IVPR_VECTOR_MSK); srcVal |= (MPC107_EPIC_IVPR_POLARITY (polarity) | MPC107_EPIC_IVPR_SENS (sense) | MPC107_EPIC_IVPR_PRIORITY (priority) | MPC107_EPIC_IVPR_VECTOR (vector)); MPC107EUMBBARWRITE(srcAddr, srcVal); return (OK); }/***************************************************************************** mpc107EpicIntSourceGet - retrieve information of an EPIC source vector reg.** This function retrieves information of an EPIC source vector register.* The information includes the Enable bit, the polarity, sense bits, the* interrupt priority and interrupt vector number.** NOMANUAL** RETURNS: OK or ERROR*/STATUS mpc107EpicIntSourceGet ( ULONG srcAddr, /* address of the source vector register */ int * pEnableMask, /* whether the interrupt is enabled */ int * pPolarity, /* interrupt polarity (high or low) */ int * pSense, /* interrupt sense (level or edge) */ int * pPriority, /* interrupt priority */ int * pVector /* interrupt vector number */ ) { ULONG srcVal; int errCode; errCode = mpc107EpicsrcAddrCheck (srcAddr); if (errCode == MPC107_EPIC_INV_INTER_SOURCE) { /* Return an error if the IVPR passed is invalid */ return errCode; } srcVal = MPC107EUMBBARREAD(srcAddr); *pEnableMask = (srcVal & 0x80000000) >> 31; /* retrieve enable mask-b31 */ *pPolarity = (srcVal & 0x00800000) >> 23; *pSense = (srcVal & 0x00400000) >> 22; *pPriority = (srcVal & 0x000F0000) >> 16; *pVector = (srcVal & 0x000000FF); return OK; }/***************************************************************************** mpc107EpicTimerInit - initialization of EPIC Timer's** This routine should be called before using any timer related routines .** NOMANUAL** RETURNS: N/A*/STATUS mpc107EpicTimerInit (void) { /* setup timer frequency register */ MPC107EUMBBARWRITE(MPC107_EPIC_TM_FREQ_REG, MPC107_DEFAULT_TIMER_CLOCK); return OK; }/***************************************************************************** mpc107EpicDelayTimer1 - generate a delay using TIMER 1 of EPIC** this routine is used for generating a delay in milliseconds using* the timer 1 on the EPIC** NOMANUAL** RETURNS: N/A*/void mpc107EpicDelayTimer1 ( UINT milliSec /* time in millisecs */ ) { UINT32 toggleInitStat = 0; /* Read the toggle bit in the global timer current count register */ toggleInitStat= MPC107EUMBBARREAD(MPC107_EPIC_TM1_CUR_COUNT_REG) & MPC107_EPIC_TM_CUR_COUNT_TB; /* enable counter and write value to count from */ MPC107EUMBBARWRITE(MPC107_EPIC_TM1_BASE_COUNT_REG, ((MPC107_DEFAULT_TIMER_CLOCK/milliSec) & ~(MPC107_EPIC_TM_BASE_COUNT_CI ))); while ((MPC107EUMBBARREAD(MPC107_EPIC_TM1_CUR_COUNT_REG) & MPC107_EPIC_TM_CUR_COUNT_TB) == toggleInitStat); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -