Skip to content

Commit

Permalink
drive
Browse files Browse the repository at this point in the history
C语言驱动之配置串口(基于S3C2440开发板)
(https://blog.csdn.net/Gaodes/article/details/81775919)
C语言驱动之配置LCD(基于S3C2440开发板)(https://blog.csdn.net/Gaodes/article/details/81775882
  • Loading branch information
774639008 committed Aug 26, 2018
1 parent 4b2daf6 commit 2129384
Show file tree
Hide file tree
Showing 10 changed files with 1,532 additions and 0 deletions.
189 changes: 189 additions & 0 deletions irq.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
#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);
}





109 changes: 109 additions & 0 deletions irq.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#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

Loading

1 comment on commit 2129384

@774639008
Copy link
Owner Author

@774639008 774639008 commented on 2129384 Aug 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

关于上面驱动的博客地址:
C语言驱动之配置中断(基于S3C2440开发板)(https://blog.csdn.net/Gaodes/article/details/81776138)
C语言驱动之配置触摸屏(基于S3C2440开发板)(https://blog.csdn.net/Gaodes/article/details/81775993)
C语言驱动之配置RTC(基于S3C2440开发板)(https://blog.csdn.net/Gaodes/article/details/81775961)
C语言驱动之配置串口(基于S3C2440开发板)(https://blog.csdn.net/Gaodes/article/details/81775919)
C语言驱动之配置LCD(基于S3C2440开发板)(https://blog.csdn.net/Gaodes/article/details/81775882)

Please sign in to comment.