epic1.c
来自「适合KS8695X」· C语言 代码 · 共 518 行 · 第 1/2 页
C
518 行
/**************************************************
*
* copyright @ motorola, 1999
*
*************************************************/
#include <mpc824x.h>
#include <common.h>
#include "epic.h"
#define PRINT(format, args...) printf(format , ## args)
typedef void (*VOIDFUNCPTR) (void); /* ptr to function returning void */
struct SrcVecTable SrcVecTable[MAXVEC] = /* Addr/Vector cross-reference tbl */
{
{ EPIC_EX_INT0_VEC_REG, "External Direct/Serial Source 0"},
{ EPIC_EX_INT1_VEC_REG, "External Direct/Serial Source 1"},
{ EPIC_EX_INT2_VEC_REG, "External Direct/Serial Source 2"},
{ EPIC_EX_INT3_VEC_REG, "External Direct/Serial Source 3"},
{ EPIC_EX_INT4_VEC_REG, "External Direct/Serial Source 4"},
{ EPIC_SR_INT5_VEC_REG, "External Serial Source 5"},
{ EPIC_SR_INT6_VEC_REG, "External Serial Source 6"},
{ EPIC_SR_INT7_VEC_REG, "External Serial Source 7"},
{ EPIC_SR_INT8_VEC_REG, "External Serial Source 8"},
{ EPIC_SR_INT9_VEC_REG, "External Serial Source 9"},
{ EPIC_SR_INT10_VEC_REG, "External Serial Source 10"},
{ EPIC_SR_INT11_VEC_REG, "External Serial Source 11"},
{ EPIC_SR_INT12_VEC_REG, "External Serial Source 12"},
{ EPIC_SR_INT13_VEC_REG, "External Serial Source 13"},
{ EPIC_SR_INT14_VEC_REG, "External Serial Source 14"},
{ EPIC_SR_INT15_VEC_REG, "External Serial Source 15"},
{ EPIC_I2C_INT_VEC_REG, "Internal I2C Source"},
{ EPIC_DMA0_INT_VEC_REG, "Internal DMA0 Source"},
{ EPIC_DMA1_INT_VEC_REG, "Internal DMA1 Source"},
{ EPIC_MSG_INT_VEC_REG, "Internal Message Source"},
};
VOIDFUNCPTR intVecTbl[MAXVEC]; /* Interrupt vector table */
/****************************************************************************
* epicInit - Initialize the EPIC registers
*
* This routine resets the Global Configuration Register, thus it:
* - Disables all interrupts
* - Sets epic registers to reset values
* - Sets the value of the Processor Current Task Priority to the
* highest priority (0xF).
* epicInit then sets the EPIC operation mode to Mixed Mode (vs. Pass
* Through or 8259 compatible mode).
*
* If IRQType (input) is Direct IRQs:
* - IRQType is written to the SIE bit of the EPIC Interrupt
* Configuration register (ICR).
* - clkRatio is ignored.
* If IRQType is Serial IRQs:
* - both IRQType and clkRatio will be written to the ICR register
*/
void epicInit
(
unsigned int IRQType, /* Direct or Serial */
unsigned int clkRatio /* Clk Ratio for Serial IRQs */
)
{
ULONG tmp;
tmp = sysEUMBBARRead(EPIC_GLOBAL_REG);
tmp |= 0xa0000000; /* Set the Global Conf. register */
sysEUMBBARWrite(EPIC_GLOBAL_REG, tmp);
/*
* Wait for EPIC to reset - CLH
*/
while( (sysEUMBBARRead(EPIC_GLOBAL_REG) & 0x80000000) == 1);
sysEUMBBARWrite(EPIC_GLOBAL_REG, 0x20000000);
tmp = sysEUMBBARRead(EPIC_INT_CONF_REG); /* Read interrupt conf. reg */
if (IRQType == EPIC_DIRECT_IRQ) /* direct mode */
sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp & 0xf7ffffff);
else /* Serial mode */
{
tmp = (clkRatio << 28) | 0x08000000; /* Set clock ratio */
sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp);
}
while (epicIntAck() != 0xff) /* Clear all pending interrupts */
epicEOI();
}
/****************************************************************************
* epicIntEnable - Enable an interrupt source
*
* This routine clears the mask bit of an external, an internal or
* a Timer register to enable the interrupt.
*
* RETURNS: None
*/
void epicIntEnable(int intVec)
{
ULONG tmp;
ULONG srAddr;
srAddr = SrcVecTable[intVec].srcAddr; /* Retrieve src Vec/Prio register */
tmp = sysEUMBBARRead(srAddr);
tmp &= ~EPIC_VEC_PRI_MASK; /* Clear the mask bit */
tmp |= (EPIC_VEC_PRI_DFLT_PRI << 16); /* Set priority to Default - CLH */
tmp |= intVec; /* Set Vector number */
sysEUMBBARWrite(srAddr, tmp);
return;
}
/****************************************************************************
* epicIntDisable - Disable an interrupt source
*
* This routine sets the mask bit of an external, an internal or
* a Timer register to disable the interrupt.
*
* RETURNS: OK or ERROR
*
*/
void epicIntDisable
(
int intVec /* Interrupt vector number */
)
{
ULONG tmp, srAddr;
srAddr = SrcVecTable[intVec].srcAddr;
tmp = sysEUMBBARRead(srAddr);
tmp |= 0x80000000; /* Set the mask bit */
sysEUMBBARWrite(srAddr, tmp);
return;
}
/****************************************************************************
* epicIntSourceConfig - Set properties of an interrupt source
*
* This function sets interrupt properites (Polarity, Sense, Interrupt
* Prority, and Interrupt Vector) of an Interrupt Source. The properties
* can be set when the current source is not in-request or in-service,
* which is determined by the Activity bit. This routine return ERROR
* if the the Activity bit is 1 (in-request or in-service).
*
* This function assumes that the Source Vector/Priority register (input)
* is a valid address.
*
* RETURNS: OK or ERROR
*/
int epicIntSourceConfig
(
int Vect, /* interrupt source vector number */
int Polarity, /* interrupt source polarity */
int Sense, /* interrupt source Sense */
int Prio /* interrupt source priority */
)
{
ULONG tmp, newVal;
ULONG actBit, srAddr;
srAddr = SrcVecTable[Vect].srcAddr;
tmp = sysEUMBBARRead(srAddr);
actBit = (tmp & 40000000) >> 30; /* retrieve activity bit - bit 30 */
if (actBit == 1)
return ERROR;
tmp &= 0xff30ff00; /* Erase previously set P,S,Prio,Vector bits */
newVal = (Polarity << 23) | (Sense << 22) | (Prio << 16) | Vect;
sysEUMBBARWrite(srAddr, tmp | newVal );
return (OK);
}
/****************************************************************************
* epicIntAck - acknowledge an interrupt
*
* This function reads the Interrupt acknowldge register and return
* the vector number of the highest pending interrupt.
*
* RETURNS: Interrupt Vector number.
*/
unsigned int epicIntAck(void)
{
return(sysEUMBBARRead( EPIC_PROC_INT_ACK_REG ));
}
/****************************************************************************
* epicEOI - signal an end of interrupt
*
* This function writes 0x0 to the EOI register to signal end of interrupt.
* It is usually called after an interrupt routine is served.
*
* RETURNS: None
*/
void epicEOI(void)
{
sysEUMBBARWrite(EPIC_PROC_EOI_REG, 0x0);
}
/****************************************************************************
* epicCurTaskPrioSet - sets the priority of the Processor Current Task
*
* This function should be called after epicInit() to lower the priority
* of the processor current task.
*
* RETURNS: OK or ERROR
*/
int epicCurTaskPrioSet
(
int prioNum /* New priority value */
)
{
if ( (prioNum < 0) || (prioNum > 0xF))
return ERROR;
sysEUMBBARWrite(EPIC_PROC_CTASK_PRI_REG, prioNum);
return OK;
}
/************************************************************************
* function: epicIntTaskGet
*
* description: Get value of processor current interrupt task priority register
*
* note:
***********************************************************************/
unsigned char epicIntTaskGet()
{
/* get the interrupt task priority register */
ULONG reg;
unsigned char rec;
reg = sysEUMBBARRead( EPIC_PROC_CTASK_PRI_REG );
rec = ( reg & 0x0F );
return rec;
}
/**************************************************************
* function: epicISR
*
* description: EPIC service routine called by the core exception
* at 0x500
*
* note:
**************************************************************/
unsigned int epicISR(void)
{
return 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?