📄 lib_aic.c
字号:
#ifndef _REFERENCE
//*-----------------------------------------------------------------------------
//* ATMEL Microcontroller Software Support - ROUSSET -
//*-----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*-----------------------------------------------------------------------------
//* File Name : lib_aic.c
//* Object : Advanced Interrupt Controller Library.
//* Translator : ARM Software Development Toolkit V2.11a
//*
//* Imported resources :
//* define_as_peripheral
//* define_as_pio
//* Exported resources :
//* init_aic
//* init_interrupt, init_fiq
//* remove_interrupt
//* simulate_interrupt
//* simulate_multiple_interrupt
//* get_interrupt_source
//*
//* 1.0 07/08/97 JCZ : Creation
//* 1.1 25/04/98 JLV : Add "get_interrupt_source"
//* 1.1 15/05/98 JLV : Prototype 'lib_pio' functions (file not included)
//* 1.2 22/09/98 JCZ : Remove automatic detection of external interrupt
//* This removes recursive inclusion with <lib_pio.c>
//* 2.0 21/10/98 JCZ : Clean up
//*-----------------------------------------------------------------------------
/*----- Called Macro instructions definition -----*/
/* None */
/*----- Files to be included Definition -----*/
#ifdef AT91_TRACE
#include <stdio.h>
#endif /* AT91_TRACE */
#include "..\Include/std_c.h"
#include "..\Include/aic.h"
/*----- Types and Constants Definition -----*/
/* None */
/*----- Imported Resources Definition -----*/
#define _REFERENCE(x) extern x;
/* None */
#undef _REFERENCE
/* Advanced Interrupt Controller Base Address Constant */
StructAIC * const Pt_AICBase = AIC_BASE ;
/*---- Internal Resources Definition -----*/
//*P
//*-----------------------------------------------------------------------------
//* Function Name : no_handler_irq
//* Object : Management of the undefined interrupt
//* Input Parameters : none
//* Output Parameters : none
//* Functions called : none
//*-----------------------------------------------------------------------------
void no_handler_irq ( void )
//* Begin
{
#ifdef AT91_TRACE
printf ( "Unknown interrupt" ) ;
#endif
//* Loop forever
for (;;) ;
}
//* End
//*P
//*-----------------------------------------------------------------------------
//* Function Name : no_handler_fiq
//* Object : Management of the undefined fast interrupt
//* Input Parameters : none
//* Output Parameters : none
//* Functions called : none
//*-----------------------------------------------------------------------------
void no_handler_fiq ( void )
//* Begin
{
#ifdef AT91_TRACE
printf ( "Unknown Fast interrupt" ) ;
#endif
//* Loop forever
for (;;) ;
}
//* End
/*---- External Resources Definition -----*/
#define _REFERENCE(x) x
#define CORPS
#endif
_REFERENCE (void (*SaveAbortHandler) ( void ))
#ifdef CORPS
;
#endif
_REFERENCE (void (*SavePrefetchHandler) ( void ))
#ifdef CORPS
;
#endif
//*P
//*-----------------------------------------------------------------------------
//* Function Name : init_aic
//* Object : Advanced Interrupt Controller Initiaization
//* Input Parameters : none
//* Output Parameters : none
//* Functions called :
//* no_handler_irq
//* no_handler_fiq
//*-----------------------------------------------------------------------------
/*
This function is called by <boot.s> in case of software reset only.
It simulates an hardware reset on the Advanced Interrupt Controller with
difference Interrupt Vector Register are not cleared, but loaded with
the address of a default handler. For this reason, this function may
be run systematically after any reset to ensure no pending interrupt
will disturb the system start-up.
Note about the need of this function :
--------------------------------------
It is particularly needed when you are debugging with ICE because the
Windows debugger by default reads firstly the ARM vectors. If the IRQ
vectors is already initialized, the IVR is read and a push in the
hardware stack of the AIC is performed. As no End of Interrupt is
made, the AIC avoids all interrupt of priority lower or equal to the
pushed one.
*/
_REFERENCE (void init_aic ( void ))
#ifdef CORPS
//* Begin
{
int irq_id ;
//* Disable all interrupts
Pt_AICBase->AIC_IDCR = 0xFFFFFFFF ;
//* Clear all interrupts
Pt_AICBase->AIC_ICCR = 0xFFFFFFFF ;
//* For each priority level
for ( irq_id = 0 ; irq_id < 8 ; irq_id ++ )
{
//* Unstack a level by writting in AIC_EOICR
/* Value written has no effect */
Pt_AICBase->AIC_EOICR = irq_id ;
}
//* Endfor
//* Initialize the fast interrupt source mode register
Pt_AICBase->AIC_SMR[0] = 0 ;
//* Fast Interrupt routine is undefined
Pt_AICBase->AIC_SVR[0] = (u_int) no_handler_fiq ;
//* For each interrupt source
for ( irq_id = 1 ; irq_id < NB_INTERRUPT + 1 ; irq_id ++ )
{
//* Priority is lowest
Pt_AICBase->AIC_SMR[irq_id] = 0 ;
//* Interrupt routine is undefined
Pt_AICBase->AIC_SVR[irq_id] = (u_int) no_handler_irq ;
}
//* Endfor
}
//* End
#endif
//*P
//*-----------------------------------------------------------------------------
//* Function Name : init_interrupt
//* Object : Interrupt Handler Initialization
//* Input Parameters : <irq_id> = interrupt number to initialize
//* : <priority> = priority to give to the interrupt
//* : <src_type> = activation and sense of activation
//* : <handler_pt> = address of the interrupt handler
//* Output Parameters : True if <irq_id> is correct
//* Functions called : none
//*-----------------------------------------------------------------------------
_REFERENCE (u_int init_interrupt ( u_int irq_id,
u_int priority,
u_int src_type,
TypeAICHandler handler_pt ))
#ifdef CORPS
//* Begin
{
u_int mask ;
mask = 0x1 << irq_id ;
//* Disable the interrupt on the interrupt controller
Pt_AICBase->AIC_IDCR = mask ;
//* If the interrupt number is not correct, return False
if ( irq_id > NB_INTERRUPT ) return ( FALSE ) ;
//* Save the interrupt handler routine pointer and the interrupt priority
Pt_AICBase->AIC_SVR[irq_id] = (u_int) handler_pt ;
//* Store the Source Mode Register
Pt_AICBase->AIC_SMR[irq_id] = src_type | priority ;
//* Clear the interrupt on the interrupt controller
Pt_AICBase->AIC_ICCR = mask ;
//* Enable the interrupt on the interrupt controller
Pt_AICBase->AIC_IECR = mask ;
//* Return OK
return ( TRUE ) ;
}
//* End
#endif
//*P
//*-----------------------------------------------------------------------------
//* Function Name : remove_interrupt
//* Object : Interrupt Handler Removing from the Interrupt Table
//* Input Parameters : <irq_id> = interrupt number to remove
//* Output Parameters : True if <irq_id> is correct
//* Functions called : none
//*-----------------------------------------------------------------------------
_REFERENCE (u_int remove_interrupt ( int irq_id ))
#ifdef CORPS
//* Begin
{
u_int mask ;
mask = 0x1 << irq_id ;
//* If the interrupt number is not correct, return False
if ( irq_id > NB_INTERRUPT ) return ( FALSE ) ;
//* Disable the interrupt on the interrupt controller
Pt_AICBase->AIC_IDCR = mask ;
//* Clear the interrupt on the Interrupt Controller ( if one is pending )
Pt_AICBase->AIC_ICCR = mask ;
//* If removing the FIQ
if ( irq_id == 0 )
{
//* Default FIQ vector to <no_handler_fiq>
Pt_AICBase->AIC_SVR[0] = (u_int) no_handler_fiq ;
}
//* Else
else
{
//* Default IRQ vector to <no_handler_irq>
Pt_AICBase->AIC_SVR[irq_id] = (u_int) no_handler_irq ;
}
//* EndIf
//* Return True
return ( TRUE ) ;
}
//* End
#endif
//*P
//*-----------------------------------------------------------------------------
//* Function Name : simulate_interrupt
//* Object : Interrupt Simulation by Setting the interrupt
//* Input Parameters : <irq_id> = interrupt number to simulate
//* Output Parameters : True if <irq_id> is correct
//* Functions called : none
//*-----------------------------------------------------------------------------
_REFERENCE (u_int simulate_interrupt ( u_int irq_id ))
#ifdef CORPS
{
//* Begin
//* If the interrupt number is not correct, return False
if ( irq_id > NB_INTERRUPT ) return ( FALSE ) ;
//* Set the interrupt on the interrupt controller
Pt_AICBase->AIC_ISCR = (1 << irq_id) ;
//* Return True
return ( TRUE ) ;
//* End
}
#endif
//*P
//*-----------------------------------------------------------------------------
//* Function Name : simulate_multiple_interrupt
//* Object : Multiple Interrupt Simulation by Setting the interrupt
//* Input Parameters : <mask> = word to be written in the ISCR
//* Output Parameters : Always True
//* Functions called : none
//*-----------------------------------------------------------------------------
_REFERENCE (u_int simulate_multiple_interrupt ( u_int mask ))
#ifdef CORPS
{
//* Begin
//* Set the interrupt on the interrupt controller
Pt_AICBase->AIC_ISCR = mask ;
//* Return True
return ( TRUE ) ;
//* End
}
#endif
//*P
//*-----------------------------------------------------------------------------
//* Function Name : get_interrupt_source
//* Object : Get identifier source identifier
//* Input Parameters : None
//* Output Parameters : <source> = source identifier
//* Functions called : none
//*-----------------------------------------------------------------------------
_REFERENCE (u_int get_interrupt_source ( void ))
#ifdef CORPS
//* Begin
{
//* Return AIC_ISR
return ( Pt_AICBase->AIC_ISR ) ;
//* End
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -