fs44b0x
驱动牛犊
驱动牛犊
  • 注册日期2004-11-13
  • 最后登录2005-09-14
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1486回复:0

关于FS44B0X的中断问题,请教各位大侠!

楼主#
更多 发布于:2004-11-13 09:46
本人已经初步改写好了s3c44b0x的VXWORKS BSP代码,调试完成了串口poll模式输出功能,中断处理也已经能进入intEnter函数,并且自己用intConnnect连接的中断处理函数也能执行,但问题是:使用外部中断4567,只要按下一次中断按键,则中断一直不停止!(清除EXTINTPND,则系统复位,若使用定时器中断,则一次定时器中断进入中断服务程序四次,然后系统复位)



相关的代码如下:(调试了很长时间,代码已经被高度简化成最简单功能,一次只能开启一个中断)



#include "vxWorks.h"
#include "config.h"
#include "intLib.h"
#include "FS44B0X.h"



/* Defines from FS44B0X100.h */



#if !defined (FS44B0X_INT_CON) || !defined (FS44B0X_INT_PEND) || \
    !defined (FS44B0X_INT_MODE) || !defined (FS44B0X_INT_MASK) || \
    !defined (FS44B0X_INT_NUM_LEVELS )
#   error missing FS44B0X interrupt definitions
#endif




#ifndef FS44B0X_INT_REG_READ
#define FS44B0X_INT_REG_READ(x,result)    ((result) = *(volatile UINT32 *)(x))
#endif /*FS44B0X_INT_REG_READ*/



#ifndef FS44B0X_INT_REG_WRITE
#define FS44B0X_INT_REG_WRITE(x,data)    (*((volatile UINT32 *)(x)) = (data))
#endif /*FS44B0X_INT_REG_WRITE*/




/*
* 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 FS44B0XIntLvlEnabled;



/* forward declarations */



STATUS FS44B0XIntLvlVecChk (int*, int*);
STATUS  FS44B0XIntLvlVecAck (int level,int vector);
STATUS FS44B0XIntLvlEnable (int);
STATUS FS44B0XIntLvlDisable (int);



/*******************************************************************************
*
* FS44B0XIntDevInit - 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 FS44B0XIntDevInit (void)
{
    /* install the driver routines in the architecture hooks */



    sysIntLvlVecChkRtn = FS44B0XIntLvlVecChk;
    sysIntLvlVecAckRtn  = FS44B0XIntLvlVecAck;
    sysIntLvlEnableRtn = FS44B0XIntLvlEnable;
    sysIntLvlDisableRtn = FS44B0XIntLvlDisable;



    FS44B0XIntLvlEnabled = 0x0;              /* all sources disabled */
    
    FS44B0X_INT_REG_WRITE (FS44B0X_INT_CON,0x05);                      /* 设置为非向量中断模式,允许IRQ中断,禁止FIQ中断 */
    FS44B0X_INT_REG_WRITE (FS44B0X_INT_MODE,0x0);         /* 全部设置为IRQ方式 */
    FS44B0X_INT_REG_WRITE (FS44B0X_INT_MASK,0x7ffffff);  /*禁止全局中断以及所有中断*/
    
    FS44B0X_INT_REG_WRITE (FS44B0X_I_ISPC,0x3ffffff);   /* all IRQ pending bits clear */
    FS44B0X_INT_REG_WRITE (FS44B0X_F_ISPC,0x3ffffff);   /* all FIQ pending bits clear */
    FS44B0X_INT_REG_WRITE(FS44B0X_EXTINTPND,0x0f);
}




/*******************************************************************************
*
* FS44B0XIntLvlVecChk - 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  FS44B0XIntLvlVecChk(int* pLevel,int* pVector)
{



    int newLevel;
    int intPendMask = 0x2000000;  
    int count;
    UINT32 isr;
  
  /*  FS44B0X_INT_REG_READ (FS44B0X_INT_PEND, newLevel); */



    FS44B0X_INT_REG_READ (FS44B0X_I_ISPR, newLevel);
    newLevel &= FS44B0XIntLvlEnabled;

    for (count = 0, isr = 25; count < FS44B0X_INT_NUM_LEVELS; count++)
    {
if (intPendMask & newLevel)
  break;
isr--;
intPendMask >>= 1;
   }
  
   *pVector = isr  ;




    if(isr == 21)
       FS44B0X_INT_REG_WRITE_BYTE(FS44B0X_EXTINTPND,0x0f);  
                            
     FS44B0X_INT_REG_WRITE(FS44B0X_I_ISPC,(1<<isr));  
    
     return OK;
}




STATUS  FS44B0XIntLvlVecAck (int level,int vector)
{
    
/*    if(vector == 21)
        FS44B0X_INT_REG_WRITE_BYTE(FS44B0X_EXTINTPND,0x0f);*/
                
    FS44B0X_INT_REG_WRITE(FS44B0X_I_ISPC,(1<<vector));  /*清除IRQ_MASK中的悬挂位*/        
    return OK;
}




/*******************************************************************************
*
* FS44B0XIntLvlEnable - 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  FS44B0XIntLvlEnable(int level)
{




    UINT32 key;
    
    if (level < 0 ||level >= FS44B0X_INT_NUM_LEVELS)
return ERROR;
    
    FS44B0XIntLvlEnabled |=(1<<level);



/*    FS44B0X_INT_REG_READ (FS44B0X_INT_MASK,key);
    key &= ~(0x1<<level);
    key &= ~(0x1<<SYS_GLOBAL_INT_LVL);
    FS44B0X_INT_REG_WRITE (FS44B0X_INT_MASK,key);*/ /*写0关闭中断屏蔽位 */



    
    FS44B0X_INT_REG_WRITE (FS44B0X_INT_MASK,~((0x1<<level)|(0x1<<SYS_GLOBAL_INT_LVL)));
    return OK;
}




/*******************************************************************************
*
* FS44B0XIntLvlDisable - 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  FS44B0XIntLvlDisable(int level)
{
    int key;



    if (level < 0 ||level >= FS44B0X_INT_NUM_LEVELS)
return ERROR;



/*    FS44B0XIntLvlEnabled &=~(1<<level);



    FS44B0X_INT_REG_READ(FS44B0X_INT_MASK,key);
    key |=(1<<level);
    key &= ~(0x1<<SYS_GLOBAL_INT_LVL);
    FS44B0X_INT_REG_WRITE (FS44B0X_INT_MASK,key);
*/
    
    FS44B0X_INT_REG_WRITE (FS44B0X_INT_MASK,(0x1<<level));
    return OK;
}

游客

返回顶部