C语言驱动之配置中断(基于S3C2440开发板)

这是irq.c文件

#include "irq.h"
#include <string.h>
#include <s3c2440.h>
#include "type.h"

static irqEvent_t G_IRQEvents[IRQ_MAX];


//中断总是初始化
void irq_init(void)
{
     int i;     

     memset(G_IRQEvents,0,sizeof(G_IRQEvents));  //初始化信息

     //初始化所有的中断寄存器
     EINTMASK = 0xFFFFFFFF;
     INTSUBMSK = 0xFFFFFFFF;
     INTMSK = 0xFFFFFFFF;
     
     EINTPEND=  0xFFFFFFFF;
     SUBSRCPND =  0xFFFFFFFF;
     SRCPND =  0xFFFFFFFF;
     INTPND =  0xFFFFFFFF;
     
     INTMOD = 0; 

     //初始化所有信息结构体
     for(i = 0; i < IRQ_MAX; i++)
     {
         G_IRQEvents[i].irqno = i;
        G_IRQEvents[i].parent = -1;
        G_IRQEvents[i].irq = NULL;

        if(i >= IRQ_SUB_EINT4 && i <= IRQ_SUB_EINT7)
        {
            G_IRQEvents[i].parent = IRQ_EINT4_7;
        }
        else if(i >= IRQ_SUB_EINT8 && i <= IRQ_SUB_EINT23)
        {
            G_IRQEvents[i].parent = IRQ_EINT8_23;
        }
        else if(i >= IRQ_SUB_RXD0 && i <= IRQ_SUB_ERR0)
        {
            G_IRQEvents[i].parent = IRQ_UART0;
        }
        else if(i >= IRQ_SUB_RXD1 && i <= IRQ_SUB_ERR1)
        {
            G_IRQEvents[i].parent = IRQ_UART1;
        }
        else if(i >= IRQ_SUB_RXD2 && i <= IRQ_SUB_ERR2)
        {
            G_IRQEvents[i].parent = IRQ_UART2;
        }
        else if(i >= IRQ_SUB_TC && i <= IRQ_SUB_ADC_S)
        {
            G_IRQEvents[i].parent = IRQ_ADC;
        }
        else if(i >= IRQ_SUB_CAM_P && i <= IRQ_SUB_CAM_C)
        {
            G_IRQEvents[i].parent = IRQ_CAM;
        }
        else if(i >= IRQ_SUB_AC97 && i <= IRQ_SUB_WDT)
        {
            G_IRQEvents[i].parent = IRQ_WDT_AC97;
        }
     }

//中断安装          
void irq_install(IRQ_E irqno, IRQHandler irq)
{
  //1.填充实际的中断处理函数
  G_IRQEvents[irqno].irq = irq;

  //2.打开对应的开关
  if(irqno >= IRQ_SUB_EINT4 && irqno <= IRQ_SUB_EINT23)
  {
      BIT_CLR(EINTMASK,(irqno- IRQ_SUB_EINT4 +4));  //打开外部二级开关
    BIT_CLR(INTMSK, G_IRQEvents[irqno].parent);   //打开对应的一级开关
  }
  else if(irqno >= IRQ_SUB_RXD0 && irqno <= IRQ_SUB_WDT)
  {
      BIT_CLR(INTSUBMSK,(irqno- IRQ_SUB_RXD0));  //打开外部二级开关
    BIT_CLR(INTMSK, G_IRQEvents[irqno].parent);   //打开对应的一级开关     
  }
  else
  {
      BIT_CLR(INTMSK,irqno);  //打开对应的一级开关
  }
}


//中断卸载        
void irq_unstall(IRQ_E irqno)
{
  //1.填充实际的中断处理函数
  G_IRQEvents[irqno].irq = NULL;

  //2.打开对应的开关
  if(irqno >= IRQ_SUB_EINT4 && irqno <= IRQ_SUB_EINT23)
  {
      BIT_SET(EINTMASK,(irqno- IRQ_SUB_EINT4 +4));  //打开外部二级开关
    BIT_SET(INTMSK, G_IRQEvents[irqno].parent);   //打开对应的一级开关
  }
  else if(irqno >= IRQ_SUB_RXD0 && irqno <= IRQ_SUB_WDT)
  {
      BIT_SET(INTSUBMSK,(irqno- IRQ_SUB_RXD0));  //打开外部二级开关
    BIT_SET(INTMSK, G_IRQEvents[irqno].parent);   //打开对应的一级开关     
  }
  else
  {
      BIT_SET(INTMSK,irqno);  //打开对应的一级开关
  }


}
#define EINTIRQ_RUN(start,end)\
  for(i = start; i <= end; i++) \
  {    \
       if(EINTPEND &(1 << i)) \
       { \
               BIT_SET(EINTPEND,i);         /*二级未决中断清除*/    \
            if(    G_IRQEvents[IRQ_SUB_EINT4+(i - 4)].irq)    \
            { \
                G_IRQEvents[IRQ_SUB_EINT4+(i - 4)].irq();\
            }  \
            break;     \
       } \
  } break;

#define SUBIRQ_RUN(start,end) \
  for(i = start; i <= end; i++) \
  {    \
       if(SUBSRCPND &(1 << i)) \
       { \
               BIT_SET(SUBSRCPND,i);  \
            if(    G_IRQEvents[IRQ_SUB_RXD0+i].irq)    \
            { \
                   G_IRQEvents[IRQ_SUB_RXD0+i].irq();\
            } \
            break;     \
       } \
  } break;

//中断分发        
void irq_dispatch(void)
{
  int ofs = INTOFFSET;
  int i;

  switch(ofs)
  {
      case IRQ_EINT4_7:
            EINTIRQ_RUN(4,7);
    case IRQ_EINT8_23:
            EINTIRQ_RUN(8,23);
    case IRQ_WDT_AC97:
            SUBIRQ_RUN(13,14);
     case IRQ_CAM:
            SUBIRQ_RUN(11,12);
    case IRQ_ADC:
            SUBIRQ_RUN(9,10);
    case IRQ_UART2:
            SUBIRQ_RUN(6,8);
    case IRQ_UART1:
            SUBIRQ_RUN(3,5);
    case IRQ_UART0:
            SUBIRQ_RUN(0,2);

    default:  //默认一级中断
        if(G_IRQEvents[ofs].irq)
        {
            G_IRQEvents[ofs].irq();
        }
        break;
  }

  //2.一级中断清除
  BIT_SET(SRCPND,ofs);
  BIT_SET(INTPND,ofs);
}  
 

------------------------------------------------------------华丽的分割线-------------------------------------------------------------

这是irq.h文件

#ifndef __IRQ_H_
#define __IRQ_H_

typedef enum
{
    //32个一级中断
    IRQ_EINT0 = 0,
    IRQ_EINT1 = 1,
    IRQ_EINT2 = 2,
    IRQ_EINT3 = 3,
    IRQ_EINT4_7,            //有二级外部中断
    IRQ_EINT8_23,            //有二级外部中断
    IRQ_CAM,
    IRQ_BATT_FLT,
    IRQ_TICK,
    IRQ_WDT_AC97,               //有二级内部中断
    IRQ_TIMER0,
    IRQ_TIMER1,
    IRQ_TIMER2,
    IRQ_TIMER3,
    IRQ_TIMER4,
    IRQ_UART2,                 //有二级内部中断
    IRQ_LCD,
    IRQ_DMA0,
    IRQ_DMA1,
    IRQ_DMA2,
    IRQ_DMA3,
    IRQ_SDI,
    IRQ_SPI0,
    IRQ_UART1,                //有二级内部中断
    IRQ_UFCON,
    IRQ_USBD,
    IRQ_USBH,
    IRQ_IIC,
    IRQ_UART0,                 //有二级内部中断
    IRQ_SPI1,
    IRQ_RTC,
    IRQ_ADC,                 //有二级内部中断

    //以下是二级外部子中断
    IRQ_SUB_EINT4 = 32,      //IRQ_SUB_EINT4-7对应一级中断
    IRQ_SUB_EINT5,
    IRQ_SUB_EINT6,
    IRQ_SUB_EINT7,

    IRQ_SUB_EINT8,
    IRQ_SUB_EINT9,
    IRQ_SUB_EINT10,
    IRQ_SUB_EINT11,
    IRQ_SUB_EINT12,
    IRQ_SUB_EINT13,
    IRQ_SUB_EINT14,
    IRQ_SUB_EINT15,
    IRQ_SUB_EINT16,
    IRQ_SUB_EINT17,
    IRQ_SUB_EINT18,
    IRQ_SUB_EINT19,
    IRQ_SUB_EINT20,
    IRQ_SUB_EINT21,
    IRQ_SUB_EINT22,
    IRQ_SUB_EINT23,

    //以下是二级内部中断
    IRQ_SUB_RXD0 = 52,
    IRQ_SUB_TXD0,
    IRQ_SUB_ERR0,

    IRQ_SUB_RXD1,
    IRQ_SUB_TXD1,
    IRQ_SUB_ERR1,

    IRQ_SUB_RXD2,
    IRQ_SUB_TXD2,
    IRQ_SUB_ERR2,

    IRQ_SUB_TC,
    IRQ_SUB_ADC_S,

    IRQ_SUB_CAM_P,
    IRQ_SUB_CAM_C,

    IRQ_SUB_AC97,
    IRQ_SUB_WDT,

    IRQ_MAX,

}IRQ_E;


//2.数据结构体
typedef void (*IRQHandler)(void);
typedef struct irqEvent_s
{
    int irqno;   //中断源
    int parent;   //二级中断对应的一级中断号

    IRQHandler irq;
    void (*irqFun)(void);    //定义一个中断的处理函数

}irqEvent_t;


void irq_init(void);           //中断总是初始化
void irq_install(IRQ_E irqno, IRQHandler irq);        //中断安装
void irq_unstall(IRQ_E irqno);        //中断卸载
void irq_dispatch(void);    //中断分发

#endif 

猜你喜欢

转载自blog.csdn.net/Gaodes/article/details/81776138
今日推荐