📄 irq.c
字号:
/*****************************************************************************
* irq.c: Interrupt handler C file for Philips LPC230x Family Microprocessors
*
* Copyright(C) 2006, Philips Semiconductor
* All rights reserved.
*
* History
* 2005.10.01 ver 1.00 Prelimnary version, first Release
*
******************************************************************************/
#include "LPC318x.h" /* LPC310X Peripheral Registers */
#include "type.h"
#include "irq.h"
DWORD IntStatus;
HandlerAddr IntVectTable[3][32]; /* 0 is MIC, 1 is SIC1, 2 is SIC2 */
/******************************************************************************
** Function name: IRQ_Exception
**
** Descriptions: Interrupt handler, called in the startup.s file.
** Check all the bits in MIR first, then SIC1 and SIC2.
**
** parameters: None
** Returned value: None
**
******************************************************************************/
void __irq IRQ_Exception( void )
{
HandlerAddr IRQHandler;
int i;
/* The first while loop is to take care of MIC1 interrupts. */
while ( (MIC_SR != 0) && (!(MIC_SR & 0x01)) && (!(MIC_SR & 0x02)) )
{
for ( i = 31; i >= 0; i-- )
{
if ( MIC_SR & (1<<i) )
{
if ( IntVectTable[0][i] != NULL )
{
IRQHandler = IntVectTable[0][i];
if ( MIC_ATR & (1<<i) ) /* If edge trigger, clear interrupt status */
{
MIC_RSR |= (1<<i); /* No need to clear on level trigger */
}
(*IRQHandler)();
}
else
{
if ( MIC_ATR & (1<<i) ) /* If edge trigger, clear interrupt status */
{
MIC_RSR |= (1<<i); /* No need to clear on level trigger */
}
}
}
}
}
/* If Sub1IRQn is not enabled in the MIC_ER, below while loop should never
be called. */
while ( SIC1_SR != 0 )
{
IntStatus = SIC1_SR;
for ( i = 31; i >= 0; i-- )
{
if ( SIC1_SR & (1<<i) )
{
if ( IntVectTable[1][i] != NULL )
{
IRQHandler = IntVectTable[1][i];
if ( SIC1_ATR & (1<<i) ) /* If edge trigger, clear interrupt status */
{
SIC1_RSR |= (1<<i); /* No need to clear on level trigger */
}
(*IRQHandler)();
}
else /* Bad thing happened, interrupt occurs, no handler installed */
{
if ( SIC1_ATR & (1<<i) ) /* If edge trigger, clear interrupt status */
{
SIC1_RSR |= (1<<i); /* No need to clear on level trigger */
}
}
}
}
}
/* If Sub2IRQn is not enabled in the MIC_ER, below while loop should never
be called. */
while ( SIC2_SR != 0 )
{
IntStatus = SIC2_SR;
for ( i = 31; i >= 0; i-- )
{
if ( SIC2_SR & (1<<i) )
{
if ( IntVectTable[2][i] != NULL )
{
IRQHandler = IntVectTable[2][i];
if ( SIC2_ATR & (1<<i) ) /* If edge trigger, clear interrupt status */
{
SIC2_RSR |= (1<<i); /* No need to clear on level trigger */
}
(*IRQHandler)();
}
else
{
if ( SIC2_ATR & (1<<i) ) /* If edge trigger, clear interrupt status */
{
SIC2_RSR |= (1<<i); /* No need to clear on level trigger */
}
}
}
}
}
return;
}
/******************************************************************************
** Function name: FIQ_Exception
**
** Descriptions: Fast interrupt handler, called in the startup.s.
**
** parameters: None
** Returned value: None
**
******************************************************************************/
void __irq FIQ_Exception( void )
{
while ( 1 );
}
/******************************************************************************
** Function name: init_irq
**
** Descriptions: Initialize interrupt controller.
** parameters: None
** Returned value: None
**
******************************************************************************/
void init_irq(void)
{
DWORD i;
MIC_ER = 0x0000;
SIC1_ER = 0x0000;
SIC2_ER = 0x0000;
for (i = 0; i < 32; i++)
{
IntVectTable[0][i] = (HandlerAddr)NULL;
IntVectTable[1][i] = (HandlerAddr)NULL;
IntVectTable[2][i] = (HandlerAddr)NULL;
}
return;
}
/******************************************************************************
** Function name: Install_MIC
**
** Descriptions: Install MIC.
** parameters: Interrupt number, polarity, action type, and
** peripheral interrupt handler
** Returned value: None
**
******************************************************************************/
void Install_MIC( BYTE IntNum, BYTE ActPol, BYTE ActType, HandlerAddr IRQHandler )
{
if ( (IntNum < 32) && (IRQHandler != (HandlerAddr)NULL) )
{
if (ActPol == INT_LOW_LEVEL)
{
MIC_APR &= ~(1 << IntNum); /* low level / falling edge */
}
else
{
MIC_APR |= (1 << IntNum); /* high level / rising edge */
}
if (ActType == INT_LEVEL_SENSITIVE)
{
MIC_ATR &= ~(1 << IntNum); /* level trigger */
}
else
{
MIC_ATR |= (1 << IntNum); /* edge trigger */
}
IntVectTable[0][IntNum] = IRQHandler;
}
return;
}
/******************************************************************************
** Function name: Enable_MIC
**
** Descriptions: Enable MIC.
** parameters: Interrupt number
** Returned value: None
**
******************************************************************************/
void Enable_MIC( BYTE IntNum )
{
if ( IntNum < 32 )
{
MIC_ER |= (1 << IntNum); /* Enable the IntNum on MIC */
}
return;
}
/******************************************************************************
** Function name: Disable_MIC
**
** Descriptions: Disable MIC.
** parameters: Interrupt number
** Returned value: None
**
******************************************************************************/
void Disable_MIC( BYTE IntNum )
{
if ( IntNum < 32 )
{
MIC_ER &= ~(1 << IntNum); /* Disable the IntNum on the MIC */
}
return;
}
/******************************************************************************
** Function name: Install_SIC1
**
** Descriptions: Install SIC1
** parameters: Interrupt number, polarity, action type, and
** peripheral interrupt handlerNone
** Returned value: None
**
******************************************************************************/
void Install_SIC1( BYTE IntNum, BYTE ActPol, BYTE ActType, HandlerAddr IRQHandler )
{
if ( (IntNum < 32) && (IRQHandler != (HandlerAddr)NULL) )
{
if (ActPol == INT_LOW_LEVEL)
{
SIC1_APR &= ~(1 << IntNum); /* low level / falling edge */
}
else
{
SIC1_APR |= (1 << IntNum); /* high level / rising edge */
}
if (ActType == INT_LEVEL_SENSITIVE)
{
SIC1_ATR &= ~(1 << IntNum); /* level trigger */
}
else
{
SIC1_ATR |= (1 << IntNum); /* edge trigger */
}
MIC_APR &= ~(1 << 0); /* MIC is always low level / falling edge */
MIC_ATR &= ~(1 << 0); /* MIC is level trigger */
IntVectTable[1][IntNum] = IRQHandler;
}
return;
}
/******************************************************************************
** Function name: Enable_SIC1
**
** Descriptions: Enable MIC.
** parameters: Interrupt number
** Returned value: None
**
******************************************************************************/
void Enable_SIC1( BYTE IntNum )
{
if ( IntNum < 32 )
{
MIC_ER |= (1 << 0); /* SUB1 IRQ is routed to MIC */
SIC1_ER |= (1 << IntNum); /* Enable the IntNum on SIC1 */
}
return;
}
/******************************************************************************
** Function name: Disable_SIC1
**
** Descriptions: Disable SIC1
** parameters: Interrupt number
** Returned value: None
**
******************************************************************************/
void Disable_SIC1( BYTE IntNum )
{
if ( IntNum < 32 )
{
SIC1_ER &= ~(1 << IntNum); /* Disable the IntNum on the SIC1 */
}
return;
}
/******************************************************************************
** Function name: Install_SIC2
**
** Descriptions: Install SIC2
** parameters: Interrupt number, polarity, action type, and
** peripheral interrupt handler
** Returned value: None
**
******************************************************************************/
void Install_SIC2( BYTE IntNum, BYTE ActPol, BYTE ActType, HandlerAddr IRQHandler )
{
if ( (IntNum < 32) && (IRQHandler != (HandlerAddr)NULL) )
{
if (ActPol == INT_LOW_LEVEL)
{
SIC2_APR &= ~(1 << IntNum); /* low level / falling edge */
}
else
{
SIC2_APR |= (1 << IntNum); /* high level / rising edge */
}
if (ActType == INT_LEVEL_SENSITIVE)
{
SIC2_ATR &= ~(1 << IntNum); /* level trigger */
}
else
{
SIC2_ATR |= (1 << IntNum); /* edge trigger */
}
MIC_APR &= ~(1 << 0); /* MIC is always low level / falling edge */
MIC_ATR &= ~(1 << 0); /* MIC is level trigger */
IntVectTable[2][IntNum] = IRQHandler;
}
return;
}
/******************************************************************************
** Function name: Enable_SIC2
**
** Descriptions: Enable SIC2
** parameters: Interrupt number
** Returned value: None
**
******************************************************************************/
void Enable_SIC2( BYTE IntNum )
{
if ( IntNum < 32 )
{
MIC_ER |= (1 << 1); /* SUB2 IRQ is routed to MIC */
SIC2_ER |= (1 << IntNum); /* Enable the IntNum on SIC2 */
}
return;
}
/******************************************************************************
** Function name: Disable_SIC2
**
** Descriptions: Disable SIC2
** parameters: Interrupt number
** Returned value: None
**
******************************************************************************/
void Disable_SIC2( BYTE IntNum )
{
if ( IntNum < 32 )
{
SIC2_ER &= ~(1 << IntNum); /* Disable the IntNum on the SIC2 */
}
return;
}
/******************************************************************************
** End Of File
******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -