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

📄 sngks32cintrctl.c

📁 Vxworks下BSP源码
💻 C
字号:
/* sngks32cIntrCtl.c - Samsung KS32C interrupt controller driver *//* Copyright 1984-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01c,02oct01,m_h  race condition01b,26apr01,m_h  convert tabs to spaces for readability01a,12apr01,m_h  created from snds100 template.*//*DESCRIPTIONThis module implements interrupt controller driver for Samsung's KS32C50100microprocessor which is an ARM based processor with several integrated peripherals.  It has an interrupt controller, two 32-bit timers, one Ethernet controller, two HDLC controllers, one IIC controller, general purpose I/O ports, and a 2-channel DMA controller.The KS32C interrupt controller is a simple, generic interrupt controllerthat manages 21 levels of interrupts from various sources internal to themicroprocessor and external to it.  For external interrupts are supported.The interrupt controller has control and pending status registers, maskregister and supports level-sensitive interrupts.  This library providesthe routines to manage interrupts multiplexed by the KS32C interrupt controller.The KS32C interrupt controller registers used by this driver are describedbelow under the symbolic names used herein.SNGKS32C_INTENB (write): this is the mask register described in theKS32C50100 Users' Manual.  When this register is written, each data bit that is clear (0) causes the corresponding interrupt to be enabled.Each bit that is set (1) causes the corresponding interrupt to be disabled.SNGKS32C_INTPEND (read): this is the interrupt pending register.When this register is read, each data bit that is set (1) indicates thatan interrupt is pending from the corresponding source. Level 20 is thehighest priority and level 0 is the lowest.SNGKS32C_INTMODE (write): this register is used to configure the interruptsin FIQ or IRQ mode.  Each bit set in this register configures the correspondinginterrupt as FIQ.  Otherwise the interrupt is treated as IRQ.  VxWorksdoes not support the high priority FIQ mode of interrupts.  Hence all theinterrupts have to be configured in IRQ mode.The interrupt priority registers can be used to change the prioritiesof the interrupts from the default settings.  This feature is notsupported in this driver.  All the interrupts are set with the defaultpriority ordering.The number of interrupts supported by the device i.e. the number ofvalid bits in the SNGKS32C_INTPEND register (21), is specified bySNGKS32C_INTNUMLEVELS.sngks32carm7.h has defined the addresses of the controller chips registers:SNGKS32C_INTENB, SNGKS32C_INTDIS and SNGKS32C_INTPEND and also the driver constants SNGKS32C_INTMASK_VAL, SNGKS32C_INTNUMLEVELS.The chip registers are memory-mapped at specified addresses internal tothe processor.  32-bit accesses can be made to these register locations.The macros SNGKS32C_INT_REG_READ and SNGKS32C_INT_REG_WRITE are used toaccess these registers.The BSP will initialize this driver in sysHwInit2(), after initializingthe main interrupt library, usually intLibInit().  The initializationroutine, sngks32cIntDevInit() will setup the interrupt controller device,it will mask off all individual interrupt sources and then set theinterrupt level to enable all interrupts.  See sngks32cIntDevInit for moreinformation.All of the functions in this library are global.  This allows them tobe used by the BSP if it is necessary to create wrapper routines or toincorporate several drivers together as one.SEE ALSO<Samsung KS32C50100 User's Manual>*/#include "vxWorks.h"#include "config.h"#include "intLib.h"#include "sngks32c.h"#include "myDef.h"void myDelay();#if !defined (AT91C_AIC_IPR) || !defined (AT91C_AIC_IECR) || \    !defined (AT91C_AIC_IDCR) || !defined (AT91C_AIC_ICCR) || \    !defined (AT91C_AIC_ISCR) || !defined (AT91C_INTNUMLEVELS)#   error missing AT91C interrupt definitions#endif/* hardware access methods */#ifndef AT91C_INT_REG_READ#   define AT91C_INT_REG_READ(x,result) \        ((result) = *(volatile UINT32 *)(x))#endif    /*AT91C_INT_REG_READ*/#ifndef AT91C_INT_REG_WRITE#   define AT91C_INT_REG_WRITE(x,data) \        (*((volatile UINT32 *)(x)) = (data))#endif /*AT91C_INT_REG_WRITE*//* Local data *//* * A mask word.  Bits are set in this word when a specific level * is enabled. It is used to mask off individual levels that have * not been explicitly enabled. */LOCAL UINT32 at91cIntLvlMask;/* forward declarations */STATUS    at91cIntLvlVecChk  (int*, int*);STATUS    at91cIntLvlEnable  (int);STATUS    at91cIntLvlDisable (int);STATUS at91cIntAck(int level);/********************************************************************************* at91cIntDevInit - initialize the interrupt controller** This routine will initialize the interrupt controller device, disabling all* interrupt sources.  It will also connect the device driver specific routines* into the architecture level hooks.  If the BSP needs to create a wrapper* routine around any of the arhitecture level routines, it should install the* pointer to the wrapper routine after calling this routine.** RETURNS: N/A*/void at91cIntDevInit (void)    {    /* install the driver routines in the architecture hooks */	UCHAR i;    sysIntLvlVecChkRtn     = at91cIntLvlVecChk;    sysIntLvlEnableRtn     = at91cIntLvlEnable;    sysIntLvlDisableRtn    = at91cIntLvlDisable;/*    sysIntLvlVecAckRtn	=at91cIntAck;	*/    at91cIntLvlMask  = 0x0;     /* all sources disabled */    for(i=0;i<32;i++)	{		*((volatile UINT32 *)(0xfffff000+i*4))=0x20;  /*所有改为边沿触发*/		*(volatile UINT32 *)(0xfffff080+i*4)=i;	}    *(volatile UINT32 *)0xfffff004=0;    *(volatile UINT32 *)0xfffff060=0;		    at91cIntLvlMask  = 0x0;     /* all sources disabled */    AT91C_INT_REG_WRITE (AT91C_AIC_IDCR, ~at91cIntLvlMask);    AT91C_INT_REG_WRITE (AT91C_AIC_ICCR, ~at91cIntLvlMask);    }/********************************************************************************* at91cIntLvlVecChk - check for and return any pending interrupts** This routine interrogates the hardware to determine the highest priority* interrupt pending.  It returns the vector associated with that interrupt, and* also the interrupt priority level prior to the interrupt (not the* level of the interrupt).  The current interrupt priority level is then* raised to the level of the current interrupt so that only higher priority* interrupts will be accepted until this interrupt is finished.** The return value ERROR indicates that no pending interrupt was found and* that the level and vector values were not returned.** RETURNS: OK or ERROR if no interrupt is pending.*/STATUS  at91cIntLvlVecChk    (    int* pLevel,  /* ptr to receive old interrupt level */    int* pVector  /* ptr to receive current interrupt vector */    )    {	UINT32 temp;/**(volatile UINT16 *)0x40000000 = 0;*(volatile UINT16 *)0x40000040 = 0x0105;*//*LED REG0*//*debug*/	myXXX++;		if((*(volatile UINT32*)AT91C_AIC_IPR&*(volatile UINT32*)AT91C_AIC_IMR) ==0) return ERROR;	*(volatile UINT32*)AT91C_AIC_EOICR=0;							temp=*(volatile UINT32*)AT91C_AIC_IVR;	*pVector=*(volatile UINT32*)AT91C_AIC_ISR;	*(volatile UINT32*)AT91C_AIC_EOICR=0;							*(volatile UINT32*)AT91C_AIC_ICCR=(1<<(*pVector));	        return OK;   }/********************************************************************************* at91cIntLvlEnable - enable a single interrupt level** Enable a specific interrupt level.  The enabled level will be allowed to* generate an interrupt, when the overall interrupt level is set below the* specified level.  Without being enabled, the interrupt is blocked regardless* of the overall interrupt level setting.** RETURNS: OK or ERROR if the specified level cannot be enabled.*/STATUS  at91cIntLvlEnable    (    int level  /* level to be enabled */    )    {    int key;    if (level < 0 ||        level >= AT91C_INTNUMLEVELS)        return ERROR;    /* clear bit in mask register */    key = intLock ();		    at91cIntLvlMask |= ((1 << level));    AT91C_INT_REG_WRITE (AT91C_AIC_IECR, at91cIntLvlMask);    intUnlock (key);			    return OK;    }/********************************************************************************* at91cIntLvlDisable - disable a single interrupt level** Disable a specific interrupt level.  The disabled level is prevented* from generating an interrupt even if the overall interrupt level is set* below the specified level.** RETURNS: OK or ERROR, if the specified interrupt level cannot be disabled.*/STATUS  at91cIntLvlDisable    (    int level  /* level to be disabled */    )    {    int key;    if (level < 0 ||        level >= AT91C_INTNUMLEVELS)        return ERROR;    /* set bit in disable register */    key = intLock ();    at91cIntLvlMask &= ~(1 << level);    AT91C_INT_REG_WRITE (AT91C_AIC_IDCR, 1<<level);    intUnlock (key);    return OK;    }STATUS at91cIntAck(int level){	return;}#if 0void myDelay(){	int i;		*(volatile UINT32 *)0xfffff800 = 0x35;	*(volatile UINT32 *)0xfffff810 = 0x35;		while(1)	{	*(volatile UINT32 *)0xfffff834 = 0x35;/*lit*/		for(i=0;i<1000000;i++);		*(volatile UINT32 *)0xfffff830 = 0x35;		for(i=0;i<1000000;i++);		}}	#endif

⌨️ 快捷键说明

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