⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lh7a400_int_driver.c

📁 sharp触摸屏测试代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/**********************************************************************
 *	$Workfile:   LH7A400_int_driver.c  $
 *	$Revision:   1.13  $
 *	$Author:   BarnettH  $
 *	$Date:   Jun 19 2002 18:06:52  $
 *
 *	Project: LH7A400 
 *
 *	Description:
 *     This file contains driver support for the LH7A400
 *     interrupt driver. This module contains the following
 *     user functions:
 *     int_init_irq_handler()--init basic interrupt driver irq handling
 *     int_init_fiq_handler()--init basic interrupt driver fiq handling
 *     int_install_irq_handler()--install a handler with a priority
 *                                for a particular IRQ source
 *     int_install_fiq_handler()--install a handler with a priority
 *                                for a particular FIQ source
 *     int_remove_irq_handler()--remove the handler for a given priority
 *                        and unhook the IRQ source for that priority
 *     int_remove_fiq_handler()--remove the handler for a given priority
 *                        and unhook the FIQ source for that priority
 *     int_enable_interrupt()--enable an interrupt source
 *     int_disable_interrupt()--disable an interrupt source
 *     int_enabled()--return true if a source is enabled
 *     int_pending()--return true if a source is pending
 *     int_priority()--return the priority assigned to the source
 *     int_handler()--return a pointer to the hander for the source
 *
 *     The interrupt controller in the LH7A400 divides interrupt
 *     sources into two categories: IRQ and FIQ. Beyond that
 *     the interrupt controller does not prioritize interrupt
 *     sources. It also does not provide a facility for vectoring
 *     interrupts. This driver provides prioritization and
 *     vectoring for all interrupt sources with minimum latency.
 *     To do this, a function called an IRQ dispatcher is
 *     installed at the IRQ exception vector, and an FIQ
 *      dispatcher is installed at the FIQ exception vector.
 *      
 *     The user should assign a priority to each IRQ interrupt 
 *     source and each FIQ interrupt source. A priority is a
 *      number from 0 (the highest priority) to the number of
 *     sources in the category (FIQ or IRQ) minus 1. Therefore,
 *     for IRQ sources, priorties are 0 (highest priority) to 23
 *     (lowest priority). For FIQ sources, priorities are 0
 *     (highest priority) to 3 (lowest priority).
 *
 *     Priorities resolve the simultaneous interrupt conflict. If
 *     many interrupt sources are simultaneously active, then the
 *     dispatcher will service the source with the highest 
 *     priority first.
 *
 *     Each source also has a handler function associated with it.
 *     The handler is a function that takes no arguments and
 *     returns nothing. It is the responsibility of the handler to
 *     clear the interrupt source or else the interrupt handler
 *     will be called in an infinite loop.
 *
 *     The dispatcher calls the handler for each active interrupt 
 *     until all sources are cleared.
 *     
 *     For maximum system performance, the FIQ handler functions
 *     should be coded in assembly language. If they are coded
 *     in C, care should be taken to preseve registers r0-r7
 *     if the C program modifies them.
 *
 *     See priority_driver.c for a description of how this collection
 *     of modules works.
 *
 * Original Author: KovitzP      
 *     
 *	References:
 *     Internal documentation
 *
 * Dependencies:
 *     This module uses the functionality contained in 
 *     priority_driver.c to implement the priority encoding scheme. 
 *     The default IRQ dispatcher function uses a macro in 
 *     priority_driver.h to make the handler.
 *
 *     This module requires LH7A400_int_vec.s. It contains the FIQ
 *     dispatcher and assembly language branch instruction that get
 *     installed at the FIQ and IRQ exception vector locations.
 *     
 *     The int_install_fiq_dispatcher() and int_install_irq_dispatcher()
 *     functions require the two words in volatile memory that 
 *     immediately follow the FIQ exception vector location. If either 
 *     of these 2 locations get modified after a call to either of 
 *     these functions, IRQ and FIQ exception processing will be 
 *     unreliable.
 *
 *	Revision History:
 *	$Log:   //smaicnt2/pvcs/VM/CHIPS/archives/LH7A400/Interrupts/Drivers/LH7A400_int_driver.c-arc  $
 * 
 *    Rev 1.13   Jun 19 2002 18:06:52   BarnettH
 * Changed register names to agree with LH7A400_intc.h
 * 
 *    Rev 1.12   Jun 13 2002 11:17:24   MaysR
 * Fixed error in unhandled IRQ handler.
 * Changed all functions back to accept UNS_32 parameters,
 * and added range checking within each function.
 * 
 *    Rev 1.11   Jun 05 2002 19:54:46   MaysR
 * Corrected all function parameters to accept proper sized arguments 
 * to be compatible with priority driver.
 * Added two new functions for getting next available IRQ & FIQ.
 * 
 *    Rev 1.10   10 Apr 2002 16:48:22   suryang
 * Uses new SMA_priority_driver.
 * 
 *    Rev 1.9   10 Apr 2002 16:07:34   suryang
 * Changed register names to lowercase.
 * 
 *    Rev 1.8   09 Apr 2002 11:51:06   suryang
 * Added initialized flag.
 * 
 *    Rev 1.7   Jan 07 2002 11:11:52   KovitzP
 * Integrated with LH7A400_cp15_driver
 * 
 *    Rev 1.6   Jan 04 2002 16:43:18   KovitzP
 * Added hooks to allow for installation of an external IRQ handler.
 * 
 *    Rev 1.5   Jan 03 2002 16:13:58   KovitzP
 * Integrated with priority_driver.c functions
 * 
 *    Rev 1.4   Nov 20 2001 07:57:28   KovitzP
 * Updated comments. Made interrupt dispatcher handle exactly
 * one interrupt at a time. Added null pointer checking for handler
 * install functions.
 * 
 *    Rev 1.3   Nov 16 2001 18:13:56   KovitzP
 * Corrected bugs that were causing FIQ priority_encode and function
 * vectors to be stored in the wrong places
 * 
 *    Rev 1.2   Nov 16 2001 16:33:26   KovitzP
 * Corrected bug in int_install_fiq_dispatcher() that was causing the
 * dispatcher to be installed in the wrong place.
 * 
 *    Rev 1.1   Nov 15 2001 17:29:16   KovitzP
 * Added FIQ support. Changed default handler operation to properly
 * handle uninstalled interrupts. Added functions to uninstall 
 * interrupts. Will not work with cache enabled; install handler
 * routines do not drain D cache or invalidate I-cache.
 * 
 *    Rev 1.0a   Nov 13 2001 17:43:14   SuryanG
 * Created new archive with new name. Updated with comments and added 
 * a few new function definitions.
 * 
 *    Rev 1.0   Nov 12 2001 12:43:44   SuryanG
 * Initial revision.
 * 
 *	COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
 *		CAMAS, WA
 *********************************************************************/
#include "LH7A400_int_driver.h"
#include "LH7A400_cp15_driver.h"
#include "SMA_priority_driver.h"

static UNS_32 initialized = 0; /* should be initialized to zero */

static UNS_32 irq_status;
static INT_8 irq_priority_encode0[INTC_N_COMBINATIONS];
static INT_8 irq_priority_encode1[INTC_N_COMBINATIONS];
static INT_8 irq_priority_encode2[INTC_N_COMBINATIONS];
static INT_8 irq_priorities[INTC_N_IRQ_HANDLERS + 1]; /* extra element 
                                                         for sentinel
                                                         search */
static void (* irq_handlers[INTC_N_IRQ_HANDLERS + 1])(void);
static PRIORITY_DATA irq_data =
{
   INTC_N_IRQ_HANDLERS,
   irq_priorities,
   irq_priority_encode0,
   irq_priority_encode1,
   irq_priority_encode2,
   0,
   irq_handlers
};


extern volatile UNS_32 irq_dispatcher_addr, irq_vec;
extern volatile UNS_32 fiq_dispatcher_addr, fiq_vec;
extern volatile UNS_32 LH7A400_FIQ_dispatcher;
extern volatile UNS_32 LH7A400_FIQ_disp_end;

/* 
note: fiq_handlers_0 and fiq_priority_encode_0
are global so that the FIQ dispatcher can be coded
in an assembly language module
*/
static INT_8 fiq_priorities[INTC_N_FIQ_HANDLERS + 1]; /* extra element
                                                         for sentinel
                                                         search */
typedef void (* * vfpp)(void);
typedef void (* vfp)(void);
extern volatile UNS_32 (* * fiq_handlers_0)(void);
extern volatile UNS_32 fiq_priority_encode_0;
extern volatile UNS_32 LH7A400_unhandled_fiq_handler;

static PRIORITY_DATA fiq_data;

/**********************************************************************
*
* Function: LH7A400_unhandled_handler
*
* Purpose:
*  This function is called when the interrupt
*  controller signals an interrupt for an unhandled source.
*
* Processing:
*  Disable the source that triggered the unhandled interrupt
* 
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*
**********************************************************************/
static void LH7A400_unhandled_handler(void)
{
   INTC->enableclear = irq_status & ~_BITMASK(INTC_N_FIQ_HANDLERS);
}

/**********************************************************************
*
* Function: LH7A400_IRQ_dispatcher
*
* Purpose:
*  This function calls the handler previously installed using
*  int_install_irq_handler. It preserves status.
*
* Processing:
*  Preserve the machine state if it was built with INTC_IRQ defined.
*  Read the interrupt status. Isolate the interrupt status register
*  IRQ status bits. Divide the interrupt status bits into three
*  bytes. Each byte is an index into an array of priorities.
*  The highest of the three priorites is used as an index into 
*  an array of pointers handler functions. Call the indexed function.
*  Restore the machine state if it was built with INTC_IRQ defined.
*  If the highest priority was ILLEGAL_PRIORITY, disable the source
*  that caused the interrupt (because there is not handler installed
*  to handle the interrupt).
* 
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*  INTC_IRQ must be defined if it is desired to use this default
*  interrupt dispatcher as the IRQ vector handler. The ARM Compiler
*  handle the saving and restoring of context when an interrupt 
*  occurs. Most operating systems require a more detailed context
*  save and restore than the default provided by the ARM compiler.
*  It is recommended that the appropriate OS-specific manuals be
*  consulted to determine whether this should be defined or not.
*
**********************************************************************/
#if defined(INTC_IRQ)
__irq 
#endif
void LH7A400_IRQ_dispatcher(void)
MAKE_DISPATCHER24(((irq_status = INTC->status) >> INTC_N_FIQ_HANDLERS),
                        irq_handlers,
                        irq_priority_encode)

/**********************************************************************
*
* Function: int_install_irq_dispatcher
*
* Purpose:
*  write to the exception vector locations so that an IRQ interrupt
*  will call LH7A400_IRQ_dispatcher() no matter where the linker
*  has decided to locate LH7A400_IRQ_dispatcher().
*
* Processing:
*  int_install_irq_dispatcher() writes an assembly language
*  instruction at memory word 0x18 that causes a branch to the
*  32-bit address stored at address 0x14. 
*
*  The entry at location 0x14 in the ARM processor is "reserved"
*  and usually populated with a NOP instruction. Here, we make
*  use of this location to store the address of the IRQ handler
*  (in our case, irq_dispatcher). The next location, 0x18, is
*  the address that the ARM processor jumps to when it encounters
*  an IRQ interrupt. Here, we place an instruction loading the
*  program counter with the address in location 0x14, which 
*  happens to be the IRQ handler address.
*
* The reason 0x14 is required is that the instruction that causes
* the branch, LDR pc,branch_address, will only work if
* branch_address is within 4095 of the current pc address. Using
* 0x14 makes sure that the address is in range independent of the 
* linker.
* 
* The simple branch instruction, B <addr> won't work here either
* if the memory space is large than 32 Meg and the handler happens to
* be located more than 32 Meg away from the exception vector address.
*
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*  This function requires that the words at memory 
*  locations 0x18 (the IRQ exception vector location) and 0x14
*  (the reserved exception vector word) are in volatile memory. 
*
*  This cannot be used with the 26-bit architecture versions
*  of ARM, where this vector was used for address exceptions; Caveat
*  code porters.
*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -