您现在的位置: 主页 > MCU > 单片机技术应用 > s3c2410 4X4矩阵键盘驱动 -
本文所属标签:
为本文创立个标签吧:

s3c2410 4X4矩阵键盘驱动 -

来源: 网络用户发布,如有版权联系网管删除 2018-09-06 

[导读]//驱动代码如下.主设备号设为232 ,适用GEC2410 十六键矩阵键盘#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #includ

//驱动代码如下.主设备号设为232 ,适用GEC2410 十六键矩阵键盘

本文引用地址: http://www.21ic.com/app/mcu/201808/784823.htm

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define S3C2410_GPG11 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 11) // S3C2410_GPG11 undefined in regs-gpio.h


#define DEVICE_NAME "matrix_button"
#define BUTTON_MAJOR 232

unsigned int s3c2410_gpio_getpin(unsigned int pin)
{
unsigned long base = S3C2410_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
return __raw_readl(base + 0x04) & (1<< offs);
}

void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
{
unsigned long base = S3C2410_GPIO_BASE(pin);
unsigned long mask;
unsigned long con;
unsigned long flags;
if(pin mask=1< else
mask =3<< (S3C2410_GPIO_OFFSET(pin)*2);
local_irq_save(flags);

con = __raw_readl(base + 0x00);

con &= ~mask;
con |= function;

__raw_writel(con, base + 0x00);

local_irq_restore(flags);
}

void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
{
unsigned long base = S3C2410_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
unsigned long flags;
unsigned long dat;

local_irq_save(flags);

dat = __raw_readl(base + 0x04);
dat &= ~(1 << offs);
dat |= to << offs;
__raw_writel(dat, base + 0x04);

local_irq_restore(flags);
}

#define EXTINT_OFF (IRQ_EINT4 - 4)

// clear SRCPND&INTPND
void s3c_irq_ack(unsigned int irqno)
{
unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
__raw_writel(bitval, S3C2410_SRCPND);
__raw_writel(bitval, S3C2410_INTPND);
return;
}
void s3c_irqext_ack(unsigned int irqno)
{
unsigned long req;
unsigned long bit;
bit = 1UL << (irqno - EXTINT_OFF);
__raw_writel(bit, S3C2410_EINTPEND);
req = __raw_readl(S3C2410_EINTPEND);
if (irqno <= IRQ_EINT7 )
{
if ((req & 0xf0) == 0)
s3c_irq_ack(IRQ_EINT4t7);
}
else
{
if ((req >> 8) == 0)
s3c_irq_ack(IRQ_EINT8t23);
}
return;
}


// set external interrupt mode, trigger type and gpio registers
int realarm_interrupt_init(unsigned int irq, unsigned int type)
{
unsigned long gpcon_reg;
unsigned long gpcon_offset;
unsigned long extint_reg;
unsigned long extint_offset;
unsigned long newvalue = 0;
unsigned long value;
if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3))
{
gpcon_reg = S3C2410_GPFCON;
extint_reg = S3C2410_EXTINT0;
gpcon_offset = (irq - IRQ_EINT0) * 2;
extint_offset = (irq - IRQ_EINT0) * 4;
}
else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7))
{
gpcon_reg = S3C2410_GPFCON;
extint_reg = S3C2410_EXTINT0;
gpcon_offset = (irq - EXTINT_OFF) * 2;
extint_offset = (irq - EXTINT_OFF) * 4;
}
else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
{
gpcon_reg = S3C2410_GPGCON;
extint_reg = S3C2410_EXTINT1;
gpcon_offset = (irq - IRQ_EINT8) * 2;
extint_offset = (irq - IRQ_EINT8) * 4;
}
else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23))
{
gpcon_reg = S3C2410_GPGCON;
extint_reg = S3C2410_EXTINT2;
gpcon_offset = (irq - IRQ_EINT8) * 2;
extint_offset = (irq - IRQ_EINT16) * 4;
} else
{
return -1;
}
/* Set the GPIO to external interrupt mode */
value = __raw_readl(gpcon_reg);
value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
__raw_writel(value, gpcon_reg);
/* Set the external interrupt to pointed trigger type */
switch (type)
{
case IRQT_NOEDGE:
printk(KERN_WARNING "No edge setting!\n");
break;
case IRQT_RISING:
newvalue = S3C2410_EXTINT_RISEEDGE;
break;
case IRQT_FALLING:
newvalue = S3C2410_EXTINT_FALLEDGE;
break;
case IRQT_BOTHEDGE:
newvalue = S3C2410_EXTINT_BOTHEDGE;
break;
case IRQT_LOW:
newvalue = S3C2410_EXTINT_LOWLEV;
break;
case IRQT_HIGH:
newvalue = S3C2410_EXTINT_HILEV;
break;
default:
printk(KERN_ERR "No such irq type %d", type);
return -1;
}
value = __raw_readl(extint_reg);
value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
__raw_writel(value, extint_reg);
return 0;
}

static struct key_info {
int irq_no;
unsigned int gpio_port;
int function_inp;
int function_eintn;
}key_info_tab[4]={
{ IRQ_EINT0, S3C2410_GPF0,S3C2410_GPF0_INP,S3C2410_GPF0_EINT0},
{ IRQ_EINT2, S3C2410_GPF2,S3C2410_GPF2_INP,S3C2410_GPF2_EINT2},
{ IRQ_EINT11,S3C2410_GPG3,S3C2410_GPG3_INP,S3C2410_GPG3_EINT11 },
{ IRQ_EINT19,S3C2410_GPG11,S3C2410_GPG11_INP,S3C2410_GPG11_EINT19}};

struct matrix_button
{
int key_value;
int ready;
int open_count;
wait_queue_head_t buttons_wait;
struct cdev cdev;
struct semaphore sem;
};

static struct matrix_button* matrix_button_dev;

static struct output_pin
{
unsigned int gpio_pin;
int function_outp;
}output_pin_tab[4]={
{S3C2410_GPE11,S3C2410_GPE11_OUTP},
{S3C2410_GPG6,S3C2410_GPG6_OUTP},
{S3C2410_GPE13,S3C2410_GPE13_OUTP},
{S3C2410_GPG2,S3C2410_GPG2_OUTP}
};

static int key_scan(void)
{

int i,j,k,ret=0;
for(i=0;i<4;i++)
{

for(j=0;j<4;j++)
{
if(i==j)s3c2410_gpio_setpin(output_pin_tab[j].gpio_pin,0);
else s3c2410_gpio_setpin(output_pin_tab[j].gpio_pin,1);
}
for(k=0;k<4;k++)
{
if(s3c2410_gpio_getpin(key_info_tab[k].gpio_port)==0)
{
ret=i*10+k+1;
return ret;
}
}
}
return ret;
}



              查看评论 回复



嵌入式交流网主页 > MCU > 单片机技术应用 > s3c2410 4X4矩阵键盘驱动 -
 

"s3c2410 4X4矩阵键盘驱动 -"的相关文章

网站地图

围观()