📄 irq.c
字号:
/*****************************************************************************/
/* irq.c: Philips LPC214x家族微控制器中断向量的C文件 */
/* 作者:焦进星 */
/* 时间:2008年月1月22日 */
/* ARM初学 */
/*****************************************************************************/
#include "target.h"
/*****************************************************************************
** Function name: Enable_IRQ
**
** Descriptions: Enable interrupt
**
** parameters: None
** Returned value: None
**
*****************************************************************************/
void Enable_IRQ(void)
{
int temp;
__asm
{
MRS temp,CPSR
BIC temp,temp, #0x80
MSR CPSR_c,temp
}
}
/*****************************************************************************
** Function name: Disable_IRQ
**
** Descriptions: Disable interrupt
**
** parameters: None
** Returned value: None
**
*****************************************************************************/
void Disable_IRQ(void)
{
int temp;
__asm
{
MRS temp,CPSR
ORR temp,temp, #0x80
MSR CPSR_c,temp
}
}
/*****************************************************************************
** Function name: FIQ_Exception
**
** Descriptions: Fast interrupt exceptional handler , change it as needed
**
** parameters: None
** Returned value: None
**
******************************************************************************/
void FIQ_Exception(void)
{
while(1); /* 改为你自己的代码 */
}
/******************************************************************************
** Function name: DefaultVICHandler
**
** Descriptions: Default VIC interrupt handler.
** This handler is set to deal with spurious
** interrupt.
** If the IRQ service routine reads the VIC
** address register, and no IRQ slot responses
** as described above, this address is returned.
** parameters: None
** Returned value: None
**
******************************************************************************/
void DefaultVIC_Exception (void)
{
/* if the IRQ is not installed into the VIC, and interrupt occurs, the
default interrupt VIC address will be used. This could happen in a race
condition. For debugging, use this endless loop to trace back. */
/* For more details, see Philips appnote AN10414 */
VICVectAddr = 0; /* Acknowledge Interrupt */
while ( 1 );
}
/******************************************************************************
** Function name: init_VIC
**
** Descriptions: Initialize VIC interrupt controller.
** parameters: None
** Returned value: None
**
******************************************************************************/
void init_VIC(void)
{
DWORD i = 0;
DWORD *vect_addr, *vect_cntl;
extern void DefaultVICHandler(void);
/* initialize VIC*/
VICIntEnClr = 0xffffffff;
VICVectAddr = 0;
VICIntSelect = 0;
/* set all the vector and vector control register to 0 */
for ( i = 0; i < VIC_SIZE; i++ )
{
vect_addr = (DWORD *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + i*4);
vect_cntl = (DWORD *)(VIC_BASE_ADDR + VECT_CNTL_INDEX + i*4);
*vect_addr = 0;
*vect_cntl = 0;
}
/* Install the default VIC handler here */
VICDefVectAddr = (DWORD)DefaultVICHandler;
return;
}
/******************************************************************************
** Function name: install_irq
**
** Descriptions: Install interrupt handler
** The max VIC size is 16, but, there are 32 interrupt
** request inputs. Not all of them can be installed into
** VIC table at the same time.
** The order of the interrupt request installation is
** first come first serve.
** parameters: Interrupt number and interrupt handler address
** Returned value: true or false, when the table is full, return false
**
******************************************************************************/
DWORD install_irq( DWORD HandlerNumber, DWORD IntNumber, void *HandlerAddr )
{
DWORD *vect_addr;
DWORD *vect_cntl;
if ( HandlerNumber >= VIC_SIZE )
{
return( FALSE ); /* fatal error, can't find empty vector slot */
}
VICIntEnClr = 1 << IntNumber; /* Disable Interrupt */
vect_addr = (DWORD *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + HandlerNumber*4);
vect_cntl = (DWORD *)(VIC_BASE_ADDR + VECT_CNTL_INDEX + HandlerNumber*4);
if (*vect_addr == (DWORD)NULL)
{
*vect_addr = (DWORD)HandlerAddr; /* set interrupt vector */
*vect_cntl = (DWORD)(IRQ_SLOT_EN | IntNumber);
}
else
{
return( FALSE ); /* fatal error, can't find empty vector slot */
}
VICIntEnable = 1 << IntNumber; /* Enable Interrupt */
return( TRUE );
}
/******************************************************************************
** Function name: uninstall_irq
**
** Descriptions: Uninstall interrupt handler
** Find the interrupt handler installed in the VIC
** based on the interrupt number, set the location
** back to NULL to uninstall it.
** parameters: Interrupt number
** Returned value: true or false, when the interrupt number is not found,
** return false
**
******************************************************************************/
DWORD uninstall_irq( DWORD IntNumber )
{
DWORD i;
DWORD *vect_addr;
DWORD *vect_cntl;
VICIntEnClr = 1 << IntNumber; /* Disable Interrupt */
for (i = 0; i < VIC_SIZE; i++)
{
/* find first un-assigned VIC address for the handler */
vect_addr = (DWORD *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + i*4);
vect_cntl = (DWORD *)(VIC_BASE_ADDR + VECT_CNTL_INDEX + i*4);
if ( (*vect_cntl & ~IRQ_SLOT_EN ) == IntNumber )
{
*vect_addr = (DWORD)NULL; /* clear the VIC entry in the VIC table */
*vect_cntl &= ~IRQ_SLOT_EN; /* disable SLOT_EN bit */
break;
}
}
if ( i == VIC_SIZE )
{
return( FALSE ); /* fatal error, can't find interrupt number
in vector slot */
}
VICIntEnable = 1 << IntNumber; /* Enable Interrupt */
return( TRUE );
}
/******************************************************************************
** End Of File
******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -